View Javadoc
1   package ejava.examples.asyncmarket.ejb;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import javax.annotation.PostConstruct;
7   import javax.annotation.Resource;
8   import javax.ejb.EJBException;
9   import javax.ejb.SessionContext;
10  import javax.ejb.Stateless;
11  import javax.ejb.Timeout;
12  import javax.ejb.Timer;
13  import javax.ejb.TimerService;
14  import javax.ejb.TransactionAttribute;
15  import javax.ejb.TransactionAttributeType;
16  import javax.jms.Connection;
17  import javax.jms.ConnectionFactory;
18  import javax.jms.Destination;
19  import javax.jms.JMSException;
20  import javax.jms.MapMessage;
21  import javax.jms.MessageProducer;
22  import javax.jms.Session;
23  import javax.jms.Topic;
24  import javax.persistence.EntityManager;
25  import javax.persistence.NoResultException;
26  import javax.persistence.PersistenceContext;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  
31  import ejava.examples.asyncmarket.MarketException;
32  import ejava.examples.asyncmarket.bo.AuctionItem;
33  import ejava.examples.asyncmarket.bo.Bid;
34  import ejava.examples.asyncmarket.bo.Person;
35  import ejava.examples.asyncmarket.dao.AuctionItemDAO;
36  import ejava.examples.asyncmarket.dao.PersonDAO;
37  import ejava.examples.asyncmarket.jpa.JPAAuctionItemDAO;
38  import ejava.examples.asyncmarket.jpa.JPAPersonDAO;
39  
40  @Stateless
41  @TransactionAttribute(TransactionAttributeType.REQUIRED)
42  public class SellerEJB
43      implements SellerLocal, SellerRemote {
44      Log log = LogFactory.getLog(SellerEJB.class);
45      
46      @Resource(lookup="java:/JmsXA")
47      private ConnectionFactory connFactory;
48      @Resource(lookup="java:/topic/ejava/examples/asyncMarket/topic1", type=Topic.class)
49      private Destination sellTopic;
50      
51      @Resource
52      private TimerService timerService;
53      @Resource
54      private SessionContext ctx;
55      @PersistenceContext(unitName="asyncMarket")
56      private EntityManager em;
57      
58      private PersonDAO sellerDAO;
59      private AuctionItemDAO auctionItemDAO;
60      
61      @PostConstruct
62      public void init() {
63          log.info("******************* SellerEJB Created ******************");
64          log.debug("ctx=" + ctx);
65          log.debug("connFactory=" + connFactory);
66          log.debug("sellTopic=" + sellTopic);
67          log.debug("em=" + em);
68          log.debug("timerService=" + timerService);
69  
70          sellerDAO = new JPAPersonDAO();
71          ((JPAPersonDAO)sellerDAO).setEntityManager(em);
72          
73          auctionItemDAO = new JPAAuctionItemDAO();
74          ((JPAAuctionItemDAO)auctionItemDAO).setEntityManager(em);        
75      }
76      
77      @TransactionAttribute(TransactionAttributeType.REQUIRED)
78      public long sellProduct(String sellerId, AuctionItem item) 
79          throws MarketException {
80          log.debug("sellProduct(sellerId=" + sellerId + ",item=" + item + ")");
81          
82          Connection connection = null;
83          Session session = null;
84          Person seller = null;
85          try {
86              connection = connFactory.createConnection();
87              session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
88                  
89              seller = sellerDAO.getPersonByUserId(sellerId);
90              seller.getItems().add(item);
91              item.setOwner(seller);
92              auctionItemDAO.createItem(item);
93              
94              publishForSale(session, item);
95              timerService.createTimer(item.getEndDate(), new Long(item.getId()));
96              return item.getId();
97          }
98          catch (JMSException ex) {
99              log.error("error publishing sell", ex);
100             ctx.setRollbackOnly();
101             throw new EJBException("error publishing sell");
102         }
103         catch (NoResultException ex) {
104             log.error("error locating information for sale, seller=" + seller, 
105                     ex);
106             ctx.setRollbackOnly();
107             throw new MarketException("error locating information for sale, " +
108                     "seller=" + seller + ":" + ex);
109         }
110         catch (Exception ex) {
111             log.error("error selling product", ex);
112             ctx.setRollbackOnly();
113             throw new MarketException("error selling product:" + ex);
114         }
115         finally {
116             try {
117                 if (session != null)    { session.close(); }
118                 if (connection != null) { connection.close(); }
119             } catch (JMSException ex) {
120                 log.error("unable to close resources", ex);
121             }
122         }
123     }    
124     
125     protected void publishForSale(Session session, AuctionItem item)
126         throws JMSException {
127         MessageProducer producer = null;
128         try {
129             producer = session.createProducer(sellTopic);
130             MapMessage message = session.createMapMessage();
131             message.setJMSType("forSale");
132             message.setLong("id", item.getId());
133             message.setString("name", item.getName());
134             message.setString("seller", item.getOwner().getUserId());
135             message.setLong("startDate", item.getStartDate().getTime());
136             message.setLong("endDate", item.getEndDate().getTime());
137             message.setDouble("minBid", item.getMinBid());
138             message.setDouble("bids", item.getBids().size());
139             message.setDouble("highestBid", 
140                     (item.getHighestBid() == null ? 0.00 :
141                         item.getHighestBid().getAmount()));            
142             producer.send(message);
143             log.debug("sent=" + message);
144         }
145         finally {
146             if (producer != null)   { producer.close(); }
147         }
148     }
149 
150 
151     public AuctionItem getItem(long id) throws MarketException {
152         try {
153             AuctionItem item = auctionItemDAO.getItem(id);
154             AuctionItem dto = null;
155             if (item != null) {
156                 dto = makeDTO(item);
157                 log.debug("dao item=" + item);
158                 log.debug("dto item=" + dto);
159             }
160             return dto;
161         }
162         catch (Exception ex) {
163             log.error("error getting auction item", ex);
164             throw new MarketException("error getting auction item" + ex);
165         }
166     }
167     
168     protected AuctionItem makeDTO(AuctionItem item) {
169         AuctionItem dto = new AuctionItem(item.getId());
170         dto.setStartDate(item.getStartDate());
171         dto.setEndDate(item.getEndDate());
172         dto.setMinBid(item.getMinBid());
173         dto.setName(item.getName());
174         dto.setProductId(item.getProductId());
175         dto.setVersion(item.getVersion());
176         dto.setBids(makeDTO(item.getBids(), dto));
177         dto.setClosed(item.isClosed());
178         dto.setWinningBid(getWinningDTO(item.getWinningBid(), dto));
179         return dto;
180     }
181     
182     protected List<Bid> makeDTO(List<Bid> bids, AuctionItem item) {
183         List<Bid> dtos = new ArrayList<Bid>();
184         for(Bid bid : bids) {
185             Bid dto = new Bid(bid.getId());
186             dto.setAmount(bid.getAmount());
187             dto.setBidder(makeDTO(bid.getBidder(), dto));
188             item.getBids().add(dto);
189             dto.setItem(item);
190             dtos.add(dto);
191         }
192         return dtos;
193     }
194     
195     protected Bid getWinningDTO(Bid winningBid, AuctionItem item) {
196         Bid dto = null;
197         if (winningBid != null) {
198             for(Bid bid : item.getBids()) {
199                 if (bid.getId() == winningBid.getId()) {
200                     dto = bid;
201                     break;
202                 }
203             }
204         }
205         return dto;
206     }
207     
208     protected Person makeDTO(Person person, Bid bid) {
209         Person dto = new Person(person.getId());
210         dto.setName(person.getName());
211         dto.setUserId(person.getUserId());
212         dto.getBids().add(bid);
213         bid.setBidder(dto);
214         return dto;
215     }    
216         
217     @Timeout
218     public void timeout(Timer timer) {
219         try {
220             long itemId = ((Long)timer.getInfo()).longValue();
221             endAuction(itemId);
222         }
223         catch (Exception ex) {
224             log.error("error ending auction for:" + timer.getInfo(), ex);
225         }
226     }
227     
228     public void endAuction(long itemId) throws MarketException {
229         Connection connection = null;
230         Session session = null;
231         try {
232             AuctionItem item = auctionItemDAO.getItem(itemId);
233             if (item != null) {
234                 item.closeBids();          
235                 log.info("ending auction for:" + item);
236     
237                 connection = connFactory.createConnection();
238                 session = connection.createSession(
239                         false, Session.AUTO_ACKNOWLEDGE);
240                 publishSold(session, item);
241             }
242         }
243         catch (JMSException jex) {
244             log.error("error publishing jms message:", jex);
245         }
246         finally {
247             try {
248                 if (session != null)    { session.close(); }
249                 if (connection != null) { connection.close(); }
250             }
251             catch (Exception ignored) {}
252         }
253     }
254     
255     protected void publishSold(Session session, AuctionItem item)
256     throws JMSException {
257     MessageProducer producer = null;
258     try {
259         producer = session.createProducer(sellTopic);
260         MapMessage message = session.createMapMessage();
261         message.setJMSType("sold");
262         message.setLong("id", item.getId());
263         message.setString("name", item.getName());
264         message.setString("seller", item.getOwner().getUserId());
265         message.setLong("startDate", item.getStartDate().getTime());
266         message.setLong("endDate", item.getEndDate().getTime());
267         message.setDouble("minBid", item.getMinBid());
268         message.setDouble("bids", item.getBids().size());
269         message.setString("buyerId", 
270                           (item.getWinningBid() == null ?
271                            "" : 
272                            item.getWinningBid().getBidder().getUserId()));
273         message.setDouble("winningBid", 
274                 (item.getHighestBid() == null ? 0.00 :
275                     item.getHighestBid().getAmount()));            
276         producer.send(message);
277         log.debug("sent=" + message);
278     }
279     finally {
280         if (producer != null)   { producer.close(); }
281     }
282 }
283 
284 }