| /******************************************************************************* |
| * Copyright (c) 2004, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.osgi.framework.adaptor.core; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.*; |
| import org.eclipse.osgi.framework.adaptor.*; |
| import org.eclipse.osgi.framework.debug.Debug; |
| import org.eclipse.osgi.framework.internal.core.Constants; |
| import org.eclipse.osgi.framework.internal.protocol.bundleentry.Handler; |
| import org.eclipse.osgi.framework.util.Headers; |
| import org.eclipse.osgi.util.ManifestElement; |
| import org.eclipse.osgi.util.NLS; |
| import org.osgi.framework.*; |
| |
| /** |
| * An abstract BundleData class that has default implementations that most |
| * BundleData implementations can use. |
| * <p> |
| * Clients may extend this class. |
| * </p> |
| * @since 3.1 |
| */ |
| public abstract class AbstractBundleData implements BundleData, Cloneable { |
| |
| /** the Adaptor for this BundleData */ |
| protected AbstractFrameworkAdaptor adaptor; |
| |
| /** |
| * The Bundle Manifest for this BundleData. |
| */ |
| protected Dictionary manifest = null; |
| |
| /** |
| * The Bundle object for this BundleData. |
| */ |
| protected Bundle bundle; |
| |
| /** bundle id */ |
| protected long id; |
| |
| /** The top level storage directory for the BundleData */ |
| protected File bundleStoreDir; |
| |
| /** The base BundleFile object for this BundleData */ |
| protected BundleFile baseBundleFile; |
| ///////////////////// Begin Meta Data for the Bundle ///////////////////// |
| |
| /** bundle location */ |
| private String location; |
| |
| /** bundle's file name */ |
| private String fileName; |
| |
| /** native code paths for this BundleData */ |
| private String[] nativePaths; |
| |
| /** bundle generation */ |
| private int generation = 1; |
| |
| /** the bundles start level */ |
| private int startLevel = -1; |
| |
| /** |
| * The BundleData data directory |
| */ |
| protected File dirData; |
| |
| /** the bundles status */ |
| private int status = 0; |
| |
| /** Is bundle a reference */ |
| private boolean reference; |
| |
| /** the bundles last modified timestamp */ |
| private long lastModified; |
| |
| ///////////////////// End Meta Data for the Bundle ///////////////////// |
| |
| ///////////////////// Begin values from Manifest ///////////////////// |
| private String symbolicName; |
| private Version version; |
| private String activator; |
| private String classpath; |
| private String executionEnvironment; |
| private String dynamicImports; |
| private int type; |
| |
| ///////////////////// End values from Manifest ///////////////////// |
| |
| /** |
| * Constructor for AbstractBundleData |
| * @param adaptor The adaptor for this bundle data |
| * @param id The bundle id for this bundle data |
| */ |
| public AbstractBundleData(AbstractFrameworkAdaptor adaptor, long id) { |
| this.adaptor = adaptor; |
| this.id = id; |
| initBundleStoreDirs(String.valueOf(id)); |
| } |
| |
| /** |
| * @see BundleData#getManifest() |
| */ |
| public Dictionary getManifest() throws BundleException { |
| if (manifest == null) { |
| synchronized (this) { |
| // make sure the manifest is still null after we have aquired the lock. |
| if (manifest == null) { |
| URL url = getEntry(Constants.OSGI_BUNDLE_MANIFEST); |
| if (url == null) { |
| throw new BundleException(NLS.bind(AdaptorMsg.MANIFEST_NOT_FOUND_EXCEPTION, Constants.OSGI_BUNDLE_MANIFEST, getLocation())); |
| } |
| try { |
| manifest = Headers.parseManifest(url.openStream()); |
| } catch (IOException e) { |
| throw new BundleException(NLS.bind(AdaptorMsg.MANIFEST_NOT_FOUND_EXCEPTION, Constants.OSGI_BUNDLE_MANIFEST, getLocation()), e); |
| } |
| } |
| } |
| } |
| return manifest; |
| } |
| |
| /** |
| * @see BundleData#setBundle(Bundle) |
| */ |
| public void setBundle(Bundle bundle) { |
| this.bundle = bundle; |
| } |
| |
| /** |
| * Returns the Bundle object for this BundleData. |
| * @return the Bundle object for this BundleData. |
| */ |
| public Bundle getBundle() { |
| return bundle; |
| } |
| |
| /** |
| * @see BundleData#getBundleID() |
| */ |
| public long getBundleID() { |
| return (id); |
| } |
| |
| /** |
| * @see BundleData#getEntry(String) |
| */ |
| public URL getEntry(String path) { |
| BundleEntry entry = getBaseBundleFile().getEntry(path); |
| if (entry == null) { |
| return null; |
| } |
| if (path.length() == 0 || path.charAt(0) != '/') |
| path = path = '/' + path; |
| try { |
| //use the constant string for the protocol to prevent duplication |
| return new URL(Constants.OSGI_ENTRY_URL_PROTOCOL, Long.toString(id), 0, path, new Handler(entry)); |
| } catch (MalformedURLException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * @see BundleData#getEntryPaths(String) |
| */ |
| public Enumeration getEntryPaths(String path) { |
| return getBaseBundleFile().getEntryPaths(path); |
| } |
| |
| /** |
| * @see BundleData#createClassLoader(ClassLoaderDelegate, BundleProtectionDomain, String[]) |
| */ |
| public org.eclipse.osgi.framework.adaptor.BundleClassLoader createClassLoader(ClassLoaderDelegate delegate, BundleProtectionDomain domain, String[] bundleclasspath) { |
| return getAdaptor().getElementFactory().createClassLoader(delegate, domain, bundleclasspath, this); |
| } |
| |
| /** |
| * Returns the adaptor for this bundle data. |
| * @return the adaptor for this bundle data. |
| */ |
| public AbstractFrameworkAdaptor getAdaptor() { |
| return adaptor; |
| } |
| |
| /** |
| * Returns a list of classpath entries from a list of manifest elements |
| * @param classpath a list of ManifestElement objects |
| * @return a list of classpath entries from a list of manifest elements |
| */ |
| static String[] getClassPath(ManifestElement[] classpath) { |
| if (classpath == null) { |
| if (Debug.DEBUG && Debug.DEBUG_LOADER) |
| Debug.println(" no classpath"); //$NON-NLS-1$ |
| /* create default BundleClassPath */ |
| return new String[] {"."}; //$NON-NLS-1$ |
| } |
| |
| ArrayList result = new ArrayList(classpath.length); |
| for (int i = 0; i < classpath.length; i++) { |
| if (Debug.DEBUG && Debug.DEBUG_LOADER) |
| Debug.println(" found classpath entry " + classpath[i].getValueComponents()); //$NON-NLS-1$ |
| String[] paths = classpath[i].getValueComponents(); |
| for (int j = 0; j < paths.length; j++) { |
| result.add(paths[j]); |
| } |
| } |
| |
| return (String[]) result.toArray(new String[result.size()]); |
| } |
| |
| ///////////////////// Begin Meta Data Accessor Methods //////////////////// |
| /** |
| * @see BundleData#getLocation() |
| */ |
| public String getLocation() { |
| return location; |
| } |
| /** |
| * Sets the location for this bundle data |
| * @param location the location string |
| */ |
| public void setLocation(String location) { |
| this.location = location; |
| } |
| |
| /** |
| * Returns the filename for the base file of this bundle data |
| * @return the filename for the base file of this bundle data |
| */ |
| public String getFileName() { |
| return fileName; |
| } |
| |
| /** |
| * Sets the filename for the base file of this bundle data |
| * @param fileName the name of the base file of this bundle data |
| */ |
| public void setFileName(String fileName) { |
| this.fileName = fileName; |
| } |
| |
| /** |
| * Returns the list of native file paths to install for this bundle |
| * @return the list of native file paths to install for this bundle |
| */ |
| public String[] getNativePaths() { |
| return nativePaths; |
| } |
| |
| /** |
| * Returns a comma separated list of native file paths to install for this bundle |
| * @return a comma separated list of native file paths to install for this bundle |
| */ |
| public String getNativePathsString() { |
| if (nativePaths == null || nativePaths.length == 0) |
| return null; |
| StringBuffer sb = new StringBuffer(); |
| for (int i = 0; i < nativePaths.length; i++) { |
| sb.append(nativePaths[i]); |
| if (i < nativePaths.length - 1) |
| sb.append(','); |
| } |
| return sb.toString(); |
| } |
| |
| /** |
| * Sets the list of native file paths to install for this bundle |
| * @param nativePaths the list of native file paths to install for this bundle |
| */ |
| public void setNativePaths(String[] nativePaths) { |
| this.nativePaths = nativePaths; |
| } |
| |
| /** |
| * Sets the comma separated list of native file paths to install for this bundle |
| * @param nativePaths the comma separated list of native file paths to install for this bundle |
| */ |
| public void setNativePaths(String nativePaths) { |
| if (nativePaths == null) |
| return; |
| ArrayList result = new ArrayList(5); |
| StringTokenizer st = new StringTokenizer(nativePaths, ","); //$NON-NLS-1$ |
| while (st.hasMoreTokens()) { |
| String path = st.nextToken(); |
| result.add(path); |
| } |
| setNativePaths((String[]) result.toArray(new String[result.size()])); |
| } |
| |
| /** |
| * Returns the generation number for this bundle |
| * @return the generation number for this bundle |
| */ |
| public int getGeneration() { |
| return generation; |
| } |
| |
| /** |
| * Sets the generation number for this bundle |
| * @param generation the generation number for this bundle |
| */ |
| public void setGeneration(int generation) { |
| this.generation = generation; |
| } |
| |
| /** |
| * @see BundleData#getLastModified() |
| */ |
| public long getLastModified() { |
| return lastModified; |
| } |
| |
| /** |
| * Sets the last modified timestamp for this bundle |
| * @param lastModified the last modified timestamp for this bundle |
| */ |
| public void setLastModified(long lastModified) { |
| this.lastModified = lastModified; |
| } |
| |
| /** |
| * @see BundleData#getStartLevel() |
| */ |
| public int getStartLevel() { |
| return startLevel; |
| } |
| |
| /** |
| * @see BundleData#setStartLevel(int) |
| */ |
| public void setStartLevel(int startLevel) { |
| this.startLevel = startLevel; |
| } |
| |
| /** |
| * @see BundleData#getStatus() |
| */ |
| public int getStatus() { |
| return status; |
| } |
| |
| /** |
| * @see BundleData#setStatus(int) |
| */ |
| public void setStatus(int status) { |
| this.status = status; |
| } |
| |
| /** |
| * Returns if this bundle is installed by reference |
| * @return true if this bundle is installed by reference |
| */ |
| public boolean isReference() { |
| return reference; |
| } |
| |
| /** |
| * Sets if this bundle is installed by reference |
| * @param reference indicates if this bundle is installed by reference |
| */ |
| public void setReference(boolean reference) { |
| this.reference = reference; |
| } |
| |
| ///////////////////// End Meta Data Accessor Methods //////////////////// |
| |
| ///////////////////// Begin Manifest Value Accessor Methods ///////////////////// |
| |
| /** |
| * @see BundleData#getSymbolicName() |
| */ |
| public String getSymbolicName() { |
| return symbolicName; |
| } |
| |
| /** |
| * Returns the base storage directory for this bundle |
| * @return the base storage directory for this bundle |
| */ |
| public File getBundleStoreDir() { |
| return bundleStoreDir; |
| } |
| |
| /** |
| * Sets the symbolic name of this bundle |
| * @param symbolicName the symbolic name of this bundle |
| */ |
| public void setSymbolicName(String symbolicName) { |
| this.symbolicName = symbolicName; |
| } |
| |
| /** |
| * Loads all metadata for this bundle from the bundle manifest |
| * @throws BundleException |
| */ |
| protected void loadFromManifest() throws BundleException { |
| getManifest(); |
| if (manifest == null) |
| throw new BundleException(NLS.bind(AdaptorMsg.ADAPTOR_ERROR_GETTING_MANIFEST, getLocation())); |
| try { |
| setVersion(Version.parseVersion((String) manifest.get(Constants.BUNDLE_VERSION))); |
| } catch (IllegalArgumentException e) { |
| setVersion(new InvalidVersion((String) manifest.get(Constants.BUNDLE_VERSION))); |
| } |
| ManifestElement[] bsnHeader = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME)); |
| int bundleType = 0; |
| if (bsnHeader != null) { |
| setSymbolicName(bsnHeader[0].getValue()); |
| String singleton = bsnHeader[0].getDirective(Constants.SINGLETON_DIRECTIVE); |
| if (singleton == null) |
| singleton = bsnHeader[0].getAttribute(Constants.SINGLETON_DIRECTIVE); |
| if ("true".equals(singleton)) //$NON-NLS-1$ |
| bundleType |= TYPE_SINGLETON; |
| } |
| setClassPathString((String) manifest.get(Constants.BUNDLE_CLASSPATH)); |
| setActivator((String) manifest.get(Constants.BUNDLE_ACTIVATOR)); |
| String host = (String) manifest.get(Constants.FRAGMENT_HOST); |
| if (host != null) { |
| bundleType |= TYPE_FRAGMENT; |
| ManifestElement[] hostElement = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, host); |
| if (Constants.getInternalSymbolicName().equals(hostElement[0].getValue()) || Constants.OSGI_SYSTEM_BUNDLE.equals(hostElement[0].getValue())) { |
| String extensionType = hostElement[0].getDirective("extension"); //$NON-NLS-1$ |
| if (extensionType == null || extensionType.equals("framework")) //$NON-NLS-1$ |
| bundleType |= TYPE_FRAMEWORK_EXTENSION; |
| else |
| bundleType |= TYPE_BOOTCLASSPATH_EXTENSION; |
| } |
| } |
| setType(bundleType); |
| setExecutionEnvironment((String) manifest.get(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT)); |
| setDynamicImports((String) manifest.get(Constants.DYNAMICIMPORT_PACKAGE)); |
| } |
| |
| /** |
| * @see BundleData#getVersion() |
| */ |
| public Version getVersion() { |
| return version; |
| } |
| |
| /** |
| * Sets the version of this bundle |
| * @param version the version of this bundle |
| */ |
| public void setVersion(Version version) { |
| this.version = version; |
| } |
| |
| /** |
| * @see BundleData#getActivator() |
| */ |
| public String getActivator() { |
| return activator; |
| } |
| |
| /** |
| * Returns the data storage directory for this bundle |
| * @return the data storage directory for this bundle |
| */ |
| protected File getDataDir() { |
| return dirData; |
| } |
| |
| /** |
| * Sets the bundle store directory for this bundle |
| * @param bundleStoreDir the store directory for this bundle |
| */ |
| protected void setBundleStoreDir(File bundleStoreDir) { |
| this.bundleStoreDir = bundleStoreDir; |
| } |
| |
| /** |
| * Sets the initial bundle store directory according to the bundle ID |
| * @param bundleID the bundle ID |
| */ |
| protected void initBundleStoreDirs(String bundleID) { |
| setBundleStoreDir(new File(((AbstractFrameworkAdaptor) adaptor).getBundleStoreRootDir(), bundleID)); |
| } |
| |
| /** |
| * Sets the activator for this bundle |
| * @param activator the activator for this bundle |
| */ |
| public void setActivator(String activator) { |
| this.activator = activator; |
| } |
| |
| /** |
| * @see BundleData#getClassPath() |
| */ |
| public String[] getClassPath() throws BundleException { |
| ManifestElement[] classpathElements = ManifestElement.parseHeader(Constants.BUNDLE_CLASSPATH, classpath); |
| return getClassPath(classpathElements); |
| } |
| |
| /** |
| * Returns the Bundle-ClassPath value as specified in the bundle manifest file. |
| * @return the Bundle-ClassPath value as specified in the bundle manifest file. |
| */ |
| public String getClassPathString() { |
| return classpath; |
| } |
| |
| /** |
| * Sets the bundle classpath value of this bundle data. |
| * @param classpath the bundle classpath |
| */ |
| public void setClassPathString(String classpath) { |
| this.classpath = classpath; |
| } |
| |
| /** |
| * @see BundleData#getExecutionEnvironment() |
| */ |
| public String getExecutionEnvironment() { |
| return executionEnvironment; |
| } |
| |
| /** |
| * Sets the execution environment for this bundle |
| * @param executionEnvironment the execution environment for this bundle |
| */ |
| public void setExecutionEnvironment(String executionEnvironment) { |
| this.executionEnvironment = executionEnvironment; |
| } |
| |
| /** |
| * @see BundleData#getDynamicImports() |
| */ |
| public String getDynamicImports() { |
| return dynamicImports; |
| } |
| |
| /** |
| * Sets the dynamic imports of this bundle data. |
| * @param dynamicImports the dynamic imports |
| */ |
| public void setDynamicImports(String dynamicImports) { |
| this.dynamicImports = dynamicImports; |
| } |
| |
| /** |
| * @see BundleData#getType() |
| */ |
| public int getType() { |
| return type; |
| } |
| |
| /** |
| * Sets the type of this bundle |
| * @param type the type of this bundle |
| */ |
| public void setType(int type) { |
| this.type = type; |
| } |
| |
| ///////////////////// End Manifest Value Accessor Methods ///////////////////// |
| |
| /** |
| * @see BundleData#matchDNChain(String) |
| */ |
| public boolean matchDNChain(String pattern) { |
| if (System.getSecurityManager() == null) |
| return false; |
| |
| if (getBaseBundleFile() instanceof SignedBundle) |
| return ((SignedBundle) getBaseBundleFile()).matchDNChain(pattern); |
| return false; |
| } |
| |
| /** |
| * Return a copy of this object with the |
| * generation dependent fields updated to |
| * the next free generation level. |
| * |
| * @throws IOException If there are no more available generation levels. |
| */ |
| protected AbstractBundleData nextGeneration(String referenceFile) throws IOException { |
| int nextGeneration = getGeneration(); |
| |
| while (nextGeneration < Integer.MAX_VALUE) { |
| nextGeneration++; |
| |
| File nextDirGeneration = new File(getBundleStoreDir(), String.valueOf(nextGeneration)); |
| |
| if (nextDirGeneration.exists()) { |
| continue; |
| } |
| |
| AbstractBundleData next; |
| try { |
| next = (AbstractBundleData) clone(); |
| } catch (CloneNotSupportedException e) { |
| // this shouldn't happen, since we are Cloneable |
| throw new InternalError(); |
| } |
| |
| next.setGeneration(nextGeneration); |
| |
| if (referenceFile != null) { |
| next.setReference(true); |
| next.setFileName(referenceFile); |
| } else { |
| if (next.isReference()) { |
| next.setReference(false); |
| next.setFileName(AbstractFrameworkAdaptor.BUNDLEFILE_NAME); |
| } |
| } |
| |
| // null out the manifest to force it to be re-read. |
| next.manifest = null; |
| return (next); |
| } |
| |
| throw new IOException(AdaptorMsg.ADAPTOR_STORAGE_EXCEPTION); |
| } |
| |
| /** |
| * Initializes a new bundle and loads all its metadata from the bundle manifest |
| * @throws IOException |
| * @throws BundleException |
| */ |
| public void initializeNewBundle() throws IOException, BundleException { |
| createBaseBundleFile(); |
| loadFromManifest(); |
| } |
| |
| /** |
| * Creates the base BundleFile for this bundle |
| * @return the base BundleFile for this bundle |
| * @throws IOException if an IOExceptions occurs |
| */ |
| protected BundleFile createBaseBundleFile() throws IOException { |
| baseBundleFile = getAdaptor().createBaseBundleFile(getBaseFile(), this); |
| return baseBundleFile; |
| } |
| |
| /** |
| * Return the base File for the bundle. |
| * Attempt to create the bundle generation directory if it does not exist. |
| * |
| * @return the base File object for the bundle. |
| */ |
| protected File getBaseFile() { |
| return isReference() ? new File(getFileName()) : new File(createGenerationDir(), getFileName()); |
| } |
| |
| /** |
| * Returns a list of files used for the classpath of this bundle data. |
| * the contents of the bundle are searched for the classpath entries. |
| * @param classpaths the classpath entries to search for |
| * @return a list of files used for the classpath of this bundle data. |
| */ |
| protected File[] getClasspathFiles(String[] classpaths) { |
| ArrayList results = new ArrayList(classpaths.length); |
| for (int i = 0; i < classpaths.length; i++) { |
| if (".".equals(classpaths[i])) //$NON-NLS-1$ |
| results.add(getBaseFile()); |
| else { |
| File result = getBaseBundleFile().getFile(classpaths[i]); |
| if (result != null) |
| results.add(result); |
| } |
| } |
| return (File[]) results.toArray(new File[results.size()]); |
| } |
| |
| /** |
| * Sets the data directory for this bundle |
| * @param dirData the data directory for this bundle |
| */ |
| protected void setDataDir(File dirData) { |
| this.dirData = dirData; |
| } |
| |
| /** |
| * @see BundleData#findLibrary(String) |
| */ |
| public String findLibrary(String libname) { |
| String mappedName = System.mapLibraryName(libname); |
| String path = null; |
| |
| if (Debug.DEBUG && Debug.DEBUG_LOADER) { |
| Debug.println(" mapped library name: " + mappedName); //$NON-NLS-1$ |
| } |
| |
| path = findNativePath(mappedName); |
| |
| if (path == null) { |
| if (Debug.DEBUG && Debug.DEBUG_LOADER) { |
| Debug.println(" library does not exist: " + mappedName); //$NON-NLS-1$ |
| } |
| path = findNativePath(libname); |
| } |
| |
| if (Debug.DEBUG && Debug.DEBUG_LOADER) { |
| Debug.println(" returning library: " + path); //$NON-NLS-1$ |
| } |
| return path; |
| } |
| |
| /** |
| * @see BundleData#open() |
| */ |
| public void open() throws IOException { |
| baseBundleFile.open(); |
| } |
| |
| /** |
| * Searches the native paths for a match against the specified libname. |
| * If a match is found then the native path is returned; otherwise a |
| * <code>null</code> value is returned. |
| * @param libname a library name |
| * @return a matching native path or <code>null</code>. |
| */ |
| protected String findNativePath(String libname) { |
| int slash = libname.lastIndexOf('/'); |
| if (slash >= 0) |
| libname = libname.substring(slash + 1); |
| String[] nativepaths = getNativePaths(); |
| if (nativepaths != null) { |
| for (int i = 0; i < nativepaths.length; i++) { |
| slash = nativepaths[i].lastIndexOf('/'); |
| String path = slash < 0 ? nativePaths[i] : nativePaths[i].substring(slash + 1); |
| if (path.equals(libname)) { |
| File nativeFile = baseBundleFile.getFile(nativepaths[i]); |
| if (nativeFile != null) |
| return nativeFile.getAbsolutePath(); |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Return the generation directory for the bundle data. The generation |
| * directory can be used by the framework to cache files from the bundle |
| * to the file system. Attempt to create the directory if it does not exist. |
| * @return The generation directory for the bundle data or null if not |
| * supported. |
| */ |
| public File createGenerationDir() { |
| File generationDir = getGenerationDir(); |
| if (!generationDir.exists() && (!adaptor.canWrite() || !generationDir.mkdirs())) { |
| if (Debug.DEBUG && Debug.DEBUG_GENERAL) { |
| Debug.println("Unable to create bundle generation directory: " + generationDir.getPath()); //$NON-NLS-1$ |
| } |
| } |
| |
| return generationDir; |
| } |
| |
| /** |
| * Return the base BundleFile for this BundleData. The base BundleFile |
| * is the BundleFile that contains all the content of the bundle. |
| * @return the base BundleFile. |
| */ |
| public BundleFile getBaseBundleFile() { |
| return baseBundleFile; |
| } |
| |
| /** |
| * Close all resources for this BundleData |
| */ |
| public void close() throws IOException { |
| if (baseBundleFile != null) { |
| baseBundleFile.close(); |
| } |
| } |
| |
| /** |
| * Return the bundle data directory. |
| * Attempt to create the directory if it does not exist. |
| * |
| * @return Bundle data directory. |
| */ |
| public File getDataFile(String path) { |
| // lazily initialize dirData to prevent early access to configuration location |
| if (getDataDir() == null) { |
| File dataRoot = adaptor.getDataRootDir(); |
| if (dataRoot == null) |
| throw new IllegalStateException(AdaptorMsg.ADAPTOR_DATA_AREA_NOT_SET); |
| setDataDir(new File(dataRoot, id + "/" + AbstractFrameworkAdaptor.DATA_DIR_NAME)); //$NON-NLS-1$ |
| } |
| if (!getDataDir().exists() && (!adaptor.canWrite() || !getDataDir().mkdirs())) { |
| if (Debug.DEBUG && Debug.DEBUG_GENERAL) { |
| Debug.println("Unable to create bundle data directory: " + getDataDir().getPath()); //$NON-NLS-1$ |
| } |
| } |
| |
| return (new File(getDataDir(), path)); |
| } |
| |
| /** |
| * @see BundleData#installNativeCode(String[]) |
| */ |
| public void installNativeCode(String[] nativepaths) throws BundleException { |
| StringBuffer sb = new StringBuffer(); |
| for (int i = 0; i < nativepaths.length; i++) { |
| // extract the native code |
| File nativeFile = baseBundleFile.getFile(nativepaths[i]); |
| if (nativeFile == null) { |
| throw new BundleException(NLS.bind(AdaptorMsg.BUNDLE_NATIVECODE_EXCEPTION, nativepaths[i])); |
| } |
| sb.append(nativepaths[i]); |
| if (i < nativepaths.length - 1) { |
| sb.append(","); //$NON-NLS-1$ |
| } |
| } |
| if (sb.length() > 0) |
| setNativePaths(sb.toString()); |
| } |
| |
| /** |
| * Returns the generation directory for the bundle data. The returned |
| * file may not exist. |
| * @return the generation directory for the bundle data. |
| */ |
| protected File getGenerationDir() { |
| return new File(getBundleStoreDir(), String.valueOf(getGeneration())); |
| } |
| |
| /** |
| * Returns the parent generation directory for the bundle data. The returned |
| * file may not exist. A value of <code>null</code> is returned if there is |
| * no parent generation directory. |
| * @return the parent gneration directory for the bundle data. |
| */ |
| public File getParentGenerationDir() { |
| return null; |
| } |
| } |