1 11 12 package org.eclipse.osgi.internal.baseadaptor; 13 14 import java.io.*; 15 import java.lang.reflect.Method ; 16 import java.net.URL ; 17 import java.net.URLConnection ; 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 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 EXTERNAL_LIB_PREFIX = "external:"; public static final String VARIABLE_DELIM_STRING = "$"; public static final char VARIABLE_DELIM_CHAR = '$'; 45 46 47 private String fileName; 48 49 private String [] nativePaths; 50 51 private int generation = 1; 52 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 ) manifest.get(Constants.BUNDLE_VERSION))); 81 } catch (IllegalArgumentException e) { 82 target.setVersion(new InvalidVersion((String ) manifest.get(Constants.BUNDLE_VERSION))); 83 } 84 ManifestElement[] bsnHeader = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, (String ) manifest.get(Constants.BUNDLE_SYMBOLICNAME)); 85 int bundleType = 0; 86 if (bsnHeader != null) { 87 target.setSymbolicName(bsnHeader[0].getValue()); 88 String singleton = bsnHeader[0].getDirective(Constants.SINGLETON_DIRECTIVE); 89 if (singleton == null) 90 singleton = bsnHeader[0].getAttribute(Constants.SINGLETON_DIRECTIVE); 91 if ("true".equals(singleton)) bundleType |= BundleData.TYPE_SINGLETON; 93 } 94 target.setClassPathString((String ) manifest.get(Constants.BUNDLE_CLASSPATH)); 95 target.setActivator((String ) manifest.get(Constants.BUNDLE_ACTIVATOR)); 96 String host = (String ) 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 extensionType = hostElement[0].getDirective("extension"); if (extensionType == null || extensionType.equals("framework")) bundleType |= BundleData.TYPE_FRAMEWORK_EXTENSION; 104 else 105 bundleType |= BundleData.TYPE_BOOTCLASSPATH_EXTENSION; 106 } 107 } 108 target.setType(bundleType); 109 target.setExecutionEnvironment((String ) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT)); 110 target.setDynamicImports((String ) 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); 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 [nativePathCount] : null; 134 for (int i = 0; i < nativePathCount; i++) 135 storageHook.nativePaths[i] = in.readUTF(); 136 return storageHook; 137 } 138 139 private String getAbsolute(boolean isReference, String path) { 140 if (!isReference) 141 return path; 142 File storedPath = new File(path); 144 if (!storedPath.isAbsolute()) 145 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 (); 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 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 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 getKey() { 196 return KEY; 197 } 198 199 public String getFileName() { 200 return fileName; 201 } 202 203 public int getGeneration() { 204 return generation; 205 } 206 207 public String [] getNativePaths() { 208 return nativePaths; 209 } 210 211 public void installNativePaths(String [] 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 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; } 221 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 path) { 239 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()); 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 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()); return generationDir; 283 } 284 285 public void setReference(boolean reference) { 286 this.reference = reference; 287 } 288 289 public void setFileName(String fileName) { 290 this.fileName = fileName; 291 this.bundleData.setFileName(fileName); 293 } 294 295 public void copy(StorageHook storageHook) { 296 if (!(storageHook instanceof BaseStorageHook)) 297 throw new IllegalArgumentException (); 298 BaseStorageHook hook = (BaseStorageHook) storageHook; 299 bundleStore = hook.bundleStore; 300 dataStore = hook.dataStore; 301 generation = hook.generation + 1; 302 } 304 305 public void validate() throws IllegalArgumentException { 306 } 308 309 public Dictionary getManifest(boolean firstLoad) throws BundleException { 310 return null; 312 } 313 314 public boolean forgetStatusChange(int status) { 315 return false; 317 } 318 319 public boolean forgetStartLevelChange(int startlevel) { 320 return false; 322 } 323 324 public boolean matchDNChain(String pattern) { 325 return false; 327 } 328 329 public void initialize(BaseAdaptor adaptor) { 330 } 332 333 public void frameworkStart(BundleContext context) throws BundleException { 334 } 336 337 public void frameworkStop(BundleContext context) throws BundleException { 338 ZipBundleFile.shutdown(); 340 } 341 342 public void frameworkStopping(BundleContext context) { 343 } 345 346 public void addProperties(Properties properties) { 347 } 349 350 public URLConnection mapLocationToURLConnection(String location) throws IOException { 351 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 ("reference:file:" + hook.getFileName()).openConnection() : null; } 363 364 public void handleRuntimeError(Throwable error) { 365 } 367 368 public boolean matchDNChain(String pattern, String [] dnChain) { 369 return false; 371 } 372 373 public FrameworkLog createFrameworkLog() { 374 return null; 376 } 377 378 public BaseStorage getStorage() { 379 return storage; 380 } 381 382 public static String substituteVars(String path) { 383 StringBuffer buf = new StringBuffer (path.length()); 384 StringTokenizer st = new StringTokenizer(path, VARIABLE_DELIM_STRING, true); 385 boolean varStarted = false; String var = null; while (st.hasMoreElements()) { 388 String tok = st.nextToken(); 389 if (VARIABLE_DELIM_STRING.equals(tok)) { 390 if (!varStarted) { 391 varStarted = true; var = ""; } else { 394 String prop = null; 396 if (var != null && var.length() > 0) 398 prop = FrameworkProperties.getProperty(var); 399 if (prop == null) { 400 try { 401 Method getenv = System .class.getMethod("getenv", new Class [] {String .class}); prop = (String ) getenv.invoke(null, new Object [] {var}); 404 } catch (Throwable t) { 405 } 409 } 410 if (prop != null) 411 buf.append(prop); 413 else 414 buf.append(var == null ? "" : var); varStarted = false; 417 var = null; 418 } 419 } else { 420 if (!varStarted) 421 buf.append(tok); else 423 var = tok; } 425 } 426 if (var != null) 427 buf.append(VARIABLE_DELIM_CHAR).append(var); 429 return buf.toString(); 430 } 431 } 432 | Popular Tags |