Copy cat > /tmp/Lab15.java << 'JAVAEOF'
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.function.*;
import java.util.stream.*;
public class Lab15 {
// Domain: sealed event hierarchy
sealed interface Event permits Event.OrderPlaced, Event.PaymentReceived, Event.Shipped, Event.Cancelled {
record OrderPlaced(int orderId, String product, int qty, double total) implements Event {}
record PaymentReceived(int orderId, double amount, String method) implements Event {}
record Shipped(int orderId, String trackingId, String carrier) implements Event {}
record Cancelled(int orderId, String reason) implements Event {}
}
// Records
record Product(int id, String name, String category, double price, int stock) {
Product withStock(int s) { return new Product(id, name, category, price, s); }
double value() { return price * stock; }
boolean inStock() { return stock > 0; }
}
// Enum state machine
enum OrderStatus {
PENDING(false) { @Override public OrderStatus next() { return PAID; } },
PAID(true) { @Override public OrderStatus next() { return PROCESSING; } },
PROCESSING(true){ @Override public OrderStatus next() { return SHIPPED; } },
SHIPPED(true) { @Override public OrderStatus next() { return DELIVERED; } },
DELIVERED(true) { @Override public OrderStatus next() { throw new IllegalStateException("Terminal"); } },
CANCELLED(false){ @Override public OrderStatus next() { throw new IllegalStateException("Terminal"); } };
final boolean isPaid;
OrderStatus(boolean isPaid) { this.isPaid = isPaid; }
public abstract OrderStatus next();
boolean isTerminal() { return this == DELIVERED || this == CANCELLED; }
}
// Pricing strategy enum
enum PricingTier {
STANDARD(0, 1.00), SILVER(1000, 0.95), GOLD(5000, 0.90), PLATINUM(20000, 0.80);
final double minSpend, multiplier;
PricingTier(double min, double mul) { minSpend=min; multiplier=mul; }
static PricingTier forSpend(double s) {
return Arrays.stream(values()).filter(t->s>=t.minSpend)
.max(Comparator.comparingDouble(t->t.minSpend)).orElse(STANDARD); }
double apply(double price) { return price * multiplier; }
}
record Order(int id, int productId, int qty, double total, OrderStatus status, String email) {
Order withStatus(OrderStatus s) { return new Order(id, productId, qty, total, s, email); }
}
// Thread-safe inventory
static class Inventory {
private final ConcurrentHashMap<Integer, Product> products = new ConcurrentHashMap<>();
void add(Product p) { products.put(p.id(), p); }
Optional<Product> find(int id) { return Optional.ofNullable(products.get(id)); }
synchronized boolean reserve(int id, int qty) {
var p = products.get(id);
if (p == null || p.stock() < qty) return false;
products.put(id, p.withStock(p.stock() - qty));
return true;
}
List<Product> inStock() { return products.values().stream().filter(Product::inStock).toList(); }
double totalValue() { return products.values().stream().mapToDouble(Product::value).sum(); }
}
// Event bus
static class EventBus {
private final Map<Class<?>, List<Consumer<Event>>> handlers = new ConcurrentHashMap<>();
<T extends Event> void on(Class<T> type, Consumer<T> handler) {
handlers.computeIfAbsent(type, k -> new ArrayList<>()).add(e -> handler.accept(type.cast(e))); }
void emit(Event event) {
handlers.getOrDefault(event.getClass(), List.of()).forEach(h -> h.accept(event)); }
}
// Order service
static class OrderService {
private final Inventory inventory; private final EventBus bus;
private final AtomicInteger seq = new AtomicInteger(1000);
private final Map<Integer, Order> orders = new ConcurrentHashMap<>();
OrderService(Inventory inv, EventBus bus) { this.inventory=inv; this.bus=bus; }
Optional<Order> placeOrder(int productId, int qty, String email) {
var product = inventory.find(productId)
.orElseThrow(() -> new RuntimeException("Product not found: " + productId));
if (!inventory.reserve(productId, qty)) return Optional.empty();
var tier = PricingTier.forSpend(qty * product.price());
double total = tier.apply(product.price() * qty);
var order = new Order(seq.getAndIncrement(), productId, qty, total, OrderStatus.PENDING, email);
orders.put(order.id(), order);
bus.emit(new Event.OrderPlaced(order.id(), product.name(), qty, total));
return Optional.of(order);
}
void processPayment(int orderId, double amount, String method) {
orders.computeIfPresent(orderId, (id, o) -> o.withStatus(OrderStatus.PAID));
bus.emit(new Event.PaymentReceived(orderId, amount, method));
}
void ship(int orderId) {
orders.computeIfPresent(orderId, (id, o) -> o.withStatus(OrderStatus.SHIPPED));
bus.emit(new Event.Shipped(orderId, "INZ" + orderId + "US" + (orderId*17), "FedEx"));
}
List<Order> allOrders() { return new ArrayList<>(orders.values()); }
OrderStatus status(int orderId) { return orders.get(orderId).status(); }
}
// Test helpers
static int pass=0, fail=0;
static void check(String name, boolean cond) {
if (cond) { System.out.println(" PASS: " + name); pass++; }
else { System.out.println(" FAIL: " + name); fail++; }
}
public static void main(String[] args) throws Exception {
System.out.println("=== innoZverse Order Platform Capstone ===\n");
var inv = new Inventory();
var bus = new EventBus();
var svc = new OrderService(inv, bus);
inv.add(new Product(1, "Surface Pro", "Laptop", 864.0, 20));
inv.add(new Product(2, "Surface Pen", "Accessory", 49.99, 100));
inv.add(new Product(3, "Office 365", "Software", 99.99, 500));
inv.add(new Product(4, "USB-C Hub", "Hardware", 29.99, 0));
inv.add(new Product(5, "Surface Book", "Laptop", 1299.0, 5));
var auditLog = new ArrayList<String>();
bus.on(Event.OrderPlaced.class, e -> auditLog.add("[PLACED] #"+e.orderId()+" "+e.product()+" x"+e.qty()+" $"+String.format("%.2f",e.total())));
bus.on(Event.PaymentReceived.class, e -> auditLog.add("[PAID] #"+e.orderId()+" via "+e.method()));
bus.on(Event.Shipped.class, e -> auditLog.add("[SHIP] #"+e.orderId()+" "+e.trackingId()));
System.out.println("--- Placing Orders ---");
var o1 = svc.placeOrder(1, 2, "[email protected] ");
var o2 = svc.placeOrder(2, 5, "[email protected] ");
var o3 = svc.placeOrder(4, 1, "[email protected] "); // OOS
var o4 = svc.placeOrder(5, 10, "[email protected] "); // exceeds stock
o1.ifPresent(o -> System.out.printf(" Order #%d: $%.2f %s%n", o.id(), o.total(), o.status()));
o2.ifPresent(o -> System.out.printf(" Order #%d: $%.2f %s%n", o.id(), o.total(), o.status()));
System.out.println(" USB-C Hub (OOS): " + (o3.isEmpty() ? "rejected" : "accepted"));
System.out.println(" Surface Book (10/5 stock): " + (o4.isEmpty() ? "rejected" : "accepted"));
System.out.println("\n--- Payment & Shipping ---");
o1.ifPresent(o -> { svc.processPayment(o.id(), o.total(), "credit_card"); svc.ship(o.id()); });
o2.ifPresent(o -> svc.processPayment(o.id(), o.total(), "paypal"));
System.out.println("\n--- Concurrent Orders ---");
var executor = Executors.newFixedThreadPool(4);
var concurrentReqs = List.of(new int[]{1,1}, new int[]{1,1}, new int[]{2,10},
new int[]{3,5}, new int[]{3,5}, new int[]{1,1});
var futures = concurrentReqs.stream().map(r ->
CompletableFuture.supplyAsync(() -> svc.placeOrder(r[0], r[1], "[email protected] "), executor)).toList();
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
long succeeded = futures.stream().filter(f -> f.join().isPresent()).count();
System.out.printf(" %d/%d concurrent orders succeeded%n", succeeded, concurrentReqs.size());
executor.shutdown();
// Analytics
System.out.println("\n--- Analytics ---");
var allOrders = svc.allOrders();
var byStatus = allOrders.stream().collect(Collectors.groupingBy(Order::status, Collectors.counting()));
byStatus.forEach((s,c) -> System.out.printf(" %-12s %d orders%n", s, c));
double totalRevenue = allOrders.stream().mapToDouble(Order::total).sum();
System.out.printf(" Revenue: $%,.2f | Orders: %d%n", totalRevenue, allOrders.size());
System.out.printf(" In stock: %d products | Inventory value: $%,.2f%n",
inv.inStock().size(), inv.totalValue());
System.out.println("\n--- Audit Log ---");
auditLog.forEach(l -> System.out.println(" " + l));
// Verification tests
System.out.println("\n=== Verification Tests ===");
check("Order 1 placed", o1.isPresent());
check("Order 2 placed", o2.isPresent());
check("OOS order rejected", o3.isEmpty());
check("Over-stock order rejected", o4.isEmpty());
check("Order 1 shipped", o1.map(o -> svc.status(o.id()) == OrderStatus.SHIPPED).orElse(false));
check("Order 2 paid", o2.map(o -> svc.status(o.id()) == OrderStatus.PAID).orElse(false));
check("Audit log non-empty", !auditLog.isEmpty());
check("Inventory value > 0", inv.totalValue() > 0);
check("Total revenue > 0", totalRevenue > 0);
System.out.printf("%n%d passed, %d failed%n", pass, fail);
System.out.println("\n=== Capstone Complete ===");
}
}
JAVAEOF
docker run --rm -v /tmp/Lab15.java:/tmp/Lab15.java zchencow/innozverse-java:latest sh -c "javac /tmp/Lab15.java -d /tmp && java -cp /tmp Lab15"