1 9 10 package org.eclipse.help.internal.xhtml; 11 12 import java.io.IOException ; 13 import java.io.InputStream ; 14 import java.net.URL ; 15 import java.util.ArrayList ; 16 import java.util.Enumeration ; 17 import java.util.Hashtable ; 18 19 import org.eclipse.core.runtime.IConfigurationElement; 20 import org.eclipse.core.runtime.IExtensionRegistry; 21 import org.eclipse.core.runtime.Path; 22 import org.eclipse.core.runtime.Platform; 23 import org.eclipse.help.internal.HelpPlugin; 24 import org.eclipse.help.internal.util.ResourceLocator; 25 import org.osgi.framework.Bundle; 26 import org.w3c.dom.Document ; 27 import org.w3c.dom.Element ; 28 import org.w3c.dom.Node ; 29 import org.w3c.dom.NodeList ; 30 31 32 36 public class UAContentMergeProcessor { 37 38 protected static final String CONTENT_EXTENSION = "org.eclipse.help.contentExtension"; 40 protected static IExtensionRegistry registry; 41 protected static IConfigurationElement[] contentExtensionElements; 42 static { 43 registry = Platform.getExtensionRegistry(); 44 contentExtensionElements = getContentExtensions(); 45 } 46 47 private Hashtable unresolvedConfigExt = new Hashtable (); 48 49 50 private String pluginID = null; 51 private String file = null; 52 private Document document = null; 53 private String locale = null; 54 55 56 protected UAContentMergeProcessor(String pluginID, String file, Document document, String locale) { 57 this.pluginID = pluginID; 58 this.file = file; 59 this.document = document; 60 this.locale = locale; 61 62 } 63 64 65 public Document resolveIncludes() { 66 67 NodeList includes = document.getElementsByTagNameNS("*", "include"); Node [] nodes = getArray(includes); 69 for (int i = 0; i < nodes.length; i++) { 70 Element includeElement = (Element) nodes[i]; 71 UAInclude include = new UAInclude(includeElement); 72 Element targetElement = findIncludeTarget(include); 73 if (targetElement == null) { 74 String message = "Could not resolve following include: "; HelpPlugin.logWarning(message); 76 return null; 77 } 78 Node targetNode = document.importNode(targetElement, true); 79 includeElement.getParentNode().replaceChild(targetNode, includeElement); 80 } 81 return document; 82 } 83 84 85 86 87 private Element findIncludeTarget(UAInclude include) { 88 String path = include.getPath(); 89 int index = path.indexOf("/"); if (index < 0) 91 return null; 92 String pluginID = path.substring(0, index); 93 int lastIndex = path.lastIndexOf("/"); String pluginRelativePath = path.substring(index + 1, lastIndex); 95 String include_id = path.substring(lastIndex + 1, path.length()); 96 97 Bundle bundle = Platform.getBundle(pluginID); 98 ArrayList pathPrefix = ResourceLocator.getPathPrefix(locale); 99 if (bundle != null) { 100 URL flatFileURL = ResourceLocator.find(bundle, new Path(pluginRelativePath), pathPrefix); 101 if (flatFileURL != null) { 102 try { 103 InputStream inputStream = flatFileURL.openStream(); 104 UAContentParser parser = new UAContentParser(inputStream); 105 Document dom = parser.getDocument(); 106 return DOMUtil.getElementById(dom, include_id, "*"); } catch (IOException e) { 108 return null; 109 } 110 } 111 } 112 return null; 113 } 114 115 116 117 118 public static Node [] getArray(NodeList nodeList) { 119 Node [] nodes = new Node [nodeList.getLength()]; 120 for (int i = 0; i < nodeList.getLength(); i++) 121 nodes[i] = nodeList.item(i); 122 return nodes; 123 } 124 125 126 127 protected static IConfigurationElement[] getContentExtensions() { 128 IConfigurationElement[] contentExtensionElements = registry 129 .getConfigurationElementsFor(CONTENT_EXTENSION); 130 return contentExtensionElements; 131 } 132 133 134 public Document resolveContentExtensions() { 135 for (int i = 0; i < contentExtensionElements.length; i++) 136 resolveContentExtension(contentExtensionElements[i]); 137 return document; 138 } 139 140 141 private void resolveContentExtension(IConfigurationElement contentExtElement) { 142 Document contentExtensionDom = loadContentExtension(contentExtElement); 143 if (contentExtensionDom == null) 144 return; 145 resolveContentExtension(contentExtensionDom, contentExtElement); 146 } 147 148 149 private void resolveContentExtension(Document contentExtensionDom, IConfigurationElement contentExtElement) { 150 Bundle bundle = BundleUtil.getBundleFromConfigurationElement(contentExtElement); 151 Element[] topicExtensions = DOMUtil.getElementsByTagName(contentExtensionDom, "topicExtension"); if (topicExtensions != null) { 153 for (int i = 0; i < topicExtensions.length; i++) 154 doResolveContentExtension(topicExtensions[i], bundle); 155 } 156 157 Element[] topicReplaces = DOMUtil.getElementsByTagName(contentExtensionDom, "topicReplace"); if (topicReplaces != null) { 159 for (int i = 0; i < topicReplaces.length; i++) 160 doResolveContentReplace(topicReplaces[i], bundle); 161 } 162 } 163 164 private void doResolveContentExtension(Element topicExtension, Bundle bundle) { 165 UATopicExtension topicExtensionModel = new UATopicExtension(topicExtension, bundle); 166 boolean isExtensionToCurrentPage = resolveTopicExtension(topicExtensionModel); 167 if (isExtensionToCurrentPage) { 168 if (topicExtension.hasAttribute("failed")) { if (!unresolvedConfigExt.containsKey(topicExtension)) 170 unresolvedConfigExt.put(topicExtension, bundle); 171 } else { 172 unresolvedConfigExt.remove(topicExtension); 173 tryResolvingExtensions(); 174 } 175 } 176 } 177 178 179 private void tryResolvingExtensions() { 180 Enumeration keys = unresolvedConfigExt.keys(); 181 while (keys.hasMoreElements()) { 182 Element topicExtensionElement = (Element) keys.nextElement(); 183 doResolveContentExtension(topicExtensionElement, (Bundle) unresolvedConfigExt 184 .get(topicExtensionElement)); 185 } 186 } 187 188 189 196 private boolean resolveTopicExtension(UATopicExtension topicExtension) { 197 198 Element anchorElement = findAnchor(topicExtension, locale); 199 if (anchorElement == null) { 200 if (topicExtension.getElement().hasAttribute("failed")) return true; 202 else 203 return false; 204 } 205 Element[] elements = topicExtension.getElements(); 206 for (int i = 0; i < elements.length; i++) { 207 Node targetNode = document.importNode(elements[i], true); 208 anchorElement.getParentNode().insertBefore(targetNode, anchorElement); 209 } 210 return true; 211 } 212 213 214 private Element findAnchor(UATopicExtension topicExtension, String locale) { 215 String path = topicExtension.getPath(); 216 int index = path.indexOf("/"); if (index < 0) 218 return null; 219 String pluginID = path.substring(0, index); 220 int lastIndex = path.lastIndexOf("/"); String pluginRelativePath = path.substring(index + 1, lastIndex); 222 String anchor_id = path.substring(lastIndex + 1, path.length()); 223 224 if (this.pluginID.equals(pluginID) && this.file.equals(pluginRelativePath)) { 225 Element anchor = DOMUtil.getElementById(document, anchor_id, "*"); if (anchor == null) 227 topicExtension.getElement().setAttribute("failed", "true"); return anchor; 229 } 230 return null; 231 } 232 233 234 protected Document loadContentExtension(IConfigurationElement cfgElement) { 235 String content = cfgElement.getAttribute("file"); content = BundleUtil.getResourceLocation(content, cfgElement); 237 Document document = new UAContentParser(content).getDocument(); 238 return document; 239 } 240 241 242 private void doResolveContentReplace(Element topicReplace, Bundle bundle) { 243 UATopicExtension topicReplaceModel = new UATopicExtension(topicReplace, bundle); 244 boolean isExtensionToCurrentPage = resolveTopicReplace(topicReplaceModel); 245 if (isExtensionToCurrentPage) { 246 if (topicReplace.hasAttribute("failed")) { if (!unresolvedConfigExt.containsKey(topicReplace)) 248 unresolvedConfigExt.put(topicReplace, bundle); 249 } else { 250 unresolvedConfigExt.remove(topicReplace); 251 } 253 } 254 } 255 256 257 258 private boolean resolveTopicReplace(UATopicExtension topicReplace) { 259 260 Element replaceElement = findReplaceElementById(topicReplace, locale); 261 if (replaceElement == null) { 262 if (topicReplace.getElement().hasAttribute("failed")) return true; 264 else 265 return false; 266 } 267 Element[] elements = topicReplace.getElements(); 268 for (int i = 0; i < elements.length; i++) { 269 Node targetNode = document.importNode(elements[i], true); 270 replaceElement.getParentNode().insertBefore(targetNode, replaceElement); 271 } 272 replaceElement.getParentNode().removeChild(replaceElement); 273 return true; 274 } 275 276 private Element findReplaceElementById(UATopicExtension topicReplace, String locale) { 277 String path = topicReplace.getPath(); 278 int index = path.indexOf("/"); if (index < 0) 280 return null; 281 String pluginID = path.substring(0, index); 282 int lastIndex = path.lastIndexOf("/"); String pluginRelativePath = path.substring(index + 1, lastIndex); 284 String element_id = path.substring(lastIndex + 1, path.length()); 285 286 if (this.pluginID.equals(pluginID) && this.file.equals(pluginRelativePath)) { 287 Element elementToReplace = DOMUtil.getElementById(document, element_id, "*"); if (elementToReplace == null) 289 topicReplace.getElement().setAttribute("failed", "true"); return elementToReplace; 291 } 292 return null; 293 } 294 295 296 297 } 298 | Popular Tags |