001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core;
011:
012: import java.io.File;
013: import java.util.ArrayList;
014: import java.util.HashMap;
015: import java.util.ListIterator;
016:
017: import org.eclipse.core.runtime.IContributor;
018: import org.eclipse.core.runtime.IExtension;
019: import org.eclipse.core.runtime.IExtensionPoint;
020: import org.eclipse.core.runtime.IExtensionRegistry;
021: import org.eclipse.core.runtime.IRegistryChangeListener;
022: import org.eclipse.core.runtime.RegistryFactory;
023: import org.eclipse.pde.core.plugin.IPluginExtension;
024: import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
025: import org.eclipse.pde.core.plugin.IPluginModelBase;
026: import org.eclipse.pde.core.plugin.ISharedPluginModel;
027: import org.eclipse.pde.core.plugin.PluginRegistry;
028: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
029: import org.eclipse.pde.internal.core.plugin.PluginExtension;
030: import org.eclipse.pde.internal.core.plugin.PluginExtensionPoint;
031: import org.eclipse.pde.internal.core.util.CoreUtility;
032:
033: public class PDEExtensionRegistry {
034:
035: private Object fMasterKey = new Object();
036: private Object fUserKey = new Object();
037: private IExtensionRegistry fRegistry = null;
038: private PDERegistryStrategy fStrategy = null;
039:
040: private IPluginModelBase[] fModels = null;
041: private ArrayList fListeners = new ArrayList();
042:
043: private static final String EXTENSION_DIR = ".extensions"; //$NON-NLS-1$
044:
045: public PDEExtensionRegistry() {
046: if (fStrategy == null) {
047: File extensionsDir = new File(PDECore.getDefault()
048: .getStateLocation().toFile(), EXTENSION_DIR);
049: // create the strategy without creating registry. That way we create the registry at the last possible moment.
050: // This way we can listen to events in PDE without creating the registry until we need it.
051: fStrategy = new PDERegistryStrategy(
052: new File[] { extensionsDir },
053: new boolean[] { false }, fMasterKey, this );
054: }
055: }
056:
057: public PDEExtensionRegistry(IPluginModelBase[] models) {
058: fModels = models;
059: if (fStrategy == null) {
060: File extensionsDir = new File(PDECore.getDefault()
061: .getStateLocation().toFile(), EXTENSION_DIR);
062: // Use TargetPDERegistryStrategy so we don't connect listeners to PluginModelManager. This is used only in target so we don't need change events.
063: fStrategy = new TargetPDERegistryStrategy(
064: new File[] { extensionsDir },
065: new boolean[] { false }, fMasterKey, this );
066: }
067: }
068:
069: // Methods used to control information/status of Extension Registry
070:
071: protected IPluginModelBase[] getModels() {
072: return (fModels == null) ? PluginRegistry.getActiveModels()
073: : fModels;
074: }
075:
076: public void stop() {
077: if (fRegistry != null)
078: fRegistry.stop(fMasterKey);
079: dispose();
080: }
081:
082: protected synchronized IExtensionRegistry getRegistry() {
083: if (fRegistry == null) {
084: fRegistry = createRegistry();
085: for (ListIterator li = fListeners.listIterator(); li
086: .hasNext();)
087: fRegistry
088: .addRegistryChangeListener((IRegistryChangeListener) li
089: .next());
090: }
091: return fRegistry;
092: }
093:
094: private IExtensionRegistry createRegistry() {
095: return RegistryFactory.createRegistry(fStrategy, fMasterKey,
096: fUserKey);
097: }
098:
099: public void targetReloaded() {
100: // stop old registry (which will write contents to FS) and delete the cache it creates
101: // might see if we can dispose of a registry without writing to file system. NOTE: Don't call stop() because we want to still reuse fStrategy
102: if (fRegistry != null)
103: fRegistry.stop(fMasterKey);
104: CoreUtility.deleteContent(new File(PDECore.getDefault()
105: .getStateLocation().toFile(), EXTENSION_DIR));
106: fRegistry = null;
107: }
108:
109: // dispose of registry without writing contents.
110: public void dispose() {
111: fStrategy.dispose();
112: fRegistry = null;
113: }
114:
115: // Methods to access data in Extension Registry
116:
117: public IPluginModelBase[] findExtensionPlugins(String pointId) {
118: IExtensionPoint point = getExtensionPoint(pointId);
119: if (point == null) {
120: // if extension point for extension does not exist, search all plug-ins manually
121: return PluginRegistry.getAllModels();
122: }
123: IExtension[] exts = point.getExtensions();
124: HashMap plugins = new HashMap();
125: for (int i = 0; i < exts.length; i++) {
126: String pluginId = exts[i].getContributor().getName();
127: if (plugins.containsKey(pluginId))
128: continue;
129: IPluginModelBase base = PluginRegistry.findModel(pluginId);
130: if (base != null)
131: plugins.put(pluginId, base);
132: }
133: java.util.Collection values = plugins.values();
134: return (IPluginModelBase[]) values
135: .toArray(new IPluginModelBase[values.size()]);
136: }
137:
138: public IPluginModelBase findExtensionPointPlugin(String pointId) {
139: IExtensionPoint point = getExtensionPoint(pointId);
140: if (point == null) {
141: return null;
142: }
143: IContributor contributor = point.getContributor();
144: return PluginRegistry.findModel(contributor.getName());
145: }
146:
147: private IExtensionPoint getExtensionPoint(String pointId) {
148: return getRegistry().getExtensionPoint(pointId);
149: }
150:
151: public boolean hasExtensionPoint(String pointId) {
152: return getExtensionPoint(pointId) != null;
153: }
154:
155: public IPluginExtensionPoint findExtensionPoint(String pointId) {
156: IExtensionPoint extPoint = getExtensionPoint(pointId);
157: if (extPoint != null) {
158: IPluginModelBase model = PluginRegistry.findModel(extPoint
159: .getContributor().getName());
160: if (model != null) {
161: IPluginExtensionPoint[] points = model.getPluginBase()
162: .getExtensionPoints();
163: for (int i = 0; i < points.length; i++) {
164: IPluginExtensionPoint point = points[i];
165: if (points[i].getFullId().equals(pointId)) {
166: return point;
167: }
168: }
169: }
170: }
171: return null;
172: }
173:
174: public IPluginExtension[] findExtensionsForPlugin(String pluginId) {
175: IPluginModelBase base = PluginRegistry.findModel(pluginId);
176: IContributor contributor = fStrategy.createContributor(base);
177: if (contributor == null)
178: return new IPluginExtension[0];
179: IExtension[] extensions = getRegistry().getExtensions(
180: fStrategy.createContributor(base));
181: ArrayList list = new ArrayList();
182: for (int i = 0; i < extensions.length; i++) {
183: PluginExtension extension = new PluginExtension(
184: extensions[i]);
185: extension.setModel(getExtensionsModel(base));
186: extension.setParent(base.getExtensions());
187: list.add(extension);
188: }
189: return (IPluginExtension[]) list
190: .toArray(new IPluginExtension[list.size()]);
191: }
192:
193: public IPluginExtensionPoint[] findExtensionPointsForPlugin(
194: String pluginId) {
195: IPluginModelBase base = PluginRegistry.findModel(pluginId);
196: IContributor contributor = fStrategy.createContributor(base);
197: if (contributor == null)
198: return new IPluginExtensionPoint[0];
199: IExtensionPoint[] extensions = getRegistry()
200: .getExtensionPoints(fStrategy.createContributor(base));
201: ArrayList list = new ArrayList();
202: for (int i = 0; i < extensions.length; i++) {
203: PluginExtensionPoint point = new PluginExtensionPoint(
204: extensions[i]);
205: point.setModel(getExtensionsModel(base));
206: point.setParent(base.getExtensions());
207: list.add(point);
208: }
209: return (IPluginExtensionPoint[]) list
210: .toArray(new IPluginExtensionPoint[list.size()]);
211: }
212:
213: private ISharedPluginModel getExtensionsModel(IPluginModelBase base) {
214: if (base instanceof IBundlePluginModelBase)
215: return ((IBundlePluginModelBase) base).getExtensionsModel();
216: return base;
217: }
218:
219: public IExtension[] findExtensions(String extensionPointId) {
220: IExtensionPoint point = getExtensionPoint(extensionPointId);
221: if (point != null)
222: return point.getExtensions();
223: ArrayList list = new ArrayList();
224: IPluginModelBase[] bases = PluginRegistry.getActiveModels();
225: for (int i = 0; i < bases.length; i++) {
226: IContributor contributor = fStrategy
227: .createContributor(bases[i]);
228: if (contributor == null)
229: continue;
230: IExtension[] extensions = getRegistry().getExtensions(
231: contributor);
232: for (int j = 0; j < extensions.length; j++) {
233: if (extensions[j].getExtensionPointUniqueIdentifier()
234: .equals(extensionPointId))
235: list.add(extensions[j]);
236: }
237: }
238: return (IExtension[]) list.toArray(new IExtension[list.size()]);
239: }
240:
241: // Methods to add/remove listeners
242:
243: public void addListener(IRegistryChangeListener listener) {
244: fRegistry.addRegistryChangeListener(listener);
245: if (!fListeners.contains(listener))
246: fListeners.add(listener);
247: }
248:
249: public void removeListener(IRegistryChangeListener listener) {
250: fRegistry.removeRegistryChangeListener(listener);
251: fListeners.remove(listener);
252: }
253:
254: }
|