001: /*
002: * Copyright (c) 1998-2000 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Emil Ong
028: */
029:
030: package com.caucho.xtpdoc;
031:
032: import com.caucho.config.Config;
033: import com.caucho.vfs.Path;
034:
035: import javax.annotation.PostConstruct;
036: import javax.xml.stream.XMLStreamException;
037: import javax.xml.stream.XMLStreamWriter;
038: import java.io.IOException;
039: import java.io.PrintWriter;
040: import java.util.ArrayList;
041: import java.util.logging.Logger;
042:
043: public class NavigationItem {
044: private static final Logger log = Logger
045: .getLogger(NavigationItem.class.getName());
046:
047: private Navigation _navigation;
048: private NavigationItem _parent;
049:
050: private String _uri;
051:
052: private int _maxDepth = 3;
053: private int _depth;
054: private boolean _isRelative;
055: private String _link;
056: private String _title;
057: private String _product;
058: private Document _document;
059: private String _description;
060: private ContentItem _fullDescription;
061: private boolean _atocDescend;
062: private Navigation _child;
063: private ArrayList<NavigationItem> _items = new ArrayList<NavigationItem>();
064:
065: public NavigationItem(Navigation navigation, NavigationItem parent,
066: int depth) {
067: _navigation = navigation;
068: _parent = parent;
069:
070: _document = navigation.getDocument();
071: _depth = depth;
072: }
073:
074: public Navigation getNavigation() {
075: return _navigation;
076: }
077:
078: NavigationItem getParent() {
079: return _parent;
080: }
081:
082: void setParent(NavigationItem parent) {
083: _parent = parent;
084: }
085:
086: NavigationItem getPrevious() {
087: NavigationItem parent = getParent();
088:
089: if (parent != null) {
090: int p = parent._items.indexOf(this );
091:
092: if (p > 0) {
093: NavigationItem ptr = _parent._items.get(p - 1);
094:
095: while (ptr != null && ptr._items.size() > 0) {
096: ptr = ptr._items.get(ptr._items.size() - 1);
097: }
098:
099: return ptr;
100: } else
101: return parent;
102: }
103:
104: return null;
105: }
106:
107: NavigationItem getNext() {
108: NavigationItem ptr = this ;
109: NavigationItem child = null;
110:
111: while (ptr != null) {
112: int p = ptr._items.indexOf(child);
113:
114: if (p < 0 && ptr._items.size() > 0)
115: return ptr._items.get(0);
116: else if (p + 1 < ptr._items.size())
117: return ptr._items.get(p + 1);
118:
119: child = ptr;
120: ptr = ptr.getParent();
121: }
122:
123: return null;
124: }
125:
126: ArrayList<NavigationItem> getChildren() {
127: return _items;
128: }
129:
130: void addChildren(ArrayList<NavigationItem> children) {
131: _items.addAll(children);
132: }
133:
134: String getUri() {
135: return _uri;
136: }
137:
138: protected void initSummary() {
139: if (_child != null || _fullDescription != null)
140: return;
141:
142: Path rootPath = _document.getDocumentPath().getParent();
143:
144: if (_uri != null) {
145: Path linkPath = _document.getRealPath(_uri);
146:
147: // System.out.println("LINK: " + linkPath);
148:
149: if (linkPath.exists()
150: && linkPath.getPath().endsWith(".xtp")) {
151: Config config = new Config();
152:
153: try {
154: config.configure(_document, linkPath);
155:
156: if (_document.getHeader() != null)
157: _fullDescription = _document.getHeader()
158: .getDescription();
159: else
160: _fullDescription = new Description(_document);
161: } catch (NullPointerException e) {
162: log
163: .info("error configuring " + linkPath
164: + ": " + e);
165: } catch (Exception e) {
166: log
167: .info("error configuring " + linkPath
168: + ": " + e);
169: }
170:
171: if (_atocDescend) {
172: Path linkRoot = linkPath.getParent();
173:
174: if (linkRoot.equals(_navigation.getRootPath()
175: .getParent()))
176: return;
177:
178: Path subToc = linkPath.getParent()
179: .lookup("toc.xml");
180:
181: if (subToc.exists()) {
182: _child = new Navigation(_navigation, _uri,
183: linkRoot, _depth + 1);
184:
185: try {
186: config.configure(_child, subToc);
187: } catch (Exception e) {
188: log.info("Failed to configure " + subToc
189: + ": " + e);
190: }
191: } else {
192: log.info(subToc + " does not exist!");
193: }
194: }
195: }
196: }
197: }
198:
199: /*
200: public ContentItem createDescription()
201: {
202: _fullDescription = new FormattedText(_document);
203: return _fullDescription;
204: }
205: */
206:
207: public void setATOCDescend(boolean atocDescend) {
208: _atocDescend = atocDescend;
209: }
210:
211: public void setLink(String link) {
212: _link = link;
213: _isRelative = (_link.indexOf(':') < 0);
214: if (_isRelative)
215: _uri = _navigation.getUri() + link;
216: else
217: _uri = _link;
218: }
219:
220: public String getLink() {
221: return _link;
222: }
223:
224: public void setTitle(String title) {
225: _title = title;
226: }
227:
228: public String getTitle() {
229: return _title;
230: }
231:
232: public void setDescription(String description) {
233: _description = description;
234: }
235:
236: public void setProduct(String product) {
237: _product = product;
238: }
239:
240: public NavigationItem createItem() {
241: NavigationItem item = new NavigationItem(_navigation, this ,
242: _depth + 1);
243: _items.add(item);
244: return item;
245: }
246:
247: @PostConstruct
248: public void init() {
249: if (_isRelative)
250: _navigation.putItem(_navigation.getUri() + _link, this );
251: else
252: _navigation.putItem(_link, this );
253: }
254:
255: public void writeHtml(XMLStreamWriter out, String path)
256: throws XMLStreamException {
257: initSummary();
258:
259: out.writeStartElement("dl");
260: out.writeAttribute("class", "atoc-top");
261:
262: for (NavigationItem item : _items)
263: item.writeHtmlImpl(out, path, 0, 0, 3);
264:
265: out.writeEndElement();
266: }
267:
268: public void writeHtml(XMLStreamWriter out, String path, int depth,
269: int styleDepth, int maxDepth) throws XMLStreamException {
270: if (depth + styleDepth <= 1)
271: initSummary();
272:
273: for (NavigationItem item : _items)
274: item.writeHtmlImpl(out, path, depth, styleDepth, maxDepth);
275: }
276:
277: protected void writeHtmlImpl(XMLStreamWriter out, String path,
278: int depth, int styleDepth, int maxDepth)
279: throws XMLStreamException {
280: if (maxDepth <= depth)
281: return;
282:
283: if (depth + styleDepth <= 1)
284: initSummary();
285:
286: if (_child != null && depth + 1 < maxDepth)
287: _child.initSummary();
288:
289: if (depth <= 1) {
290: out.writeStartElement("h2");
291: out.writeAttribute("class", "section");
292:
293: if (_link != null) {
294: out.writeStartElement("a");
295:
296: if (_isRelative)
297: out.writeAttribute("href", path + _link);
298: else
299: out.writeAttribute("href", _link);
300:
301: out.writeCharacters(_title);
302: out.writeEndElement(); // a
303: } else
304: out.writeCharacters(_title);
305:
306: out.writeEndElement();
307: } else {
308: out.writeStartElement("dt");
309:
310: out.writeStartElement("b");
311:
312: if (_link != null) {
313: out.writeStartElement("a");
314:
315: if (_isRelative)
316: out.writeAttribute("href", path + _link);
317: else
318: out.writeAttribute("href", _link);
319:
320: out.writeCharacters(_title);
321: out.writeEndElement(); // a
322: }
323:
324: out.writeEndElement(); // b
325:
326: if (_fullDescription != null && depth + styleDepth <= 1) {
327: } else if (_description != null && depth > 1) {
328: out.writeCharacters(" - ");
329: out.writeCharacters(_description);
330: }
331:
332: out.writeEndElement(); // dt
333: }
334:
335: out.writeStartElement("dd");
336:
337: // XXX: brief/paragraph/none
338: if (_fullDescription != null && depth + styleDepth <= 1) {
339: out.writeStartElement("p");
340: _fullDescription.writeHtml(out);
341: out.writeEndElement(); // p
342: }
343:
344: if (_link != null) {
345: int p = _link.lastIndexOf('/');
346: String tail;
347: if (p >= 0)
348: tail = path + _link.substring(0, p + 1);
349: else
350: tail = path;
351:
352: String depthString = (depth == 0) ? "top" : ("" + depth);
353: boolean hasDL = false;
354:
355: if (_child != null || _items.size() > 0) {
356: out.writeStartElement("dl");
357: out.writeAttribute("class", "atoc-" + (depth + 1));
358:
359: if (_child != null)
360: _child.writeHtml(out, tail, depth + 1, styleDepth,
361: maxDepth);
362: else {
363: for (NavigationItem item : _items)
364: item.writeHtmlImpl(out, tail, depth + 1,
365: styleDepth, maxDepth);
366: }
367: out.writeEndElement();
368: }
369: }
370:
371: out.writeEndElement(); // dd
372: }
373:
374: public void writeLeftNav(XMLStreamWriter out)
375: throws XMLStreamException {
376: if (_parent != null) {
377: _parent.writeLeftNav(out);
378: } else {
379: // writeLeftNavItem(out);
380: }
381:
382: if (_items.size() > 0) {
383: if (_parent != null)
384: out.writeEmptyElement("hr");
385:
386: for (NavigationItem item : _items) {
387: item.writeLeftNavItem(out);
388: }
389: }
390: }
391:
392: public void writeLeftNavItem(XMLStreamWriter out)
393: throws XMLStreamException {
394: out.writeStartElement("a");
395: out.writeAttribute("href", _uri);
396: out.writeAttribute("class", "leftnav");
397: out.writeCharacters(_title.toLowerCase());
398: out.writeEndElement(); // a
399:
400: out.writeEmptyElement("br");
401: }
402:
403: public void writeLink(XMLStreamWriter out)
404: throws XMLStreamException {
405: out.writeStartElement("a");
406: out.writeAttribute("href", _uri);
407: out.writeCharacters(_title.toLowerCase());
408: out.writeEndElement(); // a
409: }
410:
411: public void writeLaTeX(PrintWriter writer) throws IOException {
412: }
413: }
|