KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > dynamic > ExtensionResolver


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.help.internal.dynamic;
12
13 import java.io.IOException JavaDoc;
14 import java.io.InputStream JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.List JavaDoc;
17
18 import javax.xml.parsers.ParserConfigurationException JavaDoc;
19
20 import org.eclipse.help.HelpSystem;
21 import org.eclipse.help.internal.HelpPlugin;
22 import org.eclipse.help.internal.UAElement;
23 import org.eclipse.help.internal.extension.ContentExtension;
24 import org.eclipse.help.internal.extension.ContentExtensionManager;
25 import org.w3c.dom.Element JavaDoc;
26 import org.w3c.dom.Node JavaDoc;
27 import org.xml.sax.SAXException JavaDoc;
28
29 /*
30  * Resolves the content to use for extensions. For anchors, these are the
31  * nodes that will be inserted at the anchor. For replaces, these are the
32  * nodes that will replace the original nodes.
33  */

34 public class ExtensionResolver {
35
36     private static final String JavaDoc ELEMENT_BODY = "body"; //$NON-NLS-1$
37
private static final String JavaDoc ATTRIBUTE_ID = "id"; //$NON-NLS-1$
38

39     private DocumentProcessor processor;
40     private DocumentReader reader;
41     private String JavaDoc locale;
42     private ContentExtensionManager manager;
43     
44     /*
45      * Creates the resolver. The processor is needed to process the extension
46      * content, and locale because we're pulling in content from other documents.
47      */

48     public ExtensionResolver(DocumentProcessor processor, DocumentReader reader, String JavaDoc locale) {
49         this.processor = processor;
50         this.reader = reader;
51         this.locale = locale;
52     }
53     
54     /*
55      * Resolves the given path into nodes to be inserted.
56      */

57     public Node JavaDoc[] resolveExtension(String JavaDoc path, int type) {
58         if (manager == null) {
59             manager = HelpPlugin.getContentExtensionManager();
60         }
61         ContentExtension[] extensions = manager.getExtensions(path, type, locale);
62         List JavaDoc list = new ArrayList JavaDoc();
63         for (int i=0;i<extensions.length;++i) {
64             String JavaDoc content = extensions[i].getContent();
65             try {
66                 Node JavaDoc[] nodes = getContent(content);
67                 for (int j=0;j<nodes.length;++j) {
68                     list.add(nodes[j]);
69                 }
70             }
71             catch (Throwable JavaDoc t) {
72                 // ignore invalid extensions
73
}
74         }
75         return (Node JavaDoc[])list.toArray(new Node JavaDoc[list.size()]);
76     }
77     
78     /*
79      * Resolves the given content path (the content to insert/replace with) into
80      * nodes.
81      */

82     private Node JavaDoc[] getContent(String JavaDoc content) throws IOException JavaDoc, SAXException JavaDoc, ParserConfigurationException JavaDoc {
83         String JavaDoc bundleId = null;
84         String JavaDoc relativePath = null;
85         String JavaDoc nodeId = null;
86         
87         int bundleStart = 0;
88         // legacy; can omit leading slash
89
if (content.charAt(0) == '/') {
90             bundleStart = 1;
91         }
92         int bundleEnd = content.indexOf('/', bundleStart + 1);
93         if (bundleEnd > bundleStart) {
94             bundleId = content.substring(bundleStart, bundleEnd);
95             int pathStart = bundleEnd + 1;
96             int pathEnd = content.indexOf('#', pathStart + 1);
97             if (pathEnd == -1) {
98                 // legacy; slash can be used instead of '#'
99
int lastSlash = content.lastIndexOf('/');
100                 int secondLastSlash = content.lastIndexOf('/', lastSlash - 1);
101                 if (secondLastSlash != -1 && lastSlash > secondLastSlash) {
102                     String JavaDoc secondLastToken = content.substring(secondLastSlash + 1, lastSlash);
103                     if (secondLastToken.indexOf('.') != -1) {
104                         pathEnd = lastSlash;
105                     }
106                     else {
107                         pathEnd = content.length();
108                     }
109                 }
110                 else {
111                     pathEnd = content.length();
112                 }
113             }
114             relativePath = content.substring(pathStart, pathEnd);
115             if (pathEnd < content.length()) {
116                 nodeId = content.substring(pathEnd + 1);
117             }
118         }
119         
120         if (bundleId != null && relativePath != null) {
121             return getContent(bundleId, relativePath, nodeId);
122         }
123         return null;
124     }
125     
126     /*
127      * Resolves the given parsed content fragments into nodes.
128      */

129     private Node JavaDoc[] getContent(String JavaDoc bundleId, String JavaDoc relativePath, String JavaDoc nodeId) throws IOException JavaDoc, SAXException JavaDoc, ParserConfigurationException JavaDoc {
130         String JavaDoc href = '/' + bundleId + '/' + relativePath;
131         InputStream JavaDoc in = HelpSystem.getHelpContent(href, locale);
132         try {
133             if (nodeId != null) {
134                 Element element = findElement(in, nodeId);
135                 processor.process(new UAElement(element), href);
136                 return new Node JavaDoc[] { element };
137             }
138             Element body = findBody(in);
139             List JavaDoc children = new ArrayList JavaDoc();
140             Node JavaDoc node = body.getFirstChild();
141             while (node != null) {
142                 if (node.getNodeType() == Node.ELEMENT_NODE) {
143                     processor.process(new UAElement((Element)node), href);
144                 }
145                 children.add(node);
146                 node = node.getNextSibling();
147             }
148             return (Node JavaDoc[])children.toArray(new Node JavaDoc[children.size()]);
149         }
150         finally {
151             try {
152                 in.close();
153             }
154             catch (IOException JavaDoc e) {}
155         }
156     }
157     
158     /*
159      * Finds and returns the element with the given elementId from the XML input
160      * stream, or null if not found.
161      */

162     private Element findElement(InputStream JavaDoc in, String JavaDoc elementId) throws IOException JavaDoc, SAXException JavaDoc, ParserConfigurationException JavaDoc {
163         return findElement(reader.read(in).element, elementId);
164     }
165     
166     /*
167      * Finds and returns the element with the given elementId from the under the
168      * given element, or null if not found.
169      */

170     private Element findElement(Element element, String JavaDoc elementId) {
171         String JavaDoc id = element.getAttribute(ATTRIBUTE_ID);
172         if (id != null && id.equals(elementId)) {
173             return element;
174         }
175         Node JavaDoc node = element.getFirstChild();
176         while (node != null) {
177             if (node.getNodeType() == Node.ELEMENT_NODE) {
178                 element = findElement((Element)node, elementId);
179                 if (element != null) {
180                     return element;
181                 }
182             }
183             node = node.getNextSibling();
184         }
185         return null;
186     }
187     
188     /*
189      * Finds and returns the body node in the given XML input.
190      */

191     private Element findBody(InputStream JavaDoc in) throws IOException JavaDoc, SAXException JavaDoc, ParserConfigurationException JavaDoc {
192         return findBody(reader.read(in).element);
193     }
194     
195     /*
196      * Finds and returns the body node under the given node.
197      */

198     private Element findBody(Element element) {
199         if (ELEMENT_BODY.equals(element.getNodeName())) {
200             return element;
201         }
202         Node JavaDoc node = element.getFirstChild();
203         while (node != null) {
204             if (node.getNodeType() == Node.ELEMENT_NODE) {
205                 Element body = findBody((Element)node);
206                 if (body != null) {
207                     return body;
208                 }
209             }
210             node = node.getNextSibling();
211         }
212         return null;
213     }
214 }
215
Popular Tags