KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > nightlabs > ipanema > trade > Trader


1 /*
2  * Created on 27.10.2004
3  */

4 package com.nightlabs.ipanema.trade;
5
6 import java.util.Date JavaDoc;
7 import java.util.HashMap JavaDoc;
8 import java.util.Iterator JavaDoc;
9 import java.util.Map JavaDoc;
10
11 import javax.jdo.JDOHelper;
12 import javax.jdo.JDOObjectNotFoundException;
13 import javax.jdo.PersistenceManager;
14
15 import com.nightlabs.ModuleException;
16 import com.nightlabs.ipanema.accounting.Accounting;
17 import com.nightlabs.ipanema.accounting.Currency;
18 import com.nightlabs.ipanema.organisation.LocalOrganisation;
19 import com.nightlabs.ipanema.organisation.Organisation;
20 import com.nightlabs.ipanema.organisation.id.OrganisationID;
21 import com.nightlabs.ipanema.security.User;
22 import com.nightlabs.ipanema.store.Product;
23 import com.nightlabs.ipanema.store.ProductStatusTracker;
24 import com.nightlabs.ipanema.store.Store;
25 import com.nightlabs.ipanema.trade.id.OrderID;
26
27 /**
28  * Trader is responsible for purchase and sale. It manages orders, offers and delegates
29  * to the Store and to the Accounting.
30  *
31  * @author Marco Schulze - marco at nightlabs dot de
32  * @author Alexander Bieber <alex[AT]nightlabs[DOT]de>
33  *
34  * @jdo.persistence-capable
35  * identity-type = "datastore"
36  * detachable = "true"
37  *
38  * @jdo.inheritance strategy = "new-table"
39  */

