1 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 ; 42 import org.w3c.dom.Element ; 43 import org.w3c.dom.Node ; 44 45 import java.util.ArrayList ; 46 import java.util.Iterator ; 47 48 public class Navigation { 49 private Element root; 50 private String base; 51 private Tree tree; 52 53 public Navigation() 54 { 55 } 56 57 public Navigation(Path path, String base) 58 throws Exception 59 { 60 Document doc = new LooseXml().parseDocument(path); 61 62 init(doc.getDocumentElement(), base); 63 } 64 65 public Navigation(Env env, Path path, String base) 66 throws Exception 67 { 68 Document doc = new LooseXml().parseDocument(path); 69 70 init(env, doc.getDocumentElement(), base); 71 } 72 73 78 public Navigation(Env env, Element root, String base) 79 throws Exception 80 { 81 init(env, root, base); 82 } 83 84 public Navigation(Element root, String base) 85 throws Exception 86 { 87 init(root, base); 88 } 89 90 public void init(Element root, String base) 91 throws Exception 92 { 93 init(null,root,base); 94 } 95 96 public void init(Env env, Element root, String base) 97 throws Exception 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 base) 112 throws Exception 113 { 114 return createNested(null,pwd,base); 115 } 116 117 public static Navigation createNested(Env env, Path pwd, String base) 118 throws Exception 119 { 120 Navigation baseNav = null; 121 Navigation subNav = null; 122 123 if (base.startsWith("/")) 124 base = base.substring(1); 125 126 String 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 paths, String base) 160 throws Exception 161 { 162 return createNested(null,paths,base); 163 } 164 165 public static Navigation createNested(Env env, ArrayList paths, String base) 166 throws Exception 167 { 168 Navigation baseNav = null; 169 Navigation subNav = null; 170 171 if (base.startsWith("/")) 172 base = base.substring(1); 173 174 String 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 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 253 public String getAttribute(String name) 254 { 255 if (root == null) 256 return ""; 257 258 return root.getAttribute(name); 259 } 260 261 264 public NavItem findURL(String url) 265 { 266 if (tree == null) 267 return null; 268 269 url = normalizeURL(url); 270 271 Iterator 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 286 private void fillChildren(Env env, Tree tree, Node childNode, String base) 287 throws Exception 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 elt = (Element ) childNode; 299 300 NavItem item = new NavItem(); 301 String href = linkPattern.evalString(elt); 302 303 item.setLink(resolveURL(href, childNode, base)); 304 item.setTitle(titlePattern.evalString(elt)); 305 306 String 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 resolveURL(String url, Node node, String base) 320 { 321 if (url.length() == 0) 322 return "/"; 323 324 if (url.startsWith("http:") || url.charAt(0) == '/') 325 return url; 327 for (; node instanceof Element ; node = node.getParentNode()) { 328 Element elt = (Element ) node; 329 330 String 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 normalizeURL(String 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 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 e) { 379 } 380 } 381 } 382 | Popular Tags |