001: /*
002: * Enhydra Java Application Server
003: * The Initial Developer of the Original Code is Lutris Technologies Inc.
004: * Portions created by Lutris are Copyright (C) 1997-2000 Lutris Technologies
005: * Inc.
006: * All Rights Reserved.
007: *
008: * The contents of this file are subject to the Enhydra Public License Version
009: * 1.0 (the "License"); you may not use this file except in compliance with the
010: * License. You may obtain a copy of the License at
011: * http://www.enhydra.org/software/license/epl.html
012: *
013: * Software distributed under the License is distributed on an "AS IS" basis,
014: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
015: * License for the specific language governing rights and limitations under the
016: * License.
017: *
018: *
019: */
020:
021: package golfShop.presentation.xmlc.main;
022:
023: import org.enhydra.xml.xmlc.*;
024: import org.enhydra.xml.xmlc.html.*;
025: import com.lutris.appserver.server.httpPresentation.*;
026: import java.io.*;
027: import java.net.URLEncoder;
028: import java.util.*;
029: import org.w3c.dom.*;
030: import org.w3c.dom.html.*;
031: import golfShop.presentation.xmlc.utilities.*;
032: import golfShop.spec.inventory.*;
033:
034: /**
035: * This presentation object dynamically creates the hierarchical shelf
036: * (directory of categories and items in the store). With categories either
037: * open or closed. This is a fairly ugly thing to do in HTML.
038: *
039: * Parameters:
040: * <UL>
041: * <LI> button - If a open/close button was pressed, this is the category
042: * id associated with that button.
043: * <LI> open - A comma-seperated list of the catagory ids of the categories
044: * that are open.
045: * </UL>
046: */
047: public class Shelf implements HttpPresentation {
048: /**
049: * URL to reference ourselve.
050: */
051: private static final String SHELF_URL = "Shelf.po";
052:
053: /**
054: * URL to reference the item presentation object.
055: */
056: private static final String ITEM_URL = "Item.po";
057:
058: /**
059: * Image to use for open categories.
060: */
061: private static final String OPEN_CAT_IMAGE = "../media/true.gif";
062: private static final String CLOSED_CAT_IMAGE = "../media/false.gif";
063:
064: /**
065: * The catagory id of the button that was pressed or NULL if
066: * one was not pressed.
067: */
068: private Long buttonCatId;
069:
070: /**
071: * Table of category ids that are open. Each entry contains a Long
072: * object.
073: */
074: private Hashtable openCatIds = new Hashtable();
075:
076: /**
077: * CGI argument containing all open category ids. If null,
078: * then none are open.
079: */
080: private String openCatCgiArg;
081:
082: /**
083: * Shelf HTML object.
084: */
085: private ShelfHTML shelfHtml;
086:
087: /**
088: * Pointers to category prototype entries.
089: */
090: HTMLParagraphElement sampleCatBlock;
091: HTMLAnchorElement sampleCatAnchor;
092: HTMLImageElement sampleCatImg;
093: Text sampleCatText;
094:
095: /**
096: * Pointers to item prototype entries.
097: */
098: HTMLParagraphElement sampleItemBlock;
099: HTMLAnchorElement sampleItemAnchor;
100: Text sampleItemText;
101:
102: /**
103: * Remove prototype table and save pointers to the prototype
104: * entries. For easy of use, prototypes are edited and then
105: * cloned.
106: */
107: private void prepareHtml(HttpPresentationComms comms) {
108:
109: shelfHtml = (ShelfHTML) comms.xmlcFactory
110: .create(ShelfHTML.class);
111:
112: // Save pointers to prototypes, remove ids as they shouldn't be duplicated.
113: sampleCatBlock = shelfHtml.getElementSampleCatBlock();
114: sampleCatAnchor = shelfHtml.getElementSampleCatAnchor();
115: sampleCatImg = shelfHtml.getElementSampleCatImg();
116: sampleCatText = XMLCUtil.getFirstText(shelfHtml
117: .getElementSampleCatText());
118:
119: sampleItemBlock = shelfHtml.getElementSampleItemBlock();
120: sampleItemAnchor = shelfHtml.getElementSampleItemAnchor();
121: sampleItemText = XMLCUtil.getFirstText(shelfHtml
122: .getElementSampleItemText());
123:
124: // Remove children of prototype list.
125: Node listNode = shelfHtml.getElementList();
126: Node child = listNode.getFirstChild();
127: while (child != null) {
128: Node nextChild = child.getNextSibling();
129: listNode.removeChild(child);
130: child = nextChild;
131: }
132:
133: }
134:
135: /**
136: * Create a new HTML entry for a category.
137: */
138: private void makeCategoryHtml(Inventory category, Node parent,
139: boolean isOpen, int level) {
140: long id = category.getObjectId();
141:
142: String url = SHELF_URL + "?button=" + id;
143: if (openCatCgiArg != null) {
144: url += "&" + openCatCgiArg;
145: }
146: sampleCatAnchor.setHref(url);
147: if (isOpen) {
148: sampleCatImg.setSrc(OPEN_CAT_IMAGE);
149: } else {
150: sampleCatImg.setSrc(CLOSED_CAT_IMAGE);
151: }
152: sampleCatText.setData(category.getDesc());
153: sampleCatBlock.setClassName("level" + level);
154: parent.appendChild(sampleCatBlock.cloneNode(true));
155: }
156:
157: /**
158: * Create a new HTML entry for an item.
159: */
160: private void makeItemHtml(Inventory item, Node parent, int level) {
161: String url = ITEM_URL + "?ref=../contents/" + item.getRef()
162: + "&add=" + item.getObjectId();
163: sampleItemAnchor.setHref(url);
164: sampleItemAnchor.setTarget("item");
165: sampleItemText.setData(item.getDesc());
166: sampleItemBlock.setClassName("level" + level);
167: parent.appendChild(sampleItemBlock.cloneNode(true));
168: }
169:
170: /**
171: * Recursively process a category or item entry, adding it to the DOM.
172: * Sets node class using level for CSS.
173: */
174: private void processInventoryEntry(Inventory entry, Node parent,
175: int level) {
176: if (entry.isCategory()) {
177: boolean isOpen = openCatIds.contains(new Long(entry
178: .getObjectId()));
179: makeCategoryHtml(entry, parent, isOpen, level);
180: if (isOpen) {
181: Vector entries = entry.getItems(entry.getObjectId());
182: for (int idx = 0; idx < entries.size(); idx++) {
183: processInventoryEntry((Inventory) entries
184: .elementAt(idx), parent, level + 1);
185: }
186: }
187: } else {
188: makeItemHtml(entry, parent, level);
189: }
190: }
191:
192: /**
193: * Generate the DOM entries for the current state of the inventory.
194: */
195: private void processInventory() {
196: try {
197: Inventory inventory = InventoryFactory
198: .getInventory("golfShop.business.inventory.InventoryImpl");
199: processInventoryEntry(inventory.getInventoryById(0),
200: shelfHtml.getElementList(), 1);
201: /*
202: * Catch Null pointer exception ( we canot make a instances of classes from business layer when we run GolfShop_pres ) so
203: * we cannot create a list of category
204: * We need to allow GolfShop_pres to be functional
205: */
206:
207: } catch (NullPointerException ex) {
208:
209: }
210: }
211:
212: /**
213: * Parse CGI arguments into fields.
214: */
215: private void parseArgs(HttpPresentationRequest request)
216: throws HttpPresentationException {
217:
218: // Parse button id.
219: String button = request.getParameter("button");
220: if (button != null) {
221: try {
222: buttonCatId = new Long(button);
223: } catch (NumberFormatException except) {
224: // Ignore, probably a bogus URL.
225: }
226: }
227:
228: String open = request.getParameter("open");
229: if (open != null) {
230: StringTokenizer tokens = new StringTokenizer(open, ",");
231: while (tokens.hasMoreTokens()) {
232: String token = tokens.nextToken();
233: try {
234: Long id = new Long(token);
235: openCatIds.put(id, id);
236: } catch (NumberFormatException except) {
237: // Ignore, probably a bogus URL.
238: }
239: }
240: }
241: }
242:
243: /**
244: * Modify the open category list based on the currenmt button.
245: * Also generate CGI argument for the open categories.
246: */
247: private void adjustOpenCategories() {
248: if (buttonCatId != null) {
249: // Adjust the open entry for the current button.
250: if (openCatIds.containsKey(buttonCatId)) {
251: openCatIds.remove(buttonCatId);
252: } else {
253: openCatIds.put(buttonCatId, buttonCatId);
254: }
255: }
256:
257: // Generate CGI arguments.
258: StringBuffer buf = new StringBuffer();
259: Enumeration openIds = openCatIds.keys();
260:
261: while (openIds.hasMoreElements()) {
262: if (buf.length() > 0) {
263: buf.append(",");
264: }
265: buf.append(((Long) openIds.nextElement()).toString());
266: }
267: if (buf.length() > 0) {
268: openCatCgiArg = "open=" + buf.toString();
269: }
270: }
271:
272: /**
273: * Entry.
274: */
275: public void run(HttpPresentationComms comms)
276: throws HttpPresentationException {
277:
278: parseArgs(comms.request);
279: prepareHtml(comms);
280: adjustOpenCategories();
281: processInventory();
282: comms.response.writeDOM(shelfHtml);
283: }
284: }
|