KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > rice > rubis > beans > ItemBean


1 package edu.rice.rubis.beans;
2
3 import java.rmi.*;
4 import javax.ejb.*;
5 import javax.naming.Context JavaDoc;
6 import javax.naming.InitialContext JavaDoc;
7 import javax.rmi.PortableRemoteObject JavaDoc;
8 import java.util.GregorianCalendar JavaDoc;
9
10 /**
11  * ItemBean is an entity bean with "container managed persistence".
12  * The state of an instance is stored into a relational database.
13  * The following table should exist:<p>
14  * <pre>
15  * CREATE TABLE items (
16  * id INTEGER UNSIGNED NOT NULL UNIQUE,
17  * name VARCHAR(100),
18  * description TEXT,
19  * initial_price FLOAT UNSIGNED NOT NULL,
20  * quantity INTEGER UNSIGNED NOT NULL,
21  * reserve_price FLOAT UNSIGNED DEFAULT 0,
22  * buy_now FLOAT UNSIGNED DEFAULT 0,
23  * nb_of_bids INTEGER UNSIGNED DEFAULT 0,
24  * max_bid FLOAT UNSIGNED DEFAULT 0,
25  * start_date DATETIME,
26  * end_date DATETIME,
27  * seller INTEGER,
28  * category INTEGER,
29  * PRIMARY KEY(id),
30  * INDEX seller_id (seller),
31  * INDEX category_id (category)
32  * );
33  * </pre>
34  * @author <a HREF="mailto:cecchet@rice.edu">Emmanuel Cecchet</a> and <a HREF="mailto:julie.marguerite@inrialpes.fr">Julie Marguerite</a>
35  * @version 1.1
36  */

