View Javadoc

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