KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2005, 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.File JavaDoc;
14 import java.io.FileNotFoundException JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.net.MalformedURLException JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Dictionary JavaDoc;
20 import java.util.HashMap JavaDoc;
21
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IProject;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.IStatus;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.osgi.service.pluginconversion.PluginConversionException;
30 import org.eclipse.osgi.service.resolver.BundleDescription;
31 import org.eclipse.osgi.service.resolver.State;
32 import org.eclipse.pde.core.plugin.IPluginModelBase;
33 import org.eclipse.pde.core.plugin.PluginRegistry;
34 import org.eclipse.pde.internal.core.bundle.BundleFragmentModel;
35 import org.eclipse.pde.internal.core.bundle.BundlePluginModel;
36 import org.eclipse.pde.internal.core.bundle.BundlePluginModelBase;
37 import org.eclipse.pde.internal.core.bundle.WorkspaceBundleModel;
38 import org.eclipse.pde.internal.core.plugin.ExternalFragmentModel;
39 import org.eclipse.pde.internal.core.plugin.ExternalPluginModel;
40 import org.eclipse.pde.internal.core.plugin.ExternalPluginModelBase;
41 import org.eclipse.pde.internal.core.plugin.WorkspaceExtensionsModel;
42 import org.eclipse.pde.internal.core.plugin.WorkspaceFragmentModel;
43 import org.eclipse.pde.internal.core.plugin.WorkspacePluginModel;
44 import org.eclipse.pde.internal.core.plugin.WorkspacePluginModelBase;
45 import org.eclipse.pde.internal.core.util.CoreUtility;
46 import org.w3c.dom.Node JavaDoc;
47
48
49 public class PDEState extends MinimalState {
50     
51     private PDEExtensionRegistry fExtensionRegistry;
52     private PDEAuxiliaryState fAuxiliaryState;
53     
54     private ArrayList JavaDoc fTargetModels = new ArrayList JavaDoc();
55     private ArrayList JavaDoc fWorkspaceModels = new ArrayList JavaDoc();
56     private boolean fCombined;
57     private long fTargetTimestamp;
58     private boolean fNewState;
59     
60     public PDEState(PDEState state) {
61         super(state);
62         fTargetModels = new ArrayList JavaDoc(state.fTargetModels);
63         fCombined = false;
64         fTargetTimestamp = state.fTargetTimestamp;
65         fAuxiliaryState = new PDEAuxiliaryState(state.fAuxiliaryState);
66         if (fAuxiliaryState.fPluginInfos.isEmpty())
67             fAuxiliaryState.readPluginInfoCache(new File JavaDoc(DIR, Long.toString(fTargetTimestamp) + ".target")); //$NON-NLS-1$
68
fExtensionRegistry = new PDEExtensionRegistry(state.fExtensionRegistry);
69     }
70     
71     public PDEState(URL JavaDoc[] urls, boolean resolve, IProgressMonitor monitor) {
72         this(new URL JavaDoc[0], urls, resolve, monitor);
73     }
74     
75     public PDEState(URL JavaDoc[] workspace, URL JavaDoc[] target, boolean resolve, IProgressMonitor monitor) {
76         long start = System.currentTimeMillis();
77         fExtensionRegistry = new PDEExtensionRegistry();
78         fAuxiliaryState = new PDEAuxiliaryState();
79         
80         if (resolve) {
81             readTargetState(target, monitor);
82         } else {
83             createNewTargetState(resolve, target, monitor);
84             fExtensionRegistry.createExtensionDocument(fState);
85         }
86         createTargetModels(fState.getBundles());
87         
88         if (resolve && workspace.length > 0 && !fNewState && !"true".equals(System.getProperty("pde.nocache"))) //$NON-NLS-1$ //$NON-NLS-2$
89
readWorkspaceState(workspace);
90         
91         fExtensionRegistry.clear();
92         fAuxiliaryState.clear();
93         
94         if (DEBUG)
95             System.out.println("Time to create state: " + (System.currentTimeMillis() - start) + " ms"); //$NON-NLS-1$ //$NON-NLS-2$
96
}
97     
98     private void readTargetState(URL JavaDoc[] urls, IProgressMonitor monitor) {
99         fTargetTimestamp = computeTimestamp(urls);
100         File JavaDoc dir = new File JavaDoc(DIR, Long.toString(fTargetTimestamp) + ".target"); //$NON-NLS-1$
101
if ((fState = readStateCache(dir)) == null || !fAuxiliaryState.readPluginInfoCache(dir)) {
102             createNewTargetState(true, urls, monitor);
103             if (!dir.exists())
104                 dir.mkdirs();
105             fAuxiliaryState.savePluginInfo(dir);
106             resolveState(false);
107             saveState(dir);
108         } else {
109             boolean propertiesChanged = initializePlatformProperties();
110             fState.setResolver(Platform.getPlatformAdmin().getResolver());
111             if (propertiesChanged)
112                 fState.resolve(false);
113             fId = fState.getBundles().length;
114         }
115         if (!fExtensionRegistry.readExtensionsCache(dir))
116             fExtensionRegistry.saveExtensions(fState, dir);
117     }
118     
119     private void createNewTargetState(boolean resolve, URL JavaDoc[] urls, IProgressMonitor monitor) {
120         fState = stateObjectFactory.createState(resolve);
121         monitor.beginTask("", urls.length); //$NON-NLS-1$
122
for (int i = 0; i < urls.length; i++) {
123             File JavaDoc file = new File JavaDoc(urls[i].getFile());
124             try {
125                 if (monitor.isCanceled())
126                     // if canceled, stop loading bundles
127
return;
128                 monitor.subTask(file.getName());
129                 addBundle(file, -1);
130             } catch (PluginConversionException e) {
131             } catch (CoreException e) {
132             } catch (IOException JavaDoc e) {
133                 PDECore.log(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, IStatus.ERROR,
134                         "Invalid manifest format at " + file.getAbsolutePath(), //$NON-NLS-1$
135
null));
136             } finally {
137                 monitor.worked(1);
138             }
139         }
140         fNewState = true;
141     }
142     
143     protected void addAuxiliaryData(BundleDescription desc, Dictionary JavaDoc manifest, boolean hasBundleStructure) {
144         fAuxiliaryState.addAuxiliaryData(desc, manifest, hasBundleStructure);
145     }
146
147     public IPluginModelBase[] createTargetModels(BundleDescription[] bundleDescriptions) {
148         HashMap JavaDoc models = new HashMap JavaDoc((4/3) * bundleDescriptions.length + 1);
149         for (int i = 0; i < bundleDescriptions.length; i++) {
150             BundleDescription desc = bundleDescriptions[i];
151             IPluginModelBase base = createExternalModel(desc);
152             fTargetModels.add(base);
153             models.put(desc.getSymbolicName(), base);
154         }
155         if (models.isEmpty())
156             return new IPluginModelBase[0];
157         return (IPluginModelBase[]) models.values().toArray(new IPluginModelBase[models.size()]);
158     }
159     
160     private void readWorkspaceState(URL JavaDoc[] urls) {
161         long workspace = computeTimestamp(urls);
162         File JavaDoc dir = new File JavaDoc(DIR, Long.toString(workspace) + ".workspace"); //$NON-NLS-1$
163
State localState = readStateCache(dir);
164         fCombined = localState != null
165                         && fAuxiliaryState.readPluginInfoCache(dir)
166                         && fExtensionRegistry.readExtensionsCache(dir);
167         if (fCombined) {
168             long targetCount = fId;
169             BundleDescription[] bundles = localState.getBundles();
170             for (int i = 0; i < bundles.length; i++) {
171                 BundleDescription desc = bundles[i];
172                 String JavaDoc id = desc.getSymbolicName();
173                 BundleDescription[] conflicts = fState.getBundles(id);
174                 
175                 for (int j = 0; j < conflicts.length; j++) {
176                     // only remove bundles with a conflicting symblic name
177
// if the conflicting bundles come from the target.
178
// Workspace bundles with conflicting symbolic names are allowed
179
if (conflicts[j].getBundleId() <= targetCount)
180                         fState.removeBundle(conflicts[j]);
181                 }
182                 
183                 BundleDescription newbundle = stateObjectFactory.createBundleDescription(desc);
184                 IPluginModelBase model = createWorkspaceModel(newbundle);
185                 if (model != null && fState.addBundle(newbundle)) {
186                     fId = Math.max(fId, newbundle.getBundleId());
187                     fWorkspaceModels.add(model);
188                 }
189             }
190             fId = Math.max(fId, fState.getBundles().length);
191             fState.resolve(false);
192         }
193     }
194     
195     public boolean isCombined() {
196         return fCombined;
197     }
198
199     private State readStateCache(File JavaDoc dir) {
200         if (dir.exists() && dir.isDirectory()) {
201             try {
202                 return stateObjectFactory.readState(dir);
203             } catch (IllegalStateException JavaDoc e) {
204                 PDECore.log(e);
205             } catch (FileNotFoundException JavaDoc e) {
206                 PDECore.log(e);
207             } catch (IOException JavaDoc e) {
208                 PDECore.log(e);
209             } finally {
210             }
211         }
212         return null;
213     }
214     
215     private long computeTimestamp(URL JavaDoc[] urls) {
216         return computeTimestamp(urls, 0);
217     }
218     
219     private long computeTimestamp(URL JavaDoc[] urls, long timestamp) {
220         for (int i = 0; i < urls.length; i++) {
221             File JavaDoc file = new File JavaDoc(urls[i].getFile());
222             if (file.exists()) {
223                 if (file.isFile()) {
224                     timestamp ^= file.lastModified();
225                 } else {
226                     File JavaDoc manifest = new File JavaDoc(file, "META-INF/MANIFEST.MF"); //$NON-NLS-1$
227
if (manifest.exists())
228                         timestamp ^= manifest.lastModified();
229                     manifest = new File JavaDoc(file, "plugin.xml"); //$NON-NLS-1$
230
if (manifest.exists())
231                         timestamp ^= manifest.lastModified();
232                     manifest = new File JavaDoc(file, "fragment.xml"); //$NON-NLS-1$
233
if (manifest.exists())
234                         timestamp ^= manifest.lastModified();
235                 }
236                 timestamp ^= file.getAbsolutePath().hashCode();
237             }
238         }
239         return timestamp;
240     }
241     
242     private IPluginModelBase createWorkspaceModel(BundleDescription desc) {
243         String JavaDoc projectName = fAuxiliaryState.getProject(desc.getBundleId());
244         if (projectName == null)
245             return null;
246         IProject project = PDECore.getWorkspace().getRoot().getProject(projectName);
247         if (!project.exists())
248             return null;
249         if (project.exists(ICoreConstants.MANIFEST_PATH)) {
250             BundlePluginModelBase model = null;
251             if (desc.getHost() == null)
252                 model = new BundlePluginModel();
253             else
254                 model = new BundleFragmentModel();
255             model.setEnabled(true);
256             WorkspaceBundleModel bundle = new WorkspaceBundleModel(project.getFile("META-INF/MANIFEST.MF")); //$NON-NLS-1$
257
bundle.load(desc, this);
258             model.setBundleDescription(desc);
259             model.setBundleModel(bundle);
260             
261             String JavaDoc filename = (desc.getHost() == null) ? "plugin.xml" : "fragment.xml"; //$NON-NLS-1$ //$NON-NLS-2$
262
IFile file = project.getFile(filename);
263             if (file.exists()) {
264                 WorkspaceExtensionsModel extensions = new WorkspaceExtensionsModel(file);
265                 extensions.load(desc, this);
266                 extensions.setBundleModel(model);
267                 model.setExtensionsModel(extensions);
268             }
269             return model;
270         }
271         
272         WorkspacePluginModelBase model = null;
273         if (desc.getHost() == null)
274             model = new WorkspacePluginModel(project.getFile("plugin.xml"), true); //$NON-NLS-1$
275
else
276             model = new WorkspaceFragmentModel(project.getFile("fragment.xml"), true); //$NON-NLS-1$
277
model.load(desc, this);
278         model.setBundleDescription(desc);
279         return model;
280     }
281
282     private IPluginModelBase createExternalModel(BundleDescription desc) {
283         ExternalPluginModelBase model = null;
284         if (desc.getHost() == null)
285             model = new ExternalPluginModel();
286         else
287             model = new ExternalFragmentModel();
288         model.load(desc, this);
289         model.setBundleDescription(desc);
290         return model;
291     }
292     
293     public IPluginModelBase[] getTargetModels() {
294         return (IPluginModelBase[])fTargetModels.toArray(new IPluginModelBase[fTargetModels.size()]);
295     }
296     
297     public IPluginModelBase[] getWorkspaceModels() {
298         return (IPluginModelBase[])fWorkspaceModels.toArray(new IPluginModelBase[fWorkspaceModels.size()]);
299     }
300     
301     public void shutdown() {
302         IPluginModelBase[] models = PluginRegistry.getWorkspaceModels();
303         long timestamp = 0;
304         if (!"true".equals(System.getProperty("pde.nocache")) && shouldSaveState(models)) { //$NON-NLS-1$ //$NON-NLS-2$
305
timestamp = computeTimestamp(models);
306             File JavaDoc dir = new File JavaDoc(DIR, Long.toString(timestamp) + ".workspace"); //$NON-NLS-1$
307
State state = stateObjectFactory.createState(false);
308             for (int i = 0; i < models.length; i++) {
309                 state.addBundle(models[i].getBundleDescription());
310             }
311             saveState(state, dir);
312             PDEAuxiliaryState.writePluginInfo(models, dir);
313             PDEExtensionRegistry.writeExtensions(models, dir);
314         }
315         clearStaleStates(".target", fTargetTimestamp); //$NON-NLS-1$
316
clearStaleStates(".workspace", timestamp); //$NON-NLS-1$
317
clearStaleStates(".cache", 0); //$NON-NLS-1$
318
}
319     
320     private long computeTimestamp(IPluginModelBase[] models) {
321         URL JavaDoc[] urls = new URL JavaDoc[models.length];
322         for (int i = 0; i < models.length; i++) {
323             try {
324                 IProject project = models[i].getUnderlyingResource().getProject();
325                 urls[i] = new File JavaDoc(project.getLocation().toString()).toURL();
326             } catch (MalformedURLException JavaDoc e) {
327             }
328         }
329         return computeTimestamp(urls);
330     }
331     
332     private boolean shouldSaveState(IPluginModelBase[] models) {
333         for (int i = 0; i < models.length; i++) {
334             String JavaDoc id = models[i].getPluginBase().getId();
335             if (id == null
336                     || id.trim().length() == 0
337                     || !models[i].isLoaded()
338                     || !models[i].isInSync()
339                     || models[i].getBundleDescription() == null)
340                 return false;
341         }
342         return models.length > 0;
343     }
344     
345     private void clearStaleStates(String JavaDoc extension, long latest) {
346         File JavaDoc dir = new File JavaDoc(PDECore.getDefault().getStateLocation().toOSString());
347         File JavaDoc[] children = dir.listFiles();
348         if (children != null) {
349             for (int i = 0; i < children.length; i++) {
350                 File JavaDoc child = children[i];
351                 if (child.isDirectory()) {
352                     String JavaDoc name = child.getName();
353                     if (name.endsWith(extension)
354                             && name.length() > extension.length()
355                             && !name.equals(Long.toString(latest) + extension)) {
356                         CoreUtility.deleteContent(child);
357                     }
358                 }
359             }
360         }
361     }
362     
363     public Node JavaDoc[] getExtensions(long bundleID) {
364         return fExtensionRegistry.getExtensions(bundleID);
365     }
366     
367     public Node JavaDoc[] getExtensionPoints(long bundleID) {
368         return fExtensionRegistry.getExtensionPoints(bundleID);
369     }
370
371     public Node JavaDoc[] getAllExtensions(long bundleID) {
372         return fExtensionRegistry.getAllExtensions(bundleID);
373     }
374     
375     public String JavaDoc getClassName(long bundleID) {
376         return fAuxiliaryState.getClassName(bundleID);
377     }
378     
379     public boolean hasExtensibleAPI(long bundleID) {
380         return fAuxiliaryState.hasExtensibleAPI(bundleID);
381     }
382
383     public boolean isPatchFragment(long bundleID) {
384         return fAuxiliaryState.isPatchFragment(bundleID);
385     }
386     
387     public boolean hasBundleStructure(long bundleID) {
388         return fAuxiliaryState.hasBundleStructure(bundleID);
389     }
390     
391     public String JavaDoc getSchemaVersion(long bundleID) {
392         return fExtensionRegistry.getSchemaVersion(bundleID);
393     }
394
395     public String JavaDoc getPluginName(long bundleID) {
396         return fAuxiliaryState.getPluginName(bundleID);
397     }
398     
399     public String JavaDoc getProviderName(long bundleID) {
400         return fAuxiliaryState.getProviderName(bundleID);
401     }
402     
403     public String JavaDoc[] getLibraryNames(long bundleID) {
404         return fAuxiliaryState.getLibraryNames(bundleID);
405     }
406     
407     public String JavaDoc getBundleLocalization(long bundleID) {
408         return fAuxiliaryState.getBundleLocalization(bundleID);
409     }
410     
411     public String JavaDoc getProject(long bundleID) {
412         return fAuxiliaryState.getProject(bundleID);
413     }
414     
415     public BundleDescription[] addAdditionalBundles(URL JavaDoc[] newBundleURLs) {
416         // add new Bundles to the State
417
ArrayList JavaDoc descriptions = new ArrayList JavaDoc(newBundleURLs.length);
418         for (int i = 0; i < newBundleURLs.length; i++) {
419             File JavaDoc file = new File JavaDoc(newBundleURLs[i].getFile());
420             try {
421                 BundleDescription desc = addBundle(file, -1);
422                 if (desc != null)
423                     descriptions.add(desc);
424             } catch (PluginConversionException e) {
425             } catch (CoreException e) {
426             } catch (IOException JavaDoc e) {
427                 PDECore.log(new Status(IStatus.ERROR, PDECore.PLUGIN_ID, IStatus.ERROR,
428                         "Invalid manifest format at " + file.getAbsolutePath(), //$NON-NLS-1$
429
null));
430             }
431         }
432         // compute Timestamp and save all new information
433
fTargetTimestamp = computeTimestamp(newBundleURLs, fTargetTimestamp);
434         File JavaDoc dir = new File JavaDoc(DIR, Long.toString(fTargetTimestamp) + ".target"); //$NON-NLS-1$
435
if (!dir.exists())
436             dir.mkdirs();
437         fAuxiliaryState.savePluginInfo(dir);
438         saveState(dir);
439         fExtensionRegistry.saveExtensions(fState, dir);
440         
441         // resolve state - same steps as when populating a new State
442
resolveState(false);
443         
444         return (BundleDescription[]) descriptions.toArray(new BundleDescription[descriptions.size()]);
445     }
446
447 }
448
Popular Tags