37
38 public class ItemBean implements EntityBean
39 {
40   private EntityContext entityContext;
41   private transient boolean isDirty; // used for the isModified function
42

43   /* Class member variables */
44
45   public Integer JavaDoc id;
46   public String JavaDoc name;
47   public String JavaDoc description;
48   public float initialPrice;
49   public int quantity;
50   public float reservePrice;
51   public float buyNow;
52   public int nbOfBids;
53   public float maxBid;
54   public String JavaDoc startDate;
55   public String JavaDoc endDate;
56   public Integer JavaDoc sellerId;
57   public Integer JavaDoc categoryId;
58
59
60   /**
61    * Get item id.
62    *
63    * @return item id
64    * @exception RemoteException if an error occurs
65    * @since 1.0
66    */

67   public Integer JavaDoc getId() throws RemoteException
68   {
69     return id;
70   }
71
72   /**
73    * Get item name. This description is usually a short description of the item.
74    *
75    * @return item name
76    * @exception RemoteException if an error occurs
77    * @since 1.0
78    */

79   public String JavaDoc getName() throws RemoteException
80   {
81     return name;
82   }
83
84   /**
85    * Get item description . This is usually an HTML file describing the item.
86    *
87    * @return item description
88    * @exception RemoteException if an error occurs
89    * @since 1.0
90    */

91   public String JavaDoc getDescription() throws RemoteException
92   {
93     return description;
94   }
95
96   /**
97    * Get item initial price set by the seller.
98    *
99    * @return item initial price
100    * @exception RemoteException if an error occurs
101    * @since 1.0
102    */

103   public float getInitialPrice() throws RemoteException
104   {
105     return initialPrice;
106   }
107
108   /**
109    * Get how many of this item are to be sold.
110    *
111    * @return item quantity
112    * @exception RemoteException if an error occurs
113    * @since 1.0
114    */

115   public int getQuantity() throws RemoteException
116   {
117     return quantity;
118   }
119
120   /**
121    * Get item reserve price set by the seller. The seller can refuse to sell if reserve price is not reached.
122    *
123    * @return item reserve price
124    * @exception RemoteException if an error occurs
125    * @since 1.0
126    */

127   public float getReservePrice() throws RemoteException
128   {
129     return reservePrice;
130   }
131
132   /**
133    * Get item Buy Now price set by the seller. A user can directly by the item at this price (no auction).
134    *
135    * @return item Buy Now price
136    * @exception RemoteException if an error occurs
137    * @since 1.0
138    */

139   public float getBuyNow() throws RemoteException
140   {
141     return buyNow;
142   }
143
144   /**
145    * Get item maximum bid (if any) for this item. This value should be the same as doing <pre>SELECT MAX(bid) FROM bids WHERE item_id=?</pre>
146    *
147    * @return current maximum bid or 0 if no bid
148    * @exception RemoteException if an error occurs
149    * @since 1.1
150    */

151   public float getMaxBid() throws RemoteException
152   {
153     return maxBid;
154   }
155
156   /**
157    * Get number of bids for this item. This value should be the same as doing <pre>SELECT COUNT(*) FROM bids WHERE item_id=?</pre>
158    *
159    * @return number of bids
160    * @exception RemoteException if an error occurs
161    * @since 1.1
162    */

163   public int getNbOfBids() throws RemoteException
164   {
165     return nbOfBids;
166   }
167
168   /**
169    * Start date of the auction in the format 'YYYY-MM-DD hh:mm:ss'
170    *
171    * @return start date of the auction
172    * @exception RemoteException if an error occurs
173    * @since 1.0
174    */

175   public String JavaDoc getStartDate() throws RemoteException
176   {
177     return startDate;
178   }
179
180   /**
181    * End date of the auction in the format 'YYYY-MM-DD hh:mm:ss'
182    *
183    * @return end date of the auction
184    * @exception RemoteException if an error occurs
185    * @since 1.0
186    */

187   public String JavaDoc getEndDate() throws RemoteException
188   {
189     return endDate;
190   }
191
192   /**
193    * Give the user id of the seller
194    *
195    * @return seller's user id
196    * @since 1.0
197    * @exception RemoteException if an error occurs
198    */

199   public Integer JavaDoc getSellerId() throws RemoteException
200   {
201     return sellerId;
202   }
203
204
205   /**
206    * Give the category id of the item
207    *
208    * @return item's category id
209    * @exception RemoteException if an error occurs
210    * @since 1.0
211    */

212   public Integer JavaDoc getCategoryId() throws RemoteException
213   {
214     return categoryId;
215   }
216
217   
218   /**
219    * Get the seller's nickname by finding the Bean corresponding
220    * to the user.
221    *
222    * @return nickname
223    * @exception RemoteException if an error occurs
224    * @since 1.0
225    */

226   public String JavaDoc getSellerNickname() throws RemoteException
227   {
228     Context JavaDoc initialContext = null;
229     try
230     {
231       initialContext = new InitialContext JavaDoc();
232     }
233     catch (Exception JavaDoc e)
234     {
235       System.err.print("Cannot get initial context for JNDI: " + e);
236       return null;
237     }
238
239     // Try to find the user nick name corresponding to the sellerId
240
UserHome uHome;
241     try
242     {
243       uHome = (UserHome)PortableRemoteObject.narrow(initialContext.lookup("UserHome"),
244                                                     UserHome.class);
245     }
246     catch (Exception JavaDoc e)
247     {
248       System.err.print("Cannot lookup User: " +e);
249       return null;
250     }
251     try
252     {
253       User u = uHome.findByPrimaryKey(new UserPK(sellerId));
254       return u.getNickName();
255     }
256     catch (Exception JavaDoc e)
257     {
258       System.err.print("This user does not exist (got exception: " +e+")<br>");
259       return null;
260     }
261   }
262   
263
264   /**
265    * Get the category name by finding the Bean corresponding to the category Id.
266    *
267    * @return category name
268    * @exception RemoteException if an error occurs
269    * @since 1.0
270    */

271   public String JavaDoc getCategoryName() throws RemoteException
272   {
273     Context JavaDoc initialContext = null;
274     try
275     {
276       initialContext = new InitialContext JavaDoc();
277     }
278     catch (Exception JavaDoc e)
279     {
280       System.err.print("Cannot get initial context for JNDI: " + e);
281       return null;
282     }
283
284     // Try to find the CategoryName corresponding to the categoryId
285
CategoryHome cHome;
286     try
287     {
288       cHome = (CategoryHome)PortableRemoteObject.narrow(initialContext.lookup("CategoryHome"),
289                                                         CategoryHome.class);
290     }
291     catch (Exception JavaDoc e)
292     {
293       System.err.print("Cannot lookup Category: " +e);
294       return null;
295     }
296     try
297     {
298       Category c = cHome.findByPrimaryKey(new CategoryPK(id));
299       return c.getName();
300     }
301     catch (Exception JavaDoc e)
302     {
303       System.err.print("This category does not exist (got exception: " +e+")<br>");
304       return null;
305     }
306   }
307
308
309   /**
310    * Set a new item name
311    *
312    * @param newName item name
313    * @exception RemoteException if an error occurs
314    * @since 1.0
315    */

316   public void setName(String JavaDoc newName) throws RemoteException
317   {
318     name = newName;
319     isDirty = true; // the bean content has been modified
320
}
321
322   /**
323    * Set a new item description
324    *
325    * @param newDescription item description
326    * @exception RemoteException if an error occurs
327    * @since 1.0
328    */

329   public void setDescription(String JavaDoc newDescription) throws RemoteException
330   {
331     description = newDescription;
332     isDirty = true; // the bean content has been modified
333
}
334
335   /**
336    * Set a new initial price for the item
337    *
338    * @param newInitialPrice item initial price
339    * @exception RemoteException if an error occurs
340    * @since 1.0
341    */

342   public void setInitialPrice(float newInitialPrice) throws RemoteException
343   {
344     initialPrice = newInitialPrice;
345     isDirty = true; // the bean content has been modified
346
}
347
348   /**
349    * Set a new item quantity
350    *
351    * @param qty item quantity
352    * @exception RemoteException if an error occurs
353    * @since 1.0
354    */

355   public void setQuantity(int qty) throws RemoteException
356   {
357     quantity = qty;
358     isDirty = true; // the bean content has been modified
359
}
360
361   /**
362    * Set a new reserve price for the item
363    *
364    * @param newReservePrice item reserve price
365    * @exception RemoteException if an error occurs
366    * @since 1.0
367    */

368   public void setReservePrice(float newReservePrice) throws RemoteException
369   {
370     reservePrice = newReservePrice;
371   }
372
373   /**
374    * Set a new Buy Now price for the item
375    *
376    * @param newBuyNow item Buy Now price
377    * @exception RemoteException if an error occurs
378    * @since 1.0
379    */

380   public void setBuyNow(float newBuyNow) throws RemoteException
381   {
382     buyNow = newBuyNow;
383     isDirty = true; // the bean content has been modified
384
}
385
386   /**
387    * Set item maximum bid. This function checks if newMaxBid is greater
388    * than current maxBid and only updates the value in this case.
389    *
390    * @param newMaxBid new maximum bid
391    * @exception RemoteException if an error occurs
392    * @since 1.1
393    */

394   public void setMaxBid(float newMaxBid) throws RemoteException
395   {
396     if (newMaxBid > maxBid)
397       maxBid = newMaxBid;
398     isDirty = true; // the bean content has been modified
399
}
400
401   /**
402    * Set the number of bids for this item
403    *
404    * @param newNbOfBids new number of bids
405    * @exception RemoteException if an error occurs
406    * @since 1.1
407    */

408   public void setNbOfBids(int newNbOfBids) throws RemoteException
409   {
410     nbOfBids = newNbOfBids;
411     isDirty = true; // the bean content has been modified
412
}
413
414   /**
415    * Add one bid for this item
416    *
417    * @exception RemoteException if an error occurs
418    * @since 1.1
419    */

420   public void addOneBid() throws RemoteException
421   {
422     nbOfBids++;
423     isDirty = true; // the bean content has been modified
424
}
425
426   /**
427    * Set a new beginning date for the auction
428    *
429    * @param newDate auction new beginning date
430    * @exception RemoteException if an error occurs
431    * @since 1.0
432    */

433   public void setStartDate(String JavaDoc newDate) throws RemoteException
434   {
435     startDate = newDate;
436     isDirty = true; // the bean content has been modified
437
}
438
439   /**
440    * Set a new ending date for the auction
441    *
442    * @param newDate auction new ending date
443    * @exception RemoteException if an error occurs
444    * @since 1.0
445    */

446   public void setEndDate(String JavaDoc newDate) throws RemoteException
447   {
448     endDate = newDate;
449     isDirty = true; // the bean content has been modified
450
}
451
452   /**
453    * Set a new seller identifier. This id must match
454    * the primary key of the users table.
455    *
456    * @param id seller id
457    * @exception RemoteException if an error occurs
458    * @since 1.0
459    */

460   public void setSellerId(Integer JavaDoc id) throws RemoteException
461   {
462     sellerId = id;
463     isDirty = true; // the bean content has been modified
464
}
465
466   /**
467    * Set a new category identifier. This id must match
468    * the primary key of the category table.
469    *
470    * @param id category id
471    * @exception RemoteException if an error occurs
472    * @since 1.0
473    */

474   public void setCategoryId(Integer JavaDoc id) throws RemoteException
475   {
476     categoryId = id;
477     isDirty = true; // the bean content has been modified
478
}
479
480
481   /**
482    * This method is used to create a new Item Bean. Note that the item id
483    * is automatically generated by the database (AUTO_INCREMENT) on the
484    * primary key.
485    *
486    * @param itemName short item designation
487    * @param itemDescription long item description, usually an HTML file
488    * @param itemInitialPrice initial price fixed by the seller
489    * @param itemQuantity number to sell (of this item)
490    * @param itemReservePrice reserve price (minimum price the seller really wants to sell)
491    * @param itemBuyNow price if a user wants to buy the item immediatly
492    * @param duration duration of the auction in days (start date is when the method is called and end date is computed according to the duration)
493    * @param itemSellerId seller id, must match the primary key of table users
494    * @param itemCategoryId category id, must match the primary key of table categories
495    *
496    * @return pk primary key set to null
497    *
498    * @exception CreateException if an error occurs
499    * @exception RemoteException if an error occurs
500    * @exception RemoveException if an error occurs
501    * @since 1.0
502    */

503   public ItemPK ejbCreate(String JavaDoc itemName, String JavaDoc itemDescription, float itemInitialPrice,
504                           int itemQuantity, float itemReservePrice, float itemBuyNow, int duration,
505                           Integer JavaDoc itemSellerId, Integer JavaDoc itemCategoryId) throws CreateException, RemoteException, RemoveException
506   {
507     GregorianCalendar JavaDoc start = new GregorianCalendar JavaDoc();
508     // Connecting to IDManager Home interface thru JNDI
509
IDManagerHome home = null;
510       IDManager idManager = null;
511       
512       try
513       {
514         InitialContext JavaDoc initialContext = new InitialContext JavaDoc();
515         home = (IDManagerHome)PortableRemoteObject.narrow(initialContext.lookup(
516                "java:comp/env/ejb/IDManager"), IDManagerHome.class);
517       }
518       catch (Exception JavaDoc e)
519       {
520         throw new EJBException("Cannot lookup IDManager: " +e);
521       }
522      try
523       {
524         IDManagerPK idPK = new IDManagerPK();
525         idManager = home.findByPrimaryKey(idPK);
526         id = idManager.getNextItemID();
527         name = itemName;
528         description = itemDescription;
529         initialPrice = itemInitialPrice;
530         quantity = itemQuantity;
531         reservePrice = itemReservePrice;
532         buyNow = itemBuyNow;
533         sellerId = itemSellerId;
534         categoryId = itemCategoryId;
535         nbOfBids = 0;
536         maxBid = 0;
537         startDate = TimeManagement.dateToString(start);
538         endDate = TimeManagement.dateToString(TimeManagement.addDays(start, duration));
539       }
540      catch (Exception JavaDoc e)
541      {
542         throw new EJBException("Cannot create item: " +e);
543       }
544     return null;
545   }
546
547   /** This method just set an internal flag to
548       reload the id generated by the DB */

549   public void ejbPostCreate(String JavaDoc itemName, String JavaDoc itemDescription, float itemInitialPrice,
550                 int itemQuantity, float itemReservePrice, float itemBuyNow, int duration,
551                 Integer JavaDoc itemSellerId, Integer JavaDoc itemCategoryId)
552   {
553     isDirty = true; // the id has to be reloaded from the DB
554
}
555
556   /** Persistence is managed by the container and the bean
557       becomes up to date */

558   public void ejbLoad() throws RemoteException
559   {
560     isDirty = false;
561   }
562
563   /** Persistence is managed by the container and the bean
564       becomes up to date */

565   public void ejbStore() throws RemoteException
566   {
567     isDirty = false;
568   }
569
570   /** This method is empty because persistence is managed by the container */
571   public void ejbActivate() throws RemoteException {}
572   /** This method is empty because persistence is managed by the container */
573   public void ejbPassivate() throws RemoteException {}
574   /** This method is empty because persistence is managed by the container */
575   public void ejbRemove() throws RemoteException, RemoveException {}
576
577   /**
578    * Sets the associated entity context. The container invokes this method
579    * on an instance after the instance has been created.
580    *
581    * This method is called in an unspecified transaction context.
582    *
583    * @param context An EntityContext interface for the instance. The instance should
584    * store the reference to the context in an instance variable.
585    * @exception EJBException Thrown by the method to indicate a failure
586    * caused by a system-level error.
587    * @exception RemoteException - This exception is defined in the method signature
588    * to provide backward compatibility for enterprise beans
589    * written for the EJB 1.0 specification.
590    * Enterprise beans written for the EJB 1.1 and
591    * higher specification should throw the javax.ejb.EJBException
592    * instead of this exception.
593    */

594   public void setEntityContext(EntityContext context) throws RemoteException
595   {
596     entityContext = context;
597   }
598
599   /**
600    * Unsets the associated entity context. The container calls this method
601    * before removing the instance. This is the last method that the container
602    * invokes on the instance. The Java garbage collector will eventually invoke
603    * the finalize() method on the instance.
604    *
605    * This method is called in an unspecified transaction context.
606    *
607    * @exception EJBException Thrown by the method to indicate a failure
608    * caused by a system-level error.
609    * @exception RemoteException - This exception is defined in the method signature
610    * to provide backward compatibility for enterprise beans
611    * written for the EJB 1.0 specification.
612    * Enterprise beans written for the EJB 1.1 and
613    * higher specification should throw the javax.ejb.EJBException
614    * instead of this exception.
615    */

616   public void unsetEntityContext() throws RemoteException
617   {
618     entityContext = null;
619   }
620
621
622   /**
623    * Returns true if the beans has been modified.
624    * It prevents the EJB server from reloading a bean
625    * that has not been modified.
626    *
627    * @return a <code>boolean</code> value
628    */

629   public boolean isModified()
630   {
631     return isDirty;
632   }
633
634
635   /**
636    * Display item information as an HTML table row
637    *
638    * @return a <code>String</code> containing HTML code
639    * @exception RemoteException if an error occurs
640    * @since 1.0
641    */

642   public String JavaDoc printItem() throws RemoteException
643   {
644     return "<TR><TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewItem?itemId="+id+"\">"+name+
645       "<TD>"+maxBid+
646       "<TD>"+nbOfBids+
647       "<TD>"+endDate+
648       "<TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.PutBidAuth?itemId="+id+"\"><IMG SRC=\"/EJB_HTML/bid_now.jpg\" height=22 width=90></a>\n";
649   }
650
651   /**
652    * Display item information for the AboutMe servlet
653    *
654    * @return a <code>String</code> containing HTML code
655    * @exception RemoteException if an error occurs
656    * @since 1.0
657    */

658   public String JavaDoc printUserBoughtItem(int qty) throws RemoteException
659   {
660     return "<TR><TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewItem?itemId="+id+"\">"+name+"</a>\n"+
661       "<TD>"+qty+"\n"+"<TD>"+buyNow+"\n"+
662       "<TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewUserInfo?userId="+sellerId+"\">"+getSellerNickname()+"</a>\n";
663   }
664
665   /**
666    * Display item information for the AboutMe servlet
667    *
668    * @return a <code>String</code> containing HTML code (Warning last link must be completed by servlet)
669    * @exception RemoteException if an error occurs
670    * @since 1.0
671    */

672   public String JavaDoc printItemUserHasBidOn(float bidMaxBid) throws RemoteException
673   {
674     return "<TR><TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewItem?itemId="+id+"\">"+name+
675       "<TD>"+initialPrice+"<TD>"+maxBid+"<TD>"+bidMaxBid+"<TD>"+quantity+"<TD>"+startDate+"<TD>"+endDate+
676       "<TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewUserInfo?userId="+sellerId+"\">"+getSellerNickname()+
677       "<TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.PutBid?itemId="+id;
678   }
679
680
681   /**
682    * Display item information as an HTML table row
683    *
684    * @return a <code>String</code> containing HTML code
685    * @exception RemoteException if an error occurs
686    * @since 1.0
687    */

688   public String JavaDoc printSell() throws RemoteException
689   {
690     return "<TR><TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewItem?itemId="+id+"\">"+name+
691       "<TD>"+initialPrice+"<TD>"+maxBid+"<TD>"+quantity+"<TD>"+reservePrice+"<TD>"+buyNow+"<TD>"+startDate+"<TD>"+endDate+"\n";
692   }
693
694   /**
695    * Display item information for the AboutMe servlet
696    *
697    * @return a <code>String</code> containing HTML code
698    * @exception RemoteException if an error occurs
699    * @since 1.0
700    */

701   public String JavaDoc printUserWonItem() throws RemoteException
702   {
703     return "<TR><TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewItem?itemId="+id+"\">"+name+"</a>\n"+
704       "<TD>"+maxBid+"\n"+
705       "<TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewUserInfo?userId="+sellerId+"\">"+getSellerNickname()+"</a>\n";
706   }
707
708   /**
709    * Display item information for the Buy Now servlet
710    *
711    * @return a <code>String</code> containing HTML code
712    * @exception RemoteException if an error occurs
713    * @since 1.0
714    */

715   public String JavaDoc printItemDescriptionToBuyNow(int userId) throws RemoteException
716   {
717     String JavaDoc result = "<TABLE>\n"+"<TR><TD>Quantity<TD><b><BIG>"+quantity+"</BIG></b>\n"+
718       "<TR><TD>Seller<TD><a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.ViewUserInfo?userId="+sellerId+"\">"+
719       getSellerNickname()+"</a> (<a HREF=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.PutCommentAuth?to="+sellerId+"&itemId="+id+"\">Leave a comment on this user</a>)\n"+
720       "<TR><TD>Started<TD>"+startDate+"\n"+"<TR><TD>Ends<TD>"+endDate+"\n"+
721       "</TABLE>"+
722       "<TABLE width=\"100%\" bgcolor=\"#CCCCFF\">\n"+
723       "<TR><TD align=\"center\" width=\"100%\"><FONT size=\"4\" color=\"#000000\"><B>Item description</B></FONT></TD></TR>\n"+
724       "</TABLE><p>\n"+description+"<br><p>\n"+
725       "<TABLE width=\"100%\" bgcolor=\"#CCCCFF\">\n"+
726       "<TR><TD align=\"center\" width=\"100%\"><FONT size=\"4\" color=\"#000000\"><B>Buy Now</B></FONT></TD></TR>\n"+
727       "</TABLE><p>\n"+
728       "<form action=\""+BeanConfig.context+"/servlet/edu.rice.rubis.beans.servlets.StoreBuyNow\" method=POST>\n"+
729       "<input type=hidden name=userId value="+userId+">\n"+
730       "<input type=hidden name=itemId value="+id+">\n"+
731       "<input type=hidden name=maxQty value="+quantity+">\n";
732     if (quantity > 1)
733       result = result + "<center><table><tr><td>Quantity:</td>\n"+
734         "<td><input type=text size=5 name=qty></td></tr></table></center>\n";
735     else
736       result = result + "<input type=hidden name=qty value=1>\n";
737     result = result + "<p><input type=submit value=\"Buy now!\"></center><p>\n";
738     return result;
739   }
740 }
741
Popular Tags