001: /**********************************************************************
002: Copyright (c) 2006 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015:
016: Contributors:
017: ...
018: **********************************************************************/package org.jpox.plugin;
019:
020: import java.io.IOException;
021: import java.lang.reflect.Constructor;
022: import java.lang.reflect.InvocationTargetException;
023: import java.net.URL;
024: import java.util.ArrayList;
025: import java.util.HashMap;
026: import java.util.List;
027: import java.util.Map;
028:
029: import org.eclipse.core.runtime.FileLocator;
030: import org.eclipse.core.runtime.IConfigurationElement;
031: import org.eclipse.core.runtime.IExtensionPoint;
032: import org.eclipse.core.runtime.InvalidRegistryObjectException;
033: import org.eclipse.core.runtime.Platform;
034: import org.eclipse.core.runtime.RegistryFactory;
035: import org.eclipse.osgi.service.resolver.BundleDescription;
036: import org.eclipse.osgi.service.resolver.BundleSpecification;
037: import org.eclipse.osgi.service.resolver.VersionRange;
038: import org.jpox.ClassLoaderResolver;
039:
040: /**
041: * Manages the registry of Extensions and Extension Points.
042: * @version $Revision: 1.10 $
043: */
044: public class EclipsePluginRegistry implements PluginRegistry {
045: /**
046: * Constructor
047: * @param clr the ClassLoaderResolver
048: */
049: public EclipsePluginRegistry(ClassLoaderResolver clr) {
050: //check if org.jpox.store_manager is a registered extension point
051: if (RegistryFactory.getRegistry() == null
052: || RegistryFactory.getRegistry().getExtensionPoint(
053: "org.jpox.store_manager") == null) {
054: throw new RuntimeException(
055: "This plug-in registry class can only be used if JPOX Core is managed by Eclipse.");
056: }
057: }
058:
059: /**
060: * Acessor for the ExtensionPoint
061: * @param id the unique id of the extension point
062: * @return null if the ExtensionPoint is not registered
063: */
064: public ExtensionPoint getExtensionPoint(String id) {
065: IExtensionPoint eclipseExPoint = RegistryFactory.getRegistry()
066: .getExtensionPoint(id);
067: Bundle plugin = new Bundle(eclipseExPoint.getContributor()
068: .getName(), "", "", "", null);
069:
070: org.osgi.framework.Bundle bundle = Platform
071: .getBundle(eclipseExPoint.getContributor().getName());
072: try {
073: ExtensionPoint exPoint = new ExtensionPoint(eclipseExPoint
074: .getSimpleIdentifier(), eclipseExPoint.getLabel(),
075: bundle.getResource(eclipseExPoint
076: .getSchemaReference()), plugin);
077: for (int e = 0; e < eclipseExPoint.getExtensions().length; e++) {
078: Bundle pluginEx = new Bundle(eclipseExPoint
079: .getExtensions()[e].getContributor().getName(),
080: "", "", "", null);
081: Extension ex = new Extension(exPoint, pluginEx);
082: configurationElement(ex,
083: eclipseExPoint.getExtensions()[e]
084: .getConfigurationElements(), null);
085: exPoint.addExtension(ex);
086: }
087: return exPoint;
088: } catch (InvalidRegistryObjectException e) {
089: //LOG
090: }
091: return null;
092: }
093:
094: /**
095: * process configuration elements
096: * @param ex the Extension
097: * @param elms the ConfigurationElements to process
098: * @param parent the parent of this ConfigurationElement. null if none
099: */
100: private void configurationElement(Extension ex,
101: IConfigurationElement[] elms, ConfigurationElement parent) {
102: for (int c = 0; c < elms.length; c++) {
103: IConfigurationElement iconfElm = elms[c];
104: ConfigurationElement confElm = new ConfigurationElement(ex,
105: iconfElm.getName(), null);
106: for (int a = 0; a < iconfElm.getAttributeNames().length; a++) {
107: confElm.putAttribute(iconfElm.getAttributeNames()[a],
108: iconfElm.getAttribute(iconfElm
109: .getAttributeNames()[a]));
110: }
111: confElm.setText(iconfElm.getValue());
112: if (parent == null) {
113: ex.addConfigurationElement(confElm);
114: } else {
115: parent.addConfigurationElement(confElm);
116: }
117: configurationElement(ex, iconfElm.getChildren(), confElm);
118: }
119: }
120:
121: /**
122: * Acessor for the currently registed ExtensionPoints
123: * @return array of ExtensionPoints
124: */
125: public ExtensionPoint[] getExtensionPoints() {
126: IExtensionPoint[] eclipseExPoint = RegistryFactory
127: .getRegistry().getExtensionPoints();
128: List elms = new ArrayList();
129: for (int i = 0; i < eclipseExPoint.length; i++) {
130: Bundle plugin = new Bundle(eclipseExPoint[i]
131: .getContributor().getName(), "", "", "", null);
132:
133: try {
134: org.osgi.framework.Bundle bundle = Platform
135: .getBundle(eclipseExPoint[i].getContributor()
136: .getName());
137: ExtensionPoint exPoint = new ExtensionPoint(
138: eclipseExPoint[i].getSimpleIdentifier(),
139: eclipseExPoint[i].getLabel(), bundle
140: .getResource(eclipseExPoint[i]
141: .getSchemaReference()), plugin);
142: for (int e = 0; e < eclipseExPoint[i].getExtensions().length; e++) {
143: Extension ex = new Extension(exPoint, plugin);
144: configurationElement(ex, eclipseExPoint[i]
145: .getExtensions()[e]
146: .getConfigurationElements(), null);
147: exPoint.addExtension(ex);
148: }
149: elms.add(exPoint);
150: } catch (InvalidRegistryObjectException e) {
151: //LOG
152: }
153: }
154: return (ExtensionPoint[]) elms.toArray(new ExtensionPoint[elms
155: .size()]);
156: }
157:
158: /**
159: * Register Extension Points
160: */
161: public void registerExtensionPoints() {
162: //ignore. done by Eclipse
163: }
164:
165: /**
166: * Register ExtensionPoints and Extensions declared in plugin files
167: */
168: public void registerExtensions() {
169: //ignore. done by Eclipse
170: }
171:
172: /**
173: * Converts a URL that uses a user-defined protocol into a URL that uses the file protocol.
174: * @param url the url to be converted
175: * @return the converted URL
176: * @throws IOException
177: */
178: public URL resolveURLAsFileURL(URL url) throws IOException {
179: return FileLocator.toFileURL(url);
180: }
181:
182: /**
183: * Loads a class (do not initialize) from an attribute of {@link ConfigurationElement}
184: * @param confElm the configuration element
185: * @param name the attribute name
186: * @return the Class
187: * @throws NoSuchMethodException
188: * @throws SecurityException
189: * @throws InvocationTargetException
190: * @throws IllegalAccessException
191: * @throws InstantiationException
192: * @throws IllegalArgumentException
193: */
194: public Object createExecutableExtension(
195: ConfigurationElement confElm, String name,
196: Class[] argsClass, Object[] args)
197: throws ClassNotFoundException, SecurityException,
198: NoSuchMethodException, IllegalArgumentException,
199: InstantiationException, IllegalAccessException,
200: InvocationTargetException {
201: Class cls = Platform.getBundle(
202: confElm.getExtension().getPlugin().getSymbolicName())
203: .loadClass(confElm.getAttribute(name));
204: Constructor constructor = cls.getConstructor(argsClass);
205: return constructor.newInstance(args);
206: }
207:
208: /**
209: * Loads a class (do not initialize)
210: * @param pluginId the plugin id
211: * @param className the class name
212: * @return the Class
213: * @throws ClassNotFoundException
214: */
215: public Class loadClass(String pluginId, String className)
216: throws ClassNotFoundException {
217: return Platform.getBundle(pluginId).loadClass(className);
218: }
219:
220: /**
221: * Resolve constraints declared in bundle manifest.mf files.
222: * This must be invoked after registering all bundles.
223: * Should log errors if bundles are not resolvable, or raise runtime exceptions.
224: */
225: public void resolveConstraints() {
226: //ignored. Eclipse will handle this
227: }
228:
229: /**
230: * Converts {@link BundleSpecification} into {@link BundleDescription}
231: * @param bs the {@link BundleSpecification}
232: * @return the {@link BundleDescription}
233: */
234: private Bundle.BundleDescription getBundleDescription(
235: BundleSpecification bs) {
236: Bundle.BundleDescription bd = new Bundle.BundleDescription();
237: bd.setBundleSymbolicName(bs.getBundle().getSymbolicName());
238: Map parameters = new HashMap();
239: if (bs.isOptional()) {
240: parameters.put("resolution", "optional");
241: }
242: if (VersionRange.emptyRange != bs.getVersionRange()) {
243: parameters.put("bundle-version", bs.getVersionRange()
244: .toString());
245: }
246: bd.setParameters(parameters);
247: return bd;
248: }
249:
250: /**
251: * Accessor for all registered bundles
252: * @return the bundles
253: * @throws UnsupportedOperationException if this operation is not supported by the implementation
254: */
255: public Bundle[] getBundles() {
256: int size = Platform.getPlatformAdmin().getState().getBundles().length;
257: Bundle[] bundles = new Bundle[size];
258: for (int i = 0; i < size; i++) {
259: BundleDescription bd = Platform.getPlatformAdmin()
260: .getState().getBundles()[i];
261: bundles[i] = new Bundle(bd.getSymbolicName(), bd
262: .getSymbolicName(), bd.getSupplier().getName(), bd
263: .getVersion().toString(), null);
264: BundleSpecification[] bs = bd.getRequiredBundles();
265: List requiredBundles = new ArrayList();
266: for (int j = 0; j < bs.length; j++) {
267: requiredBundles.add(getBundleDescription(bs[j]));
268: }
269: bundles[i].setRequireBundle(requiredBundles);
270: }
271: return bundles;
272: }
273: }
|