/*******************************************************************************
 * Copyright (c) 2003, 2007 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.internal.archive;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jst.common.internal.modulecore.SingleRootUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.archive.operations.EARArchiveOpsResourceHandler;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyManifestUtil;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.jee.archive.AbstractArchiveLoadAdapter;
import org.eclipse.jst.jee.archive.ArchiveModelLoadException;
import org.eclipse.jst.jee.archive.IArchive;
import org.eclipse.jst.jee.archive.IArchiveLoadAdapter;
import org.eclipse.jst.jee.archive.IArchiveResource;
import org.eclipse.jst.jee.archive.internal.ArchiveURIConverter;
import org.eclipse.jst.jee.archive.internal.ArchiveUtil;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.DependencyType;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualContainer;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;

public abstract class ComponentArchiveLoadAdapter extends AbstractArchiveLoadAdapter {

	protected static final String DOT_SQLJ = ".sqlj"; //$NON-NLS-1$

	protected static final String DOT_JSP = ".jsp"; //$NON-NLS-1$

	protected static final String DOT_PROJECT = ".project"; //$NON-NLS-1$

	protected static final String DOT_CLASSPATH = ".classpath"; //$NON-NLS-1$

	protected static final String DOT_SETTINGS = ".settings"; //$NON-NLS-1$

	protected static final String DOT_CVS_IGORE = ".cvsignore"; //$NON-NLS-1$

	protected IVirtualComponent vComponent;

	protected boolean exportSource = true;
	
	protected boolean optimizeMembers = false;

	private List<ZipFile> zipFiles = new ArrayList<ZipFile>();

	private List<String> javaClasspathURIs = new ArrayList<String>();

	protected boolean includeClasspathComponents = true;

	protected class FilesHolder {

		private Map<IPath, IArchiveResource> pathsToArchiveResources = new HashMap<IPath, IArchiveResource>();

		private Map<IPath, IResource> pathsToWorkbenchResources = new HashMap<IPath, IResource>();

		private Map<IResource, IPath> workbenchResourcesToPaths = new HashMap<IResource, IPath>();

		private Map<IPath, java.io.File> pathsToDiskFiles = new HashMap<IPath, java.io.File>();

		private Map pathsToZipEntry = new HashMap();

		public void removeIFile(IFile file) {
			IPath path = workbenchResourcesToPaths.get(file);
			remove(path);
		}

		public void remove(IPath path) {
			pathsToArchiveResources.remove(path);
			Object resource = pathsToWorkbenchResources.remove(path);
			if (resource != null) {
				workbenchResourcesToPaths.remove(resource);
			}
			pathsToDiskFiles.remove(path);
		}

		public void addFile(IArchiveResource file) {
			IPath path = file.getPath();
			pathsToArchiveResources.put(path, file);
		}

		public void addFile(IArchiveResource file, java.io.File externalDiskFile) {
			IPath path = file.getPath();
			pathsToArchiveResources.put(path, file);
			pathsToDiskFiles.put(path, externalDiskFile);
		}

		public void addFile(IArchiveResource file, IResource resource) {
			IPath path = file.getPath();
			pathsToArchiveResources.put(path, file);
			pathsToWorkbenchResources.put(path, resource);
		}

		public InputStream getInputStream(IPath path) throws IOException, FileNotFoundException {
			java.io.File diskFile = null;

			if (pathsToDiskFiles.containsKey(path)) {
				diskFile = pathsToDiskFiles.get(path);
			} else if (pathsToWorkbenchResources.containsKey(path)) {
				IResource resource = pathsToWorkbenchResources.get(path);
				diskFile = new java.io.File(resource.getLocation().toOSString());
			}
			if (diskFile != null) {
				return new FileInputStream(diskFile);
			} else if (pathsToZipEntry.containsKey(path)) {
				Map fileURIMap = (Map) pathsToZipEntry.get(path);
				Iterator it = fileURIMap.keySet().iterator();

				String sourceFileUri = ""; //$NON-NLS-1$
				ZipFile zipFile = null;

				// there is only one key, pair
				while (it.hasNext()) {
					sourceFileUri = (String) it.next();
					zipFile = (ZipFile) fileURIMap.get(sourceFileUri);
				}
				if(zipFile != null){
					ZipEntry entry = zipFile.getEntry(sourceFileUri);
					InputStream in = zipFile.getInputStream(entry);
					return in;
				}
				throw new IOException();
			} else {
				IArchiveResource res = getArchiveResource(path);
				return ComponentArchiveLoadAdapter.this.getSuperInputStream(res);
			}
		}

		public List<IArchiveResource> getFiles() {
			return new ArrayList<IArchiveResource>(pathsToArchiveResources.values());
		}

		public boolean contains(IPath path) {
			return pathsToArchiveResources.containsKey(path);
		}

		public IArchiveResource getArchiveResource(IPath path) {
			return pathsToArchiveResources.get(path);
		}

		public void addEntry(ZipEntry entry, ZipFile zipFile, IPath runtimePath) {
			IPath innerRuntimePath = runtimePath;
			if (innerRuntimePath != null) {
				if (!innerRuntimePath.equals("/")) //$NON-NLS-1$
					innerRuntimePath = innerRuntimePath.append(entry.getName());
				else
					innerRuntimePath = new Path(entry.getName());
			} else {
				innerRuntimePath = new Path(entry.getName());
			}

			IArchiveResource file = createFile(innerRuntimePath);

			Map<String, ZipFile> fileURIMap = new HashMap<String, ZipFile>();
			fileURIMap.put(entry.getName(), zipFile);

			pathsToZipEntry.put(file.getPath(), fileURIMap);
			pathsToArchiveResources.put(file.getPath(), file);
		}
	}

	protected FilesHolder filesHolder;

	private IVirtualFile manifestFile = null;

	public ComponentArchiveLoadAdapter(IVirtualComponent vComponent) {
		this(vComponent, true);
	}

	public ComponentArchiveLoadAdapter(IVirtualComponent vComponent, boolean includeClasspathComponents) {
		this.vComponent = vComponent;
		filesHolder = new FilesHolder();
		setIncludeClasspathComponents(includeClasspathComponents);
	}

	public void setIncludeClasspathComponents(boolean includeClasspathComponents) {
		this.includeClasspathComponents = includeClasspathComponents;
		if (includeClasspathComponents) {
			this.manifestFile = vComponent.getRootFolder().getFile(new Path(J2EEConstants.MANIFEST_URI));
			saveJavaClasspathReferences();
		} else {
			this.manifestFile = null;
			javaClasspathURIs.clear();
		}
	}

	@Override
	public IArchiveResource getArchiveResource(IPath resourcePath) throws FileNotFoundException {
		initArchiveResource(resourcePath);
		return filesHolder.getArchiveResource(resourcePath);
	}

	@Override
	public boolean containsArchiveResource(IPath path) {
		initArchiveResource(path);
		return filesHolder.contains(path);
	}

	/**
	 * Will lazily initialize File type ArchiveResources contained in the component structure without loading the entire
	 * archive.  If the File can not be found, then the entire structure will be loaded.
	 * @param resourcePath
	 */
	protected void initArchiveResource(IPath resourcePath) {
		if(archiveResourcesInitialized) {
			//if the entire archive has been initialized, there is no need to repeat
			return;
		}
		if(filesHolder.contains(resourcePath)){
			//if the archive already knows about the resource return
			return;
		}
		initSourceRoots();
		// want to be quick if possible, so only try to load from the component structure
		// if the file is not present there, then look everywhere
		IVirtualFolder rootFolder = vComponent.getRootFolder();
		IVirtualFile vFile = rootFolder.getFile(resourcePath);
		if (vFile.exists()) {
			IPath runtimePath = vFile.getRuntimePath();
			if (runtimePath != null){
				runtimePath = runtimePath.setDevice(null).makeRelative();
				if(runtimePath.equals(resourcePath)){
					boolean inJavaSrc = inJavaSrc(vFile);
					if(aggregateResource(vFile, runtimePath, inJavaSrc, IArchiveResource.FILE_TYPE) != null){
						return; //found the file and added it
					}
				}								
			}
		}
		//if it was not found above then do the full initialize
		initArchiveResources();
	}
	
	protected boolean sourceRootsInitialized = false;
	
	protected void initSourceRoots() {
		if(!sourceRootsInitialized){
			sourceRootsInitialized = true;
			try {
				IPackageFragmentRoot[] srcPkgs = J2EEProjectUtilities.getSourceContainers(vComponent.getProject());
				sourceRoots = new IResource[srcPkgs.length];
				for (int i = 0; i < srcPkgs.length; i++) {
					sourceRoots[i] = srcPkgs[i].getCorrespondingResource();
				}
				inJavaSrc = false;
			} catch (CoreException e) {
				J2EEPlugin.logError(e);
			}
		}
	}
	
	protected boolean archiveResourcesInitialized = false;
	protected boolean membersOptimized = false;

	protected void initArchiveResources() {
		if (!archiveResourcesInitialized) {
			archiveResourcesInitialized = true;
			if (shouldOptimize()) {
				attemptOptimization();
			}
			if (!membersOptimized) {
				aggregateSourceFiles();
				aggregateClassFiles();
			}
			addUtilities();
		}
	}

	protected void attemptOptimization() {
		SingleRootUtil util = new SingleRootUtil(getComponent());
		IContainer rootContainer = util.getSingleRoot();
		if (rootContainer != null) {
			try {
				membersOptimized = true;
				optimizeMembers(Path.EMPTY, rootContainer);
			} catch (CoreException e) {
				J2EEPlugin.logError(e);
			}
		}
	}

	@Override
	public List<IArchiveResource> getArchiveResources() {
		initArchiveResources();
		return filesHolder.getFiles();
	}
	
	public IResource getWorkbenchResources(IPath path) {
		return filesHolder.pathsToWorkbenchResources.get(path);
	}
	
	public File getExternalFiles(IPath path) {
		return filesHolder.pathsToDiskFiles.get(path);
	}

	/**
	 * Adds library cp entries that point to class folders and have been tagged with the publish/export attribute.
	 */
	protected void addMappedClassFolders(final IPath targetRuntimePath) {
		// retrieve all mapped class folders
		if (vComponent instanceof J2EEModuleVirtualComponent) {
			try {
				final J2EEModuleVirtualComponent j2eeComponent = (J2EEModuleVirtualComponent) vComponent;
				final IVirtualReference[] cpRefs = j2eeComponent.getJavaClasspathReferences();
				for (int j = 0; j < cpRefs.length; j++) {
					final IVirtualReference ref = cpRefs[j];
					final IPath runtimePath = ref.getRuntimePath();
					// only process mappings with the specified runtime path
					if (ref.getReferencedComponent() instanceof ClasspathDependencyVirtualComponent) {
						if (runtimePath.equals(targetRuntimePath) || runtimePath.equals(IClasspathDependencyConstants.WEB_INF_CLASSES_PATH)) {
							final ClasspathDependencyVirtualComponent comp = (ClasspathDependencyVirtualComponent) ref.getReferencedComponent();
							if (comp.isClassFolder()) {
								final IContainer classFolder = comp.getClassFolder();
								if (classFolder != null && classFolder.exists()) {
									aggregateOutputFiles(new IResource[]{classFolder}, runtimePath.makeRelative(), classFolder.getProjectRelativePath().segmentCount());
								}
							}
						}
					}
				}
			} catch (CoreException e) {
				J2EEPlugin.logError(e);
			}
		}
	}
	
	protected void saveJavaClasspathReferences() {
		if (vComponent instanceof J2EEModuleVirtualComponent) {
			final J2EEModuleVirtualComponent j2eeComp = (J2EEModuleVirtualComponent) vComponent;
			final IVirtualReference[] refs = j2eeComp.getJavaClasspathReferences();
			if (refs == null) {
				return;
			}
			for (int i = 0; i < refs.length; i++) {
				if (refs[i].getRuntimePath().equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
					javaClasspathURIs.add(refs[i].getArchiveName());
				}
			}
		}
	}

	protected void addUtilities() {
		IVirtualReference[] components = vComponent.getReferences();
		for (int i = 0; i < components.length; i++) {
			IVirtualReference reference = components[i];
			IVirtualComponent referencedComponent = reference.getReferencedComponent();

			if (referencedComponent.isBinary() && reference.getDependencyType() == DependencyType.CONSUMES) {
				java.io.File diskFile = (java.io.File) referencedComponent.getAdapter(java.io.File.class);
				ZipFile zipFile;
				IPath path = reference.getRuntimePath();
				try {
					zipFile = ArchiveUtil.newZipFile(diskFile);
					zipFiles.add(zipFile);
					Enumeration enumeration = zipFile.entries();
					while (enumeration.hasMoreElements()) {
						ZipEntry entry = (ZipEntry) enumeration.nextElement();
						filesHolder.addEntry(entry, zipFile, path);
					}
				} catch (ZipException e) {
					J2EEPlugin.logError(e);
				} catch (IOException e) {
					J2EEPlugin.logError(e);
				}
			}
		}
	}

	/**
	 * This is a cache of the IResource roots for all java source folders and is
	 * used by {@link #inJavaSrc(IVirtualResource)}.
	 */
	private IResource[] sourceRoots = null;

	protected void aggregateSourceFiles() {
		try {
			initSourceRoots();
			IVirtualFolder rootFolder = vComponent.getRootFolder();
			IVirtualResource[] members = rootFolder.members();
			inJavaSrc = false;
			aggregateFiles(members);
		} catch (CoreException e) {
			J2EEPlugin.logError(e);
		}
	}

	protected void aggregateClassFiles() {
		StructureEdit se = null;
		try {
			IPackageFragmentRoot[] sourceRoots = J2EEProjectUtilities.getSourceContainers(vComponent.getProject());
			se = StructureEdit.getStructureEditForRead(vComponent.getProject());
			for (int i = 0; i < sourceRoots.length; i++) {
				IPath outputPath = sourceRoots[i].getRawClasspathEntry().getOutputLocation();
				if (outputPath == null) {
					IProject project = vComponent.getProject();
					if (project.hasNature(JavaCore.NATURE_ID)) {
						IJavaProject javaProject = JavaCore.create(project);
						outputPath = javaProject.getOutputLocation();
					}
				}

				if (outputPath != null) {
					IContainer javaOutputContainer = outputPath.segmentCount() > 1 ? (IContainer) ResourcesPlugin.getWorkspace().getRoot().getFolder(outputPath) : (IContainer) ResourcesPlugin
							.getWorkspace().getRoot().getProject(outputPath.lastSegment());
					IPath runtimePath = null;
					try {
						ComponentResource[] componentResources = se.findResourcesBySourcePath(sourceRoots[i].getResource().getProjectRelativePath());
						if (componentResources.length > 0) {
							IPath tmpRuntimePath = componentResources[0].getRuntimePath();
							IPath tmpSourcePath = componentResources[0].getSourcePath();
							if (!tmpRuntimePath.equals(tmpSourcePath)) {
								while (tmpSourcePath.segmentCount() > 0 && tmpRuntimePath.segmentCount() > 0 && tmpRuntimePath.lastSegment().equals(tmpSourcePath.lastSegment())) {
									tmpRuntimePath = tmpRuntimePath.removeLastSegments(1);
									tmpSourcePath = tmpSourcePath.removeLastSegments(1);
								}
								if (tmpRuntimePath.segmentCount() != 0) {
									runtimePath = tmpRuntimePath.makeRelative();
								}
							}
						}
					} catch (UnresolveableURIException e) {
						J2EEPlugin.logError(e);
					}
					if (null == runtimePath) {
						runtimePath = new Path(""); //$NON-NLS-1$
					}

					aggregateOutputFiles(new IResource[] { javaOutputContainer }, runtimePath, javaOutputContainer.getProjectRelativePath().segmentCount());
				}
			}
		} catch (CoreException e) {
			J2EEPlugin.logError(e);
		} finally {
			if (se != null) {
				se.dispose();
			}
		}
	}

	protected boolean aggregateOutputFiles(IResource[] resources, final IPath runtimePathPrefix, int outputFolderSegmentCount) throws CoreException {
		boolean fileAdded = false;
		for (int i = 0; i < resources.length; i++) {
			IArchiveResource cFile = null;
			if (!resources[i].exists()) {
				continue;
			}
			// We have to avoid duplicates between the source and output folders
			// (non-java
			// resources)
			IPath runtimePath = runtimePathPrefix.append(resources[i].getProjectRelativePath().removeFirstSegments(outputFolderSegmentCount));
			if (runtimePath == null)
				continue;
			if (resources[i].getType() == IResource.FILE) {
				if (!shouldInclude(runtimePath))
					continue;
				cFile = createFile(runtimePath);
				cFile.setLastModified(getLastModified(resources[i]));
				filesHolder.addFile(cFile, resources[i]);
				fileAdded = true;
			} else if (shouldInclude((IContainer) resources[i])) {
				IResource[] nestedResources = ((IContainer) resources[i]).members();
				aggregateOutputFiles(nestedResources, runtimePathPrefix, outputFolderSegmentCount);
				if (!filesHolder.contains(runtimePath)) {
					if (!shouldInclude(runtimePath))
						continue;
					cFile = createDirectory(runtimePath);
					cFile.setLastModified(getLastModified(resources[i]));
					filesHolder.addFile(cFile, resources[i]);
					fileAdded = true;
				}
			}
		}
		return fileAdded;
	}

	/**
	 * This is used to track whether {@link #aggregateFiles(IVirtualResource[])}
	 * is currently within a Java Source folder.
	 */
	private boolean inJavaSrc = false;


	protected boolean aggregateFiles(IVirtualResource[] virtualResources) throws CoreException {
		boolean fileAdded = false;
		for (int i = 0; i < virtualResources.length; i++) {
			if (!virtualResources[i].exists()) {
				continue;
			}
			// We have to avoid duplicates between the source and output folders
			// (non-java
			// resources)
			IPath runtimePath = virtualResources[i].getRuntimePath();
			if (runtimePath == null)
				continue;
			runtimePath = runtimePath.setDevice(null).makeRelative();
			if (filesHolder.contains(runtimePath))
				continue;

			if (virtualResources[i].getType() == IVirtualResource.FILE) {
				if(aggregateResource(virtualResources[i], runtimePath, inJavaSrc, IArchiveResource.FILE_TYPE) != null){
					fileAdded = true;
				}
			} else if (shouldInclude((IVirtualContainer) virtualResources[i])) {
				boolean inJavaSrcAtThisLevel = inJavaSrc;
				try {
					if (!inJavaSrc) {
						// if not already inside a Java src dir, check again
						inJavaSrc = inJavaSrc(virtualResources[i]);
					}
					IVirtualResource[] nestedVirtualResources = ((IVirtualContainer) virtualResources[i]).members();
					aggregateFiles(nestedVirtualResources);
					if (!filesHolder.contains(runtimePath)) {
						if(aggregateResource(virtualResources[i], runtimePath, inJavaSrc, IArchiveResource.DIRECTORY_TYPE) != null){
							fileAdded = true;
						}
					}
				} finally {
					inJavaSrc = inJavaSrcAtThisLevel;
				}
			}
		}
		return fileAdded;
	}

	
	protected IArchiveResource aggregateResource(IVirtualResource virtualResource, IPath runtimePath, boolean inJavaSrc, int archiveResourceType){
		if (!shouldInclude(runtimePath)){
			return null;
		}
		IResource resource = virtualResource.getUnderlyingResource();
		// want to ignore derived resources nested within Java src
		// directories; this covers the case where
		// a user has nested a Java output directory within a Java src
		// directory (note: should ideally be
		// respecting Java src path exclusion filters)
		if (inJavaSrc && resource.isDerived()) {
			return null;
		}
		IArchiveResource cFile = null;
		switch(archiveResourceType){
		case IArchiveResource.FILE_TYPE:
			cFile = createFile(runtimePath);
			break;
		case IArchiveResource.DIRECTORY_TYPE:
			cFile = createDirectory(runtimePath);
			break;
		default:
			return null;
		}
		
		cFile.setLastModified(getLastModified(resource));
		filesHolder.addFile(cFile, resource);
		return cFile;
	}

	
	/**
	 * Determines if the specified IVirtualResource maps to a IResource that is
	 * contained within a Java src root.
	 * 
	 * @param virtualResource
	 *            IVirtualResource to check.
	 * @param sourceRoots
	 *            Current Java src roots.
	 * @return True if contained in a Java src root, false otherwise.
	 */
	protected boolean inJavaSrc(final IVirtualResource virtualResource) {
		if (sourceRoots.length == 0) {
			return false;
		}
		// all mapped resources must be associated with Java src for the
		// resource to be considered in Java src
		final IResource[] resources = virtualResource.getUnderlyingResources();
		boolean inJavaSrc = false;
		for (int i = 0; i < resources.length; i++) {
			inJavaSrc = false;
			for (int j = 0; j < sourceRoots.length; j++) {
				if (sourceRoots[j].getFullPath().isPrefixOf(resources[i].getFullPath())) {
					inJavaSrc = true;
					break;
				}
			}
			// if this one was not in Java src, can break
			if (!inJavaSrc) {
				break;
			}
		}

		return inJavaSrc;
	}

	protected long getLastModified(IResource aResource) {
		return aResource.getLocation().toFile().lastModified();
	}
	
	protected void optimizeMembers(IPath path, IContainer container) throws CoreException {
		IResource[] resources;
		resources = container.members();
		if (resources != null) {
			int size = resources.length;
			for (int i = 0; i < size; i++) {
				IResource resource = resources[i];
				IArchiveResource cFile = null;
				if (resource != null && resource.exists()) {
					IPath deployPath = path.append(resource.getName());
					if (filesHolder.contains(deployPath)) {
						continue;
					}
					if (resource instanceof IContainer) {
						IContainer container2 = (IContainer) resource;
						cFile = createDirectory(deployPath);
						optimizeMembers(deployPath, container2);

					} else if ((resource instanceof IFile) && (isExportSource() || !isSource(deployPath))) {
						cFile = createFile(deployPath);
					}
				}
				if (cFile != null) {
					cFile.setLastModified(getLastModified(resource));
					filesHolder.addFile(cFile, resource);
				}
			}
		}
	} 

	public void setExportSource(boolean newExportSource) {
		exportSource = newExportSource;
	}

	public boolean isExportSource() {
		return exportSource;
	}

	public void setOptimize(boolean optimize) {
		optimizeMembers = optimize;
	}
	
	public boolean shouldOptimize() {
		return optimizeMembers;
	}
	
	public boolean shouldUpdateManifest(IArchiveResource archiveResource) {
		IPath path = archiveResource.getPath();
		if (includeClasspathComponents && path.equals(new Path(J2EEConstants.MANIFEST_URI)) && !javaClasspathURIs.isEmpty() && manifestFile != null
				&& manifestFile.getUnderlyingFile() != null && manifestFile.getUnderlyingFile().exists()) {
			return true;
		}
		return false;
	}
	
	protected boolean shouldInclude(IContainer aContainer) {
		return true;
	}

	protected boolean shouldInclude(IVirtualContainer vContainer) {
		IContainer iContainer = (IContainer) vContainer.getUnderlyingResource();
		return shouldInclude(iContainer);
	}

	// TODO add a mechanism for ignoring specific file types
	protected boolean shouldInclude(IPath path) {
		String lastSegment = path.lastSegment();
		if (null == lastSegment) {
			return false;
		}
		if (lastSegment.endsWith(DOT_PROJECT) || lastSegment.endsWith(DOT_CLASSPATH) || lastSegment.endsWith(DOT_CVS_IGORE) || path.segment(0).startsWith(DOT_SETTINGS)) {
			return false;
		}
		return isExportSource() || !isSource(path);
	}
	
	// TODO add a mechanism for ignoring specific file types
	protected boolean isSource(IPath path) {
		if (path == null)
			return false;
		return path.lastSegment().endsWith(JavaEEArchiveUtilities.DOT_JAVA) || path.lastSegment().endsWith(DOT_SQLJ);
	}

	protected void addExternalFile(IPath path, java.io.File externalDiskFile) {
		IArchiveResource aFile = createFile(path);
		filesHolder.addFile(aFile, externalDiskFile);
	}

	protected InputStream getSuperInputStream(IArchiveResource archiveResource) throws IOException, FileNotFoundException {
		if (archiveResource.getType() == IArchive.ARCHIVE_TYPE) {
			IArchiveLoadAdapter nestedLoadAdapter = ((IArchive)archiveResource).getLoadAdapter();
			if(nestedLoadAdapter instanceof ComponentArchiveLoadAdapter){
				((ComponentArchiveLoadAdapter)nestedLoadAdapter).setExportSource(isExportSource());
			}
		}
		
		return super.getInputStream(archiveResource);
	}

	@Override
	public InputStream getInputStream(IArchiveResource archiveResource) throws IOException, FileNotFoundException {
		// If the MANIFEST.MF of a module component is being requested and that
		// module component references
		// Java build path-based components, need to dynamically update the
		// manifest classpath to reflect the resolved
		// contributions from the build path
		if (shouldUpdateManifest(archiveResource)) {
			// update the manifest classpath for the component
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ClasspathDependencyManifestUtil.updateManifestClasspath(manifestFile.getUnderlyingFile(), javaClasspathURIs, baos);
			return new ByteArrayInputStream(baos.toByteArray());
		}
		IPath path = archiveResource.getPath();
		if (filesHolder.contains(path)) {
			return filesHolder.getInputStream(path);
		}
		IVirtualFolder rootFolder = vComponent.getRootFolder();
		IVirtualResource vResource = rootFolder.findMember(path);
		String filePath = null;
		if (null != vResource && vResource.exists()) {
			filePath = vResource.getUnderlyingResource().getLocation().toOSString();
			java.io.File file = new java.io.File(filePath);
			return new FileInputStream(file);
		}
		String eString = EARArchiveOpsResourceHandler.ARCHIVE_OPERATION_FileNotFound;
		throw new FileNotFoundException(eString);
	}

	public IVirtualComponent getComponent() {
		return vComponent;
	}

	protected JavaEEEMFArchiveAdapterHelper emfHelper = null;

	protected void initEMFHelper() {
		if (emfHelper == null) {
			emfHelper = new JavaEEEMFArchiveAdapterHelper(getArchive());
			emfHelper.setArchiveURIConverter(new ArchiveURIConverter(emfHelper.getArchive()) {
				@Override
				protected URI convertPathToURI(IPath modelObjectPath) {
					// TODO find a better way to getplatformURI
					IPath path = getComponent().getRootFolder().getFile(modelObjectPath).getUnderlyingFile().getFullPath();
					return URI.createURI("platform:/resource/" + path.toString()); //$NON-NLS-1$
				}
			});
		}
	}

	@Override
	public boolean containsModelObject(IPath modelObjectPath) {
		initEMFHelper();
		IPath innerModelObjectPath = modelObjectPath;
		if (IArchive.EMPTY_MODEL_PATH == innerModelObjectPath) {
			innerModelObjectPath = getDefaultModelObjectPath();
		}
		return emfHelper.containsModelObject(innerModelObjectPath);
	}

	@Override
	public Object getModelObject(IPath modelObjectPath) throws ArchiveModelLoadException {
		initEMFHelper();
		IPath innerModelObjectPath = modelObjectPath;
		if (IArchive.EMPTY_MODEL_PATH == innerModelObjectPath) {
			innerModelObjectPath = getDefaultModelObjectPath();
		}
		return emfHelper.getModelObject(innerModelObjectPath);
	}

	protected IPath getDefaultModelObjectPath() {
		return new Path("/"); //$NON-NLS-1$
	}

	@Override
	public String toString() {
		int packageLength = this.getClass().getPackage().getName().length() + 1;
		StringBuffer buffer = new StringBuffer(this.getClass().getName().substring(packageLength));
		buffer.append(", Component: "); //$NON-NLS-1$
		buffer.append(getComponent());
		return buffer.toString();
	}

	/**
	 * protected IProgressMonitor monitor = null;
	 * 
	 * public void setProgressMonitor(IProgressMonitor monitor){ this.monitor =
	 * monitor; }
	 * 
	 * protected final int FILE_SAVE_WORK = 100;
	 * 
	 * public FileIterator getFileIterator() throws IOException { return new
	 * FileIteratorImpl(getContainer().getFiles()){ protected SubProgressMonitor
	 * lastSubMon = null; boolean firstVisit = true;
	 * 
	 * public File next() { if(firstVisit){ firstVisit = false; if(monitor !=
	 * null){
	 * monitor.beginTask(ProjectSupportResourceHandler.getString(ProjectSupportResourceHandler.Exporting_archive,
	 * new Object [] { getContainer().getURI() }), files.size() *
	 * FILE_SAVE_WORK); } } if(lastSubMon != null){ lastSubMon.done();
	 * lastSubMon = null; } else if(monitor != null){
	 * monitor.worked(FILE_SAVE_WORK); } File file = super.next(); if(monitor !=
	 * null){ if(file.isContainer() &&
	 * ComponentArchiveLoadAdapter.class.isInstance(((ContainerImpl)file).getLoadStrategy())){
	 * ComponentArchiveLoadAdapter ls =
	 * (ComponentArchiveLoadAdapter)((ContainerImpl)file).getLoadStrategy();
	 * lastSubMon = new SubProgressMonitor(monitor, FILE_SAVE_WORK,
	 * SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
	 * ls.setProgressMonitor(lastSubMon); } else {
	 * monitor.subTask(file.getURI()); } } return file; } }; }
	 */
}
