Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: info/crossbar/state/Sitemap.java


1   /*
2    *  @(#)Sitemap.java $Revision: 1.2 $ $Date: 2003/06/04 04:55:32 $
3    *
4    *  Copyright 2002 by Daniel Kehoe <kehoe@fortuity.com>
5    *  All Rights Reserved
6    *
7    *  Redistribution and use in source and binary forms, with or without
8    *  modification, are permitted provided that the following conditions
9    *  are met:
10   *  1. Redistributions of source code must retain the above copyright
11   *  notice, this list of conditions and the following disclaimer.
12   *  2. Redistributions in binary form must reproduce the above copyright
13   *  notice, this list of conditions and the following disclaimer in the
14   *  documentation and/or other materials provided with the distribution.
15   *
16   *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17   *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18   *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19   *  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20   *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21   *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22   *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23   *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24   *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25   *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26   *  SUCH DAMAGE.
27   */
28  package info.crossbar.state;
29  
30  import java.util.logging.Logger;
31  import java.util.logging.Level;
32  import java.util.*;
33  
34  import java.io.InputStream;
35  
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.ServletException;
38  
39  import java.sql.SQLException;
40  import java.sql.ResultSet;
41  
42  import sun.jdbc.rowset.*;
43  
44  import org.apache.commons.digester.*;
45  
46  import info.crossbar.state.CrossbarBaseBean;
47  
48  import info.crossbar.model.sitemap.Menu;
49  import info.crossbar.model.sitemap.MenuCategory;
50  import info.crossbar.model.sitemap.MenuItem;
51  
52  /**
53   * Sitemap class for use by <a href="http://www.crossbar.info/">Crossbar</a>
54   *
55   * @author     Daniel Kehoe, <a href="http://www.fortuity.com/">Fortuity Consulting</a>
56   * @created    January 23, 2002
57   * @version    <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/crossbar/crossbar-sitemap/src/java/info/crossbar/state/Sitemap.java">View source, revision history</a>
58   * $Revision: 1.2 $ $Date: 2003/06/04 04:55:32 $
59   * <p>
60   * DESCRIPTION:
61   * Delineates a web site's structure for rendering by a navigation menu tag.
62   */
63  
64  public class Sitemap extends CrossbarBaseBean {
65  
66    /**
67     * Set up logging.
68     *
69     */
70    private static Logger log = Logger.getLogger(Sitemap.class.getName());
71  
72    /**
73     * A look-up dictionary of menus.
74     *
75     */  
76    private static HashMap menus = new HashMap(); 
77    
78    /**
79     * A look-up dictionary of menu categories
80     *
81     */  
82    private static HashMap categories = new HashMap(); 
83    
84    /**
85     * A look-up dictionary of menu items (pages and locations)
86     *
87     */  
88    private static HashMap menuItems = new HashMap(); 
89    
90    /**
91     * By default, construct a menu defined by the "navigation" name in the
92     * sitemap.xml file.
93     *
94     */  
95    private String menuName = "navigation"; 
96    
97    /**
98     * By default, the HttpServletRequest will be null and the user 
99     * will not be allowed to see any menu items meant for users in a
100    * specific role.
101    *
102    */  
103   private HttpServletRequest request = null; 
104   
105   /**
106    * No argument Constructor.
107    *
108    */
109   public Sitemap() 
110     throws SQLException {
111     log.entering(Sitemap.class.getName(), "Constructor");
112     init();
113     log.exiting(Sitemap.class.getName(), "Constructor");
114   }
115   
116   /**
117    * Alternative Constructor to construct a menu other than the 
118    * default "navigation" menu defined in the sitemap.xml file.
119    *
120    * @param  menuNameIn  a String menu name set in the sitemap.xml file
121    */
122   public Sitemap(String menuNameIn) 
123     throws SQLException {
124     log.entering(Sitemap.class.getName(), "Constructor");
125     menuName = menuNameIn;
126     init();
127     log.exiting(Sitemap.class.getName(), "Constructor");
128   }
129 
130   /**
131    * Alternative Constructor takes HttpServletRequest as an argument to determine 
132    * which menu items the user is in a role to see.
133    *
134    * @param  request  HttpServletRequest needed to determine the user's role(s)
135    */
136   public Sitemap(HttpServletRequest requestIn) 
137     throws SQLException {
138     log.entering(Sitemap.class.getName(), "Constructor");
139     request = requestIn;
140     init();
141     log.exiting(Sitemap.class.getName(), "Constructor");
142   }
143   
144   /**
145    * Alternative Constructor to construct a menu other than the 
146    * default "navigation" menu defined in the sitemap.xml file.
147    * Takes HttpServletRequest as an argument to determine 
148    * which menu items the user is in a role to see.
149    *
150    * @param  menuNameIn  a String menu name set in the sitemap.xml file
151    * @param  request  HttpServletRequest needed to obtain the userID and session
152    */
153   public Sitemap(String menuNameIn, HttpServletRequest requestIn) 
154     throws SQLException {
155     log.entering(Sitemap.class.getName(), "Constructor");
156     request = requestIn;
157     menuName = menuNameIn;
158     init();
159     log.exiting(Sitemap.class.getName(), "Constructor");
160   }
161   
162   /**
163    * Obtain data somewhere and create a CachedRowSet. 
164    *
165    */
166   public void init() {
167     log.entering(Sitemap.class.getName(), "init",
168       "trying to generate data for a menu");
169     // parse the sitemap.xml file:
170     readXML();
171     // begin constructing menus;
172     ArrayList categories = getCategoriesForMenu(menuName);
173     if (categories == null || categories.isEmpty()) {
174       error("Could not find any categories for the menu");
175     }
176     try {
177       // create an empty CachedRowSet:
178       this.release(); // clear any previous records
179       this.setTableName("Sitemap");
180       this.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
181       this.setConcurrency(ResultSet.CONCUR_UPDATABLE);
182       // create metadata:
183       RowSetMetaDataImpl meta = new RowSetMetaDataImpl();
184       meta.setColumnCount(categories.size());
185       int col = 1;
186       String category;
187       Iterator cols = categories.iterator();
188       while (cols.hasNext()) {
189         // assign column labels
190         // (SQL metadata starts at "1", Java list starts at "0"):
191         category = (String) cols.next().toString();
192         meta.setColumnName(col, category);
193         meta.setColumnLabel(col, category);
194         meta.setColumnType(col, 12);//String
195         col++;
196       }
197       // assign the metadata to the CachedRowSet:
198       this.setMetaData(meta);
199       try {
200         // iterate through each category and item to populate the CachedRowSet:
201         int maxcount = 0;
202         int colIndex = 1;
203         cols = categories.iterator(); // (consumed all so must reset)
204         while (cols.hasNext()) {
205           int i = 1;
206           category = (String) cols.next().toString();
207           ArrayList itemsList = getItemsForCategory(category);
208           if (itemsList == null || itemsList.isEmpty()) {
209             error("Could not find any items for the category \""
210               + category + "\"");
211             break;
212           }
213           Iterator items = itemsList.iterator();
214           while (items.hasNext()) {
215             String item = (String) items.next();
216             if (maxcount < i) {
217               // if no previous category had
218               // more items than this category:
219               this.afterLast();
220               this.moveToInsertRow();
221               for (int j=1; j<categories.size()+1; j++) {
222                 if (j != colIndex) this.updateString(j, null);
223               }
224               this.updateString(colIndex, item);
225               this.insertRow();
226               this.moveToCurrentRow();
227             } else {
228               // if a previous category had
229               // more items than this category:
230               this.absolute(i);
231               this.updateString(colIndex, item);
232               this.updateRow();
233             }
234             if (maxcount < i) maxcount = i;
235             i++;
236           }
237           colIndex++;
238         }
239       } catch (NullPointerException cause) {
240         error("NullPointerException: " + cause);
241       } catch (ArrayIndexOutOfBoundsException cause) {
242         error("ArrayIndexOutOfBoundsException: " + cause);
243       } catch (Exception cause) {
244         error("Exception: " + cause);
245         cause.printStackTrace();
246       }
247     } catch (SQLException e) {
248         String error = e.getMessage();
249         log.warning(error);
250     } catch (Exception e) {
251         String error = e.getMessage();
252         log.warning(error);
253         e.printStackTrace();
254     }
255     log.exiting(Sitemap.class.getName(), "init");
256     return;
257   }
258   
259   protected ArrayList getCategoriesForMenu(String menuName) {
260     log.entering(Sitemap.class.getName(), "getCategoriesForMenu");
261     Menu menu = (Menu) this.menus.get(menuName);
262     log.fine("got " + menu);
263     ArrayList list = menu.getItems(request, categories);
264     log.fine("categories list contains " + list.size() + " items");
265     log.exiting(Sitemap.class.getName(), "getCategoriesForMenu");
266         return list;
267     }
268   
269   public String getDisplayNameOfCategory(String locale, String categoryName) {
270     log.entering(Sitemap.class.getName(), "getDisplayNameOfCategory",
271       "for category named \"" + categoryName + "\"");
272     MenuCategory menuCategory = (MenuCategory) categories.get(categoryName);
273     if (menuCategory == null) log.fine("can't find \"" + categoryName + "\"");
274     String value = menuCategory.getDisplayName(locale);
275     log.exiting(Sitemap.class.getName(), "getDisplayNameOfCategory");
276         return value;
277     }
278   
279   public String getLocationOfMenuCategory(String categoryName) {
280     log.entering(Sitemap.class.getName(), "getLocationOfMenuCategory",
281       "for category named \"" + categoryName + "\"");
282     MenuCategory menuCategory = (MenuCategory) categories.get(categoryName);
283     if (menuCategory == null) log.fine("can't find \"" + categoryName + "\"");
284     String value = menuCategory.getLocation();
285     log.exiting(Sitemap.class.getName(), "getLocationOfMenuCategory");
286         return value;
287     }
288   
289   protected ArrayList getItemsForCategory(String category) {
290     log.entering(Sitemap.class.getName(), "getItemsForCategory",
291       "for category named \"" + category + "\"");
292     MenuCategory menuCategory = (MenuCategory) categories.get(category);
293     if (menuCategory == null) log.fine("can't find \"" + category + "\"");
294     ArrayList list = menuCategory.getItems(request, menuItems);
295     log.fine("items list contains " + list.size() + " items");
296     log.exiting(Sitemap.class.getName(), "getItemsForCategory");
297         return list;
298     }
299 
300   public String getDisplayNameOfMenuItem(String locale, String itemName) {
301     log.entering(Sitemap.class.getName(), "getDisplayNameOfMenuItem",
302       "for item named \"" + itemName + "\"");
303     MenuItem menuItem = (MenuItem) menuItems.get(itemName);
304     if (menuItem == null) log.fine("can't find \"" + itemName + "\"");
305     String value = menuItem.getDisplayName(locale);
306     log.exiting(Sitemap.class.getName(), "getDisplayNameOfMenuItem");
307         return value;
308     }
309   
310   public String getLocationOfMenuItem(String itemName) {
311     log.entering(Sitemap.class.getName(), "getLocationOfMenuItem",
312       "for item named \"" + itemName + "\"");
313     MenuItem menuItem = (MenuItem) menuItems.get(itemName);
314     if (menuItem == null) log.fine("can't find \"" + itemName + "\"");
315     String value = menuItem.getLocation();
316     log.exiting(Sitemap.class.getName(), "getLocationOfMenuItem");
317         return value;
318     }
319   
320   public String getDescriptionOfMenuItem(String locale, String itemName) {
321     log.entering(Sitemap.class.getName(), "getDescriptionOfMenuItem",
322       "for item named \"" + itemName + "\"");
323     MenuItem menuItem = (MenuItem) menuItems.get(itemName);
324     if (menuItem == null) log.fine("can't find \"" + itemName + "\"");
325     String value = menuItem.getDescription(locale);
326     log.exiting(Sitemap.class.getName(), "getDescriptionOfMenuItem");
327         return value;
328     }
329   
330   /**
331    * Parse the sitemap.xml file to obtain data to drive a navigation menu.
332    *
333    */
334   public void readXML() {
335     log.entering(Sitemap.class.getName(), "readXML",
336       "trying to read sitemap.xml to obtain data for a menu");
337     try {
338       // reset the menus list:
339       this.menus = new HashMap();
340       // use the Jakarta Commons Digester API to read the xml file:
341       Digester digester = new Digester(); 
342       // This method pushes this class to the Digester's 
343       // object stack making its methods available to processing rules. 
344       digester.push(this); 
345       // create Menu objects:
346       digester.addObjectCreate("crossbar/menu", Menu.class);
347       digester.addSetProperties("crossbar/menu", "name", "name"); 
348       digester.addCallMethod("crossbar/menu/display", "setDisplayName", 2); 
349       digester.addCallParam("crossbar/menu/display", 0, "locale");
350       digester.addCallParam("crossbar/menu/display", 1);
351       digester.addCallMethod("crossbar/menu/categories", "setSortOrder", 2); 
352       digester.addCallParam("crossbar/menu/categories", 0, "sort-order");
353       digester.addCallParam("crossbar/menu/categories", 1);
354       digester.addCallMethod("crossbar/menu/roles", "setRole", 1); 
355       digester.addCallParam("crossbar/menu/roles", 0);
356       digester.addSetNext("crossbar/menu", "addMenu");
357       // create MenuCategory objects:
358       digester.addObjectCreate("crossbar/category", MenuCategory.class);
359       digester.addSetProperties("crossbar/category", "name", "name"); 
360       digester.addCallMethod("crossbar/category/display", "setDisplayName", 2); 
361       digester.addCallParam("crossbar/category/display", 0, "locale");
362       digester.addCallParam("crossbar/category/display", 1);
363       digester.addBeanPropertySetter("crossbar/category/location", "location");
364       digester.addCallMethod("crossbar/category/pages", "setSortOrder", 2); 
365       digester.addCallParam("crossbar/category/pages", 0, "sort-order");
366       digester.addCallParam("crossbar/category/pages", 1);
367       digester.addCallMethod("crossbar/category/roles", "setRole", 1); 
368       digester.addCallParam("crossbar/category/roles", 0);
369       digester.addSetNext("crossbar/category", "addMenuCategory");
370       // create MenuItem objects:
371       digester.addObjectCreate("crossbar/page", MenuItem.class);
372       digester.addSetProperties("crossbar/page", "name", "name"); 
373       digester.addCallMethod("crossbar/page/display", "setDisplayName", 2); 
374       digester.addCallParam("crossbar/page/display", 0, "locale");
375       digester.addCallParam("crossbar/page/display", 1);
376       digester.addCallMethod("crossbar/page/description", "setDescription", 2); 
377       digester.addCallParam("crossbar/page/description", 0, "locale");
378       digester.addCallParam("crossbar/page/description", 1);
379       digester.addBeanPropertySetter("crossbar/page/location", "location"); 
380       digester.addCallMethod("crossbar/page/roles", "setRole", 1); 
381       digester.addCallParam("crossbar/page/roles", 0);
382       digester.addSetNext("crossbar/page", "addMenuItem");
383       log.fine("ready to parse");
384       // This doesn't work when the app is installed from a war file:
385       // String xmlFilePath = App.context.getRealPath("/WEB-INF/sitemap.xml");
386       // Use this instead:
387       InputStream xmlFile = App.context.getResourceAsStream("/WEB-INF/sitemap.xml");
388       // This method starts the parsing of the document.
389       digester.parse(xmlFile);
390       log.fine("menus list contains " + this.menus.size() + " items");
391     } catch (Exception e) {
392       log.warning(e.getMessage());
393       e.printStackTrace();
394     } 
395     log.exiting(Sitemap.class.getName(), "readXML");
396     return;
397   } 
398 
399   /**
400    * Invoked by the Digester.
401    *
402    */
403   public void addMenu(Menu item) {
404     log.fine("adding menu named \"" + item.getName() + "\"");
405     this.menus.put(item.getName(),item);
406     log.fine("menus list contains " + this.menus.size() + " items");
407   }
408   
409   /**
410    * Invoked by the Digester.
411    *
412    */
413   public void addMenuCategory(MenuCategory item) {
414     log.fine("adding menu category named \"" + item.getName() + "\"");
415     this.categories.put(item.getName(),item);
416     log.fine("categories list contains " + this.categories.size() + " items");
417   }
418   
419   /**
420    * Invoked by the Digester.
421    *
422    */
423   public void addMenuItem(MenuItem item) {
424     log.fine("adding menu item named \"" + item.getName() + "\"");
425     this.menuItems.put(item.getName(),item);
426     log.fine("menuItems list contains " + this.menuItems.size() + " items");
427   }
428   
429 
430 }// end of class Sitemap