KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > internal > baseadaptor > BaseStorageHook


1 /*******************************************************************************
2  * Copyright (c) 2005, 2006 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
12 package org.eclipse.osgi.internal.baseadaptor;
13
14 import java.io.*;
15 import java.lang.reflect.Method JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.net.URLConnection JavaDoc;
18 import java.util.*;
19 import org.eclipse.core.runtime.adaptor.LocationManager;
20 import org.eclipse.osgi.baseadaptor.*;
21 import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
22 import org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleFile;
23 import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook;
24 import org.eclipse.osgi.baseadaptor.hooks.StorageHook;
25 import org.eclipse.osgi.framework.adaptor.*;
26 import org.eclipse.osgi.framework.debug.Debug;
27 import org.eclipse.osgi.framework.internal.core.*;
28 import org.eclipse.osgi.framework.internal.core.Constants;
29 import org.eclipse.osgi.framework.log.FrameworkLog;
30 import org.eclipse.osgi.framework.util.KeyedElement;
31 import org.eclipse.osgi.service.datalocation.Location;
32 import org.eclipse.osgi.util.ManifestElement;
33 import org.eclipse.osgi.util.NLS;
34 import org.osgi.framework.*;
35
36 public class BaseStorageHook implements StorageHook, AdaptorHook{
37     public static final String JavaDoc KEY = BaseStorageHook.class.getName();
38     public static final int HASHCODE = KEY.hashCode();
39     public static final int DEL_BUNDLE_STORE = 0x01;
40     public static final int DEL_GENERATION = 0x02;
41     private static final int STORAGE_VERSION = 1;
42     public static final String JavaDoc EXTERNAL_LIB_PREFIX = "external:"; //$NON-NLS-1$
43
public static final String JavaDoc VARIABLE_DELIM_STRING = "$"; //$NON-NLS-1$
44
public static final char VARIABLE_DELIM_CHAR = '$';
45
46     /** bundle's file name */
47     private String JavaDoc fileName;
48     /** native code paths for this BundleData */
49     private String JavaDoc[] nativePaths;
50     /** bundle generation */
51     private int generation = 1;
52     /** Is bundle a reference */
53     private boolean reference;
54
55     private BaseData bundleData;
56     private BaseStorage storage;
57     private File bundleStore;
58     private File dataStore;
59
60     public BaseStorageHook(BaseStorage storage) {
61         this.storage = storage;
62     }
63
64     public int getStorageVersion() {
65         return STORAGE_VERSION;
66     }
67
68     public StorageHook create(BaseData bundledata) throws BundleException {
69         BaseStorageHook storageHook = new BaseStorageHook(storage);
70         storageHook.bundleData = bundledata;
71         return storageHook;
72     }
73
74     public void initialize(Dictionary manifest) throws BundleException {
75         BaseStorageHook.loadManifest(bundleData, manifest);
76     }
77
78     static void loadManifest(BaseData target, Dictionary manifest) throws BundleException {
79         try {
80             target.setVersion(Version.parseVersion((String JavaDoc) manifest.get(Constants.BUNDLE_VERSION)));
81         } catch (IllegalArgumentException JavaDoc e) {
82             target.setVersion(new InvalidVersion((String JavaDoc) manifest.get(Constants.BUNDLE_VERSION)));
83         }
84         ManifestElement[] bsnHeader = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, (String JavaDoc) manifest.get(Constants.BUNDLE_SYMBOLICNAME));
85         int bundleType = 0;
86         if (bsnHeader != null) {
87             target.setSymbolicName(bsnHeader[0].getValue());
88             String JavaDoc singleton = bsnHeader[0].getDirective(Constants.SINGLETON_DIRECTIVE);
89             if (singleton == null)
90                 singleton = bsnHeader[0].getAttribute(Constants.SINGLETON_DIRECTIVE);
91             if ("true".equals(singleton)) //$NON-NLS-1$
92
bundleType |= BundleData.TYPE_SINGLETON;
93         }
94         target.setClassPathString((String JavaDoc) manifest.get(Constants.BUNDLE_CLASSPATH));
95         target.setActivator((String JavaDoc) manifest.get(Constants.BUNDLE_ACTIVATOR));
96         String JavaDoc host = (String JavaDoc) manifest.get(Constants.FRAGMENT_HOST);
97         if (host != null) {
98             bundleType |= BundleData.TYPE_FRAGMENT;
99             ManifestElement[] hostElement = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, host);
100             if (Constants.getInternalSymbolicName().equals(hostElement[0].getValue()) || Constants.OSGI_SYSTEM_BUNDLE.equals(hostElement[0].getValue())) {
101                 String JavaDoc extensionType = hostElement[0].getDirective("extension"); //$NON-NLS-1$
102
if (extensionType == null || extensionType.equals("framework")) //$NON-NLS-1$
103
bundleType |= BundleData.TYPE_FRAMEWORK_EXTENSION;
104                 else
105                     bundleType |= BundleData.TYPE_BOOTCLASSPATH_EXTENSION;
106             }
107         }
108         target.setType(bundleType);
109         target.setExecutionEnvironment((String JavaDoc) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT));
110         target.setDynamicImports((String JavaDoc) manifest.get(Constants.DYNAMICIMPORT_PACKAGE));
111     }
112
113     public StorageHook load(BaseData target, DataInputStream in) throws IOException {
114         target.setLocation(AdaptorUtil.readString(in, false));
115         target.setSymbolicName(AdaptorUtil.readString(in, false));
116         target.setVersion(AdaptorUtil.loadVersion(in));
117         target.setActivator(AdaptorUtil.readString(in, false));
118         target.setClassPathString(AdaptorUtil.readString(in, false));
119         target.setExecutionEnvironment(AdaptorUtil.readString(in, false));
120         target.setDynamicImports(AdaptorUtil.readString(in, false));
121         target.setStartLevel(in.readInt());
122         target.setStatus(in.readInt());
123         target.setType(in.readInt());
124         target.setLastModified(in.readLong());
125         target.setDirty(false); // make sure to reset the dirty bit;
126

127         BaseStorageHook storageHook = new BaseStorageHook(storage);
128         storageHook.bundleData = target;
129         storageHook.generation = in.readInt();
130         storageHook.reference = in.readBoolean();
131         storageHook.setFileName(getAbsolute(storageHook.reference, AdaptorUtil.readString(in, false)));
132         int nativePathCount = in.readInt();
133         storageHook.nativePaths = nativePathCount > 0 ? new String JavaDoc[nativePathCount] : null;
134         for (int i = 0; i < nativePathCount; i++)
135             storageHook.nativePaths[i] = in.readUTF();
136         return storageHook;
137     }
138
139     private String JavaDoc getAbsolute(boolean isReference, String JavaDoc path) {
140         if (!isReference)
141             return path;
142         // fileName for bundles installed with reference URLs is stored relative to the install location
143
File storedPath = new File(path);
144         if (!storedPath.isAbsolute())
145             // make sure it has the absolute location instead
146
return new FilePath(storage.getInstallPath() + path).toString();
147         return path;
148     }
149
150     public void save(DataOutputStream out) throws IOException {
151         if (bundleData == null)
152             throw new IllegalStateException JavaDoc();
153         AdaptorUtil.writeStringOrNull(out, bundleData.getLocation());
154         AdaptorUtil.writeStringOrNull(out, bundleData.getSymbolicName());
155         AdaptorUtil.writeStringOrNull(out, bundleData.getVersion().toString());
156         AdaptorUtil.writeStringOrNull(out, bundleData.getActivator());
157         AdaptorUtil.writeStringOrNull(out, bundleData.getClassPathString());
158         AdaptorUtil.writeStringOrNull(out, bundleData.getExecutionEnvironment());
159         AdaptorUtil.writeStringOrNull(out, bundleData.getDynamicImports());
160         StorageHook[] hooks = bundleData.getStorageHooks();
161         boolean forgetStartLevel = false;
162         for (int i = 0; i < hooks.length && !forgetStartLevel; i++)
163             forgetStartLevel = hooks[i].forgetStartLevelChange(bundleData.getStartLevel());
164         out.writeInt(!forgetStartLevel ? bundleData.getStartLevel() : 1);
165         boolean forgetStatus = false;
166         // see if we should forget the persistently started flag
167
for (int i = 0; i < hooks.length && !forgetStatus; i++)
168             forgetStatus = hooks[i].forgetStatusChange(bundleData.getStatus());
169         out.writeInt(!forgetStatus ? bundleData.getStatus() : (~Constants.BUNDLE_STARTED) & bundleData.getStatus());
170         out.writeInt(bundleData.getType());
171         out.writeLong(bundleData.getLastModified());
172
173         out.writeInt(getGeneration());
174         out.writeBoolean(isReference());
175         String JavaDoc storedFileName = isReference() ? new FilePath(storage.getInstallPath()).makeRelative(new FilePath(getFileName())) : getFileName();
176         AdaptorUtil.writeStringOrNull(out, storedFileName);
177         if (nativePaths == null)
178             out.writeInt(0);
179         else {
180             out.writeInt(nativePaths.length);
181             for (int i = 0; i < nativePaths.length; i++)
182                 out.writeUTF(nativePaths[i]);
183         }
184
185     }
186
187     public int getKeyHashCode() {
188         return HASHCODE;
189     }
190
191     public boolean compare(KeyedElement other) {
192         return other.getKey() == KEY;
193     }
194
195     public Object JavaDoc getKey() {
196         return KEY;
197     }
198
199     public String JavaDoc getFileName() {
200         return fileName;
201     }
202
203     public int getGeneration() {
204         return generation;
205     }
206
207     public String JavaDoc[] getNativePaths() {
208         return nativePaths;
209     }
210
211     public void installNativePaths(String JavaDoc[] installPaths) throws BundleException {
212         this.nativePaths = installPaths;
213         for (int i = 0; i < installPaths.length; i++) {
214             if (installPaths[i].startsWith(EXTERNAL_LIB_PREFIX)) {
215                 String JavaDoc path = substituteVars(installPaths[i].substring(EXTERNAL_LIB_PREFIX.length()));
216                 File nativeFile = new File(path);
217                 if (!nativeFile.exists())
218                     throw new BundleException(NLS.bind(AdaptorMsg.BUNDLE_NATIVECODE_EXCEPTION, nativeFile.getAbsolutePath()));
219                 continue; // continue to next path
220
}
221             // ensure the file exists in the bundle; it will get extracted later on demand
222
BundleEntry nativeEntry = bundleData.getBundleFile().getEntry(installPaths[i]);
223             if (nativeEntry == null)
224                 throw new BundleException(NLS.bind(AdaptorMsg.BUNDLE_NATIVECODE_EXCEPTION, installPaths[i]));
225         }
226     }
227
228     public boolean isReference() {
229         return reference;
230     }
231
232     public File getBundleStore() {
233         if (bundleStore == null)
234             bundleStore = new File(storage.getBundleStoreRoot(), String.valueOf(bundleData.getBundleID()));
235         return bundleStore;
236     }
237
238     public File getDataFile(String JavaDoc path) {
239         // lazily initialize dirData to prevent early access to configuration location
240
if (dataStore == null)
241             dataStore = new File(getBundleStore(), BaseStorage.DATA_DIR_NAME);
242         if (path != null && !dataStore.exists() && (storage.isReadOnly() || !dataStore.mkdirs()))
243             if (Debug.DEBUG && Debug.DEBUG_GENERAL)
244                 Debug.println("Unable to create bundle data directory: " + dataStore.getPath()); //$NON-NLS-1$
245
return path == null ? dataStore : new File(dataStore, path);
246     }
247
248     void delete(boolean postpone, int type) throws IOException {
249         File delete = null;
250         switch (type) {
251             case DEL_GENERATION :
252                 delete = getGenerationDir();
253                 break;
254             case DEL_BUNDLE_STORE :
255                 delete = getBundleStore();
256                 break;
257         }
258         if (delete != null && delete.exists() && (postpone || !AdaptorUtil.rm(delete))) {
259             /* create .delete */
260             FileOutputStream out = new FileOutputStream(new File(delete, BaseStorage.DELETE_FLAG));
261             out.close();
262         }
263     }
264
265     File getGenerationDir() {
266         return new File(getBundleStore(), String.valueOf(getGeneration()));
267     }
268
269     File getParentGenerationDir() {
270         Location parentConfiguration = null;
271         Location currentConfiguration = LocationManager.getConfigurationLocation();
272         if (currentConfiguration != null && (parentConfiguration = currentConfiguration.getParentLocation()) != null)
273             return new File(parentConfiguration.getURL().getFile(), FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME + '/' + LocationManager.BUNDLES_DIR + '/' + bundleData.getBundleID() + '/' + getGeneration());
274         return null;
275     }
276
277     File createGenerationDir() {
278         File generationDir = getGenerationDir();
279         if (!generationDir.exists() && (storage.isReadOnly() || !generationDir.mkdirs()))
280             if (Debug.DEBUG && Debug.DEBUG_GENERAL)
281                 Debug.println("Unable to create bundle generation directory: " + generationDir.getPath()); //$NON-NLS-1$
282
return generationDir;
283     }
284
285     public void setReference(boolean reference) {
286         this.reference = reference;
287     }
288
289     public void setFileName(String JavaDoc fileName) {
290         this.fileName = fileName;
291         // This is only done for PDE source lookup (bug 126517)
292
this.bundleData.setFileName(fileName);
293     }
294
295     public void copy(StorageHook storageHook) {
296         if (!(storageHook instanceof BaseStorageHook))
297             throw new IllegalArgumentException JavaDoc();
298         BaseStorageHook hook = (BaseStorageHook) storageHook;
299         bundleStore = hook.bundleStore;
300         dataStore = hook.dataStore;
301         generation = hook.generation + 1;
302         // fileName and reference will be set by update
303
}
304
305     public void validate() throws IllegalArgumentException JavaDoc {
306         // do nothing
307
}
308
309     public Dictionary getManifest(boolean firstLoad) throws BundleException {
310         // do nothing
311
return null;
312     }
313
314     public boolean forgetStatusChange(int status) {
315         // do nothing
316
return false;
317     }
318
319     public boolean forgetStartLevelChange(int startlevel) {
320         // do nothing
321
return false;
322     }
323
324     public boolean matchDNChain(String JavaDoc pattern) {
325         // do nothing
326
return false;
327     }
328
329     public void initialize(BaseAdaptor adaptor) {
330         // do nothing
331
}
332
333     public void frameworkStart(BundleContext context) throws BundleException {
334         // do nothing
335
}
336
337     public void frameworkStop(BundleContext context) throws BundleException {
338         // shutdown the bundle file closer thread if it exists
339
ZipBundleFile.shutdown();
340     }
341
342     public void frameworkStopping(BundleContext context) {
343         // do nothing
344
}
345
346     public void addProperties(Properties properties) {
347         // do nothing
348
}
349
350     public URLConnection JavaDoc mapLocationToURLConnection(String JavaDoc location) throws IOException {
351         // see if this is an existing location
352
Bundle[] bundles = storage.getAdaptor().getContext().getBundles();
353         AbstractBundle bundle = null;
354         for (int i = 0; i < bundles.length && bundle == null; i++)
355             if (location.equals(bundles[i].getLocation()))
356                 bundle = (AbstractBundle) bundles[i];
357         if (bundle == null)
358             return null;
359         BaseData data = (BaseData) bundle.getBundleData();
360         BaseStorageHook hook = (BaseStorageHook) data.getStorageHook(BaseStorageHook.KEY);
361         return hook.isReference() ? new URL JavaDoc("reference:file:" + hook.getFileName()).openConnection() : null; //$NON-NLS-1$
362
}
363
364     public void handleRuntimeError(Throwable JavaDoc error) {
365         // do nothing
366
}
367
368     public boolean matchDNChain(String JavaDoc pattern, String JavaDoc[] dnChain) {
369         // do nothing
370
return false;
371     }
372
373     public FrameworkLog createFrameworkLog() {
374         // do nothing
375
return null;
376     }
377
378     public BaseStorage getStorage() {
379         return storage;
380     }
381
382     public static String JavaDoc substituteVars(String JavaDoc path) {
383         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(path.length());
384         StringTokenizer st = new StringTokenizer(path, VARIABLE_DELIM_STRING, true);
385         boolean varStarted = false; // indicates we are processing a var subtitute
386
String JavaDoc var = null; // the current var key
387
while (st.hasMoreElements()) {
388             String JavaDoc tok = st.nextToken();
389             if (VARIABLE_DELIM_STRING.equals(tok)) {
390                 if (!varStarted) {
391                     varStarted = true; // we found the start of a var
392
var = ""; //$NON-NLS-1$
393
} else {
394                     // we have found the end of a var
395
String JavaDoc prop = null;
396                     // get the value of the var from system properties
397
if (var != null && var.length() > 0)
398                         prop = FrameworkProperties.getProperty(var);
399                     if (prop == null) {
400                         try {
401                             // try using the System.getenv method if it exists (bug 126921)
402
Method JavaDoc getenv = System JavaDoc.class.getMethod("getenv", new Class JavaDoc[] {String JavaDoc.class}); //$NON-NLS-1$
403
prop = (String JavaDoc) getenv.invoke(null, new Object JavaDoc[] {var});
404                         } catch (Throwable JavaDoc t) {
405                             // do nothing;
406
// on 1.4 VMs this throws an error
407
// on J2ME this method does not exist
408
}
409                     }
410                     if (prop != null)
411                         // found a value; use it
412
buf.append(prop);
413                     else
414                         // could not find a value append the var name w/o delims
415
buf.append(var == null ? "" : var); //$NON-NLS-1$
416
varStarted = false;
417                     var = null;
418                 }
419             } else {
420                 if (!varStarted)
421                     buf.append(tok); // the token is not part of a var
422
else
423                     var = tok; // the token is the var key; save the key to process when we find the end token
424
}
425         }
426         if (var != null)
427             // found a case of $var at the end of the path with no trailing $; just append it as is.
428
buf.append(VARIABLE_DELIM_CHAR).append(var);
429         return buf.toString();
430     }
431 }
432
Popular Tags