--- a/jdk/src/share/classes/sun/jkernel/Bundle.java Wed Jul 05 17:32:52 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,922 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.jkernel;
-
-import java.io.*;
-import java.net.HttpRetryException;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.jar.*;
-import java.util.zip.GZIPInputStream;
-
-/**
- * Represents a bundle which may or may not currently be installed.
- *
- *@author Ethan Nicholas
- */
-public class Bundle {
- static {
- if (!DownloadManager.jkernelLibLoaded) {
- // This code can be invoked directly by the deploy build.
- System.loadLibrary("jkernel");
- }
- }
- /**
- * Compress file sourcePath with "extra" algorithm (e.g. 7-Zip LZMA)
- * if available, put the uncompressed data into file destPath and
- * return true. If not available return false and do nothing with destPath.
- *
- * @param srcPath path to existing uncompressed file
- * @param destPath path for the compressed file to be created
- * @returns true if extra algorithm used, false if not
- * @throws IOException if the extra compression code should be available
- * but cannot be located or linked to, the destination file already
- * exists or cannot be opened for writing, or the compression fails
- */
- public static native boolean extraCompress(String srcPath,
- String destPath) throws IOException;
-
- /**
- * Decompress file sourcePath with "extra" algorithm (e.g. 7-Zip LZMA)
- * if available, put the uncompressed data into file destPath and
- * return true. If not available return false and do nothing with
- * destPath.
- * @param srcPath path to existing compressed file
- * @param destPath path to uncompressed file to be created
- * @returns true if extra algorithm used, false if not
- * @throws IOException if the extra uncompression code should be available
- * but cannot be located or linked to, the destination file already
- * exists or cannot be opened for writing, or the uncompression fails
- */
- public static native boolean extraUncompress(String srcPath,
- String destPath) throws IOException;
-
- private static final String BUNDLE_JAR_ENTRY_NAME = "classes.jar";
-
- /** The bundle is not present. */
- protected static final int NOT_DOWNLOADED = 0;
-
- /**
- * The bundle is in the download queue but has not finished downloading.
- */
- protected static final int QUEUED = 1;
-
- /** The bundle has finished downloading but is not installed. */
- protected static final int DOWNLOADED = 2;
-
- /** The bundle is fully installed and functional. */
- protected static final int INSTALLED = 3;
-
- /** Thread pool used to manage dependency downloads. */
- private static ExecutorService threadPool;
-
- /** Size of thread pool. */
- static final int THREADS;
-
- static {
- String downloads = System.getProperty(
- DownloadManager.KERNEL_SIMULTANEOUS_DOWNLOADS_PROPERTY);
- if (downloads != null)
- THREADS = Integer.parseInt(downloads.trim());
- else
- THREADS = 1;
- }
-
- /** Mutex used to safely access receipts file. */
- private static Mutex receiptsMutex;
-
- /** Maps bundle names to known bundle instances. */
- private static Map<String, Bundle> bundles =
- new HashMap<String, Bundle>();
-
- /** Contains the names of currently-installed bundles. */
- static Set<String> receipts = new HashSet<String>();
-
- private static int bytesDownloaded;
-
- /** Path where bundle receipts are written. */
- private static File receiptPath = new File(DownloadManager.getBundlePath(),
- "receipts");
-
- /** The size of the receipts file the last time we saw it. */
- private static int receiptsSize;
-
- /** The bundle name, e.g. "java_awt". */
- private String name;
-
- /** The path to which we are saving the downloaded bundle file. */
- private File localPath;
-
- /**
- * The path of the extracted JAR file containing the bundle's classes.
- */
- private File jarPath;
-
- // for vista IE7 protected mode
- private File lowJarPath;
- private File lowJavaPath = null;
-
- /** The current state (DOWNLOADED, INSTALLED, etc.). */
- protected int state;
-
- /**
- * True if we should delete the downloaded bundle after installing it.
- */
- protected boolean deleteOnInstall = true;
-
- private static Mutex getReceiptsMutex() {
- if (receiptsMutex == null)
- receiptsMutex = Mutex.create(DownloadManager.MUTEX_PREFIX +
- "receipts");
- return receiptsMutex;
- }
-
-
- /**
- * Reads the receipts file in order to seed the list of currently
- * installed bundles.
- */
- static synchronized void loadReceipts() {
- getReceiptsMutex().acquire();
- try {
- if (receiptPath.exists()) {
- int size = (int) receiptPath.length();
- if (size != receiptsSize) { // ensure that it has actually
- // been modified
- DataInputStream in = null;
- try {
- receipts.clear();
- for (String bundleName : DownloadManager.getBundleNames()) {
- if ("true".equals(DownloadManager.getBundleProperty(bundleName,
- DownloadManager.INSTALL_PROPERTY)))
- receipts.add(bundleName);
- }
- if (receiptPath.exists()) {
- in = new DataInputStream(new BufferedInputStream(
- new FileInputStream(receiptPath)));
- String line;
- while ((line = in.readLine()) != null) {
- receipts.add(line.trim());
- }
- }
- receiptsSize = size;
- }
- catch (IOException e) {
- DownloadManager.log(e);
- // safe to continue, as the worst that happens is
- // we re-download existing bundles
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ioe) {
- DownloadManager.log(ioe);
- }
- }
- }
- }
- }
- }
- finally {
- getReceiptsMutex().release();
- }
- }
-
-
- /** Returns the bundle corresponding to the specified name. */
- public static synchronized Bundle getBundle(String bundleId)
- throws IOException {
- Bundle result =(Bundle) bundles.get(bundleId);
- if (result == null && (bundleId.equals("merged") ||
- Arrays.asList(DownloadManager.getBundleNames()).contains(bundleId))) {
- result = new Bundle();
- result.name = bundleId;
-
- if (DownloadManager.isWindowsVista()) {
- result.localPath =
- new File(DownloadManager.getLocalLowTempBundlePath(),
- bundleId + ".zip");
- result.lowJavaPath = new File(
- DownloadManager.getLocalLowKernelJava() + bundleId);
- } else {
- result.localPath = new File(DownloadManager.getBundlePath(),
- bundleId + ".zip");
- }
-
- String jarPath = DownloadManager.getBundleProperty(bundleId,
- DownloadManager.JAR_PATH_PROPERTY);
- if (jarPath != null) {
- if (DownloadManager.isWindowsVista()) {
- result.lowJarPath = new File(
- DownloadManager.getLocalLowKernelJava() + bundleId,
- jarPath);
- }
- result.jarPath = new File(DownloadManager.JAVA_HOME,
- jarPath);
-
- } else {
-
- if (DownloadManager.isWindowsVista()) {
- result.lowJarPath = new File(
- DownloadManager.getLocalLowKernelJava() + bundleId +
- "\\lib\\bundles",
- bundleId + ".jar");
- }
-
- result.jarPath = new File(DownloadManager.getBundlePath(),
- bundleId + ".jar");
-
- }
-
- bundles.put(bundleId, result);
- }
- return result;
- }
-
-
- /**
- * Returns the name of this bundle. The name is typically defined by
- * the bundles.xml file.
- */
- public String getName() {
- return name;
- }
-
-
- /**
- * Sets the name of this bundle.
- */
- public void setName(String name) {
- this.name = name;
- }
-
-
- /**
- * Returns the path to the bundle file on the local filesystem. The file
- * will only exist if the bundle has already been downloaded; otherwise
- * it will be created when download() is called.
- */
- public File getLocalPath() {
- return localPath;
- }
-
-
- /**
- * Sets the location of the bundle file on the local filesystem. If the
- * file already exists, the bundle will be considered downloaded;
- * otherwise the file will be created when download() is called.
- */
- public void setLocalPath(File localPath) {
- this.localPath = localPath;
- }
-
-
- /**
- * Returns the path to the extracted JAR file containing this bundle's
- * classes. This file should only exist after the bundle has been
- * installed.
- */
- public File getJarPath() {
- return jarPath;
- }
-
-
- /**
- * Sets the path to the extracted JAR file containing this bundle's
- * classes. This file will be created as part of installing the bundle.
- */
- public void setJarPath(File jarPath) {
- this.jarPath = jarPath;
- }
-
-
- /**
- * Returns the size of the bundle download in bytes.
- */
- public int getSize() {
- return Integer.valueOf(DownloadManager.getBundleProperty(getName(),
- DownloadManager.SIZE_PROPERTY));
- }
-
-
- /**
- * Returns true if the bundle file (getLocalPath()) should be deleted
- * when the bundle is successfully installed. Defaults to true.
- */
- public boolean getDeleteOnInstall() {
- return deleteOnInstall;
- }
-
-
- /**
- * Sets whether the bundle file (getLocalPath()) should be deleted
- * when the bundle is successfully installed. Defaults to true.
- */
- public void setDeleteOnInstall(boolean deleteOnInstall) {
- this.deleteOnInstall = deleteOnInstall;
- }
-
-
- /** Sets the current state of this bundle to match reality. */
- protected void updateState() {
- synchronized(Bundle.class) {
- loadReceipts();
- if (receipts.contains(name) ||
- "true".equals(DownloadManager.getBundleProperty(name,
- DownloadManager.INSTALL_PROPERTY)))
- state = Bundle.INSTALLED;
- else if (localPath.exists())
- state = Bundle.DOWNLOADED;
- }
- }
-
-
- private String getURL(boolean showUI) throws IOException {
- Properties urls = DownloadManager.getBundleURLs(showUI);
- String result = urls.getProperty(name + ".zip");
- if (result == null) {
- result = urls.getProperty(name);
- if (result == null) {
- DownloadManager.log("Unable to determine bundle URL for " + this);
- DownloadManager.log("Bundle URLs: " + urls);
- DownloadManager.sendErrorPing(DownloadManager.ERROR_NO_SUCH_BUNDLE);
-
- throw new NullPointerException("Unable to determine URL " +
- "for bundle: " + this);
- }
- }
- return result;
- }
-
-
- /**
- * Downloads the bundle. This method blocks until the download is
- * complete.
- *
- *@param showProgress true to display a progress dialog
- */
- private void download(boolean showProgress) {
- if (DownloadManager.isJREComplete())
- return;
- Mutex mutex = Mutex.create(DownloadManager.MUTEX_PREFIX + name +
- ".download");
- mutex.acquire();
- try {
- long start = System.currentTimeMillis();
-
- boolean retry;
-
- do {
- retry = false;
- updateState();
- if (state == DOWNLOADED || state == INSTALLED) {
- return;
- }
- File tmp = null;
- try {
- tmp = new File(localPath + ".tmp");
-
- // tmp.deleteOnExit();
-
- if (DownloadManager.getBaseDownloadURL().equals(
- DownloadManager.RESOURCE_URL)) {
- // RESOURCE_URL is used during build process, to
- // avoid actual network traffic. This is called in
- // the SplitJRE DownloadTest to determine which
- // classes are needed to support downloads, but we
- // bypass the actual HTTP download to simplify the
- // build process (it's all native code, so from
- // DownloadTest's standpoint it doesn't matter if we
- // really call it or not).
- String path = "/" + name + ".zip";
- InputStream in =
- getClass().getResourceAsStream(path);
- if (in == null)
- throw new IOException("could not locate " +
- "resource: " + path);
- FileOutputStream out = new FileOutputStream(tmp);
- DownloadManager.send(in, out);
- in.close();
- out.close();
- }
- else {
- try {
- String bundleURL = getURL(showProgress);
- DownloadManager.log("Downloading from: " +
- bundleURL);
- DownloadManager.downloadFromURL(bundleURL, tmp,
- name.replace('_', '.'), showProgress);
- }
- catch (HttpRetryException e) {
- // Akamai returned a 403, get new URL
- DownloadManager.flushBundleURLs();
- String bundleURL = getURL(showProgress);
- DownloadManager.log("Retrying at new " +
- "URL: " + bundleURL);
- DownloadManager.downloadFromURL(bundleURL, tmp,
- name.replace('_', '.'),
- showProgress);
- // we intentionally don't do a 403 retry
- // again, to avoid infinite retries
- }
- }
- if (!tmp.exists() || tmp.length() == 0) {
- if (showProgress) {
- // since showProgress = true, native code should
- // have offered to retry. Since we ended up here,
- // we conclude that download failed & user opted to
- // cancel. Set complete to true to stop bugging
- // him in the future (if one bundle fails, the
- // rest are virtually certain to).
- DownloadManager.complete = true;
- }
- DownloadManager.fatalError(DownloadManager.ERROR_UNSPECIFIED);
- }
-
- /**
- * Bundle security
- *
- * Check for corruption/spoofing
- */
-
-
- /* Create a bundle check from the tmp file */
- BundleCheck gottenCheck = BundleCheck.getInstance(tmp);
-
- /* Get the check expected for the Bundle */
- BundleCheck expectedCheck = BundleCheck.getInstance(name);
-
- // Do they match?
-
- if (expectedCheck.equals(gottenCheck)) {
-
- // Security check OK, uncompress the bundle file
- // into the local path
-
- long uncompressedLength = tmp.length();
- localPath.delete();
-
- File uncompressedPath = new File(tmp.getPath() +
- ".jar0");
- if (! extraUncompress(tmp.getPath(),
- uncompressedPath.getPath())) {
- // Extra uncompression not available, fall
- // back to alternative if it is enabled.
- if (DownloadManager.debug) {
- DownloadManager.log("Uncompressing with GZIP");
- }
- GZIPInputStream in = new GZIPInputStream( new
- BufferedInputStream(new FileInputStream(tmp),
- DownloadManager.BUFFER_SIZE));
- BufferedOutputStream out = new BufferedOutputStream(
- new FileOutputStream(uncompressedPath),
- DownloadManager.BUFFER_SIZE);
- DownloadManager.send(in,out);
- in.close();
- out.close();
- if (! uncompressedPath.renameTo(localPath)) {
- throw new IOException("unable to rename " +
- uncompressedPath + " to " + localPath);
- }
- } else {
- if (DownloadManager.debug) {
- DownloadManager.log("Uncompressing with LZMA");
- }
- if (! uncompressedPath.renameTo(localPath)) {
- throw new IOException("unable to rename " +
- uncompressedPath + " to " + localPath);
- }
- }
- state = DOWNLOADED;
- bytesDownloaded += uncompressedLength;
- long time = (System.currentTimeMillis() -
- start);
- DownloadManager.log("Downloaded " + name +
- " in " + time + "ms. Downloaded " +
- bytesDownloaded + " bytes this session.");
-
- // Normal completion
- } else {
-
- // Security check not OK: remove the temp file
- // and consult the user
-
- tmp.delete();
-
- DownloadManager.log(
- "DownloadManager: Security check failed for " +
- "bundle " + name);
-
- // only show dialog if we are not in silent mode
- if (showProgress) {
- retry = DownloadManager.askUserToRetryDownloadOrQuit(
- DownloadManager.ERROR_UNSPECIFIED);
- }
-
- if (!retry) {
- // User wants to give up
- throw new RuntimeException(
- "Failed bundle security check and user " +
- "canceled");
- }
- }
- }
- catch (IOException e) {
- // Look for "out of space" using File.getUsableSpace()
- // here when downloadFromURL starts throwing IOException
- // (or preferably a distinct exception for this case).
- DownloadManager.log(e);
- }
- } while (retry);
- } finally {
- mutex.release();
- }
- }
-
-
- /**
- * Calls {@link #queueDownload()} on all of this bundle's dependencies.
- */
- void queueDependencies(boolean showProgress) {
- try {
- String dependencies =
- DownloadManager.getBundleProperty(name,
- DownloadManager.DEPENDENCIES_PROPERTY);
- if (dependencies != null) {
- StringTokenizer st = new StringTokenizer(dependencies,
- " ,");
- while (st.hasMoreTokens()) {
- Bundle b = getBundle(st.nextToken());
- if (b != null && !b.isInstalled()) {
- if (DownloadManager.debug) {
- DownloadManager.log("Queueing " + b.name +
- " as a dependency of " + name + "...");
- }
- b.install(showProgress, true, false);
- }
- }
- }
- } catch (IOException e) {
- // shouldn't happen
- DownloadManager.log(e);
- }
- }
-
-
- static synchronized ExecutorService getThreadPool() {
- if (threadPool == null) {
- threadPool = Executors.newFixedThreadPool(THREADS,
- new ThreadFactory () {
- public Thread newThread(Runnable r) {
- Thread result = new Thread(r);
- result.setDaemon(true);
- return result;
- }
- }
- );
- }
- return threadPool;
- }
-
-
- private void unpackBundle() throws IOException {
- File useJarPath = null;
- if (DownloadManager.isWindowsVista()) {
- useJarPath = lowJarPath;
- File jarDir = useJarPath.getParentFile();
- if (jarDir != null) {
- jarDir.mkdirs();
- }
- } else {
- useJarPath = jarPath;
- }
-
- DownloadManager.log("Unpacking " + this + " to " + useJarPath);
-
- InputStream rawStream = new FileInputStream(localPath);
- JarInputStream in = new JarInputStream(rawStream) {
- public void close() throws IOException {
- // prevent any sub-processes here from actually closing the
- // input stream; we'll use rawsStream.close() when we're
- // done with it
- }
- };
-
- try {
- File jarTmp = null;
- JarEntry entry;
- while ((entry = in.getNextJarEntry()) != null) {
- String entryName = entry.getName();
- if (entryName.equals("classes.pack")) {
- File packTmp = new File(useJarPath + ".pack");
- packTmp.getParentFile().mkdirs();
- DownloadManager.log("Writing temporary .pack file " + packTmp);
- OutputStream tmpOut = new FileOutputStream(packTmp);
- try {
- DownloadManager.send(in, tmpOut);
- } finally {
- tmpOut.close();
- }
- // we unpack to a temporary file and then, towards the end
- // of this method, use a (hopefully atomic) rename to put it
- // into its final location; this should avoid the problem of
- // partially-completed downloads. Doing the rename last
- // allows us to check for the presence of the JAR file to
- // see whether the bundle has in fact been downloaded.
- jarTmp = new File(useJarPath + ".tmp");
- DownloadManager.log("Writing temporary .jar file " + jarTmp);
- unpack(packTmp, jarTmp);
- packTmp.delete();
- } else if (!entryName.startsWith("META-INF")) {
- File dest;
- if (DownloadManager.isWindowsVista()) {
- dest = new File(lowJavaPath,
- entryName.replace('/', File.separatorChar));
- } else {
- dest = new File(DownloadManager.JAVA_HOME,
- entryName.replace('/', File.separatorChar));
- }
- if (entryName.equals(BUNDLE_JAR_ENTRY_NAME))
- dest = useJarPath;
- File destTmp = new File(dest + ".tmp");
- boolean exists = dest.exists();
- if (!exists) {
- DownloadManager.log(dest + ".mkdirs()");
- dest.getParentFile().mkdirs();
- }
- try {
- DownloadManager.log("Using temporary file " + destTmp);
- FileOutputStream out =
- new FileOutputStream(destTmp);
- try {
- byte[] buffer = new byte[2048];
- int c;
- while ((c = in.read(buffer)) > 0)
- out.write(buffer, 0, c);
- } finally {
- out.close();
- }
- if (exists)
- dest.delete();
- DownloadManager.log("Renaming from " + destTmp + " to " + dest);
- if (!destTmp.renameTo(dest)) {
- throw new IOException("unable to rename " +
- destTmp + " to " + dest);
- }
-
- } catch (IOException e) {
- if (!exists)
- throw e;
- // otherwise the file already existed and the fact
- // that we failed to re-write it probably just
- // means that it was in use
- }
- }
- }
-
- // rename the temporary jar into its final location
- if (jarTmp != null) {
- if (useJarPath.exists())
- jarTmp.delete();
- else if (!jarTmp.renameTo(useJarPath)) {
- throw new IOException("unable to rename " + jarTmp +
- " to " + useJarPath);
- }
- }
- if (DownloadManager.isWindowsVista()) {
- // move bundle to real location
- DownloadManager.log("Using broker to move " + name);
- if (!DownloadManager.moveDirWithBroker(
- DownloadManager.getKernelJREDir() + name)) {
- throw new IOException("unable to create " + name);
- }
- DownloadManager.log("Broker finished " + name);
- }
- DownloadManager.log("Finished unpacking " + this);
- } finally {
- rawStream.close();
- }
- if (deleteOnInstall) {
- localPath.delete();
- }
-
- }
-
-
- public static void unpack(File pack, File jar) throws IOException {
- Process p = Runtime.getRuntime().exec(DownloadManager.JAVA_HOME + File.separator +
- "bin" + File.separator + "unpack200 -Hoff \"" + pack + "\" \"" + jar + "\"");
- try {
- p.waitFor();
- }
- catch (InterruptedException e) {
- }
- }
-
-
- /**
- * Unpacks and installs the bundle. The bundle's classes are not
- * immediately added to the boot class path; this happens when the VM
- * attempts to load a class and calls getBootClassPathEntryForClass().
- */
- public void install() throws IOException {
- install(true, false, true);
- }
-
-
- /**
- * Unpacks and installs the bundle, optionally hiding the progress
- * indicator. The bundle's classes are not immediately added to the
- * boot class path; this happens when the VM attempts to load a class
- * and calls getBootClassPathEntryForClass().
- *
- *@param showProgress true to display a progress dialog
- *@param downloadOnly true to download but not install
- *@param block true to wait until the operation is complete before returning
- */
- public synchronized void install(final boolean showProgress,
- final boolean downloadOnly, boolean block) throws IOException {
- if (DownloadManager.isJREComplete())
- return;
- if (state == NOT_DOWNLOADED || state == QUEUED) {
- // we allow an already-queued bundle to be placed into the queue
- // again, to handle the case where the bundle is queued with
- // downloadOnly true and then we try to queue it again with
- // downloadOnly false -- the second queue entry will actually
- // install it.
- if (state != QUEUED) {
- DownloadManager.addToTotalDownloadSize(getSize());
- state = QUEUED;
- }
- if (getThreadPool().isShutdown()) {
- if (state == NOT_DOWNLOADED || state == QUEUED)
- doInstall(showProgress, downloadOnly);
- }
- else {
- Future task = getThreadPool().submit(new Runnable() {
- public void run() {
- try {
- if (state == NOT_DOWNLOADED || state == QUEUED ||
- (!downloadOnly && state == DOWNLOADED)) {
- doInstall(showProgress, downloadOnly);
- }
- }
- catch (IOException e) {
- // ignore
- }
- }
- });
- queueDependencies(showProgress);
- if (block) {
- try {
- task.get();
- }
- catch (Exception e) {
- throw new Error(e);
- }
- }
- }
- }
- else if (state == DOWNLOADED && !downloadOnly)
- doInstall(showProgress, false);
- }
-
-
- private void doInstall(boolean showProgress, boolean downloadOnly)
- throws IOException {
- Mutex mutex = Mutex.create(DownloadManager.MUTEX_PREFIX + name +
- ".install");
- DownloadManager.bundleInstallStart();
- try {
- mutex.acquire();
- updateState();
- if (state == NOT_DOWNLOADED || state == QUEUED) {
- download(showProgress);
- }
-
- if (state == DOWNLOADED && downloadOnly) {
- return;
- }
-
- if (state == INSTALLED) {
- return;
- }
- if (state != DOWNLOADED) {
- DownloadManager.fatalError(DownloadManager.ERROR_UNSPECIFIED);
- }
-
- DownloadManager.log("Calling unpackBundle for " + this);
- unpackBundle();
- DownloadManager.log("Writing receipt for " + this);
- writeReceipt();
- updateState();
- DownloadManager.log("Finished installing " + this + ", state=" + state);
- } finally {
- if (lowJavaPath != null) {
- lowJavaPath.delete();
- }
- mutex.release();
- DownloadManager.bundleInstallComplete();
- }
- }
-
-
- synchronized void setState(int state) {
- this.state = state;
- }
-
-
- /** Returns <code>true</code> if this bundle has been installed. */
- public boolean isInstalled() {
- synchronized (Bundle.class) {
- updateState();
- return state == INSTALLED;
- }
- }
-
-
- /**
- * Adds an entry to the receipts file indicating that this bundle has
- * been successfully downloaded.
- */
- private void writeReceipt() {
- getReceiptsMutex().acquire();
- File useReceiptPath = null;
- try {
-
- try {
-
- receipts.add(name);
-
- if (DownloadManager.isWindowsVista()) {
- // write out receipts to locallow
- useReceiptPath = new File(
- DownloadManager.getLocalLowTempBundlePath(),
- "receipts");
-
- if (receiptPath.exists()) {
- // copy original file to locallow location
- DownloadManager.copyReceiptFile(receiptPath,
- useReceiptPath);
- }
-
- // update receipt in locallow path
- // only append if original receipt path exists
- FileOutputStream out = new FileOutputStream(useReceiptPath,
- receiptPath.exists());
- out.write((name + System.getProperty("line.separator")).getBytes("utf-8"));
- out.close();
-
- // use broker to move back to real path
- if (!DownloadManager.moveFileWithBroker(
- DownloadManager.getKernelJREDir()
- + "-bundles" + File.separator + "receipts")) {
- throw new IOException("failed to write receipts");
- }
- } else {
- useReceiptPath = receiptPath;
- FileOutputStream out = new FileOutputStream(useReceiptPath,
- true);
- out.write((name + System.getProperty("line.separator")).getBytes("utf-8"));
- out.close();
- }
-
-
- } catch (IOException e) {
- DownloadManager.log(e);
- // safe to continue, as the worst that happens is we
- // re-download existing bundles
- }
- }
- finally {
- getReceiptsMutex().release();
- }
- }
-
-
- public String toString() {
- return "Bundle[" + name + "]";
- }
-}