KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > update > internal > core > FeaturePackagedContentProvider


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.update.internal.core;
12
13 import java.io.*;
14 import java.net.URL JavaDoc;
15 import java.util.*;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.osgi.internal.provisional.verifier.CertificateVerifierFactory;
20 import org.eclipse.osgi.util.NLS;
21 import org.eclipse.update.core.*;
22 import org.eclipse.update.internal.jarprocessor.JarProcessor;
23 import org.eclipse.update.internal.jarprocessor.Utils;
24 import org.eclipse.update.internal.security.JarVerifier;
25 import org.eclipse.update.internal.verifier.CertVerifier;
26
27 /**
28  * Content Provider of a Feature Package
29  */

30 public class FeaturePackagedContentProvider extends FeatureContentProvider {
31
32     private ContentReference localManifest = null;
33     private ContentReference[] localFeatureFiles = new ContentReference[0];
34     private IVerifier jarVerifier = null;
35     private ExtendedSite siteModel = null;
36     private boolean continueOnError;
37     /*
38      * filter for file with .jar
39      */

40     public static final FilenameFilter filter = new FilenameFilter() {
41         public boolean accept(File dir, String JavaDoc name) {
42             return name.endsWith(FeaturePackagedContentProvider.JAR_EXTENSION);
43         }
44     };
45
46     /*
47      * Constructor
48      */

49     public FeaturePackagedContentProvider(URL JavaDoc url, ISite site) {
50         super(url);
51         if (site instanceof ExtendedSite) {
52             this.siteModel = (ExtendedSite) site;
53         }
54     }
55     
56     /*
57      * Returns a new verifier for each top-level install
58      * (if the verifier has a parent, return the verifier
59      * otherwise reinitialize)
60      */

61     public IVerifier getVerifier() throws CoreException {
62         CertificateVerifierFactory factory = UpdateCore.getPlugin().getVerifierFactory();
63         if (jarVerifier == null || jarVerifier.getParent() == null) {
64             if (factory != null)
65                 jarVerifier = new CertVerifier(UpdateCore.getPlugin().getVerifierFactory());
66             else
67                 jarVerifier = new JarVerifier();
68             return jarVerifier;
69         }
70
71         // re-init will be done if the parent changes
72
return jarVerifier;
73     }
74
75     /*
76      * @see IFeatureContentProvider#getFeatureManifestReference()
77      */

78     public ContentReference getFeatureManifestReference(InstallMonitor monitor) throws CoreException {
79
80         // check to see if we already have local copy of the manifest
81
if (localManifest != null)
82             return localManifest;
83         ContentReference[] featureArchiveReference = getFeatureEntryArchiveReferences(monitor);
84         JarContentReference featureJarReference = null;
85         try {
86
87             // force feature archive to local.
88
// This content provider always assumes exactly 1 archive file (index [0])
89
featureJarReference = (JarContentReference) asLocalReference(featureArchiveReference[0], null);
90             // we need to unpack archive locally for UI browser references to be resolved correctly
91
localFeatureFiles = featureJarReference.unpack(getWorkingDirectory(), null, monitor);
92         } catch (IOException e) {
93             throw errorRetrieving(Feature.FEATURE_XML, featureJarReference, e);
94         }
95
96         // find the manifest in the unpacked feature files
97
for (int i = 0; i < localFeatureFiles.length; i++) {
98             if (localFeatureFiles[i].getIdentifier().equals(Feature.FEATURE_XML)) {
99                 localManifest = localFeatureFiles[i];
100                 // cache reference to manifest
101
return localManifest;
102             }
103         }
104
105         // the manifest has not been found
106
String JavaDoc[] values = new String JavaDoc[] { Feature.FEATURE_XML, getURL().toExternalForm()};
107         throw Utilities.newCoreException(NLS.bind(Messages.FeaturePackagedContentProvider_NoManifestFile, values), new Exception JavaDoc());
108
109     }
110
111     /*
112      * @see IFeatureContentProvider#getArchiveReferences()
113      */

114     public ContentReference[] getArchiveReferences(InstallMonitor monitor) throws CoreException {
115
116         IPluginEntry[] entries = getFeature().getPluginEntries();
117         INonPluginEntry[] nonEntries = getFeature().getNonPluginEntries();
118         List listAllContentRef = new ArrayList();
119         ContentReference[] allContentRef = new ContentReference[0];
120
121         // feature
122
listAllContentRef.addAll(Arrays.asList(getFeatureEntryArchiveReferences(monitor)));
123
124         // plugins
125
for (int i = 0; i < entries.length; i++) {
126             listAllContentRef.addAll(Arrays.asList(getPluginEntryArchiveReferences(entries[i], monitor)));
127         }
128
129         // non plugins
130
for (int i = 0; i < nonEntries.length; i++) {
131             listAllContentRef.addAll(Arrays.asList(getNonPluginEntryArchiveReferences(nonEntries[i], monitor)));
132         }
133
134         // transform List in Array
135
if (listAllContentRef.size() > 0) {
136             allContentRef = new ContentReference[listAllContentRef.size()];
137             listAllContentRef.toArray(allContentRef);
138         }
139
140         return allContentRef;
141     }
142
143     /*
144      * @see IFeatureContentProvider#getFeatureEntryArchiveReferences()
145      */

146     public ContentReference[] getFeatureEntryArchiveReferences(InstallMonitor monitor) throws CoreException {
147
148         //1 jar file <-> 1 feature
149
// we will return the JAR file
150
ContentReference[] references = new ContentReference[1];
151         ContentReference currentReference = null;
152         String JavaDoc archiveID = null;
153
154         try {
155             archiveID = (getFeature() != null) ? getFeature().getVersionedIdentifier().toString() : ""; //$NON-NLS-1$
156
currentReference = new JarContentReference(archiveID, getURL());
157             currentReference = asLocalReference(currentReference, monitor);
158             references[0] = currentReference;
159         } catch (IOException e) {
160             references[0] = continueOnErrorOrRethrow(archiveID, e);
161         }
162         return references;
163     }
164
165     /*
166      * @see IFeatureContentProvider#getPluginEntryArchiveReferences(IPluginEntry)
167      */

168     public ContentReference[] getPluginEntryArchiveReferences(IPluginEntry pluginEntry, InstallMonitor monitor) throws CoreException {
169
170         // 1 plugin <-> 1 jar
171
// we return the JAR file
172
ContentReference[] references = new ContentReference[1];
173         String JavaDoc archiveID = getPathID(pluginEntry);
174         ISite site = (getFeature() == null) ? null : getFeature().getSite();
175         ISiteContentProvider siteContentProvider = (site == null) ? null : site.getSiteContentProvider();
176         URL JavaDoc url = (siteContentProvider == null) ? null : siteContentProvider.getArchiveReference(archiveID);
177
178         try {
179             references[0] = retrieveLocalJar(new JarContentReference(archiveID, url), monitor);
180         } catch (IOException e) {
181             references[0] = continueOnErrorOrRethrow(archiveID, e);
182         }
183         return references;
184     }
185
186     private ContentReference retrieveLocalJar(JarContentReference reference, InstallMonitor monitor) throws IOException, CoreException {
187         //If the site does not support pack200, just get the jar as normal
188
if(siteModel == null || !siteModel.supportsPack200() || !JarProcessor.canPerformUnpack()) {
189             ContentReference contentReference = null;
190             try {
191                 contentReference = asLocalReference(reference, monitor);
192             }
193             catch (FileNotFoundException e) {
194                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
195             }
196             catch (IOException e) {
197                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
198             }
199             catch (CoreException e) {
200                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
201             }
202             return contentReference;
203         }
204         
205         ContentReference packedRef = null;
206         String JavaDoc key = reference.toString();
207         Object JavaDoc jarLock = LockManager.getLock(key);
208         synchronized (jarLock) {
209             //do we have this jar already?
210
File localFile = Utilities.lookupLocalFile(key);
211             if (localFile != null) {
212                 // check if the cached file is still valid (no newer version on server)
213
if (UpdateManagerUtils.isSameTimestamp(reference.asURL(), localFile.lastModified())) {
214                     LockManager.returnLock(key);
215                     return reference.createContentReference(reference.getIdentifier(), localFile);
216                 }
217             }
218
219             try {
220                 //don't have jar, check for pack.gz
221
URL JavaDoc packGZURL = new URL JavaDoc(reference.asURL().toExternalForm() + ".pack.gz"); //$NON-NLS-1$
222
packedRef = asLocalReference(new JarContentReference(reference.getIdentifier(), packGZURL), monitor);
223             } catch (IOException e) {
224                 //no pack.gz
225
} catch (CoreException e){
226                 //no pack.gz
227
}
228         }
229         
230         if (packedRef == null) {
231             //no pack.gz on server, get normal jar
232
ContentReference contentReference = null;
233             try {
234                 contentReference = asLocalReference(reference, monitor);
235             }
236             catch (FileNotFoundException e) {
237                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
238             }
239             catch (IOException e) {
240                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
241             }
242             catch (CoreException e) {
243                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
244             }
245             return contentReference;
246         }
247
248         boolean success = false;
249         synchronized (jarLock) {
250             String JavaDoc packed = packedRef.toString();
251             Object JavaDoc packedLock = LockManager.getLock(packed);
252             synchronized (packedLock) {
253                 try {
254                     File tempFile = packedRef.asFile();
255                     long timeStamp = tempFile.lastModified();
256     
257                     JarProcessor processor = JarProcessor.getUnpackProcessor(null);
258                     processor.setWorkingDirectory(tempFile.getParent());
259     
260                     File packedFile = new File(tempFile.toString() + Utils.PACKED_SUFFIX);
261                     tempFile.renameTo(packedFile);
262                     
263                     if (monitor != null) {
264                         monitor.saveState();
265                         monitor.subTask(Messages.JarContentReference_Unpacking + " " + reference.getIdentifier() + Utils.PACKED_SUFFIX); //$NON-NLS-1$
266
monitor.showCopyDetails(false);
267                     }
268                     //unpacking the jar will strip the ".pack.gz" and leave us back with the original filename
269
try {
270                         processor.processJar(packedFile);
271                     } catch (Throwable JavaDoc e) {
272                         //something is wrong unpacking
273
}
274     
275                     if(tempFile.exists() && tempFile.length() > 0){
276                         success = true;
277                         tempFile.setLastModified(timeStamp);
278                         Utilities.mapLocalFile(key, tempFile);
279                         UpdateCore.getPlugin().getUpdateSession().markVisited(reference.asURL());
280                     }
281                 } finally {
282                     LockManager.returnLock(packed);
283                     LockManager.returnLock(key);
284                     if(monitor != null)
285                         monitor.restoreState();
286                 }
287             }
288         }
289         if(!success){
290             //Something went wrong with the unpack, get the normal jar.
291
ContentReference contentReference = null;
292             try {
293                 contentReference = asLocalReference(reference, monitor);
294             }
295             catch (FileNotFoundException e) {
296                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
297             }
298             catch (IOException e) {
299                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
300             }
301             catch (CoreException e) {
302                 contentReference = continueOnErrorOrRethrow(reference.getIdentifier(), e);
303             }
304             return contentReference;
305         }
306         return packedRef;
307     }
308
309     /*
310      * @see IFeatureContentProvider#getNonPluginEntryArchiveReferences(INonPluginEntry)
311      */

312     public ContentReference[] getNonPluginEntryArchiveReferences(INonPluginEntry nonPluginEntry, InstallMonitor monitor) throws CoreException {
313
314         // archive = feature/<id>_<ver>/<file>
315
String JavaDoc archiveID = Site.DEFAULT_FEATURE_PATH + ((getFeature() != null) ? getFeature().getVersionedIdentifier().toString() : ""); //$NON-NLS-1$
316
archiveID += "/" + nonPluginEntry.getIdentifier(); //$NON-NLS-1$
317

318         ContentReference[] references = new ContentReference[1];
319         ContentReference currentReference = null;
320
321         try {
322             ISite site = (getFeature() == null) ? null : getFeature().getSite();
323             ISiteContentProvider siteContentProvider = (site == null) ? null : site.getSiteContentProvider();
324             URL JavaDoc url = (siteContentProvider == null) ? null : siteContentProvider.getArchiveReference(archiveID);
325
326             currentReference = new ContentReference(nonPluginEntry.getIdentifier(), url);
327             currentReference = asLocalReference(currentReference, monitor);
328             references[0] = currentReference;
329
330         } catch (IOException e) {
331             references[0] = continueOnErrorOrRethrow(archiveID, e);
332         }
333
334         return references;
335     }
336
337
338     /*
339      * @see IFeatureContentProvider#getFeatureEntryContentReferences()
340      */

341     public ContentReference[] getFeatureEntryContentReferences(InstallMonitor monitor) throws CoreException {
342
343         return localFeatureFiles; // return cached feature references
344
// Note: assumes this content provider is always called first to
345
// get the feature manifest. This forces the feature files
346
// to be unpacked and caches the references
347
}
348
349     /*
350      * @see IFeatureContentProvider#getPluginEntryContentReferences(IPluginEntry)
351      */

352     public ContentReference[] getPluginEntryContentReferences(IPluginEntry pluginEntry, InstallMonitor monitor) throws CoreException {
353
354         ContentReference[] references = getPluginEntryArchiveReferences(pluginEntry, monitor);
355         ContentReference[] pluginReferences = new ContentReference[0];
356
357         try {
358             if (references[0] instanceof JarContentReference) {
359                 JarContentReference localRef = (JarContentReference) asLocalReference(references[0], monitor);
360                 pluginReferences = localRef.peek(null, monitor);
361             } else {
362                 // return the list of all subdirectories
363
List files = getFiles(references[0].asFile());
364                 pluginReferences = new ContentReference[files.size()];
365                 for (int i = 0; i < pluginReferences.length; i++) {
366                     File currentFile = (File) files.get(i);
367                     pluginReferences[i] = new ContentReference(null, currentFile.toURL());
368                 }
369             }
370
371             //[20866] we did not preserve executable bit
372
validatePermissions(pluginReferences);
373
374         } catch (IOException e) {
375             throw errorRetrieving(pluginEntry.getVersionedIdentifier().toString(), references[0], e);
376         }
377         return pluginReferences;
378     }
379
380     /*
381      * return all the files under the directory
382      */

383     private List getFiles(File dir) throws IOException {
384         List result = new ArrayList();
385
386         if (!dir.isDirectory())
387             throw new IOException(NLS.bind(Messages.FeaturePackagedContentProvider_InvalidDirectory, (new String JavaDoc[] { dir.getPath() })));
388
389         File[] files = dir.listFiles();
390         if (files != null) // be careful since it can be null
391
for (int i = 0; i < files.length; ++i) {
392                 if (files[i].isDirectory()) {
393                     result.addAll(getFiles(files[i]));
394                 } else {
395                     result.add(files[i]);
396                 }
397             }
398         return result;
399     }
400
401     /*
402      *
403      */

404     private CoreException errorRetrieving(String JavaDoc obj, ContentReference archive, Exception JavaDoc e) {
405
406         String JavaDoc[] values = new String JavaDoc[] { obj };
407
408         return Utilities.newCoreException(NLS.bind(Messages.FeaturePackagedContentProvider_ErrorRetrieving, values), e);
409
410     }
411
412
413     public void setContinueOnError(boolean continueOnError) {
414         this.continueOnError = continueOnError;
415     }
416     
417     /**
418      * This method is used for when a core exception is detected, so, if its decided to rethrow, then
419      * a core exception odes not have to be recreated.
420      *
421      * @param archiveID id of the archive file
422      * @param CoreException
423      * @return NullReference if its decided not to continue
424      * @throws CoreException
425      */

426     /*private ContentReference continueOrErrorOrRethrow(String archiveID, CoreException coreException) throws CoreException {
427         ContentReference reference = null;
428
429         if (continueOnError) {
430             // this ContentReference without a file or URL is purely a
431             // "missing jar" reference.
432             reference = new NullContentReference(archiveID);
433
434             String msg = " ContinueOnError: The following ID was not found, so was skipped, and is not on miror site: " + archiveID; //$NON-NLS-1$
435             String id = UpdateCore.getPlugin().getBundle().getSymbolicName();
436             IStatus status = new Status(IStatus.WARNING, id , 0, msg, null);
437             UpdateCore.log(status);
438             
439         }
440         else {
441             throw coreException;
442         }
443         return reference;
444     }*/

445     
446     private ContentReference continueOnErrorOrRethrow(String JavaDoc archiveID, Exception JavaDoc e) throws CoreException {
447         ContentReference reference = null;
448
449         if (continueOnError) {
450             // this ContentReference without a file or URL is purely a
451
// "missing jar" reference.
452
reference = new NullContentReference(archiveID);
453             
454             String JavaDoc msg = " ContinueOnError: The following ID was not found, so was skipped, and is not on miror site: " + archiveID; //$NON-NLS-1$
455
String JavaDoc id = UpdateCore.getPlugin().getBundle().getSymbolicName();
456             IStatus status = new Status(IStatus.WARNING, id , 0, msg, null);
457             UpdateCore.log(status);
458             
459         }
460         else {
461             throw errorRetrieving(archiveID, reference, e);
462         }
463         return reference;
464     }
465
466 }
467
Popular Tags