40 public class Trader
41 {
42     /**
43      * This method returns the singleton instance of Trader. If there is
44      * no instance of Trader in the datastore, yet, it will be created.
45      *
46      * @param pm
47      * @return
48      */

49     public static Trader getTrader(PersistenceManager pm)
50     {
51         Iterator JavaDoc it = pm.getExtent(Trader.class).iterator();
52         if (it.hasNext())
53             return (Trader)it.next();
54
55         Trader trader = new Trader();
56
57         LocalOrganisation localOrganisation = LocalOrganisation.getLocalOrganisation(pm);
58         trader.organisationID = localOrganisation.getOrganisation().getOrganisationID();
59         trader.mandator = new OrganisationLegalEntity(localOrganisation.getOrganisation());
60         trader.addVendor(trader.mandator);
61         trader.addCustomer(trader.mandator);
62         trader.store = Store.getStore(pm);
63         trader.accounting = Accounting.getAccounting(pm);
64
65         pm.makePersistent(trader);
66         return trader;
67     }
68
69     /**
70      * @jdo.field persistence-modifier="persistent"
71      * @jdo.column length="100"
72      */

73     private String JavaDoc organisationID;
74     
75     private Accounting accounting;
76
77     private Store store;
78
79     /**
80      * The mandator is the LegalEntity that is represented by this Trader.
81      */

82     private OrganisationLegalEntity mandator;
83
84     /**
85      * In this Map, all business partners are registered - as well customers as vendors.
86      *
87      * key: String anchorPK<br/>
88      * value: LegalEntity legalEntity
89      *
90      * @jdo.field
91      * persistence-modifier="persistent"
92      * collection-type="map"
93      * key-type="java.lang.String"
94      * value-type="LegalEntity"
95      * dependent="true"
96      *
97      * @jdo.join
98      *
99      * @jdo.map-vendor-extension vendor-name="jpox" key="key-length" value="max 201"
100      */

101     protected Map JavaDoc legalEntities = new HashMap JavaDoc();
102
103     /**
104      * This Map contains all LegalEntity-s who have bought something from the mandator of
105      * this Trader. Every entry in this Map exists as well in the Map legalEntities. An entry
106      * in this Map might exist in the Map vendors, too.
107      *
108      * key: String anchorPK<br/>
109      * value: LegalEntity legalEntity
110      *
111      * @jdo.field
112      * persistence-modifier="persistent"
113      * collection-type="map"
114      * key-type="java.lang.String"
115      * value-type="LegalEntity"
116      *
117      * @jdo.join
118      *
119      * @jdo.map-vendor-extension vendor-name="jpox" key="key-length" value="max 201"
120      */

121     protected Map JavaDoc customers = new HashMap JavaDoc();
122
123     /**
124      * This Map contains all LegalEntity-s who have sold something to the mandator of
125      * this Trader. Every entry in this Map exists as well in the Map legalEntities. An entry
126      * in this Map might exist in the Map customers, too.
127      *
128      * key: String anchorPK<br/>
129      * value: LegalEntity legalEntity
130      *
131      * @jdo.field
132      * persistence-modifier="persistent"
133      * collection-type="map"
134      * key-type="java.lang.String"
135      * value-type="LegalEntity"
136      *
137      * @jdo.join
138      *
139      * @jdo.map-vendor-extension vendor-name="jpox" key="key-length" value="max 201"
140      */

141     protected Map JavaDoc vendors = new HashMap JavaDoc();
142
143     /**
144      * key: String orderPK<br/>
145      * value: OrderRequirement orderRequirement
146      *
147      * @jdo.field
148      * persistence-modifier="persistent"
149      * collection-type="map"
150      * key-type="java.lang.String"
151      * value-type="OrderRequirement"
152      *
153      * @jdo.join
154      *
155      * @jdo.map-vendor-extension vendor-name="jpox" key="key-length" value="max 201"
156      */

157     protected Map JavaDoc orderRequirements = new HashMap JavaDoc();
158
159     /**
160      * key: String offerPK<br/>
161      * value: OfferRequirement offerRequirement
162      *
163      * @jdo.field
164      * persistence-modifier="persistent"
165      * collection-type="map"
166      * key-type="java.lang.String"
167      * value-type="OfferRequirement"
168      *
169      * @jdo.join
170      *
171      * @jdo.map-vendor-extension vendor-name="jpox" key="key-length" value="max 201"
172      */

173     protected Map JavaDoc offerRequirements = new HashMap JavaDoc();
174
175     /**
176      * @return Returns the organisationID.
177      */

178     public String JavaDoc getOrganisationID()
179     {
180         return organisationID;
181     }
182
183     /**
184      * The mandator is the OrganisationLegalEntity which is represented by this Trader,
185      * means this Trader manages the datastore on behalf of this entity.
186      *
187      * @return Returns the mandator.
188      */

189     protected OrganisationLegalEntity getMandator()
190     {
191         return mandator;
192     }
193     public void addVendor(LegalEntity vendor)
194     {
195         vendors.put(vendor.getPrimaryKey(), vendor);
196     }
197     public void addCustomer(LegalEntity customer)
198     {
199         customers.put(customer.getPrimaryKey(), customer);
200     }
201
202     public LegalEntity getVendor(String JavaDoc organisationID, String JavaDoc anchorID)
203     {
204         String JavaDoc vendorPK = LegalEntity.getPrimaryKey(organisationID, anchorID);
205         return (LegalEntity) vendors.get(vendorPK);
206     }
207     
208     public LegalEntity getCustomer(String JavaDoc organisationID, String JavaDoc anchorID)
209     {
210         String JavaDoc customerPK = LegalEntity.getPrimaryKey(organisationID, anchorID);
211         return (LegalEntity) vendors.get(customerPK);
212     }
213
214     /**
215      * Creates a new OrganisationLegalEntity and registers it as customer, if it does not yet exist.
216      * If it is already existing, this method doesn't do anything but only returns the previously
217      * created instance.
218      *
219      * @param organisationID
220      * @return Returns an OrganisationLegalEntity that is registered as being a customer.
221      */

222     public OrganisationLegalEntity createCustomerOrganisationLegalEntity(String JavaDoc organisationID)
223     {
224         String JavaDoc anchorPK = OrganisationLegalEntity.getPrimaryKey(organisationID);
225         OrganisationLegalEntity res = (OrganisationLegalEntity)customers.get(anchorPK);
226         if (res != null)
227             return res;
228         
229         res = createOrganisationLegalEntity(organisationID);
230         customers.put(anchorPK, res);
231         return res;
232     }
233
234     /**
235      * Creates a new OrganisationLegalEntity and registers it as vendor, if it does not yet exist.
236      * If it is already existing, this method doesn't do anything but only returns the previously
237      * created instance.
238      *
239      * @param organisationID
240      * @return Returns an OrganisationLegalEntity that is registered as being a vendor.
241      */

242     public OrganisationLegalEntity createVendorOrganisationLegalEntity(String JavaDoc organisationID)
243     {
244         String JavaDoc anchorPK = OrganisationLegalEntity.getPrimaryKey(organisationID);
245         OrganisationLegalEntity res = (OrganisationLegalEntity)vendors.get(anchorPK);
246         if (res != null)
247             return res;
248
249         res = createOrganisationLegalEntity(organisationID);
250         vendors.put(anchorPK, res);
251         return res;
252     }
253
254     private OrganisationLegalEntity createOrganisationLegalEntity(String JavaDoc organisationID)
255     {
256         String JavaDoc anchorPK = OrganisationLegalEntity.getPrimaryKey(organisationID);
257         OrganisationLegalEntity res = (OrganisationLegalEntity)legalEntities.get(anchorPK);
258         if (res != null)
259             return res;
260
261         PersistenceManager pm = JDOHelper.getPersistenceManager(this);
262         if (pm == null)
263             throw new IllegalStateException JavaDoc("This instance of Trader is currently not persistent!");
264
265         pm.getExtent(Organisation.class);
266         Organisation organisation;
267         try {
268             organisation = (Organisation) pm.getObjectById(OrganisationID.create(organisationID), true);
269         } catch (JDOObjectNotFoundException x) {
270             throw new JDOObjectNotFoundException("There is no organisation existing for organisationID=\""+organisationID+"\"! Cannot create an OrganisationLegalEntity for a non-existent Organisation!");
271         }
272         res = new OrganisationLegalEntity(organisation);
273
274         legalEntities.put(anchorPK, res);
275         return res;
276     }
277
278     /**
279      * @jdo.field persistence-modifier="persistent"
280      */

281     protected long nextOrderID = 0;
282     
283         
284     /**
285      * Creates a new order and persits it.
286      *
287      * @param customer
288      * @param currency
289      * @return
290      */

291     public synchronized Order createLocalOrder(LegalEntity customer, Currency currency) {
292         Order order = new Order(getMandator(), customer, nextOrderID++, currency);
293         String JavaDoc pk = order.getPrimaryKey();
294         getPersistenceManager().makePersistent(order);
295         return order;
296     }
297     
298     public Order getOrder(OrderID orderID) throws OrderNotFoundException {
299         Order order = null;
300         try {
301             order = (Order) getPersistenceManager().getObjectById(orderID);
302         } catch (JDOObjectNotFoundException e) {
303             throw new OrderNotFoundException("Could not find order with OrderID: "+orderID);
304         }
305         return order;
306     }
307     
308     public synchronized Order createOrder(OrganisationLegalEntity vendor, LegalEntity customer, Currency currency)
309     throws ModuleException
310     {
311         if (customer == null)
312             throw new NullPointerException JavaDoc("customer");
313         
314         if (currency == null)
315             throw new NullPointerException JavaDoc("currency");
316         
317         PersistenceManager pm = JDOHelper.getPersistenceManager(this);
318         if (pm == null)
319             throw new IllegalStateException JavaDoc("This OrganisationLegalEntity is currently not persistent! Can invoke this method only on a persistent object!");
320         
321         LocalOrganisation localOrganisation = LocalOrganisation.getLocalOrganisation(pm);
322         
323         Order order = null;
324         
325         if (mandator.getPrimaryKey().equals(vendor.getPrimaryKey())) {
326             // local the vendor is the le owning the datastore
327
return createLocalOrder(customer, currency);
328         }
329         else {
330             // TODO: Implement foreign stuff
331
// // not local, means it's a remote organisation...
332
// // Thus, we delegate to the TradeManager of the other organisation.
333
// Hashtable props = Lookup.getInitialContextProps(pm, getOrganisationID());
334
// try {
335
// TradeManager tm = TradeManagerUtil.getHome(props).create();
336
// Order order = tm.createOrder(currency.getCurrencyID());
337
// tm.remove();
338
//
339
// String pk = order.getPrimaryKey();
340
// orders.put(pk, order);
341
// return order;
342
// } catch (ModuleException e) {
343
// throw e;
344
// } catch (Exception e) {
345
// throw new ModuleException(e);
346
// }
347
// return null;
348
}
349         return order;
350     }
351     
352     public OrderRequirement createOrderRequirement(Order order)
353     {
354         if (!order.getOrganisationID().equals(this.getOrganisationID()))
355             throw new IllegalArgumentException JavaDoc("Cannot create an instance of OrderRequirement for a foreign Organisation!");
356         
357         OrderRequirement orderRequirement = (OrderRequirement)orderRequirements.get(order.getPrimaryKey());
358         if (orderRequirement == null) {
359             orderRequirement = new OrderRequirement(this, order);
360             orderRequirements.put(order.getPrimaryKey(), orderRequirement);
361         }
362         return orderRequirement;
363     }
364     
365     public OfferRequirement createOfferRequirement(Offer offer)
366     {
367         if (!offer.getOrganisationID().equals(this.getOrganisationID()))
368             throw new IllegalArgumentException JavaDoc("Cannot create an instance of OfferRequirement for a foreign Organisation!");
369         
370         OfferRequirement offerRequirement = (OfferRequirement)offerRequirements.get(offer.getPrimaryKey());
371         if (offerRequirement == null) {
372             offerRequirement = new OfferRequirement(this, offer);
373             offerRequirements.put(offer.getPrimaryKey(), offerRequirement);
374         }
375         return offerRequirement;
376     }
377     
378     /**
379      * This method creates a new Offer for the given vendor
380      * or returns a previously created one.
381      *
382      * @param vendor
383      * @return Returns the offer for the given vendor. Never returns <tt>null</tt>.
384      * @throws ModuleException
385      */

386     public Offer createOfferRequirementOffer(OfferRequirement offerRequirement, OrganisationLegalEntity vendor)
387         throws ModuleException
388     {
389         Offer offer = offerRequirement.getOfferByVendor(vendor);
390         if (offer == null) {
391             // We don't have an Offer registered, thus we need to create one.
392
// Therefore, we first need the OrderRequirement instance assigned
393
// for the order equivalent.
394
OrderRequirement orderRequirement = createOrderRequirement(offerRequirement.getOffer().getOrder());
395
396             // From the OrderRequirement, we obtain the order for the given vendor.
397
// Order order = orderRequirement.createOrder(vendor);
398
Order order = createOrderRequirenmentOrder(orderRequirement,vendor);
399
400 // offer = createOffer();
401
offerRequirement.addOffer(offer);
402         }
403         return offer;
404     }
405     
406     
407     /**
408      * This method creates a new Order for the given vendor
409      * or returns a previously created one.
410      *
411      * @param vendor
412      * @return Returns the order for the given vendor. Never returns <tt>null</tt>.
413      * @throws ModuleException
414      */

415     public Order createOrderRequirenmentOrder(OrderRequirement orderRequirement, OrganisationLegalEntity vendor)
416         throws ModuleException
417     {
418         Order order = orderRequirement.getOrder(vendor);
419         if (order == null) {
420             order = createOrder(vendor, getMandator(), order.getCurrency());
421             orderRequirement.addOrder(order);
422         }
423         return order;
424     }
425     
426
427     // TODO put this logic into the bean?!
428
protected void allocateProduct(User user, OfferItem offerItem, Product product, Date JavaDoc autoReleaseDT)
429             throws ModuleException
430     {
431         ProductStatusTracker psr = store.getProductStatusTracker(product);
432
433         if (this.organisationID.equals(product.getOrganisationID())) {
434             // the product is local => we need to allocate all packaged products
435
synchronized (product) {
436                 for (Iterator JavaDoc it = product.getPackagedProducts().iterator(); it.hasNext(); ) {
437                     Product packagedProduct = (Product)it.next();
438                     allocateProduct(user, offerItem, packagedProduct, autoReleaseDT);
439                 }
440             }
441         }
442         else {
443             // This product is not produced by this local organisation, thus we
444
// must check, whether it is hollow and if so, create an offer
445
// to buy the product from the remote side.
446
if (psr.getCurrentStatus().isHollow()) {
447                 OfferRequirement offerRequirement = createOfferRequirement(offerItem.getOffer());
448                 OrganisationLegalEntity vendor = createVendorOrganisationLegalEntity(product.getOrganisationID());
449                 Offer backhandOffer = createOfferRequirementOffer(offerRequirement, vendor);
450
451                 backhandOffer.createOfferItemToSell(user, product, autoReleaseDT);
452             } // if (psr.getCurrentStatus().isHollow()) {
453
}
454
455         // The packaged products or the remote product are now allocated.
456
// Thus, we need to register the allocation of the container.
457
psr.allocate(user, offerItem.getOffer().getPrimaryKey());
458     }
459     
460     /**
461      * @jdo.field persistence-modifier="persistent"
462      */

463     protected long nextOfferID = 0;
464     
465     protected synchronized long createOfferID()
466     {
467         return nextOfferID++;
468     }
469     
470     public synchronized Offer createLocalOffer(Order order) {
471         Offer offer = new Offer(order, createOfferID());
472         String JavaDoc pk = offer.getPrimaryKey();
473         getPersistenceManager().makePersistent(offer);
474 // offers.put(pk, offer);
475
return offer;
476     }
477     
478     public synchronized Offer createOffer(Order order)
479     throws ModuleException
480 {
481     if (mandator.getPrimaryKey().equals(order.getVendor().getPrimaryKey())) {
482         return createLocalOffer(order);
483     }
484 //TODO: Implement Offer creating on foreign servers
485
// // order is not local, thus we must delegate to the remote bean...
486
// Hashtable props = Lookup.getInitialContextProps(pm, vendor.getOrganisationID());
487
// try {
488
// TradeManager tm = TradeManagerUtil.getHome(props).create();
489
// Offer offer = tm.createOffer(OrderID.create(getOrganisationID(), getOrderID()));
490
// tm.remove();
491
// String pk = offer.getPrimaryKey();
492
// offers.put(pk, offer);
493
// return offer;
494
// } catch (ModuleException e) {
495
// throw e;
496
// } catch (Exception e) {
497
// throw new ModuleException(e);
498
// }
499
return null;
500 }
501
502     public void allocateOfferItem(User user, OfferItem offerItem, Date JavaDoc autoReleaseDT)
503             throws ModuleException
504     {
505         Product product = offerItem.getProduct();
506         allocateProduct(user, offerItem, product, autoReleaseDT);
507     }
508
509     protected void releaseProduct(User user, OfferItem offerItem, Product product)
510             throws ModuleException
511     {
512         ProductStatusTracker psr = store.getProductStatusTracker(product);
513
514         if (this.organisationID.equals(product.getOrganisationID())) {
515             // the product is local => we need to allocate all packaged products
516
synchronized (product) {
517                 for (Iterator JavaDoc it = product.getPackagedProducts().iterator(); it.hasNext(); ) {
518                     Product packagedProduct = (Product)it.next();
519                     releaseProduct(user, offerItem, packagedProduct);
520                 }
521             }
522         }
523         else {
524             // This product is not produced by this local organisation, thus we
525
// must check, whether it is hollow and if so, get the requirement-offer
526
// to release the product on the remote side.
527
if (psr.getCurrentStatus().isHollow()) {
528                 OfferRequirement offerRequirement = createOfferRequirement(offerItem.getOffer());
529                 OrganisationLegalEntity vendor = createVendorOrganisationLegalEntity(product.getOrganisationID());
530                 Offer backhandOffer = createOfferRequirementOffer(offerRequirement, vendor);
531
532                 deleteOfferItemToSell(backhandOffer, user, product);
533             } // if (psr.getCurrentStatus().isHollow()) {
534
}
535
536         // The packaged products or the remote product are now allocated.
537
// Thus, we need to register the allocation of the container.
538
psr.release(user);
539     }
540     
541     public void releaseOfferItem(User user, OfferItem offerItem)
542             throws ModuleException
543     {
544         Product product = offerItem.getProduct();
545         releaseProduct(user, offerItem, product);
546     }
547     
548     
549     public void deleteOfferItemToSell(Offer offer, User user, Product product)
550     throws ModuleException
551     {
552         deleteOfferItemToSell(offer, user, product.getOrganisationID(), product.getProductID());
553     }
554     
555     public void deleteOfferItemToSell(Offer offer, User user, String JavaDoc productOrganisationID, String JavaDoc productID)
556             throws ModuleException
557     {
558         if (offer.isConfirmed())
559             throw new IllegalStateException JavaDoc("The given offer is already confirmed! Cannot create a new OfferItem!");
560
561         PersistenceManager pm = JDOHelper.getPersistenceManager(offer);
562         if (pm == null)
563             throw new IllegalStateException JavaDoc("This instance of Offer is not persistent! Cannot delete an OfferItem!");
564
565         // Whenever an Offer is changed, it needs to be marked as not valid to force a new validation!
566
offer.setValid(false);
567         
568         String JavaDoc productPK = Product.getPrimaryKey(productOrganisationID, productID);
569         
570         OfferItem offerItem = (OfferItem) offer.getItemsToSellMap().get(productPK);
571         if (offerItem == null) // if there is no item, silently return - mission completed without action ;-)
572
return;
573
574         offerItem.release(user);
575         offer.getItemsToSellMap().remove(productPK);
576     }
577
578     /**
579      * @jdo.field persistence-modifier="none"
580      */

581     protected transient PersistenceManager traderPM = null;
582     
583     protected PersistenceManager getPersistenceManager() {
584         if (traderPM == null) {
585             traderPM = JDOHelper.getPersistenceManager(this);
586             if (traderPM == null)
587                 throw new IllegalStateException JavaDoc("This instance of Trader is not persistent, can not get a PersistenceManager!");
588         }
589         return traderPM;
590     }
591 }
592
Popular Tags