KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > core > SearchablePluginsManager


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.pde.internal.core;
12
13 import java.io.ByteArrayInputStream JavaDoc;
14 import java.io.ByteArrayOutputStream JavaDoc;
15 import java.io.File JavaDoc;
16 import java.io.IOException JavaDoc;
17 import java.io.InputStream JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Locale JavaDoc;
21 import java.util.Map JavaDoc;
22 import java.util.Properties JavaDoc;
23 import java.util.Set JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25 import java.util.TreeMap JavaDoc;
26 import java.util.TreeSet JavaDoc;
27
28 import org.eclipse.core.resources.IFile;
29 import org.eclipse.core.resources.IProject;
30 import org.eclipse.core.resources.ISaveContext;
31 import org.eclipse.core.resources.ISaveParticipant;
32 import org.eclipse.core.resources.IWorkspaceRoot;
33 import org.eclipse.core.runtime.CoreException;
34 import org.eclipse.core.runtime.IPath;
35 import org.eclipse.core.runtime.NullProgressMonitor;
36 import org.eclipse.core.runtime.Path;
37 import org.eclipse.jdt.core.ElementChangedEvent;
38 import org.eclipse.jdt.core.IClasspathContainer;
39 import org.eclipse.jdt.core.IClasspathEntry;
40 import org.eclipse.jdt.core.IElementChangedListener;
41 import org.eclipse.jdt.core.IJavaElementDelta;
42 import org.eclipse.jdt.core.IJavaModel;
43 import org.eclipse.jdt.core.IJavaProject;
44 import org.eclipse.jdt.core.IPackageFragmentRoot;
45 import org.eclipse.jdt.core.JavaCore;
46 import org.eclipse.jdt.core.JavaModelException;
47 import org.eclipse.pde.core.plugin.IPluginModelBase;
48 import org.eclipse.pde.core.plugin.ModelEntry;
49 import org.eclipse.pde.core.plugin.PluginRegistry;
50
51 /**
52  * This class manages the ability of external plug-ins in the model manager to
53  * take part in the Java search. It manages a proxy Java projects and for each
54  * external plug-in added to Java search, it adds its Java libraries as external
55  * JARs to the proxy project. This makes the libraries visible to the Java
56  * model, and they can take part in various Java searches.
57  */

