/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jst.j2ee.commonarchivecore.internal.impl;



import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonArchiveResourceHandler;
import org.eclipse.jst.j2ee.commonarchivecore.internal.CommonarchivePackage;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.WARFile;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DeploymentDescriptorLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.DuplicateObjectException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveConstants;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.RuntimeClasspathEntry;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.WarFileDynamicClassLoader;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseLibrary;
import org.eclipse.jst.j2ee.commonarchivecore.looseconfig.internal.LooseWARFile;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.common.XMLResource;
import org.eclipse.jst.j2ee.webapplication.WebApp;
import org.eclipse.jst.j2ee.webapplication.WebapplicationPackage;


/**
 * @generated
 */
public class WARFileImpl extends ModuleFileImpl implements WARFile {

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	protected WebApp deploymentDescriptor = null;
	protected List sourceFiles;

	public WARFileImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	protected EClass eStaticClass() {
		return CommonarchivePackage.Literals.WAR_FILE;
	}

	/**
	 * @see com.ibm.etools.commonarchive.WARFile
	 */
	public File addCopyClass(File aFile) throws DuplicateObjectException {
		if (aFile.isReadOnlyDirectory())
			throw new IllegalArgumentException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.add_copy_class_dir_EXC_, (new Object[]{aFile.getURI()}))); // = "Method addCopyClass not supported for directories :"
		return addCopyFileAddingPrefix(aFile, ArchiveConstants.WEBAPP_CLASSES_URI);
	}

	protected File addCopyFileAddingPrefix(File aFile, String uriPrefix) throws DuplicateObjectException {
		String swizzledUri = aFile.getURI();
		if (!swizzledUri.startsWith(uriPrefix)) {
			swizzledUri = ArchiveUtil.concatUri(uriPrefix, swizzledUri, '/');
		}
		checkAddValid(swizzledUri);
		File copy = copy(aFile);
		copy.setURI(swizzledUri);
		getFiles().add(copy);
		return copy;
	}

	/**
	 * @see com.ibm.etools.commonarchive.WARFile
	 */
	public File addCopyLib(File aFile) throws DuplicateObjectException {
		if (aFile.isReadOnlyDirectory())
			throw new IllegalArgumentException(CommonArchiveResourceHandler.getString(CommonArchiveResourceHandler.add_copy_lib_dir_EXC_, (new Object[]{aFile.getURI()}))); // = "Method addCopyLib not supported for directories :"
		return addCopyFileAddingPrefix(aFile, ArchiveConstants.WEBAPP_LIB_URI);
	}

	protected RuntimeClasspathEntry createLibClasspathEntry(String libPath) {
		RuntimeClasspathEntry entry = createRuntimeClasspathEntry(libPath);
		entry.setWarFile(this);
		return entry;
	}

	/**
	 * Used internally for building the runtime class path
	 * 
	 * @return List of Strings, the absolute paths of all file entries (no directories)
	 */
	protected List getAllFileEntriesRecursive(java.io.File aFile, List aList) {
		if (!aFile.exists())
			return aList;
		//modified for botp 126140 05.29.02
		String name = aFile.getName();
		if (name.regionMatches(true, name.length() - 4, ".jar", 0, 4)) {//$NON-NLS-1$
			aList.add(aFile.getAbsolutePath());
		} else if (aFile.isDirectory()) {
			java.io.File[] children = aFile.listFiles();
			for (int i = 0; i < children.length; i++) {
				getAllFileEntriesRecursive(children[i], aList);
			}
		}
		return aList;
	}

	/**
	 * @see com.ibm.etools.commonarchive.WARFile
	 */
	public java.util.List getClasses() {
		return filterFilesByPrefix(ArchiveConstants.WEBAPP_CLASSES_URI);
	}

	/**
	 * @throws DeploymentDescriptorLoadException -
	 *             is a runtime exception, because we can't override the signature of the generated
	 *             methods
	 */
	public WebApp getDeploymentDescriptor() throws DeploymentDescriptorLoadException {
		WebApp dd = this.getDeploymentDescriptorGen();
		if (dd == null && canLazyInitialize())
			try {
				getImportStrategy().importMetaData();
			} catch (Exception e) {
				throw new DeploymentDescriptorLoadException(getDeploymentDescriptorUri(), e);
			}
		return this.getDeploymentDescriptorGen();
	}

	public String getDeploymentDescriptorUri() {
		return J2EEConstants.WEBAPP_DD_URI;
	}


	/**
	 * @see com.ibm.etools.commonarchive.WARFile
	 */
	public java.util.List getLibs() {
		return filterFilesByPrefix(ArchiveConstants.WEBAPP_LIB_URI);
	}

	/**
	 * @see com.ibm.etools.commonarchive.WARFile
	 */
	public List getLibArchives() {
		return filterFiles(ArchiveConstants.WEBAPP_LIB_URI, new String[]{"jar", "zip"}); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * @see com.ibm.etools.commonarchive.WARFile
	 */
	public java.util.List getResources() {
		String[] prefixes = {J2EEConstants.META_INF, J2EEConstants.WEB_INF};
		return filterFilesWithoutPrefix(prefixes);
	}

	/**
	 * Overridden from superclass to include the claseses and libs of a WARFile There also is an
	 * assumption that this is an exploded war file The following is what should be returned:
	 * 
	 * 1) WAR directory + /WEB-INF/classes 2) all JAR files contained in [WAR directory +
	 * /WEB-INF/lib] 3) WAR directory
	 */
	public RuntimeClasspathEntry[] getLocalRuntimeClassPath() {

		String absolutePath;
		try {
			absolutePath = getLoadStrategy().getBinariesPath();
		} catch (IOException ex) {
			return new RuntimeClasspathEntry[0];
		}

		List entries = new ArrayList();

		if (getLoadStrategy().isDirectory()) {
			String classesPath = ArchiveUtil.getOSUri(absolutePath, ArchiveConstants.WEBAPP_CLASSES_URI);
			entries.add(createRuntimeClasspathEntry(classesPath));
			addWebLibs(absolutePath, entries);
		}

		entries.add(createRuntimeClasspathEntry(absolutePath));
		return (RuntimeClasspathEntry[]) entries.toArray(new RuntimeClasspathEntry[entries.size()]);
	}

	protected RuntimeClasspathEntry[] getDependencyClassPathAtThisLevel() {

		String absolutePath = internalGetBinariesPath();
		if (absolutePath == null)
			return emptyClasspath();
		RuntimeClasspathEntry[] mfEntries = super.getDependencyClassPathAtThisLevel();
		List entries = new ArrayList();
		entries.addAll(Arrays.asList(mfEntries));

		return (RuntimeClasspathEntry[]) entries.toArray(new RuntimeClasspathEntry[entries.size()]);
	}

	protected void addWebLibs(String absolutePath, List entries) {
		/*******************************************************************************************
		 * Optimization*********** We could have used the helper getlibs here; however, that could
		 * drag down performance as the full file list would have to get built, and this is runtime;
		 * if the classes portion is huge then building the file list would be slow; moreover, we
		 * would then have to clear the index from this war file. therefore, we'll do a little extra
		 * work to get the libs
		 ******************************************************************************************/
		java.io.File aFile = new java.io.File(ArchiveUtil.getOSUri(absolutePath, ArchiveConstants.WEBAPP_LIB_URI));
		List libs = getAllFileEntriesRecursive(aFile, new ArrayList());
		for (int i = 0; i < libs.size(); i++) {
			String libPath = (String) libs.get(i);
			entries.add(createLibClasspathEntry(libPath));
		}
		addLooseLibsToRuntimeClasspath(entries);
	}

	protected void addLooseLibsToRuntimeClasspath(List entries) {
		LooseWARFile loose = (LooseWARFile) getLoadStrategy().getLooseArchive();
		if (loose == null)
			return;

		List looseLibs = loose.getLooseLibs();
		for (int i = 0; i < looseLibs.size(); i++) {
			LooseLibrary lib = (LooseLibrary) looseLibs.get(i);
			entries.add(createLibClasspathEntry(lib.getBinariesPath()));
		}
	}

	protected List calculateSourceCandidateFiles() {
		List filesList = getFiles();
		List retFiles = new Vector();
		for (Iterator iter = filesList.iterator(); iter.hasNext();) {
			File file = (File) iter.next();
			String aUri = file.getURI();
			if (aUri.startsWith(J2EEConstants.WEB_INF) && !aUri.startsWith(ArchiveConstants.WEBAPP_LIB_URI))
				retFiles.add(file);
		}
		return retFiles;
	}

	protected List getSourceCandidateFiles() {
		if (sourceFiles == null) {
			sourceFiles = calculateSourceCandidateFiles();
		}
		return sourceFiles;
	}

	protected String makeRelative(String pathString, String relToPathString) {

		if (pathString.startsWith(relToPathString))
			return ArchiveUtil.truncateFromFrontIgnoreCase(pathString, relToPathString);

		return pathString;
	}

	/**
	 * Return the source file that matches the output file passed in
	 * 
	 * @param aClassFile
	 *            The .class file or other output file to find the source for
	 * @return String The matching source. Null if there is no matching source found
	 */
	public File getSourceFile(File aClassFile) {
		List sourceFilesList = getSourceCandidateFiles();
		String classURI = aClassFile.getURI();
		String convertedClassURI = classURI;
		if (classURI.endsWith(".class")) //$NON-NLS-1$
			convertedClassURI = ArchiveUtil.classUriToJavaUri(aClassFile.getURI());
		else 
			return null;
		convertedClassURI = makeRelative(convertedClassURI, ArchiveConstants.WEBAPP_CLASSES_URI);
		int bestLength = 32767;
		File bestMatch = null;
		File file = null;
		String aUri = null;
		for (Iterator iter = sourceFilesList.iterator(); iter.hasNext();) {
			file = (File) iter.next();
			aUri = file.getURI();
			if (aUri.endsWith(convertedClassURI) && !aUri.equals(classURI)) {
				int excessLength = aUri.length() - convertedClassURI.length();
				if (excessLength < bestLength) {
					bestMatch = file;
					bestLength = excessLength;
				}
			}
		}
		return bestMatch;
	}

	/**
	 * Return the DeployementDescriptor.
	 */
	public EObject getStandardDeploymentDescriptor() throws DeploymentDescriptorLoadException {
		return getDeploymentDescriptor();
	}

	public boolean isDeploymentDescriptorSet() {
		return deploymentDescriptor != null;
	}

	/**
	 * @see com.ibm.etools.commonarchive.File
	 */
	public boolean isWARFile() {
		return true;
	}

	/**
	 * @see com.ibm.etools.commonarchive.impl.ModuleFileImpl
	 */
	public org.eclipse.emf.ecore.EObject makeDeploymentDescriptor(XMLResource resource) {
		WebApp webApp = ((WebapplicationPackage) EPackage.Registry.INSTANCE.getEPackage(WebapplicationPackage.eNS_URI)).getWebapplicationFactory().createWebApp();
		resource.setID(webApp, J2EEConstants.WEBAPP_ID);
		setDeploymentDescriptorGen(webApp);
		resource.getContents().add(webApp);
		return webApp;
	}

	public void setDeploymentDescriptor(WebApp l) {
		this.setDeploymentDescriptorGen(l);
		replaceRoot(getMofResourceMakeIfNecessary(getDeploymentDescriptorUri()), l);
	}

	/**
	 * @generated This field/method will be replaced during code generation
	 */
	public WebApp getDeploymentDescriptorGen() {
		if (deploymentDescriptor != null && deploymentDescriptor.eIsProxy()) {
			InternalEObject oldDeploymentDescriptor = (InternalEObject)deploymentDescriptor;
			deploymentDescriptor = (WebApp)eResolveProxy(oldDeploymentDescriptor);
			if (deploymentDescriptor != oldDeploymentDescriptor) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR, oldDeploymentDescriptor, deploymentDescriptor));
			}
		}
		return deploymentDescriptor;
	}

	/**
	 * <!-- begin-user-doc --> <!-- end-user-doc -->
	 * @generated
	 */
	public WebApp basicGetDeploymentDescriptor() {
		return deploymentDescriptor;
	}

	/**
	 * @generated This field/method will be replaced during code generation.
	 */
	public void setDeploymentDescriptorGen(WebApp newDeploymentDescriptor) {
		WebApp oldDeploymentDescriptor = deploymentDescriptor;
		deploymentDescriptor = newDeploymentDescriptor;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR, oldDeploymentDescriptor, deploymentDescriptor));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
				if (resolve) return getDeploymentDescriptor();
				return basicGetDeploymentDescriptor();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
				setDeploymentDescriptor((WebApp)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void eUnset(int featureID) {
		switch (featureID) {
			case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
				setDeploymentDescriptor((WebApp)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case CommonarchivePackage.WAR_FILE__DEPLOYMENT_DESCRIPTOR:
				return deploymentDescriptor != null;
		}
		return super.eIsSet(featureID);
	}

	public ClassLoader createDynamicClassLoader(ClassLoader parentCl, ClassLoader extraCl) {
		return new WarFileDynamicClassLoader(this, parentCl, extraCl);
	}

}
