/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.core;

import java.io.*;
import java.net.*;
import java.util.*;
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
 */
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(Policy.bind("JarContentReference.Unpacking"));	//$NON-NLS-1$
				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 ...
			}
		}
	}
}
