📄 defaultbundlearchive.java
字号:
} } private JarFile openBundleJarUnchecked(File revisionDir) throws Exception { // Get bundle jar file. File bundleJar = new File(revisionDir, BUNDLE_JAR_FILE); // Get bundle jar file. return new JarFile(bundleJar); } public String[] getClassPath(int revision) throws Exception { if (System.getSecurityManager() != null) { try { return (String []) AccessController.doPrivileged( new PrivilegedAction( PrivilegedAction.GET_CLASS_PATH_ACTION, this, revision)); } catch (PrivilegedActionException ex) { throw ((PrivilegedActionException) ex).getException(); } } else { return getClassPathUnchecked(revision); } } private String[] getClassPathUnchecked(int revision) throws Exception { // Get the revision directory. File revisionDir = new File( m_dir, REVISION_DIRECTORY + getRefreshCount() + "." + revision); // Get the bundle's manifest header. Map map = getManifestHeader(revision); if (map == null) { map = new HashMap(); } // Find class path meta-data. String classPath = null; Iterator iter = map.entrySet().iterator(); while ((classPath == null) && iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); if (entry.getKey().toString().toLowerCase().equals( OscarConstants.BUNDLE_CLASSPATH.toLowerCase())) { classPath = entry.getValue().toString(); } } // Parse the class path into strings. String[] classPathStrings = TextUtil.parseCommaDelimitedString(classPath); if (classPathStrings == null) { classPathStrings = new String[0]; } // Now, check for "." in the class path. boolean includeDot = false; for (int i = 0; !includeDot && (i < classPathStrings.length); i++) { if (classPathStrings[i].equals(OscarConstants.CLASS_PATH_DOT)) { includeDot = true; } } // Include all JARs in the embedded jar directory, since they // were extracted when the bundle was initially saved. File embedDir = new File(revisionDir, EMBEDDED_DIRECTORY); String[] paths = null; if (embedDir.exists()) { // The size of the paths array is the number of // embedded JAR files plus one, if we need to include // ".", otherwise it is just the number of JAR files. // If "." is included, then it will be added to the // first place in the path array below. File[] children = embedDir.listFiles(); int size = (children == null) ? 0 : children.length; size = (includeDot) ? size + 1 : size; paths = new String[size]; for (int i = 0; i < children.length; i++) { // If we are including "." then skip the first slot, // because this is where we will put the bundle JAR file. paths[(includeDot) ? i + 1 : i] = children[i].getPath(); } } // If there is nothing on the class path, then include // "." by default, as per the spec. if ((paths == null) || (paths.length == 0)) { includeDot = true; paths = new String[1]; } // Put the bundle jar file first, if included. if (includeDot) { paths[0] = revisionDir + File.separator + BUNDLE_JAR_FILE; } return paths; }// TODO: This will need to consider security. public String findLibrary(int revision, String libName) throws Exception { return findLibraryUnchecked(revision, libName); } private String findLibraryUnchecked(int revision, String libName) throws Exception { // Get the revision directory. File revisionDir = new File( m_dir.getAbsoluteFile(), REVISION_DIRECTORY + getRefreshCount() + "." + revision); // Get bundle lib directory. File libDir = new File(revisionDir, LIBRARY_DIRECTORY); // Get lib file. File libFile = new File(libDir, File.separatorChar + libName); // Make sure that the library's parent directory exists; // it may be in a sub-directory. libDir = libFile.getParentFile(); if (!libDir.exists()) { if (!libDir.mkdirs()) { throw new IOException("Unable to create library directory."); } } // Extract the library from the JAR file if it does not // already exist. if (!libFile.exists()) { JarFile jarFile = null; InputStream is = null; try { jarFile = openBundleJarUnchecked(revisionDir); ZipEntry ze = jarFile.getEntry(libName); if (ze == null) { throw new IOException("No JAR entry: " + libName); } is = new BufferedInputStream( jarFile.getInputStream(ze), DefaultBundleCache.BUFSIZE); if (is == null) { throw new IOException("No input stream: " + libName); } // Create the file. copy(is, libFile); } finally { if (jarFile != null) jarFile.close(); if (is != null) is.close(); } } return libFile.toString(); } /** * This utility method is used to retrieve the current refresh * counter value for the bundle. This value is used when generating * the bundle JAR directory name where native libraries are extracted. * This is necessary because Sun's JVM requires a one-to-one mapping * between native libraries and class loaders where the native library * is uniquely identified by its absolute path in the file system. This * constraint creates a problem when a bundle is refreshed, because it * gets a new class loader. Using the refresh counter to generate the name * of the bundle JAR directory resolves this problem because each time * bundle is refresh, the native library will have a unique name. * As a result of the unique name, the JVM will then reload the * native library without a problem. **/ private long getRefreshCount() throws Exception { // If we have already read the update counter file, // then just return the result. if (m_refreshCount >= 0) { return m_refreshCount; } // Get update counter file. File counterFile = new File(m_dir, REFRESH_COUNTER_FILE); // If the update counter file doesn't exist, then // assume the counter is at zero. if (!counterFile.exists()) { return 0; } // Read the bundle update counter. FileReader fr = null; BufferedReader br = null; try { fr = new FileReader(counterFile); br = new BufferedReader(fr); long counter = Long.parseLong(br.readLine()); return counter; } finally { if (br != null) br.close(); if (fr != null) fr.close(); } } /** * This utility method is used to retrieve the current refresh * counter value for the bundle. This value is used when generating * the bundle JAR directory name where native libraries are extracted. * This is necessary because Sun's JVM requires a one-to-one mapping * between native libraries and class loaders where the native library * is uniquely identified by its absolute path in the file system. This * constraint creates a problem when a bundle is refreshed, because it * gets a new class loader. Using the refresh counter to generate the name * of the bundle JAR directory resolves this problem because each time * bundle is refresh, the native library will have a unique name. * As a result of the unique name, the JVM will then reload the * native library without a problem. **/ private void setRefreshCount(long counter) throws Exception { // Get update counter file. File counterFile = new File(m_dir, REFRESH_COUNTER_FILE); // Write the update counter. FileWriter fw = null; BufferedWriter bw = null; try { fw = new FileWriter(counterFile); bw = new BufferedWriter(fw); String s = Long.toString(counter); bw.write(s, 0, s.length()); m_refreshCount = counter; } catch (IOException ex) { Oscar.error("DefaultBundleArchive: Unable to write counter: " + ex); throw ex; } finally { if (bw != null) bw.close(); if (fw != null) fw.close(); } } // // File-oriented utility methods. // protected static boolean deleteDirectoryTree(File target) { if (!target.exists()) { return true; } if (target.isDirectory()) { File[] files = target.listFiles(); for (int i = 0; i < files.length; i++) { deleteDirectoryTree(files[i]); } } return target.delete(); } /** * This method copies an input stream to the specified file. * <p> * Security: This method must be called from within a <tt>doPrivileged()</tt> * block since it accesses the disk. * @param is the input stream to copy. * @param outputFile the file to which the input stream should be copied. **/ private void copy(InputStream is, File outputFile) throws IOException { OutputStream os = null; try { os = new BufferedOutputStream( new FileOutputStream(outputFile), DefaultBundleCache.BUFSIZE); byte[] b = new byte[DefaultBundleCache.BUFSIZE]; int len = 0; while ((len = is.read(b)) != -1) os.write(b, 0, len); } finally { if (is != null) is.close(); if (os != null) os.close(); } } /** * This method pre-processes a bundle JAR file making it ready * for use. This entails extracting all embedded JAR files and * all native libraries. * @throws java.lang.Exception if any error occurs while processing JAR file. **/ private void preprocessBundleJar(int revision, File revisionDir) throws Exception { // // Create special directories so that we can avoid checking // for their existence all the time. // File embedDir = new File(revisionDir, EMBEDDED_DIRECTORY); if (!embedDir.exists()) { if (!embedDir.mkdir()) { throw new IOException("Could not create embedded JAR directory."); } } File libDir = new File(revisionDir, LIBRARY_DIRECTORY); if (!libDir.exists()) { if (!libDir.mkdir()) { throw new IOException("Unable to create native library directory."); } } // // This block extracts all embedded JAR files. // try { // Get the bundle's manifest header.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -