View Javadoc

1   /*
2    * BusinesspPurchase.java Created @ Jun 16, 2004
3    * 
4    * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands. All rights reserved.
6    * 
7    * See for project information <a href="http://www.simulation.tudelft.nl/">
8    * www.simulation.tudelft.nl </a>.
9    * 
10   * The source code and binary code of this software is proprietary information
11   * of Delft University of Technology.
12   */
13  
14  package org.gscg.singleuser.interactionlayer.business;
15  
16  import java.rmi.RemoteException;
17  import java.util.ArrayList;
18  import java.util.HashSet;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Set;
22  import java.util.SortedSet;
23  import java.util.TreeSet;
24  
25  import nl.tudelft.simulation.event.Event;
26  import nl.tudelft.simulation.event.EventInterface;
27  import nl.tudelft.simulation.event.EventProducer;
28  import nl.tudelft.simulation.event.EventType;
29  import nl.tudelft.simulation.logger.Logger;
30  import nl.tudelft.simulation.supplychain.actor.Trader;
31  import nl.tudelft.simulation.supplychain.product.Product;
32  
33  import org.gscg.common.interactionlayer.AnnounceInterface;
34  import org.gscg.common.interactionlayer.timecontrol.GlobalRowOrColumnNumber;
35  import org.gscg.gameactors.GameDistributor;
36  import org.gscg.gameactors.GameManufacturer;
37  import org.gscg.singleuser.interactionlayer.SingleUserInteractionLayerInterface;
38  import org.gscg.singleuser.interactionlayer.dataobjects.BusinessData;
39  import org.gscg.singleuser.interactionlayer.dataobjects.BusinessHeaderData;
40  
41  /***
42   * The BusinessPurchase manages all the server-side actions related to the
43   * purchase decisions of a player. It manages initializing and updating the
44   * purchase panel.
45   * 
46   * <p>
47   * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
48   * Delft, the Netherlands. All rights reserved.
49   * 
50   * See for project information <a href="http://www.simulation.tudelft.nl/">
51   * www.simulation.tudelft.nl </a>.
52   * 
53   * The source code and binary code of this software is proprietary information
54   * of Delft University of Technology.
55   * 
56   * @author <a
57   *         href="http://www.tbm.tudelft.nl/webstaf/stijnh/index.htm">Stijn-Pieter
58   *         van Houten </a>
59   * @version $Revision: 1.2 $ $Date: 2005/08/09 15:43:41 $
60   * @since 1.0.0
61   */
62  public class BusinessPurchase extends EventProducer implements
63  		AnnounceInterface
64  {
65  	/*** the serial version uid */
66  	private static final long serialVersionUID = 11L;
67  
68  	/*** updates the rows in a table */
69  	public static final EventType UPDATE_BUSINESS_PURCHASE_PANEL_DAY = new EventType(
70  			"UPDATE_BUSINESS_PURCHASE_PANEL_DAY");
71  
72  	/*** updates the rows in a table */
73  	public static final EventType UPDATE_BUSINESS_PURCHASE_PANEL_WEEK = new EventType(
74  			"UPDATE_BUSINESS_PURCHASE_PANEL_WEEK");
75  
76  	/*** updates the rows in a table */
77  	public static final EventType UPDATE_BUSINESS_PURCHASE_PANEL_MONTH = new EventType(
78  			"UPDATE_BUSINESS_PURCHASE_PANEL_MONTH");
79  
80  	/*** updates the product headers and the number of required columns */
81  	public static final EventType UPDATE_BUSINESS_PURCHASE_PRODUCT_HEADERS = new EventType(
82  			"UPDATE_BUSINESS_PURCHASE_PRODUCT_HEADERS");
83  
84  	/*** the owner of the economics */
85  	private SingleUserInteractionLayerInterface owner = null;
86  
87  	/*** the events to subscribe the owner to */
88  	private EventType[] eventsToSubscribeOwnerTo = {
89  			BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_DAY,
90  			BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_WEEK,
91  			BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_MONTH,
92  			BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PRODUCT_HEADERS};
93  
94  	/*** indicates whether the product headers are already updated */
95  	private boolean productHeadersUpdated = false;
96  
97  	/***
98  	 * the cached announce events should be fired after the product headers have
99  	 * been updated
100 	 */
101 	private ArrayList cachedAnnounceEvents = new ArrayList();
102 
103 	/***
104 	 * constructs a new BusinessPurchase
105 	 * 
106 	 * @param owner the owner
107 	 */
108 	public BusinessPurchase(final SingleUserInteractionLayerInterface owner)
109 	{
110 		super();
111 		this.owner = owner;
112 
113 		// subscribe the owner to events fired from this object
114 		// also add the necessary announce events
115 		for (int i = 0; i < this.eventsToSubscribeOwnerTo.length; i++)
116 		{
117 			this.addListener(this.owner, this.eventsToSubscribeOwnerTo[i]);
118 			try
119 			{
120 				this.owner.addEventType(this.eventsToSubscribeOwnerTo[i]);
121 				this.owner.addEventTypeToAnnounceList(
122 						this.eventsToSubscribeOwnerTo[i], this);
123 			} catch (RemoteException remoteException)
124 			{
125 				Logger.severe(this, "<init>", remoteException);
126 			}
127 		}
128 	}
129 
130 	/***
131 	 * Method calculateNumberOfRows.
132 	 * 
133 	 * @param announce indicates whether this is an announce
134 	 */
135 	private void calculateNumberOfRowsDays(final boolean announce)
136 	{
137 		ArrayList dayHeaderValues = GlobalRowOrColumnNumber
138 				.getDayHeaderValues();
139 
140 		List dataList = new ArrayList();
141 		for (int i = 0; i < dayHeaderValues.size(); i++)
142 		{
143 			dataList.add(new BusinessData(0, i, "", (String) dayHeaderValues
144 					.get(i)));
145 		}
146 		if (announce)
147 		{
148 			if (this.productHeadersUpdated)
149 			{
150 				try
151 				{
152 					this.owner
153 							.notifyAnnounced(new Event(
154 									BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_DAY,
155 									this, dataList));
156 				} catch (RemoteException remoteException)
157 				{
158 					Logger.severe(this, "calculateNumberOfDays",
159 							remoteException);
160 				}
161 			} else
162 			{
163 				this.cachedAnnounceEvents.add(new Event(
164 						BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_DAY,
165 						this, dataList));
166 			}
167 		} else
168 		{
169 			this.fireEvent(new Event(
170 					BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_DAY, this,
171 					dataList));
172 		}
173 	}
174 
175 	/***
176 	 * Method calculateNumberOfRowsWeeks.
177 	 * 
178 	 * @param announce indicates whether this is an announce
179 	 */
180 	private void calculateNumberOfRowsWeeks(final boolean announce)
181 	{
182 		ArrayList weekHeaderValues = GlobalRowOrColumnNumber
183 				.getWeekHeaderValues();
184 
185 		List dataList = new ArrayList();
186 		for (int i = 0; i < weekHeaderValues.size(); i++)
187 		{
188 			dataList.add(new BusinessData(0, i, "", (String) weekHeaderValues
189 					.get(i)));
190 		}
191 		if (announce)
192 		{
193 			if (this.productHeadersUpdated)
194 			{
195 				try
196 				{
197 					this.owner
198 							.notifyAnnounced(new Event(
199 									BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_WEEK,
200 									this, dataList));
201 				} catch (RemoteException remoteException)
202 				{
203 					Logger.severe(this, "calculateNumberOfRowsWeeks",
204 							remoteException);
205 				}
206 			} else
207 			{
208 				this.cachedAnnounceEvents.add(new Event(
209 						BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_WEEK,
210 						this, dataList));
211 			}
212 		} else
213 		{
214 			this.fireEvent(new Event(
215 					BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_WEEK, this,
216 					dataList));
217 		}
218 	}
219 
220 	/***
221 	 * Method calculateNumberOfRowsMonths.
222 	 * 
223 	 * @param announce indicates whether this is an announce
224 	 */
225 	private void calculateNumberOfRowsMonths(final boolean announce)
226 	{
227 		ArrayList monthHeaderValues = GlobalRowOrColumnNumber
228 				.getMonthHeaderValues();
229 
230 		List dataList = new ArrayList();
231 		for (int i = 0; i < monthHeaderValues.size(); i++)
232 		{
233 			dataList.add(new BusinessData(0, i, "", (String) monthHeaderValues
234 					.get(i)));
235 		}
236 		if (announce)
237 		{
238 			if (this.productHeadersUpdated)
239 			{
240 				try
241 				{
242 					this.owner
243 							.notifyAnnounced(new Event(
244 									BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_MONTH,
245 									this, dataList));
246 				} catch (RemoteException remoteException)
247 				{
248 					Logger.severe(this, "calculateNumberOfRowsMonths",
249 							remoteException);
250 				}
251 			} else
252 			{
253 				this.cachedAnnounceEvents.add(new Event(
254 						BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_MONTH,
255 						this, dataList));
256 			}
257 		} else
258 		{
259 			this.fireEvent(new Event(
260 					BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_MONTH,
261 					this, dataList));
262 		}
263 	}
264 
265 	/***
266 	 * @see org.gscg.common.interactionlayer.AnnounceInterface#announce(nl.tudelft.simulation.event.EventType,
267 	 *      boolean)
268 	 */
269 	public void announce(final EventType eventType, final boolean announce)
270 	{
271 		if (eventType
272 				.equals(BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_DAY))
273 		{
274 			this.calculateNumberOfRowsDays(announce);
275 			return;
276 		}
277 		if (eventType
278 				.equals(BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_WEEK))
279 		{
280 			this.calculateNumberOfRowsWeeks(announce);
281 			return;
282 		}
283 		if (eventType
284 				.equals(BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PANEL_MONTH))
285 		{
286 			this.calculateNumberOfRowsMonths(announce);
287 			return;
288 		}
289 		if (eventType
290 				.equals(BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PRODUCT_HEADERS))
291 		{
292 			try
293 			{
294 				if (announce)
295 				{
296 					this.owner
297 							.notifyAnnounced(new Event(
298 									BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PRODUCT_HEADERS,
299 									this, new BusinessHeaderData(this
300 											.getProducts())));
301 
302 					this.productHeadersUpdated = true;
303 					for (int i = 0; i < this.cachedAnnounceEvents.size(); i++)
304 					{
305 						this.owner
306 								.notifyAnnounced((EventInterface) this.cachedAnnounceEvents
307 										.remove(i));
308 					}
309 				} else
310 				{
311 					this
312 							.fireEvent(new Event(
313 									BusinessPurchase.UPDATE_BUSINESS_PURCHASE_PRODUCT_HEADERS,
314 									this, new BusinessHeaderData(this
315 											.getProducts())));
316 				}
317 			} catch (RemoteException remoteException)
318 			{
319 				Logger.severe(this, "announce", remoteException);
320 			}
321 			return;
322 		}
323 	}
324 
325 	/***
326 	 * Method getProducts returns a sorted set with products to extract product
327 	 * headers from
328 	 * 
329 	 * @return the sorted set
330 	 */
331 	private SortedSet getProducts()
332 	{
333 		try
334 		{
335 			List products = ((Trader) this.owner.getOwner())
336 					.getProductsOnStock();
337 			TreeSet sortedSet = new TreeSet(new ProductComparator());
338 
339 			// make a distinction between actor role; a manufacturer has to
340 			// consider the BOM, a retailer doesn't
341 
342 			if (GameDistributor.class.isAssignableFrom(this.owner.getOwner()
343 					.getClass()))
344 			{
345 				for (int i = 0; i < products.size(); i++)
346 				{
347 					sortedSet.add(products.get(i));
348 				}
349 			} else if (GameManufacturer.class.isAssignableFrom(this.owner
350 					.getOwner().getClass()))
351 			{
352 				Set checkList = new HashSet();
353 				for (int i = 0; i < products.size(); i++)
354 				{
355 					Product product = (Product) products.get(i);
356 					Map materials = product.getBillOfMaterials().getMaterials();
357 					if (materials.keySet().isEmpty())
358 					{
359 						// no bom, we may add
360 						if (!checkList.contains(product.getName()))
361 						{
362 							sortedSet.add(product);
363 							checkList.add(product.getName());
364 						}
365 					}
366 				}
367 			} else
368 			{
369 				Logger.severe(this, "getProducts", "Unknown actor class: "
370 						+ this.owner.getOwner().getClass());
371 				return null;
372 			}
373 			return sortedSet;
374 		} catch (RemoteException remoteException)
375 		{
376 			Logger.severe(this, "getProducts", remoteException);
377 			return null;
378 		}
379 	}
380 }