58 public class SearchablePluginsManager
59         implements IFileAdapterFactory, IPluginModelListener, ISaveParticipant {
60     
61     private static final String JavaDoc PROXY_FILE_NAME = ".searchable"; //$NON-NLS-1$
62
public static final String JavaDoc PROXY_PROJECT_NAME = "External Plug-in Libraries"; //$NON-NLS-1$
63
private static final String JavaDoc KEY = "searchablePlugins"; //$NON-NLS-1$
64

65     private Listener fElementListener;
66     private Set JavaDoc fPluginIdSet;
67     private ArrayList JavaDoc fListeners;
68
69     class Listener implements IElementChangedListener {
70         public void elementChanged(ElementChangedEvent e) {
71             if (e.getType() == ElementChangedEvent.POST_CHANGE) {
72                 handleDelta(e.getDelta());
73             }
74         }
75         private boolean handleDelta(IJavaElementDelta delta) {
76             Object JavaDoc element = delta.getElement();
77             if (element instanceof IJavaModel) {
78                 IJavaElementDelta[] projectDeltas = delta.getAffectedChildren();
79                 for (int i = 0; i < projectDeltas.length; i++) {
80                     if (handleDelta(projectDeltas[i]))
81                         break;
82                 }
83                 return true;
84             }
85             if (delta.getElement() instanceof IJavaProject) {
86                 IJavaProject project = (IJavaProject) delta.getElement();
87                 if (project.getElementName().equals(PROXY_PROJECT_NAME)) {
88                     if (delta.getKind() == IJavaElementDelta.REMOVED) {
89                         fPluginIdSet.clear();
90                     } else if (delta.getKind() == IJavaElementDelta.ADDED) {
91                         initializeStates();
92                     }
93                 }
94                 return true;
95             }
96             return false;
97         }
98     }
99
100     public SearchablePluginsManager() {
101         initializeStates();
102         fElementListener = new Listener();
103         JavaCore.addElementChangedListener(fElementListener);
104         PDECore.getDefault().getModelManager().addPluginModelListener(this);
105     }
106
107     private void initializeStates() {
108         fPluginIdSet = new TreeSet JavaDoc();
109         IWorkspaceRoot root = PDECore.getWorkspace().getRoot();
110         IProject project = root.getProject(PROXY_PROJECT_NAME);
111         if (project.exists() && project.isOpen()) {
112             IFile proxyFile = project.getFile(PROXY_FILE_NAME);
113             if (proxyFile.exists()) {
114                 Properties JavaDoc properties = new Properties JavaDoc();
115                 try {
116                     InputStream JavaDoc stream = proxyFile.getContents(true);
117                     properties.load(stream);
118                     stream.close();
119                     String JavaDoc value = properties.getProperty(KEY);
120                     if (value != null) {
121                         StringTokenizer JavaDoc stok = new StringTokenizer JavaDoc(value, ","); //$NON-NLS-1$
122
while(stok.hasMoreTokens())
123                             fPluginIdSet.add(stok.nextToken());
124                     }
125                 } catch (IOException JavaDoc e) {
126                 } catch (CoreException e) {
127                 }
128             }
129         }
130     }
131     
132     public IJavaProject getProxyProject() {
133         IWorkspaceRoot root = PDECore.getWorkspace().getRoot();
134         IProject project = root.getProject(PROXY_PROJECT_NAME);
135         try {
136             if (project.exists() && project.isOpen() && project.hasNature(JavaCore.NATURE_ID)) {
137                 return JavaCore.create(project);
138             }
139         } catch (CoreException e) {
140         }
141         return null;
142     }
143
144     public void shutdown() throws CoreException {
145         // remove listener
146
JavaCore.removeElementChangedListener(fElementListener);
147         PDECore.getDefault().getModelManager().removePluginModelListener(this);
148         if (fListeners != null)
149             fListeners.clear();
150     }
151     
152     public IClasspathEntry[] computeContainerClasspathEntries()
153             throws CoreException {
154         ArrayList JavaDoc result = new ArrayList JavaDoc();
155         
156         IPluginModelBase[] wModels = PluginRegistry.getWorkspaceModels();
157         for (int i = 0; i < wModels.length; i++) {
158             IProject project = wModels[i].getUnderlyingResource().getProject();
159             if (project.hasNature(JavaCore.NATURE_ID)) {
160                 result.add(JavaCore.newProjectEntry(project.getFullPath()));
161             }
162         }
163         Iterator JavaDoc iter = fPluginIdSet.iterator();
164         while (iter.hasNext()) {
165             ModelEntry entry = PluginRegistry.findEntry(iter.next().toString());
166             if (entry != null) {
167                 boolean addModel = true;
168                 wModels = entry.getWorkspaceModels();
169                 for (int i = 0; i < wModels.length; i++) {
170                     IProject project = wModels[i].getUnderlyingResource().getProject();
171                     if (project.hasNature(JavaCore.NATURE_ID))
172                         addModel = false;
173                 }
174                 if (!addModel)
175                     continue;
176                 IPluginModelBase[] models = entry.getExternalModels();
177                 for (int i = 0; i < models.length; i++) {
178                     if (models[i].isEnabled())
179                         ClasspathUtilCore.addLibraries(models[i], result);
180                 }
181             }
182         }
183         
184         if (result.size() > 1) {
185             // sort
186
Map JavaDoc map = new TreeMap JavaDoc();
187             for (int i = 0; i < result.size(); i++) {
188                 IClasspathEntry entry = (IClasspathEntry)result.get(i);
189                 String JavaDoc key = entry.getPath().lastSegment().toString();
190                 if (map.containsKey(key)) {
191                     key += System.currentTimeMillis();
192                 }
193                 map.put(key, entry);
194             }
195             return (IClasspathEntry[]) map.values().toArray(new IClasspathEntry[map.size()]);
196         }
197         return (IClasspathEntry[]) result.toArray(new IClasspathEntry[result.size()]);
198     }
199
200     public Object JavaDoc createAdapterChild(FileAdapter parent, File JavaDoc file) {
201         if (!file.isDirectory()) {
202             String JavaDoc name = file.getName().toLowerCase(Locale.ENGLISH);
203             try {
204                 if (name.endsWith(".jar")) { //$NON-NLS-1$
205
IPackageFragmentRoot root = findPackageFragmentRoot(new Path(file.getAbsolutePath()));
206                     if (root != null)
207                         return root;
208                 }
209             } catch (CoreException e) {
210                 PDECore.log(e);
211             }
212         }
213         return new FileAdapter(parent, file, this);
214     }
215
216     private IPackageFragmentRoot findPackageFragmentRoot(IPath jarPath) throws CoreException {
217         IJavaProject jProject = getProxyProject();
218         if (jProject != null) {
219             try {
220                 IPackageFragmentRoot[] roots = jProject.getAllPackageFragmentRoots();
221                 for (int i = 0; i < roots.length; i++) {
222                     IPackageFragmentRoot root = roots[i];
223                     IPath path = root.getPath();
224                     if (path.equals(jarPath))
225                         return root;
226     
227                 }
228             } catch (JavaModelException e) {
229             }
230         }
231     
232         // Find in other plugin (and fragments) projects dependencies
233
IPluginModelBase[] pluginModels = PluginRegistry.getWorkspaceModels();
234         for (int i = 0; i < pluginModels.length; i++) {
235             IProject project = pluginModels[i].getUnderlyingResource().getProject();
236             IJavaProject javaProject = JavaCore.create(project);
237             try {
238                 IPackageFragmentRoot[] roots = javaProject.getAllPackageFragmentRoots();
239                 for (int j = 0; j < roots.length; j++) {
240                     IPackageFragmentRoot root = roots[j];
241                     IPath path = root.getPath();
242                     if (path.equals(jarPath))
243                         return root;
244                 }
245             } catch (JavaModelException e) {
246             }
247         }
248
249         return null;
250     }
251         
252     public void addToJavaSearch(IPluginModelBase[] models) {
253         PluginModelDelta delta = new PluginModelDelta();
254         int size = fPluginIdSet.size();
255         for (int i = 0; i < models.length; i++) {
256             String JavaDoc id = models[i].getPluginBase().getId();
257             if (fPluginIdSet.add(id)) {
258                 ModelEntry entry = PluginRegistry.findEntry(id);
259                 if (entry != null)
260                     delta.addEntry(entry, PluginModelDelta.CHANGED);
261             }
262         }
263         if (fPluginIdSet.size() > size) {
264             resetContainer();
265             fireDelta(delta);
266         }
267     }
268     
269     public void removeFromJavaSearch(IPluginModelBase[] models) {
270         PluginModelDelta delta = new PluginModelDelta();
271         int size = fPluginIdSet.size();
272         for (int i = 0; i < models.length; i++) {
273             String JavaDoc id = models[i].getPluginBase().getId();
274             if (fPluginIdSet.remove(id)) {
275                 ModelEntry entry = PluginRegistry.findEntry(id);
276                 if (entry != null) {
277                     delta.addEntry(entry, PluginModelDelta.CHANGED);
278                 }
279             }
280         }
281         if (fPluginIdSet.size() < size) {
282             resetContainer();
283             fireDelta(delta);
284         }
285     }
286     
287     public boolean isInJavaSearch(String JavaDoc symbolicName) {
288         return fPluginIdSet.contains(symbolicName);
289     }
290     
291     private void resetContainer() {
292         IJavaProject jProject = getProxyProject();
293         try {
294             if (jProject != null) {
295                 JavaCore.setClasspathContainer(
296                         PDECore.JAVA_SEARCH_CONTAINER_PATH,
297                         new IJavaProject[] {jProject},
298                         new IClasspathContainer[]{new ExternalJavaSearchClasspathContainer()},
299                         null);
300             }
301         } catch (JavaModelException e) {
302         }
303     }
304
305     public void modelsChanged(PluginModelDelta delta) {
306         ModelEntry[] entries = delta.getRemovedEntries();
307         for (int i = 0; i < entries.length; i++) {
308             if (fPluginIdSet.contains(entries[i].getId())) {
309                 fPluginIdSet.remove(entries[i].getId());
310             }
311         }
312         resetContainer();
313     }
314     
315     private void fireDelta(PluginModelDelta delta) {
316         if (fListeners != null) {
317             for (int i = 0; i < fListeners.size(); i++) {
318                 ((IPluginModelListener)fListeners.get(i)).modelsChanged(delta);
319             }
320         }
321     }
322     
323     public void addPluginModelListener(IPluginModelListener listener) {
324         if (fListeners == null)
325             fListeners = new ArrayList JavaDoc();
326         if (!fListeners.contains(listener))
327             fListeners.add(listener);
328     }
329     
330     public void removePluginModelListener(IPluginModelListener listener) {
331         if (fListeners != null)
332             fListeners.remove(listener);
333     }
334
335     public void doneSaving(ISaveContext context) {
336         // nothing is required here
337
}
338
339     public void prepareToSave(ISaveContext context) throws CoreException {
340         // no need for preparation
341
}
342
343     public void rollback(ISaveContext context) {
344         // do nothing. not the end of the world.
345
}
346
347     public void saving(ISaveContext context) throws CoreException {
348         if (context.getKind() != ISaveContext.FULL_SAVE)
349             return;
350         
351         // persist state
352
IWorkspaceRoot root = PDECore.getWorkspace().getRoot();
353         IProject project = root.getProject(PROXY_PROJECT_NAME);
354         if (project.exists() && project.isOpen()) {
355             IFile file = project.getFile(PROXY_FILE_NAME);
356             Properties JavaDoc properties = new Properties JavaDoc();
357             StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
358             Iterator JavaDoc iter = fPluginIdSet.iterator();
359             while (iter.hasNext()) {
360                 if (buffer.length() > 0)
361                     buffer.append(","); //$NON-NLS-1$
362
buffer.append(iter.next().toString());
363             }
364             properties.setProperty(KEY, buffer.toString());
365             try {
366                 ByteArrayOutputStream JavaDoc outStream = new ByteArrayOutputStream JavaDoc();
367                 properties.store(outStream, ""); //$NON-NLS-1$
368
outStream.flush();
369                 outStream.close();
370                 ByteArrayInputStream JavaDoc inStream = new ByteArrayInputStream JavaDoc(outStream.toByteArray());
371                 if (file.exists())
372                     file.setContents(inStream, true, false, new NullProgressMonitor());
373                 else
374                     file.create(inStream, true, new NullProgressMonitor());
375                 inStream.close();
376             } catch (IOException JavaDoc e) {
377                 PDECore.log(e);
378             }
379         }
380     }
381     
382 }
383
Popular Tags