KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > web > Navigation


1 /*
2  * Copyright (c) 1998-2000 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  *
28  * $Id: Navigation.java,v 1.2 2004/09/29 00:13:49 cvs Exp $
29  */

30
31 package com.caucho.web;
32
33 import com.caucho.util.Tree;
34 import com.caucho.vfs.Path;
35 import com.caucho.xml.LooseXml;
36 import com.caucho.xpath.Env;
37 import com.caucho.xpath.Expr;
38 import com.caucho.xpath.XPath;
39 import com.caucho.xpath.XPathFun;
40
41 import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.Element JavaDoc;
43 import org.w3c.dom.Node JavaDoc;
44
45 import java.util.ArrayList JavaDoc;
46 import java.util.Iterator JavaDoc;
47
48 public class Navigation {
49   private Element JavaDoc root;
50   private String JavaDoc base;
51   private Tree tree;
52
53   public Navigation()
54   {
55   }
56
57   public Navigation(Path path, String JavaDoc base)
58     throws Exception JavaDoc
59   {
60     Document JavaDoc doc = new LooseXml().parseDocument(path);
61
62     init(doc.getDocumentElement(), base);
63   }
64
65   public Navigation(Env env, Path path, String JavaDoc base)
66     throws Exception JavaDoc
67   {
68     Document JavaDoc doc = new LooseXml().parseDocument(path);
69
70     init(env, doc.getDocumentElement(), base);
71   }
72
73   /**
74    * Create a new navigation structure.
75    *
76    * @param root the top of the navigation
77    */

78   public Navigation(Env env, Element JavaDoc root, String JavaDoc base)
79     throws Exception JavaDoc
80   {
81     init(env, root, base);
82   }
83
84   public Navigation(Element JavaDoc root, String JavaDoc base)
85     throws Exception JavaDoc
86   {
87     init(root, base);
88   }
89
90   public void init(Element JavaDoc root, String JavaDoc base)
91     throws Exception JavaDoc
92   {
93     init(null,root,base);
94   }
95
96   public void init(Env env, Element JavaDoc root, String JavaDoc base)
97     throws Exception JavaDoc
98   {
99     tree = new Tree(null);
100
101     this.root = root;
102     if (base == null || base == "")
103       base = "/";
104
105     this.base = base;
106     
107     if (root != null)
108       fillChildren(env, tree, root.getFirstChild(), base);
109   }
110
111   public static Navigation createNested(Path pwd, String JavaDoc base)
112     throws Exception JavaDoc
113   {
114     return createNested(null,pwd,base);
115   }
116
117   public static Navigation createNested(Env env, Path pwd, String JavaDoc base)
118     throws Exception JavaDoc
119   {
120     Navigation baseNav = null;
121     Navigation subNav = null;
122
123     if (base.startsWith("/"))
124       base = base.substring(1);
125     
126     String JavaDoc dir = base;
127     while (true) {
128       Path path = pwd.lookup(dir).lookup("toc.xml");
129
130       Navigation nav = null;
131
132       if (path.exists())
133         nav = new Navigation(env, path, dir);
134
135       if (baseNav == null)
136         baseNav = nav;
137       else if (nav != null)
138         baseNav.linkParent(nav);
139
140       if (dir.equals(""))
141         break;
142
143       int p;
144       if (dir.endsWith("/")) {
145         p = dir.lastIndexOf('/', dir.length() - 2);
146       }
147       else
148         p = dir.lastIndexOf('/');
149
150       if (p <= 0)
151         dir = "";
152       else
153         dir = dir.substring(0, p + 1);
154     }
155
156     return baseNav;
157   }
158
159   public static Navigation createNested(ArrayList JavaDoc paths, String JavaDoc base)
160     throws Exception JavaDoc
161   {
162     return createNested(null,paths,base);
163   }
164
165   public static Navigation createNested(Env env, ArrayList JavaDoc paths, String JavaDoc base)
166     throws Exception JavaDoc
167   {
168     Navigation baseNav = null;
169     Navigation subNav = null;
170
171     if (base.startsWith("/"))
172       base = base.substring(1);
173     
174     String JavaDoc dir = base;
175     for (int i = 0; i < paths.size(); i++) {
176       Path path = ((Path) paths.get(i)).lookup("toc.xml");
177
178       Navigation nav = null;
179
180       if (path.exists())
181         nav = new Navigation(env, path, dir);
182
183       if (baseNav == null)
184         baseNav = nav;
185       else if (nav != null)
186         baseNav.linkParent(nav);
187
188       if (dir.equals(""))
189         break;
190
191       int p;
192       if (dir.endsWith("/")) {
193         p = dir.lastIndexOf('/', dir.length() - 2);
194       }
195       else
196         p = dir.lastIndexOf('/');
197
198       if (p <= 0)
199         dir = "";
200       else
201         dir = dir.substring(0, p + 1);
202     }
203     
204     return baseNav;
205   }
206
207   public Navigation linkParent(Navigation parent)
208   {
209     if (tree == null) {
210       tree = parent.tree;
211       return this;
212     }
213
214     if (tree.getFirst() == null)
215       return this;
216
217     NavItem test = (NavItem) tree.getFirst().getData();
218     NavItem link = parent.findURL(test.getLink());
219
220     if (link == null)
221       return null;
222
223     Tree parentTree = link.getTree();
224     linkTree(link.getTree(), tree.getFirst());
225     this.tree = parent.tree;
226
227     return this;
228   }
229
230   /**
231    * Attaches the child tree in its proper location in the dest tree
232    *
233    * @param destTree parent tree
234    * @param subTree child tree
235    */

236   private void linkTree(Tree destTree, Tree subTree)
237   {
238     for (Tree child = subTree.getFirst();
239          child != null;
240          child = child.getNext()) {
241       NavItem item = (NavItem) child.getData();
242       Tree childTree = destTree.append(item);
243       item.setTree(childTree);
244       linkTree(childTree, child);
245     }
246   }
247
248   /**
249    * Returns an attribute from the top-level navigation element.
250    *
251    * @param name The name of the attribute.
252    */

253   public String JavaDoc getAttribute(String JavaDoc name)
254   {
255     if (root == null)
256       return "";
257     
258     return root.getAttribute(name);
259   }
260
261   /**
262    * @param url the url to match
263    */

264   public NavItem findURL(String JavaDoc url)
265   {
266     if (tree == null)
267       return null;
268     
269     url = normalizeURL(url);
270     
271     Iterator JavaDoc iter = tree.dfs();
272     while (iter.hasNext()) {
273       Tree tree = (Tree) iter.next();
274       NavItem item = (NavItem) tree.getData();
275
276       if (item.getLink().equals(url)) {
277     return item;
278       }
279     }
280
281     return null;
282   }
283   
284   /**
285    */

286   private void fillChildren(Env env, Tree tree, Node JavaDoc childNode, String JavaDoc base)
287     throws Exception JavaDoc
288   {
289     XPathFun docShouldDisplay = env == null ? null : env.getFunction("doc-should-display");
290
291     for (; childNode != null; childNode = childNode.getNextSibling()) {
292       if (! childNode.getNodeName().equals("item"))
293     continue;
294
295       if (docShouldDisplay != null && !Expr.toBoolean(docShouldDisplay.eval(childNode,env,null,null)))
296         continue;
297
298       Element JavaDoc elt = (Element JavaDoc) childNode;
299
300       NavItem item = new NavItem();
301       String JavaDoc href = linkPattern.evalString(elt);
302
303       item.setLink(resolveURL(href, childNode, base));
304       item.setTitle(titlePattern.evalString(elt));
305
306       String JavaDoc desc;
307       desc = descPattern.evalString(elt);
308       item.setDescription(desc);
309
310       item.setProduct(_productPattern.evalString(elt));
311
312       Tree childTree = tree.append(item);
313       item.setTree(childTree);
314
315       fillChildren(env, childTree, childNode.getFirstChild(), base);
316     }
317   }
318
319   private String JavaDoc resolveURL(String JavaDoc url, Node JavaDoc node, String JavaDoc base)
320   {
321     if (url.length() == 0)
322       return "/";
323     
324     if (url.startsWith("http:") || url.charAt(0) == '/')
325       return url; // normalizeURL(url);
326

327     for (; node instanceof Element JavaDoc; node = node.getParentNode()) {
328       Element JavaDoc elt = (Element JavaDoc) node;
329     
330       String JavaDoc nodeBase = elt.getAttribute("xml:base");
331
332       if (nodeBase.equals(""))
333         continue;
334       
335       if (! nodeBase.endsWith("/"))
336         return resolveURL(nodeBase + "/" + url, elt.getParentNode(), base);
337       else
338         return resolveURL(nodeBase + url, elt.getParentNode(), base);
339     }
340     
341     if (! base.endsWith("/"))
342       return normalizeURL(base + "/" + url);
343     else
344       return normalizeURL(base + url);
345   }
346   
347   private String JavaDoc normalizeURL(String JavaDoc url)
348   {
349     if (url.startsWith("/"))
350       return url;
351     else if (url.startsWith("http://"))
352       return url;
353     else
354       return "/" + url;
355
356     /*
357     int i;
358     for (i = "http://".length(); i < url.length(); i++) {
359       if (url.charAt(i) == '/') {
360         return url.substring(i);
361       }
362     }
363     
364     return "/";
365     */

366   }
367
368   static Expr linkPattern;
369   static Expr titlePattern;
370   static Expr descPattern;
371   static Expr _productPattern;
372   static {
373     try {
374       linkPattern = XPath.parseExpr("if(@link,@link,link)");
375       titlePattern = XPath.parseExpr("if(@title,@title,title)");
376       descPattern = XPath.parseExpr("if(@description,@description,description)");
377       _productPattern = XPath.parseExpr("if(@product,@product,product)");
378     } catch (Exception JavaDoc e) {
379     }
380   }
381 }
382
Popular Tags