KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > help > internal > extension > ContentExtensionManager


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.extension;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.core.runtime.CoreException;
21 import org.eclipse.core.runtime.IConfigurationElement;
22 import org.eclipse.core.runtime.IExtensionRegistry;
23 import org.eclipse.core.runtime.Platform;
24 import org.eclipse.help.AbstractContentExtensionProvider;
25 import org.eclipse.help.IContentExtension;
26 import org.eclipse.help.internal.HelpPlugin;
27 import org.eclipse.help.internal.UAElementFactory;
28
29 /*
30  * Manages content extensions (contributions into anchors and element
31  * replacements) for user assistance documents.
32  */

33 public class ContentExtensionManager {
34
35     private static final String JavaDoc EXTENSION_POINT_ID_CONTENT_EXTENSION = HelpPlugin.PLUGIN_ID + ".contentExtension"; //$NON-NLS-1$
36
private static final String JavaDoc ELEMENT_NAME_CONTENT_EXTENSION_PROVIDER = "contentExtensionProvider"; //$NON-NLS-1$
37
private static final String JavaDoc ATTRIBUTE_NAME_CLASS = "class"; //$NON-NLS-1$
38
private static final ContentExtension[] EMPTY_ARRAY = new ContentExtension[0];
39     
40     private AbstractContentExtensionProvider[] contentExtensionProviders;
41     private Map JavaDoc extensionsByPath;
42     private Map JavaDoc replacesByPath;
43     
44     /*
45      * Returns all known extensions for the given locale.
46      */

47     public ContentExtension[] getExtensions(String JavaDoc locale) {
48         if (extensionsByPath == null) {
49             loadExtensions(locale);
50         }
51         List JavaDoc extensions = new ArrayList JavaDoc();
52         Iterator JavaDoc iter = extensionsByPath.values().iterator();
53         while (iter.hasNext()) {
54             extensions.addAll((Collection JavaDoc)iter.next());
55         }
56         iter = replacesByPath.values().iterator();
57         while (iter.hasNext()) {
58             extensions.addAll((Collection JavaDoc)iter.next());
59         }
60         return (ContentExtension[])extensions.toArray(new ContentExtension[extensions.size()]);
61     }
62     
63     /*
64      * Get all extensions of the given type whose target matches the given path.
65      */

66     public ContentExtension[] getExtensions(String JavaDoc path, int type, String JavaDoc locale) {
67         if (extensionsByPath == null) {
68             loadExtensions(locale);
69         }
70         Map JavaDoc map = (type == ContentExtension.CONTRIBUTION ? extensionsByPath : replacesByPath);
71         List JavaDoc extensions = (List JavaDoc)map.get(path);
72         if (extensions != null) {
73             return (ContentExtension[])extensions.toArray(new ContentExtension[extensions.size()]);
74         }
75         return EMPTY_ARRAY;
76     }
77     
78     /*
79      * Clears all cached data, forcing the manager to query the
80      * providers again next time a request is made.
81      */

82     public void clearCache() {
83         if (extensionsByPath != null) {
84             extensionsByPath.clear();
85         }
86         if (replacesByPath != null) {
87             replacesByPath.clear();
88         }
89     }
90
91     /*
92      * Retrieves all extensions from all providers and organizes them by
93      * type.
94      */

95     private void loadExtensions(String JavaDoc locale) {
96         extensionsByPath = new HashMap JavaDoc();
97         replacesByPath = new HashMap JavaDoc();
98         contentExtensionProviders = getContentExtensionProviders();
99         for (int i=0;i<contentExtensionProviders.length;++i) {
100             IContentExtension[] extensions = contentExtensionProviders[i].getContentExtensions(locale);
101             for (int j=0;j<extensions.length;++j) {
102                 ContentExtension extension = (extensions[j] instanceof ContentExtension ? (ContentExtension)extensions[j] : (ContentExtension)UAElementFactory.newElement(extensions[j]));
103                 String JavaDoc content = extension.getContent();
104                 String JavaDoc path = extension.getPath();
105                 if (content != null && path != null) {
106                     int type = extension.getType();
107                     Map JavaDoc map = (type == IContentExtension.CONTRIBUTION ? extensionsByPath : replacesByPath);
108                     content = normalizePath(content);
109                     path = normalizePath(path);
110                     extension.setContent(content);
111                     extension.setPath(path);
112                     List JavaDoc list = (List JavaDoc)map.get(path);
113                     if (list == null) {
114                         list = new ArrayList JavaDoc();
115                         map.put(path, list);
116                     }
117                     list.add(extension);
118                 }
119             }
120         }
121     }
122     
123     /*
124      * Returns all registered content extension providers (potentially cached).
125      */

126     private AbstractContentExtensionProvider[] getContentExtensionProviders() {
127         if (contentExtensionProviders == null) {
128             List JavaDoc providers = new ArrayList JavaDoc();
129             IExtensionRegistry registry = Platform.getExtensionRegistry();
130             IConfigurationElement[] elements = registry.getConfigurationElementsFor(EXTENSION_POINT_ID_CONTENT_EXTENSION);
131             for (int i=0;i<elements.length;++i) {
132                 IConfigurationElement elem = elements[i];
133                 if (elem.getName().equals(ELEMENT_NAME_CONTENT_EXTENSION_PROVIDER)) {
134                     try {
135                         AbstractContentExtensionProvider provider = (AbstractContentExtensionProvider)elem.createExecutableExtension(ATTRIBUTE_NAME_CLASS);
136                         providers.add(provider);
137                     }
138                     catch (CoreException e) {
139                         // log and skip
140
String JavaDoc msg = "Error instantiating user assistance content extension provider class \"" + elem.getAttribute(ATTRIBUTE_NAME_CLASS) + '"'; //$NON-NLS-1$
141
HelpPlugin.logError(msg, e);
142                     }
143                 }
144             }
145             contentExtensionProviders = (AbstractContentExtensionProvider[])providers.toArray(new AbstractContentExtensionProvider[providers.size()]);
146         }
147         return contentExtensionProviders;
148     }
149     
150     /*
151      * Normalizes the given path by adding a leading slash if one doesn't
152      * exist, and converting the final slash into a '#' if it is thought to
153      * separate the end of the document with the element (legacy form).
154      */

155     private String JavaDoc normalizePath(String JavaDoc path) {
156         int bundleStart, bundleEnd;
157         int pathStart, pathEnd;
158         int elementStart, elementEnd;
159         
160         bundleStart = path.charAt(0) == '/' ? 1 : 0;
161         bundleEnd = path.indexOf('/', bundleStart);
162         
163         pathStart = bundleEnd + 1;
164         pathEnd = path.indexOf('#', pathStart);
165         if (pathEnd == -1) {
166             int lastSlash = path.lastIndexOf('/');
167             if (lastSlash > 0) {
168                 int secondLastSlash = path.lastIndexOf('/', lastSlash - 1);
169                 if (secondLastSlash != -1) {
170                     String JavaDoc secondLastToken = path.substring(secondLastSlash, lastSlash);
171                     boolean hasDot = (secondLastToken.indexOf('.') != -1);
172                     if (hasDot) {
173                         pathEnd = lastSlash;
174                     }
175                 }
176             }
177             if (pathEnd == -1) {
178                 pathEnd = path.length();
179             }
180         }
181         
182         elementStart = Math.min(pathEnd + 1, path.length());
183         elementEnd = path.length();
184         
185         if (bundleEnd > bundleStart && pathStart > bundleEnd && pathEnd > pathStart && elementStart >= pathEnd && elementEnd >= elementStart) {
186             String JavaDoc bundleId = path.substring(bundleStart, bundleEnd);
187             String JavaDoc relativePath = path.substring(pathStart, pathEnd);
188             String JavaDoc elementId = path.substring(elementStart, elementEnd);
189             path = '/' + bundleId + '/' + relativePath;
190             if (elementId.length() > 0) {
191                 path += '#' + elementId;
192             }
193         }
194         return path;
195     }
196 }
197
Popular Tags