/*******************************************************************************
 * 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> 
 * @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);
			if (file != null && !file.exists()) {
				UpdateCore.warn("JarFile does not exits:" + file);
				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 ...
			}
		}
	}
}
