1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gscg.gameactors;
15
16 import java.net.URL;
17 import java.rmi.RemoteException;
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25
26 import javax.media.j3d.Bounds;
27 import javax.vecmath.Point2d;
28 import javax.vecmath.Point3d;
29
30 import nl.tudelft.simulation.actor.messagehandlers.HandleAllMessages;
31 import nl.tudelft.simulation.actor.messagehandlers.MessageHandlerInterface;
32 import nl.tudelft.simulation.content.HandlerInterface;
33 import nl.tudelft.simulation.dsol.experiment.TimeUnit;
34 import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
35 import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
36 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
37 import nl.tudelft.simulation.dsol.statistics.charts.XYChart;
38 import nl.tudelft.simulation.jstats.distributions.DistConstant;
39 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
40 import nl.tudelft.simulation.jstats.streams.StreamInterface;
41 import nl.tudelft.simulation.language.d3.BoundingBox;
42 import nl.tudelft.simulation.language.d3.DirectedPoint;
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.Content;
51 import nl.tudelft.simulation.supplychain.content.InternalDemand;
52 import nl.tudelft.simulation.supplychain.content.Order;
53 import nl.tudelft.simulation.supplychain.handlers.InternalDemandHandlerRFQ;
54 import nl.tudelft.simulation.supplychain.product.Product;
55 import nl.tudelft.simulation.supplychain.reference.Manufacturer;
56 import nl.tudelft.simulation.supplychain.roles.Role;
57 import nl.tudelft.simulation.supplychain.stock.Stock;
58
59 import org.gscg.common.GameActorInterface;
60 import org.gscg.common.geo.CalculateLatLonDistance;
61 import org.gscg.experiment.HandlerParser;
62 import org.gscg.game.GameActorContentStore;
63 import org.gscg.game.GameGlobalData;
64 import org.gscg.gameleader.animation2D.GisActorAnimation;
65 import org.gscg.singleuser.handlers.InteractiveQuoteHandler;
66 import org.gscg.singleuser.interactionlayer.business.statistics.CustomerStatistics;
67 import org.gscg.singleuser.interactionlayer.dataobjects.DateIntData;
68 import org.gscg.singleuser.interactionlayer.dataobjects.content.RFQDataSuppliers;
69 import org.jdom.Element;
70 import org.jdom.input.SAXBuilder;
71
72 /***
73 * The GameManufacturer extends a Manufacturer from the supplychain project and
74 * provides additional game-specific functionalities.
75 * <p>
76 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
77 * Delft, the Netherlands. All rights reserved.
78 *
79 * See for project information <a href="http://www.simulation.tudelft.nl/">
80 * www.simulation.tudelft.nl </a>.
81 *
82 * The source code and binary code of this software is proprietary information
83 * of Delft University of Technology.
84 *
85 * @author <a
86 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
87 * Verbraeck </a>
88 * @version $Revision: 1.4 $ $Date: 2005/08/10 11:23:30 $
89 * @since 1.0.0 <br>
90 */
91
92 public class GameManufacturer extends Manufacturer implements
93 GameActorInterface, GameInteractiveActorRoleInterface
94 {
95 /*** builder the xerces parser with validation turned on */
96 protected static SAXBuilder builder = new SAXBuilder(
97 "org.apache.xerces.parsers.SAXParser", true);
98
99 static
100 {
101
102 GameManufacturer.builder.setFeature(
103 "http://xml.org/sax/features/validation", true);
104 GameManufacturer.builder.setFeature(
105 "http://apache.org/xml/features/validation/schema", true);
106
107
108 String xsd = URLResource.getResource("/handler.xsd").toExternalForm();
109 GameManufacturer.builder
110 .setProperty(
111 "http://apache.org/xml/properties/schema/external-schemaLocation",
112 "http://www.simulation.tudelft.nl/dsol " + xsd);
113 }
114
115 /*** the serial version uid */
116 private static final long serialVersionUID = 12L;
117
118 /*** debug */
119 private static final boolean DEBUG = false;
120
121 /*** the suppliers where the GameManufacturer buys */
122 protected Trader[] suppliers;
123
124 /*** the global supply chain game data */
125 protected GameGlobalData globalSupplyChainData = null;
126
127 /*** the customer statistisc for this player */
128 protected CustomerStatistics customerStatistics = null;
129
130 /*** the special interactive quotehander */
131 protected InteractiveQuoteHandler interactiveQuoteHandler = null;
132
133 /*** if true than we use any human intervention */
134 protected boolean humanControlled = false;
135
136 /*** true for warming-up */
137 protected boolean warmingUp = false;
138
139 /*** the lat lon distance calculator to use */
140 protected CalculateLatLonDistance latLonDistanceCalculator = null;
141
142 /*** the location on the small map */
143 private DirectedPoint smallMapLocation = new DirectedPoint();
144
145 /*** the animation used for serialization */
146 private GisActorAnimation animation = null;
147
148
149 /*** the map with product names and their suppliers */
150 private Map productNameToSuppliers = null;
151
152 /***
153 * constructs a new GameManufacturer; used when dragging and dropping an
154 * actor
155 *
156 * @param name the name
157 * @param simulator the simulator
158 * @param position the position
159 * @param bank the bank
160 */
161 public GameManufacturer(final String name,
162 final DEVSSimulatorInterface simulator, final Point3d position,
163 final Bank bank)
164 {
165 super(name, simulator, position, new Role[]{}, bank);
166 this.initAnimation();
167 }
168
169 /***
170 * constructs a new GameManufacturer
171 *
172 * @param name the name
173 * @param simulator the simulator
174 * @param position the position on the map
175 * @param roles the roles to implement
176 * @param bank the bank
177 * @param product the product
178 * @param amount the amount
179 * @param globalSupplyChainData the global supply chain data
180 * @param suppliers the suppliers
181 */
182 public GameManufacturer(final String name,
183 final DEVSSimulatorInterface simulator, final Point3d position,
184 final Role[] roles, final Bank bank, final Product[] product,
185 final Double[] amount, final GameGlobalData globalSupplyChainData,
186 final Trader[] suppliers)
187 {
188 this(name, simulator, position, roles, bank, 0.0, product, amount,
189 globalSupplyChainData, suppliers);
190 }
191
192 /***
193 * constructs a new GameManufacturer
194 *
195 * @param name the name
196 * @param simulator the simulator
197 * @param position the position on the map
198 * @param roles the roles to implement
199 * @param bank the bank
200 * @param initialBankAccount the initial bank account
201 * @param product the product
202 * @param amount the amount
203 * @param globalSupplyChainData the global supply chain data
204 * @param suppliers the suppliers
205 */
206 public GameManufacturer(final String name,
207 final DEVSSimulatorInterface simulator, final Point3d position,
208 final Role[] roles, final Bank bank,
209 final double initialBankAccount, final Product[] product,
210 final Double[] amount, final GameGlobalData globalSupplyChainData,
211 final Trader[] suppliers)
212 {
213 super(name, simulator, position, roles, bank, initialBankAccount);
214 super.setContentStore(new GameActorContentStore(this, simulator));
215 this.suppliers = (Trader[]) suppliers.clone();
216 this.globalSupplyChainData = globalSupplyChainData;
217 this.latLonDistanceCalculator = new CalculateLatLonDistance();
218
219
220
221 this.productNameToSuppliers = new HashMap();
222 for (int i = 0; i < this.suppliers.length; i++)
223 {
224 Trader trader = this.suppliers[i];
225 List productsOnStock = trader.getProductsOnStock();
226 for (int ii = 0; ii < productsOnStock.size(); ii++)
227 {
228 Product productOnStock = (Product) productsOnStock.get(ii);
229 if (GameManufacturer.DEBUG)
230 {
231 System.out
232 .println("DEBUG -- GameManufacturer: <init> : supplier: "
233 + trader.getName()
234 + "has product: "
235 + productOnStock.getName() + " on stock");
236 }
237 if (!this.productNameToSuppliers.containsKey(productOnStock
238 .getName()))
239 {
240 this.productNameToSuppliers.put(productOnStock.getName(),
241 new HashSet());
242 }
243 Set set = (Set) this.productNameToSuppliers.get(productOnStock
244 .getName());
245 set.add(trader);
246 this.productNameToSuppliers.put(productOnStock.getName(), set);
247 }
248 }
249
250
251 Stock stock = new Stock(this);
252 for (int i = 0; i < product.length; i++)
253 {
254 stock.addStock(product[i], amount[i].doubleValue(), amount[i]
255 .doubleValue()
256 * product[i].getUnitMarketPrice());
257 }
258 super.setInitialStock(stock);
259
260
261 this.addDevices();
262
263
264 this.init();
265
266
267 if (this.animation == null)
268 {
269 this.initAnimation();
270 }
271 }
272
273 /***
274 * Initializes the animation.
275 */
276 private void initAnimation()
277 {
278
279 this.animation = new GisActorAnimation(
280 this,
281 this.simulator,
282 GameManufacturer.class
283 .getResource("/nl/tudelft/simulation/supplychain/images/Manufacturer.gif"));
284 }
285
286 /***
287 * Method init
288 */
289 protected void init()
290 {
291 this.addComputerControlledContentHandlers();
292 try
293 {
294
295
296
297 if (this.simulator instanceof AnimatorInterface)
298 {
299 XYChart bankChart = new XYChart(this.simulator, "BankAccount "
300 + this.name);
301 bankChart.add("bank account", this.bankAccount,
302 BankAccount.BANK_ACCOUNT_CHANGED_EVENT);
303 }
304 } catch (RemoteException remoteException)
305 {
306 Logger.severe(this, "init", remoteException);
307 }
308
309 if (GameManufacturer.DEBUG)
310 {
311 System.out.println("GameManufacturer: player: " + this.name
312 + " initialized.");
313 }
314 }
315
316 /***
317 * adds computer-controlled interactive content handlers
318 */
319 protected void addComputerControlledContentHandlers()
320 {
321
322 this.removeAllContentHandlers();
323
324
325 URL url = URLResource.getResource("/" + this.name
326 + "_computer_controlled.xml");
327 url=null;
328 if (url == null)
329 {
330 url = URLResource.getResource("/manufacturer_default_handler.xml");
331 }
332 Logger
333 .info(
334 this,
335 "addComputerControlledContentHandlers",
336 "Using: "
337 + url.toExternalForm()
338 + " as the file containing the configuration for the handlers.");
339 try
340 {
341
342 Element rootElement = GameManufacturer.builder.build(url)
343 .getRootElement();
344 HandlerParser.parseAndAddHandler(this, rootElement);
345 } catch (Exception exception)
346 {
347 Logger.severe(this, "addComputerControlledContentHandlers",
348 exception);
349 }
350
351
352
353 if (this.contentHandlers.containsKey(InternalDemand.class))
354 {
355 Set resolvedHandlers = (Set) this.contentHandlers
356 .get(InternalDemand.class);
357 for (Iterator resolvedHandlersIterator = resolvedHandlers
358 .iterator(); resolvedHandlersIterator.hasNext();)
359 {
360 HandlerInterface handler = (HandlerInterface) resolvedHandlersIterator
361 .next();
362
363 if (handler instanceof InternalDemandHandlerRFQ)
364 {
365 Iterator productIterator = this.getStock().iterator();
366 while (productIterator.hasNext())
367 {
368 Product product = (Product) productIterator.next();
369 Set suppliers = (Set) this.getProductNameToSuppliers()
370 .get(product.getName());
371
372 if (suppliers != null)
373 {
374 for (Iterator supplierIterator = suppliers
375 .iterator(); supplierIterator.hasNext();)
376 {
377 ((InternalDemandHandlerRFQ) handler)
378 .addSupplier(product,
379 (Trader) supplierIterator
380 .next());
381 if (GameManufacturer.DEBUG)
382 {
383
384 System.out
385 .println("DEBUG -- GameManufacturer: addComputerControlledContentHandlers : added supplier to internaldemand handler rfq");
386 }
387 }
388 } else
389 {
390 Logger.warning(this,
391 "addComputerControlledContentHandlers",
392 "No suppliers found for product: "
393 + product);
394 }
395 }
396 }
397 }
398 }
399 }
400
401 /***
402 * @see nl.tudelft.simulation.supplychain.actor.SupplyChainActor#sendContent(nl.tudelft.simulation.supplychain.content.Content, double)
403 */
404 public void sendContent(final Content content,
405 final double administrativeDelay)
406 {
407
408
409 if (content instanceof Order)
410 {
411
412 }
413 super.sendContent(content, administrativeDelay);
414 }
415
416 /***
417 * @see nl.tudelft.simulation.dsol.animation.LocatableInterface#getBounds()
418 */
419 public Bounds getBounds()
420 {
421 return new BoundingBox(1.0, 1.0, 0.0);
422 }
423
424 /***
425 * @see org.gscg.gameactors.GameInteractiveActorRoleInterface#getGameContentStore()
426 */
427 public GameActorContentStore getGameContentStore()
428 {
429 return (GameActorContentStore) super.getContentStore();
430 }
431
432 /***
433 * Method getContent returns all data objects of type contentClass
434 *
435 * @param contentClass the content class to look for
436 * @param sent indicates whether the content is sent or received
437 * @param productName the name of the product
438 */
439 public void fireAllContentData(final Class contentClass,
440 final boolean sent, final String productName)
441 {
442 getGameContentStore().fireAllProductContentData(contentClass, sent,
443 productName);
444 }
445
446 /***
447 * Method fireAllNumberData.
448 */
449 public void fireAllNumberData()
450 {
451 Collection products = this.globalSupplyChainData.getProducts();
452 Iterator prodIter = products.iterator();
453 while (prodIter.hasNext())
454 {
455 Product product = (Product) prodIter.next();
456 getGameContentStore().fireAllProductNumberData(product.getName());
457 }
458 }
459
460 /***
461 * @param productName the product we want
462 * @return an initialized RFQData object with potential suppliers
463 */
464 public RFQDataSuppliers getInitialRFQData(final String productName)
465 {
466 double day = 0;
467 try
468 {
469 day = TimeUnit.convert(1, TimeUnitInterface.DAY, this.simulator);
470 } catch (Exception exception)
471 {
472 Logger.severe(this, "getInitialRFQData", "TimeUnit.convert failed");
473 }
474
475
476 double earliestDeliveryDate = this.getSimulatorTime() + 14 * day;
477 double defaultAmount = 100;
478 double latestDeliveryDate = earliestDeliveryDate + 7.0 * day;
479
480 String[] supplierNames = new String[0];
481 String[] supplierNickNames = new String[0];
482 Point2d ownLocation = new Point2d(this.getLocation().x, this
483 .getLocation().y);
484 Point2d[] suppliersLocations = new Point2d[0];
485
486 Set suppliers = (Set) this.productNameToSuppliers.get(productName);
487 if (suppliers != null)
488 {
489 supplierNames = new String[suppliers.size()];
490 supplierNickNames = new String[suppliers.size()];
491 suppliersLocations = new Point2d[suppliers.size()];
492
493 int counter = 0;
494 for (Iterator it = suppliers.iterator(); it.hasNext();)
495 {
496 Trader trader = (Trader) it.next();
497 supplierNames[counter] = trader.getName();
498 supplierNickNames[counter] = trader.getLocationDescription();
499 suppliersLocations[counter] = new Point2d(
500 trader.getLocation().x, trader.getLocation().y);
501 counter++;
502 }
503 }
504 return new RFQDataSuppliers(this.name, supplierNames,
505 supplierNickNames, DateIntData.makeDateIntData(
506 earliestDeliveryDate, this.simulator), DateIntData
507 .makeDateIntData(latestDeliveryDate, this.simulator),
508 defaultAmount, productName, ownLocation, suppliersLocations);
509 }
510
511 /***
512 * @return Returns the smallMapLocation.
513 */
514 public DirectedPoint getSmallMapLocation()
515 {
516 return this.smallMapLocation;
517 }
518
519 /***
520 * @param smallMapLocation The smallMapLocation to set.
521 */
522 public void setSmallMapLocation(final DirectedPoint smallMapLocation)
523 {
524 this.smallMapLocation = smallMapLocation;
525 }
526
527 /***
528 * @see nl.tudelft.simulation.actor.ActorInterface#getName()
529 */
530 public String getName()
531 {
532 return this.name;
533 }
534
535 /***
536 * @return Returns the animation
537 */
538 protected GisActorAnimation getAnimation()
539 {
540 return this.animation;
541 }
542
543 /***
544 * @see nl.tudelft.simulation.supplychain.actor.SupplyChainActor#calculateDistance(nl.tudelft.simulation.supplychain.actor.SupplyChainActor)
545 */
546 public double calculateDistance(final SupplyChainActor actor)
547 {
548 return new CalculateLatLonDistance().getDistance(new Point2d(
549 this.location.x, this.location.y), new Point2d(actor
550 .getLocation().x, actor.getLocation().y));
551 }
552
553 /***
554 * @return Returns the productNameToSuppliers.
555 */
556 public Map getProductNameToSuppliers()
557 {
558 return this.productNameToSuppliers;
559 }
560
561 /***
562 * @return true if human controlled, false otherwise
563 */
564 public boolean isHumanControlled()
565 {
566 return this.humanControlled;
567 }
568
569 /***
570 * sets the interactive quote handler
571 *
572 * @param interactiveQuoteHandler the interactive quote handler to set
573 */
574 public void setInteractiveQuoteHandler(
575 final InteractiveQuoteHandler interactiveQuoteHandler)
576 {
577 this.interactiveQuoteHandler = interactiveQuoteHandler;
578 }
579
580 /***
581 * removes all the content handlers
582 */
583 protected void removeAllContentHandlers()
584 {
585 super.contentHandlers.clear();
586 }
587
588 protected void addDevices()
589 {
590 try
591 {
592 StreamInterface stream = this.simulator.getReplication().getStream(
593 "default");
594 double hour = TimeUnit.convert(1.0, TimeUnitInterface.HOUR,
595 this.simulator);
596 DistContinuous hourDist = new DistConstant(stream, hour);
597
598
599
600 FaxDevice fax = new FaxDevice("GameManufacturerFax", this.simulator);
601 addSendingDevice(fax);
602 MessageHandlerInterface secretary = new HandleAllMessages(this);
603 addReceivingDevice(fax, secretary, hourDist);
604 } catch (RemoteException remoteException)
605 {
606 Logger.severe(this, "addDevices", remoteException);
607 }
608 }
609 }