| /******************************************************************************* |
| * Copyright (c) 2000, 2010 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.update.core; |
| |
| import java.io.*; |
| import java.net.*; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.List; |
| import java.util.jar.*; |
| |
| import org.eclipse.update.core.model.*; |
| import org.eclipse.update.internal.core.*; |
| |
| /** |
| * Local .jar file content reference. |
| * <p> |
| * This class may be instantiated or subclassed by clients. |
| * </p> |
| * <p> |
| * <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to |
| * change significantly before reaching stability. It is being made available at this early stage to solicit feedback |
| * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken |
| * (repeatedly) as the API evolves. |
| * </p> |
| * @see org.eclipse.update.core.ContentReference |
| * @see org.eclipse.update.core.JarEntryContentReference |
| * @since 2.0 |
| * @deprecated The org.eclipse.update component has been replaced by Equinox p2. |
| * This API will be deleted in a future release. See bug 311590 for details. |
| */ |
| public class JarContentReference extends ContentReference { |
| |
| //private static ArrayList referenceList = new ArrayList(); |
| private JarFile jarFile; |
| |
| /** |
| * Content selector used in .jar operations. |
| * Default implementation causes all file entries to be selected with |
| * generated identifiers being the same as the original .jar entry name. |
| * |
| * @since 2.0 |
| */ |
| public static class ContentSelector { |
| |
| /** |
| * Indicates whether the .jar entry should be selected. |
| * Default behavior is to select all non-directory entries. |
| * |
| * @param entry .jar entry |
| * @return <code>true</code> if entry is to be selected, |
| * <code>false</code> otherwise |
| * @since 2.0 |
| */ |
| public boolean include(JarEntry entry) { |
| return entry == null ? false : !entry.isDirectory(); |
| } |
| |
| /** |
| * Defines the "symbolic" path identifier for the |
| * entry. Default identifier is the same as the jar entry name. |
| * |
| * @param entry .jar entry |
| * @return "symbolic" path identifier |
| * @since 2.0 |
| */ |
| public String defineIdentifier(JarEntry entry) { |
| return entry == null ? null : entry.getName(); |
| } |
| } |
| |
| /** |
| * Create jar content reference from URL. |
| * |
| * @param id "symbolic" path identifier |
| * @param url actual referenced URL |
| * @since 2.0 |
| */ |
| public JarContentReference(String id, URL url) { |
| super(id, url); |
| this.jarFile = null; |
| //referenceList.add(this); // keep track of archives |
| } |
| |
| /** |
| * Create jar content reference from file. |
| * |
| * @param id "symbolic" path identifier |
| * @param file actual referenced file |
| * @since 2.0 |
| */ |
| public JarContentReference(String id, File file) { |
| super(id, file); |
| this.jarFile = null; |
| //referenceList.add(this); // keep track of archives |
| } |
| |
| /** |
| * A factory method to create a jar content reference. |
| * |
| * @param id "symbolic" path identifier |
| * @param file actual referenced file |
| * @return jar content reference |
| * @since 2.0 |
| */ |
| public ContentReference createContentReference(String id, File file) { |
| return new JarContentReference(id, file,true); |
| } |
| /** |
| * Constructor JarContentReference. |
| * @param id |
| * @param file |
| * @param b |
| */ |
| public JarContentReference(String id, File file, boolean b) { |
| this(id,file); |
| setTempLocal(b); |
| } |
| |
| /** |
| * Returns the content reference as a jar file. Note, that this method |
| * <b>does not</b> cause the file to be downloaded if it |
| * is not already local. |
| * |
| * @return reference as jar file |
| * @exception IOException reference cannot be returned as jar file |
| * @since 2.0 |
| */ |
| protected JarFile asJarFile() throws IOException { |
| if (this.jarFile == null) { |
| File file = asFile(); |
| if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_INSTALL) |
| UpdateCore.debug("asJarFile :" + file); //$NON-NLS-1$ |
| if (file != null && !file.exists()) { |
| UpdateCore.warn("JarFile does not exits:" + file); //$NON-NLS-1$ |
| throw new FileNotFoundException(file.getAbsolutePath()); |
| } |
| this.jarFile = new JarFile(file); |
| } |
| return jarFile; |
| } |
| |
| /** |
| * Unpacks the referenced jar archive into the specified location. |
| * Returns content references to the unpacked files. |
| * |
| * @param dir location to unpack the jar into |
| * @param selector selector, used to select entries to unpack, and to define |
| * "symbolic" path identifiers for the entries. |
| * @param monitor progress monitor |
| * @exception IOException |
| * @exception InstallAbortedException |
| * @since 2.0 |
| */ |
| public ContentReference[] unpack(File dir, ContentSelector selector, InstallMonitor monitor) throws IOException, InstallAbortedException { |
| |
| // make sure we have a selector |
| if (selector == null) |
| selector = new ContentSelector(); |
| |
| // get archive content |
| JarFile jarArchive = this.asJarFile(); |
| List content = new ArrayList(); |
| Enumeration entries = jarArchive.entries(); |
| |
| // run through the entries and unjar |
| String entryId; |
| JarEntry entry; |
| InputStream is; |
| OutputStream os; |
| File localFile; |
| try { |
| if (monitor != null) { |
| monitor.saveState(); |
| monitor.setTaskName(Messages.JarContentReference_Unpacking); |
| monitor.subTask(this.getIdentifier()); |
| monitor.showCopyDetails(false); |
| } |
| while (entries.hasMoreElements()) { |
| entry = (JarEntry) entries.nextElement(); |
| if (entry != null && selector.include(entry)) { |
| is = null; |
| os = null; |
| entryId = selector.defineIdentifier(entry); |
| localFile = Utilities.createLocalFile(dir, entryId); // create temp file |
| if (!entry.isDirectory()) { |
| try { |
| is = jarArchive.getInputStream(entry); |
| os = new FileOutputStream(localFile); |
| Utilities.copy(is, os, monitor); |
| } finally { |
| if (is != null) |
| try { |
| is.close(); |
| } catch (IOException e) { |
| } |
| if (os != null) |
| try { |
| os.close(); |
| } catch (IOException e) { |
| } |
| } |
| content.add(new ContentReference(entryId, localFile)); |
| } |
| } |
| } |
| } finally { |
| if (monitor != null) |
| monitor.restoreState(); |
| } |
| return (ContentReference[]) content.toArray(new ContentReference[0]); |
| } |
| |
| /** |
| * Unpacks the named jar entry into the specified location. |
| * Returns content reference to the unpacked file. |
| * |
| * @param dir location to unpack the jar into |
| * @param entryName name of the jar entry |
| * @param selector selector, used to define "symbolic" path identifier |
| * for the entry |
| * @param monitor progress monitor |
| * @exception IOException |
| * @exception InstallAbortedException |
| * @since 2.0 |
| */ |
| public ContentReference unpack(File dir, String entryName, ContentSelector selector, InstallMonitor monitor) throws IOException, InstallAbortedException { |
| |
| // make sure we have a selector |
| if (selector == null) |
| selector = new ContentSelector(); |
| |
| // unjar the entry |
| JarFile jarArchive = this.asJarFile(); |
| entryName = entryName.replace(File.separatorChar, '/'); |
| JarEntry entry = jarArchive.getJarEntry(entryName); |
| String entryId; |
| if (entry != null) { |
| InputStream is = null; |
| OutputStream os = null; |
| entryId = selector.defineIdentifier(entry); |
| File localFile = Utilities.createLocalFile(dir, entryId); // create temp file |
| if (!entry.isDirectory()) { |
| try { |
| is = jarArchive.getInputStream(entry); |
| os = new FileOutputStream(localFile); |
| Utilities.copy(is, os, monitor); |
| } finally { |
| if (is != null) |
| try { |
| is.close(); |
| } catch (IOException e) { |
| } |
| if (os != null) |
| try { |
| os.close(); |
| } catch (IOException e) { |
| } |
| } |
| return new ContentReference(entryId, localFile); |
| } else |
| return null; // entry was a directory |
| } else |
| throw new FileNotFoundException(this.asFile().getAbsolutePath() + " " + entryName); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Peeks into the referenced jar archive. |
| * Returns content references to the jar entries within the jar file. |
| * |
| * @param selector selector, used to select entries to return, and to define |
| * "symbolic" path identifiers for the entries. |
| * @param monitor progress monitor |
| * @exception IOException |
| * @since 2.0 |
| */ |
| public ContentReference[] peek(ContentSelector selector, InstallMonitor monitor) throws IOException { |
| |
| // make sure we have a selector |
| if (selector == null) |
| selector = new ContentSelector(); |
| |
| // get archive content |
| JarFile jarArchive = this.asJarFile(); |
| List content = new ArrayList(); |
| Enumeration entries = jarArchive.entries(); |
| |
| // run through the entries and create content references |
| JarEntry entry; |
| String entryId; |
| while (entries.hasMoreElements()) { |
| entry = (JarEntry) entries.nextElement(); |
| if (selector.include(entry)) { |
| entryId = selector.defineIdentifier(entry); |
| content.add(new JarEntryContentReference(entryId, this, entry)); |
| } |
| } |
| return (ContentReference[]) content.toArray(new ContentReference[0]); |
| } |
| |
| /** |
| * Peeks into the referenced jar archive looking for the named entry. |
| * Returns content reference to the jar entry within the jar file. |
| * |
| * @param entryName name of the jar entry |
| * @param selector selector, used to define "symbolic" path identifier |
| * for the entry |
| * @param monitor progress monitor |
| * @return the content reference ofr <code>null</null> if the entry doesn't exist |
| * @exception IOException |
| * @since 2.0 |
| */ |
| public ContentReference peek(String entryName, ContentSelector selector, InstallMonitor monitor) throws IOException { |
| |
| // make sure we have a selector |
| if (selector == null) |
| selector = new ContentSelector(); |
| |
| // assume we have a reference that represents a jar archive. |
| JarFile jarArchive = this.asJarFile(); |
| entryName = entryName.replace(File.separatorChar, '/'); |
| JarEntry entry = jarArchive.getJarEntry(entryName); |
| if (entry == null) |
| return null; |
| |
| String entryId = selector.defineIdentifier(entry); |
| return new JarEntryContentReference(entryId, this, entry); |
| } |
| |
| /** |
| * Closes the jar archive corresponding to this reference. |
| * |
| * @exception IOException |
| * @since 2.0 |
| */ |
| public void closeArchive() throws IOException { |
| if (this.jarFile != null) { |
| this.jarFile.close(); |
| this.jarFile = null; |
| } |
| } |
| |
| /** |
| * Perform shutdown processing for jar archive handling. |
| * This method is called when platform is shutting down. |
| * It is not intended to be called at any other time under |
| * normal circumstances. A side-effect of calling this method |
| * is that all jars referenced by JarContentReferences are closed. |
| * |
| * @since 2.0 |
| */ |
| public static void shutdown() { |
| /*for (int i = 0; i < referenceList.size(); i++) { |
| JarContentReference ref = (JarContentReference) referenceList.get(i); |
| try { |
| ref.closeArchive(); // ensure we are not leaving open jars |
| } catch (IOException e) { |
| // we tried, nothing we can do ... |
| } |
| }*/ |
| } |
| } |