1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gscg.gameactors;
15
16 import java.io.IOException;
17 import java.io.ObjectOutputStream;
18 import java.io.Serializable;
19 import java.net.URL;
20 import java.rmi.RemoteException;
21 import java.util.HashSet;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Properties;
25 import java.util.Set;
26
27 import javax.vecmath.Point3d;
28
29 import nl.tudelft.simulation.actor.messagehandlers.HandleAllMessages;
30 import nl.tudelft.simulation.actor.messagehandlers.MessageHandlerInterface;
31 import nl.tudelft.simulation.dsol.experiment.TimeUnit;
32 import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
33 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
34 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
35 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
36 import nl.tudelft.simulation.dsol.statistics.charts.XYChart;
37 import nl.tudelft.simulation.event.Event;
38 import nl.tudelft.simulation.event.EventInterface;
39 import nl.tudelft.simulation.event.EventType;
40 import nl.tudelft.simulation.jstats.distributions.DistConstant;
41 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
42 import nl.tudelft.simulation.jstats.streams.StreamInterface;
43 import nl.tudelft.simulation.language.io.URLResource;
44 import nl.tudelft.simulation.logger.Logger;
45 import nl.tudelft.simulation.messaging.devices.reference.FaxDevice;
46 import nl.tudelft.simulation.supplychain.actor.SupplyChainActor;
47 import nl.tudelft.simulation.supplychain.actor.Trader;
48 import nl.tudelft.simulation.supplychain.banking.Bank;
49 import nl.tudelft.simulation.supplychain.banking.BankAccount;
50 import nl.tudelft.simulation.supplychain.content.Bill;
51 import nl.tudelft.simulation.supplychain.content.Content;
52 import nl.tudelft.simulation.supplychain.content.InternalDemand;
53 import nl.tudelft.simulation.supplychain.content.Order;
54 import nl.tudelft.simulation.supplychain.content.OrderBasedOnQuote;
55 import nl.tudelft.simulation.supplychain.content.OrderConfirmation;
56 import nl.tudelft.simulation.supplychain.content.Payment;
57 import nl.tudelft.simulation.supplychain.content.Quote;
58 import nl.tudelft.simulation.supplychain.content.RequestForQuote;
59 import nl.tudelft.simulation.supplychain.product.Product;
60 import nl.tudelft.simulation.supplychain.roles.Role;
61 import nl.tudelft.simulation.supplychain.stock.StockInterface;
62 import nl.tudelft.simulation.supplychain.stock.StockUpdateData;
63 import nl.tudelft.simulation.supplychain.transport.TransportMode;
64
65 import org.gscg.common.GameActorInterface;
66 import org.gscg.common.gui.exceptions.ReceivedUnknownEventException;
67 import org.gscg.common.interactionlayer.AnnounceInterface;
68 import org.gscg.common.interactionlayer.timecontrol.GlobalRowOrColumnNumber;
69 import org.gscg.experiment.HandlerParser;
70 import org.gscg.game.GameGlobalData;
71 import org.gscg.singleuser.handlers.InteractiveOrderHandlerStock;
72 import org.gscg.singleuser.interactionlayer.SingleUserInteractionLayerInterface;
73 import org.gscg.singleuser.interactionlayer.business.statistics.CustomerStatistics;
74 import org.gscg.singleuser.interactionlayer.dataobjects.DateIntData;
75 import org.gscg.singleuser.interactionlayer.dataobjects.content.BillData;
76 import org.gscg.singleuser.interactionlayer.dataobjects.content.QuoteData;
77 import org.gscg.singleuser.interactionlayer.dataobjects.content.RFQData;
78 import org.gscg.singleuser.interactionlayer.dataobjects.content.RFQDataSuppliers;
79 import org.gscg.singleuser.interactionlayer.dataobjects.content.SentOrderConfirmationData;
80 import org.gscg.singleuser.interactionlayer.dataobjects.content.SentQuoteData;
81 import org.jdom.Element;
82
83 /***
84 * The GameDistributorInteractive extends a GameDistributor from the
85 * supplychain-game project and provides additional interactive functionalities.
86 * <br>
87 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
88 * Delft, the Netherlands. All rights reserved.
89 *
90 * See for project information <a href="http://www.simulation.tudelft.nl/">
91 * www.simulation.tudelft.nl </a>.
92 *
93 * The source code and binary code of this software is proprietary information
94 * of Delft University of Technology.
95 *
96 * @author <a
97 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
98 * Verbraeck </a>
99 * @version $Revision: 1.3 $ $Date: 2005/08/10 11:23:30 $
100 * @since 1.0.0 <br>
101 */
102
103 public class GameManufacturerInteractive extends GameManufacturer implements
104 GameActorInteractiveInterface, GameActorInterface, AnnounceInterface
105 {
106 /*** the map with manufacturers after deserialization */
107 private static Set manufacturers = new HashSet();
108
109 /***
110 * @return returns the set with manufacturers of which the interactivity
111 * mode has changed after deseriliazation due to changes in the
112 * manufacturer.properties file
113 */
114 public static Set getChangedManufacturers()
115 {
116 return GameManufacturerInteractive.manufacturers;
117 }
118
119 /*** the serial version uid */
120 private static final long serialVersionUID = 13L;
121
122 /*** a client has sent an RFQ which forms the basis for a quote */
123 public static final EventType RFQ_SENT_BY_CLIENT_EVENT = new EventType(
124 "RFQ_SENT_BY_CLIENT_EVENT");
125
126 /*** a client has selected a quote which forms the basis for an order */
127 public static final EventType SELECTED_QUOTE_EVENT = new EventType(
128 "SELECTED_QUOTE_EVENT");
129
130 /*** a client has selected a bill to pay */
131 public static final EventType PAY_BILL_EVENT = new EventType(
132 "PAY_BILL_EVENT");
133
134 /*** a client has selected an rfq and sent a quote */
135 public static final EventType QUOTE_SENT_BY_CLIENT_EVENT = new EventType(
136 "QUOTE_SENT_BY_CLIENT_EVENT");
137
138 /*** a client has deleted an rfq */
139 public static final EventType RFQ_DELETED_BY_CLIENT_EVENT = new EventType(
140 "RFQ_DELETED_BY_CLIENT_EVENT");
141
142 /*** a client has confirmed an order */
143 public static final EventType ORDER_CONFIRMATION_SENT_BY_CLIENT_EVENT = new EventType(
144 "ORDER_CONFIRMATION_SENT_BY_CLIENT_EVENT");
145
146 /*** events fired by client */
147 private EventType[] eventsSentByClientArray = {
148 GameManufacturerInteractive.ORDER_CONFIRMATION_SENT_BY_CLIENT_EVENT,
149 GameManufacturerInteractive.RFQ_SENT_BY_CLIENT_EVENT,
150 GameManufacturerInteractive.SELECTED_QUOTE_EVENT,
151 GameManufacturerInteractive.PAY_BILL_EVENT,
152 GameManufacturerInteractive.QUOTE_SENT_BY_CLIENT_EVENT,
153 GameManufacturerInteractive.RFQ_DELETED_BY_CLIENT_EVENT};
154
155 /*** the SingleUserInteractionLayerInterface */
156 private SingleUserInteractionLayerInterface singleUserInteractionLayer;
157
158 /***
159 * constructs a new GameDistributorInteractive; used when dragging and
160 * dropping an actor
161 *
162 * @param name the name
163 * @param simulator the simulator
164 * @param position the position
165 * @param bank the bank
166 */
167 public GameManufacturerInteractive(final String name,
168 final DEVSSimulatorInterface simulator, final Point3d position,
169 final Bank bank)
170 {
171 super(name, simulator, position, bank);
172 }
173
174 /***
175 * constructs a new GameDistributorInteractive
176 *
177 * @param globalSupplyChainData the global supply chain data
178 * @param name the name
179 * @param simulator the simulator
180 * @param position the position
181 * @param roles the roles to implement
182 * @param bank the bank
183 * @param initialBankAccount the initial bank account
184 * @param product the product
185 * @param amount the amount
186 * @param suppliers the suppliers
187 */
188 public GameManufacturerInteractive(
189 final GameGlobalData globalSupplyChainData, final String name,
190 final DEVSSimulatorInterface simulator, final Point3d position,
191 final Role[] roles, final Bank bank,
192 final double initialBankAccount, final Product[] product,
193 final Double[] amount, final Trader[] suppliers)
194 {
195 super(name, simulator, position, roles, bank, initialBankAccount,
196 product, amount, globalSupplyChainData, suppliers);
197 }
198
199 /***
200 * constructs a new GameDistributorInteractive
201 *
202 * @param globalSupplyChainData the global supply chain data
203 * @param name the name
204 * @param simulator the simulator
205 * @param position the position
206 * @param roles the roles to implement
207 * @param bank the bank
208 * @param product the product
209 * @param amount the amount
210 * @param suppliers the suppliers
211 */
212 public GameManufacturerInteractive(
213 final GameGlobalData globalSupplyChainData, final String name,
214 final DEVSSimulatorInterface simulator, final Point3d position,
215 final Role[] roles, final Bank bank, final Product[] product,
216 final Double[] amount, final Trader[] suppliers)
217 {
218 super(name, simulator, position, roles, bank, product, amount,
219 globalSupplyChainData, suppliers);
220 }
221
222 /***
223 * @see org.gscg.gameactors.GameManufacturer#init()
224 */
225 protected void init()
226 {
227
228
229
230
231 Properties properties = new Properties();
232 try
233 {
234 properties.load(URLResource
235 .getResourceAsStream("/manufacturer.properties"));
236 } catch (Exception exception)
237 {
238 exception.printStackTrace();
239 }
240 if (properties.getProperty(this.name) != null)
241 {
242 String result = properties.getProperty(this.name);
243 if (result.equalsIgnoreCase("false"))
244 {
245 super.humanControlled = false;
246 Logger.info(this, "init", "GameManufacturerInteractive: "
247 + this.name + " set to computer-controlled mode");
248 this.addComputerControlledContentHandlers();
249 } else if (result.equalsIgnoreCase("true"))
250 {
251 try
252 {
253 if (this.simulator.getReplication().getRunControl()
254 .getWarmupPeriod() > 0.0)
255 {
256
257
258
259
260
261 this.simulator.addListener(this,
262 SimulatorInterface.WARMUP_EVENT);
263 super.humanControlled = false;
264 super.warmingUp = true;
265 Logger
266 .info(
267 this,
268 "init",
269 "GameManufacturerInteractive: "
270 + this.name
271 + " set to computer-controlled mode due to the presence of a warm-up period.");
272 this.addComputerControlledContentHandlers();
273 } else
274 {
275 super.humanControlled = true;
276 Logger.info(this, "init",
277 "GameManufacturerInteractive: " + this.name
278 + " set to interactive mode");
279 this.addInteractiveContentHandlers();
280 }
281 } catch (RemoteException remoteException)
282 {
283 Logger.severe(this, "init", remoteException);
284 }
285 }
286 } else
287 {
288
289 Logger.severe(this, "init",
290 "GameManufacturerInteractive: no key found for "
291 + this.name + " in properties: ." + properties);
292 }
293
294
295
296
297 try
298 {
299 if (this.simulator instanceof AnimatorInterface)
300 {
301 XYChart bankChart = new XYChart(this.simulator, "BankAccount "
302 + this.name);
303 bankChart.add("bank account", this.bankAccount,
304 BankAccount.BANK_ACCOUNT_CHANGED_EVENT);
305 }
306 } catch (RemoteException remoteException)
307 {
308 Logger.severe(this, "init", remoteException);
309 }
310 }
311
312 /***
313 * @see org.gscg.gameactors.GameManufacturer#addDevices()
314 */
315 protected void addDevices()
316 {
317 try
318 {
319 StreamInterface stream = this.simulator.getReplication().getStream(
320 "default");
321 double hour = TimeUnit.convert(1.0, TimeUnitInterface.HOUR,
322 this.simulator);
323 DistContinuous hourDist = new DistConstant(stream, hour);
324
325 FaxDevice fax = new FaxDevice("GameManufacturerFax", this.simulator);
326 addSendingDevice(fax);
327 MessageHandlerInterface secretary = new HandleAllMessages(this);
328 addReceivingDevice(fax, secretary, hourDist);
329 } catch (RemoteException remoteException)
330 {
331 Logger.severe(this, "addDevices", remoteException);
332 }
333 }
334
335 /***
336 * @see org.gscg.common.interactionlayer.AnnounceInterface#announce(nl.tudelft.simulation.event.EventType,
337 * boolean)
338 */
339 public void announce(final EventType eventType, final boolean announce)
340 {
341 if (eventType.equals(StockInterface.STOCK_CHANGE_EVENT))
342 {
343 List products = super.getProductsOnStock();
344 for (int i = 0; i < products.size(); i++)
345 {
346 Product product = (Product) products.get(i);
347 this.stock.getActualAmount(product);
348 StockUpdateData data = new StockUpdateData(product.getName(),
349 this.stock.getActualAmount(product), this.stock
350 .getClaimedAmount(product), this.stock
351 .getOrderedAmount(product));
352 try
353 {
354 this.singleUserInteractionLayer.notifyAnnounced(new Event(
355 StockInterface.STOCK_CHANGE_EVENT, this, data));
356 } catch (RemoteException remoteException)
357 {
358 Logger.severe(this, "announce", remoteException);
359 }
360 }
361 return;
362 }
363 new ReceivedUnknownEventException(this, "announce", eventType);
364 }
365
366 /***
367 * @see nl.tudelft.simulation.event.EventListenerInterface#notify(nl.tudelft.simulation.event.EventInterface)
368 */
369 public void notify(final EventInterface event)
370 {
371 if (event.getType().equals(GlobalRowOrColumnNumber.UPDATE_CURRENT_DAY))
372 {
373
374 this.sendStockUpdateEvent();
375 this.bankAccount.sendBalanceUpdateEvent();
376 return;
377 }
378 if (event.getType().equals(
379 GameManufacturerInteractive.RFQ_SENT_BY_CLIENT_EVENT))
380 {
381
382 RFQDataSuppliers submitRFQData = (RFQDataSuppliers) event
383 .getContent();
384 Product product = this.globalSupplyChainData
385 .getProduct(submitRFQData.getProductName());
386 double earliestDeliveryDate = DateIntData.makeSimulationDate(
387 submitRFQData.getEarliestDelivery(), this.simulator);
388
389 double latestDeliveryDate = DateIntData.makeSimulationDate(
390 submitRFQData.getLatestDelivery(), this.simulator);
391
392
393 try
394 {
395 if (earliestDeliveryDate > this.simulator.getSimulatorTime())
396 {
397 InternalDemand internalDemand = new InternalDemand(this,
398 product, submitRFQData.getAmount(),
399 earliestDeliveryDate, latestDeliveryDate);
400 String[] suppliers = submitRFQData.getSuppliers();
401 handleContent(internalDemand);
402
403 for (int i = 0; i < suppliers.length; i++)
404 {
405 SupplyChainActor supplier = this.globalSupplyChainData
406 .getSupplyChainActor(suppliers[i]);
407 RequestForQuote rfq = new RequestForQuote(this,
408 supplier, internalDemand, product,
409 submitRFQData.getAmount());
410 this.sendContent(rfq, 0.0);
411 }
412 } else
413 {
414 Logger
415 .info(
416 this,
417 "notify",
418 "GameManufacturerInteractive did not send RFQ since the earliest delivery date has already been passed in the game.");
419 }
420 } catch (RemoteException remoteException)
421 {
422 Logger.severe(this, "notify", remoteException);
423 }
424 return;
425 }
426 if (event.getType().equals(
427 GameManufacturerInteractive.SELECTED_QUOTE_EVENT))
428 {
429 QuoteData data = (QuoteData) event.getContent();
430
431
432 SupplyChainActor sender = this.globalSupplyChainData
433 .getSupplyChainActor(data.getSenderName());
434 try
435 {
436 double proposedDeliveryDate = DateIntData.makeSimulationDate(
437 data.getProposedDelivery(), this.simulator);
438
439 List quotes = super.getGameContentStore().getContentList(
440 data.getRfqData().getInternalDemandIdentifier(),
441 Quote.class, false);
442 OrderBasedOnQuote order = null;
443 for (int i = 0; i < quotes.size(); i++)
444 {
445 Quote quote = (Quote) quotes.get(i);
446 if (quote.getSender().getName().equalsIgnoreCase(
447 sender.getName()))
448 {
449 order = new OrderBasedOnQuote(quote.getReceiver(),
450 quote.getSender(), data.getRfqData()
451 .getInternalDemandIdentifier(),
452 proposedDeliveryDate, quote);
453 break;
454 }
455 }
456
457
458
459
460 if (order != null)
461 {
462 super.interactiveQuoteHandler.addAnsweredQuote(order
463 .getQuote());
464 }
465
466 this.sendContent(order, 0.0);
467
468
469 for (int i = 0; i < quotes.size(); i++)
470 {
471 super.getGameContentStore().removeContent(
472 (Content) quotes.get(i), false);
473 }
474 } catch (Exception exception)
475 {
476 Logger.severe(this, "notify", exception);
477 }
478 return;
479 }
480 if (event.getType().equals(GameManufacturerInteractive.PAY_BILL_EVENT))
481 {
482 BillData data = (BillData) event.getContent();
483 Bill bill = (Bill) super.getGameContentStore().getContentList(
484 data.getInternalDemandID(), Bill.class, false).get(0);
485 if (bill == null)
486 {
487 Logger.severe(this, "notify PAY_BILL_EVENT",
488 "bill not found in ContentStore");
489 } else
490 {
491
492 this.pay(bill);
493
494
495 Payment payment = new Payment(bill.getReceiver(), bill
496 .getSender(), bill.getInternalDemandID(), bill, bill
497 .getPrice());
498 this.sendContent(payment, 0.0);
499 }
500 return;
501 }
502 if (event.getType().equals(
503 GameManufacturerInteractive.QUOTE_SENT_BY_CLIENT_EVENT))
504 {
505 SentQuoteData data = (SentQuoteData) event.getContent();
506 try
507 {
508 SupplyChainActor sender = this.globalSupplyChainData
509 .getSupplyChainActor(data.getSenderName());
510 SupplyChainActor receiver = this.globalSupplyChainData
511 .getSupplyChainActor(data.getReceiverName());
512
513
514 List rfqs = super.getGameContentStore().getContentList(
515 data.getRfqData().getInternalDemandIdentifier(),
516 RequestForQuote.class, false);
517 RequestForQuote rfq = null;
518 for (int i = 0; i < rfqs.size(); i++)
519 {
520 RequestForQuote result = (RequestForQuote) rfqs.get(i);
521 if (result.getReceiver().getName().equalsIgnoreCase(
522 sender.getName()))
523 {
524 rfq = result;
525 break;
526 }
527 }
528
529 double proposedDeliveryDate = DateIntData.makeSimulationDate(
530 data.getProposedDelivery(), this.simulator);
531
532 if (proposedDeliveryDate > this.simulator.getSimulatorTime())
533 {
534 double price = data.getPrice();
535
536 double weight = rfq.getAmount()
537 * rfq.getProduct().getAverageUnitWeight();
538
539
540 double transportCosts = TransportMode.PLANE.transportCosts(
541 super.latLonDistanceCalculator.getDistance(rfq
542 .getSender(), rfq.getReceiver()), weight);
543
544
545 price += transportCosts;
546
547 Quote quote = new Quote(sender, receiver, data.getRfqData()
548 .getInternalDemandIdentifier(), rfq, rfq
549 .getProduct(), data.getAmount(), price,
550 proposedDeliveryDate, TransportMode.PLANE);
551 this.sendContent(quote, 0.0);
552 } else
553 {
554 Logger
555 .info(
556 this,
557 "notify",
558 "GameManufacturerInteractive did not send Quote since the proposed delivery date has already been passed in the game. The accompanying rfq has been deleted.");
559
560
561 super.getGameContentStore().removeContent(rfq, false);
562 }
563 } catch (Exception exception)
564 {
565 Logger.severe(this, "notify", exception);
566 }
567 return;
568 }
569 if (event.getType().equals(
570 GameManufacturerInteractive.RFQ_DELETED_BY_CLIENT_EVENT))
571 {
572 RFQData data = (RFQData) event.getContent();
573 try
574 {
575 SupplyChainActor receiver = this.globalSupplyChainData
576 .getSupplyChainActor(data.getReceiverName());
577
578
579 List rfqs = super.getGameContentStore().getContentList(
580 data.getInternalDemandIdentifier(),
581 RequestForQuote.class, false);
582 RequestForQuote rfq = null;
583 for (int i = 0; i < rfqs.size(); i++)
584 {
585 RequestForQuote result = (RequestForQuote) rfqs.get(i);
586 if (result.getReceiver().getName().equalsIgnoreCase(
587 receiver.getName()))
588 {
589 rfq = result;
590 break;
591 }
592 }
593
594
595 super.getGameContentStore().removeContent(rfq, false);
596 } catch (Exception exception)
597 {
598 Logger.severe(this, "notify", exception);
599 }
600 return;
601
602 }
603 if (event
604 .getType()
605 .equals(
606 GameManufacturerInteractive.ORDER_CONFIRMATION_SENT_BY_CLIENT_EVENT))
607 {
608 SentOrderConfirmationData data = (SentOrderConfirmationData) event
609 .getContent();
610 try
611 {
612 SupplyChainActor sender = this.globalSupplyChainData
613 .getSupplyChainActor(data.getSenderName());
614 SupplyChainActor receiver = this.globalSupplyChainData
615 .getSupplyChainActor(data.getReceiverName());
616 Order order = (Order) super.getGameContentStore()
617 .getContentList(
618 data.getOrderData().getInternalDemandID(),
619 Order.class, false).get(0);
620 if (order == null)
621 {
622 Logger.severe(this,
623 "notify ORDER_CONFIRMATION_SENT_BY_CLIENT_EVENT",
624 "order not found in ContentStore");
625 } else
626 {
627 OrderConfirmation confirmation = new OrderConfirmation(
628 sender, receiver, data.getOrderData()
629 .getInternalDemandID(), order, data
630 .getConfirmationStatus());
631
632 this.sendContent(confirmation, 0.0);
633 InteractiveOrderHandlerStock handler = new InteractiveOrderHandlerStock(
634 this, super.stock);
635 handler.handleOrder(order);
636
637
638 super.customerStatistics.handleContent(confirmation);
639 }
640 return;
641 } catch (Exception exception)
642 {
643 Logger.severe(this, "notify", exception);
644 }
645 return;
646 }
647 if (event.getType().equals(SimulatorInterface.WARMUP_EVENT))
648 {
649 super.humanControlled = true;
650 super.warmingUp = false;
651 Logger
652 .info(
653 this,
654 "init",
655 "GameManufacturerInteractive: "
656 + this.name
657 + " set to interactive mode since the warm-up period has been finished");
658 this.addInteractiveContentHandlers();
659 return;
660 }
661 new ReceivedUnknownEventException(this, "notify", event.getType());
662 }
663
664 /***
665 * pays the bill
666 *
667 * @param bill the bill to pay
668 */
669 public void pay(final Bill bill)
670 {
671 this.bankAccount.withdrawFromBalance(bill.getPrice());
672 }
673
674 /***
675 * @see nl.tudelft.simulation.content.HandlerInterface#handleContent(java.io.Serializable)
676 */
677 public boolean handleContent(final Serializable content)
678 {
679 try
680 {
681 if (super.humanControlled)
682 {
683 if (content instanceof Quote)
684 {
685
686 if (super.interactiveQuoteHandler.handleContent(content))
687 {
688
689 super.getContentStore().addContent((Content) content,
690 false);
691 }
692 return true;
693 }
694 }
695 return super.handleContent(content);
696 } catch (Exception exception)
697 {
698 Logger.severe(this, "handleContent", exception);
699 return false;
700 }
701 }
702
703 /***
704 * @see nl.tudelft.simulation.supplychain.actor.SupplyChainActor#sendContent(nl.tudelft.simulation.supplychain.content.Content,
705 * double)
706 */
707 public void sendContent(final Content content,
708 final double administrativeDelay)
709 {
710 super.sendContent(content, administrativeDelay);
711 }
712
713 /***
714 * @see org.gscg.gameactors.GameActorInteractiveInterface#getSingleUserInteractionLayer()
715 */
716 public SingleUserInteractionLayerInterface getSingleUserInteractionLayer()
717 {
718 return this.singleUserInteractionLayer;
719 }
720
721 /***
722 * @see org.gscg.gameactors.GameActorInteractiveInterface#setSingleUserInteractionLayer(org.gscg.singleuser.interactionlayer.SingleUserInteractionLayerInterface)
723 */
724 public void setSingleUserInteractionLayer(
725 final SingleUserInteractionLayerInterface singleUserInteractionLayer)
726 {
727 this.singleUserInteractionLayer = singleUserInteractionLayer;
728 getGameContentStore().setSingleUserInteractionlayer(
729 this.singleUserInteractionLayer);
730
731 try
732 {
733 for (int i = 0; i < this.eventsSentByClientArray.length; i++)
734 {
735 this.singleUserInteractionLayer.addListener(this,
736 this.eventsSentByClientArray[i], false);
737
738 this.singleUserInteractionLayer
739 .addEventTypeSentByClient(this.eventsSentByClientArray[i]);
740
741 }
742
743
744
745 singleUserInteractionLayer.addEventTypeToAnnounceList(
746 StockInterface.STOCK_CHANGE_EVENT, this);
747
748
749
750
751
752
753 this.singleUserInteractionLayer.addListener(this,
754 GlobalRowOrColumnNumber.UPDATE_CURRENT_DAY);
755 } catch (RemoteException remoteException)
756 {
757 Logger.severe(this, "<init>", remoteException);
758 }
759
760
761
762
763 this.customerStatistics = new CustomerStatistics(this.simulator,
764 this.singleUserInteractionLayer);
765 }
766
767 /***
768 * adds computer-controlled interactive content handlers
769 */
770 public void addComputerControlledContentHandlers()
771 {
772 super.addComputerControlledContentHandlers();
773 }
774
775 /***
776 * adds interactive content handlers
777 */
778 public void addInteractiveContentHandlers()
779 {
780
781 this.removeAllContentHandlers();
782
783
784 URL url = URLResource.getResource("/" + this.name + "_interactive.xml");
785 if (url == null)
786 {
787 url = URLResource
788 .getResource("/manufacturer_interactive_default_handler.xml");
789 }
790 Logger
791 .info(
792 this,
793 "addInteractiveContentHandlers",
794 "Using: "
795 + url.toExternalForm()
796 + " as the file containing the configuration for the handlers.");
797 try
798 {
799
800 Element rootElement = GameManufacturer.builder.build(url)
801 .getRootElement();
802 HandlerParser.parseAndAddHandler(this, rootElement);
803 } catch (Exception exception)
804 {
805 Logger.severe(this, "addInteractiveContentHandlers", exception);
806 }
807 }
808
809
810 /***
811 * Method sendStockUpdateEvent fires an update for all the products
812 * available in the stock
813 */
814 private void sendStockUpdateEvent()
815 {
816 for (Iterator i = this.stock.iterator(); i.hasNext();)
817 {
818 this.stock.sendStockUpdateEvent((Product) i.next());
819 }
820 }
821
822 /***
823 * writes a serializable method to stream
824 *
825 * @param out the outputstream
826 * @throws IOException on IOException
827 */
828 private synchronized void writeObject(final ObjectOutputStream out)
829 throws IOException
830 {
831 out.defaultWriteObject();
832 }
833
834 /***
835 * reads a serializable method from stream
836 *
837 * @param in the inputstream
838 */
839 private synchronized void readObject(final java.io.ObjectInputStream in)
840 {
841 try
842 {
843 in.defaultReadObject();
844
845
846
847
848 Properties properties = new Properties();
849 try
850 {
851 properties.load(URLResource
852 .getResourceAsStream("/manufacturer.properties"));
853 } catch (Exception exception)
854 {
855 exception.printStackTrace();
856 }
857 if (properties.getProperty(this.name) != null)
858 {
859 String result = properties.getProperty(this.name);
860 if (result.equalsIgnoreCase("false"))
861 {
862
863
864
865
866
867 if (super.humanControlled)
868 {
869 GameManufacturerInteractive.manufacturers.add(this);
870 super.humanControlled = false;
871 System.out
872 .println("GameManufacturerInteractive: "
873 + this.name
874 + ": mode has been changed to computer-controlled mode");
875 }
876 } else if (result.equalsIgnoreCase("true"))
877 {
878
879
880
881
882
883
884 if (!super.humanControlled && !super.warmingUp)
885 {
886 System.out
887 .println("GameManufacturerInteractive: Deserializing: "
888 + this + " warm-up finished");
889 GameManufacturerInteractive.manufacturers.add(this);
890 super.humanControlled = true;
891 System.out
892 .println("GameManufacturerInteractive: "
893 + this.name
894 + ": mode has been changed to interactive mode");
895 } else if (!super.humanControlled)
896 {
897 System.out.println("Deserializing: " + this
898 + " however warm-up not finished yet");
899 }
900 }
901 } else
902 {
903
904 System.out
905 .println("GameManufacturerInteractive: no key found for "
906 + this.name + " in properties.");
907 }
908 } catch (IOException exception)
909 {
910 Logger.severe(this, "readObject", exception);
911 } catch (ClassNotFoundException exception)
912 {
913 Logger.severe(this, "readObject", exception);
914 }
915 }
916 }