/*******************************************************************************
 * 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.operations;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
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.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.commonarchivecore.internal.File;
import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.ResourceLoadException;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.FileIterator;
import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.FileIteratorImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.impl.ContainerImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategyImpl;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.archive.ArchiveMessages;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyEnablement;
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.j2ee.internal.project.ProjectSupportResourceHandler;
import org.eclipse.wst.common.componentcore.ArtifactEdit;
import org.eclipse.wst.common.componentcore.UnresolveableURIException;
import org.eclipse.wst.common.componentcore.internal.ArtifactEditModel;
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.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
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 ComponentLoadStrategyImpl extends LoadStrategyImpl {

	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;
	protected ArtifactEdit artifactEdit;
	private List zipFiles = new ArrayList();
	private List javaClasspathURIs = new ArrayList();
	protected boolean includeClasspathComponents = true;

	protected class FilesHolder {

		private Map urisToFiles = new HashMap();
		private Map urisToResources = new HashMap();
		private Map resourcesToURI = new HashMap();
		private Map urisToDiskFiles;
		private Map urisToZipEntry = new HashMap();

		public void removeIFile(IFile file) {
			String uri = (String) resourcesToURI.get(file);
			remove(uri);
		}

		public void remove(String uri) {
			urisToFiles.remove(uri);
			Object resource = urisToResources.remove(uri);
			if (resource != null) {
				resourcesToURI.remove(resource);
			}
			if (urisToDiskFiles != null) {
				urisToDiskFiles.remove(uri);
			}
		}

		public void addDirectory(File directory) {
			String uri = directory.getURI();
			urisToFiles.put(uri, directory);
		}

		public void addFile(File file) {
			String uri = file.getURI();
			urisToFiles.put(uri, file);
		}

		public void addFile(File file, java.io.File externalDiskFile) {
			String uri = file.getURI();
			urisToFiles.put(uri, file);
			if (null == urisToDiskFiles) {
				urisToDiskFiles = new HashMap();
			}
			urisToDiskFiles.put(uri, externalDiskFile);
		}

		public void addFile(File file, IResource resource) {
			String uri = file.getURI();
			urisToFiles.put(uri, file);
			urisToResources.put(uri, resource);
		}

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

			if (urisToDiskFiles != null && urisToDiskFiles.containsKey(uri)) {
				diskFile = (java.io.File) urisToDiskFiles.get(uri);
			} else if (urisToResources != null && urisToResources.containsKey(uri)) {
				IResource resource = (IResource) urisToResources.get(uri);
				diskFile = new java.io.File(resource.getLocation().toOSString());
			} else {
				Map fileURIMap = (Map) urisToZipEntry.get(uri);
				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){
					throw new FileNotFoundException(uri);
				}
				ZipEntry entry = zipFile.getEntry(sourceFileUri);
				InputStream in = zipFile.getInputStream(entry);
				return in;
			}
			return new FileInputStream(diskFile);
		}

		public List getFiles() {
			return new ArrayList(urisToFiles.values());
		}

		public boolean contains(String uri) {
			return urisToFiles.containsKey(uri);
		}

		public void addEntry(ZipEntry entry, ZipFile zipFile, IPath runtimePath) {
			String uri = runtimePath == null ? null : runtimePath.toString();
			String fileURI = ""; //$NON-NLS-1$
			if (uri != null) {
				if (!uri.equals("/")) //$NON-NLS-1$
					fileURI = uri + entry.getName();
				else
					fileURI = entry.getName();
			} else {
				fileURI = entry.getName();
			}

			File file = createFile(fileURI);

			Map fileURIMap = new HashMap();
			fileURIMap.put(entry.getName(), zipFile);

			urisToZipEntry.put(file.getURI(), fileURIMap);
			urisToFiles.put(file.getURI(), file);
		}
	}

	protected FilesHolder filesHolder;

	private Exception exception; //TEMP TODO REMOVE
	
	private IVirtualFile manifestFile = null;
	 
	public ComponentLoadStrategyImpl(IVirtualComponent vComponent) {
		this(vComponent, true);
	}
	
	public ComponentLoadStrategyImpl(IVirtualComponent vComponent, boolean includeClasspathComponents) {
		this.vComponent = vComponent;
		filesHolder = new FilesHolder();
		exception = new Exception();
		this.includeClasspathComponents = includeClasspathComponents;
		if (includeClasspathComponents && ClasspathDependencyEnablement.isAllowClasspathComponentDependency()) {
			this.manifestFile = vComponent.getRootFolder().getFile(new Path(J2EEConstants.MANIFEST_URI));
			saveJavaClasspathReferences();
		}
	}

	@Override
	public boolean contains(String uri) {
		IVirtualFolder rootFolder = vComponent.getRootFolder();
		return rootFolder.getFile(new Path(uri)).exists();
	}

	@Override
	protected void initializeResourceSet() {
		resourceSet = WorkbenchResourceHelperBase.getResourceSet(vComponent.getProject());
	}

	@Override
	protected boolean primContains(String uri) {
		return false;
	}

	@Override
	public List getFiles() {
		aggregateSourceFiles();
		aggregateClassFiles();
		addUtilities();
		return filesHolder.getFiles();
	}
	
	/**
	 * 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
							&& runtimePath.equals(targetRuntimePath)) {
						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 = ((VirtualArchiveComponent) referencedComponent).getUnderlyingDiskFile();
				ZipFile zipFile;
				IPath path = reference.getRuntimePath();
				try {
					zipFile = org.eclipse.jst.jee.archive.internal.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 {
			IVirtualFolder rootFolder = vComponent.getRootFolder();
			IVirtualResource[] members = rootFolder.members();
			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;
			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++) {
			File 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));
			String uri = runtimePath == null ? null : runtimePath.toString();
			if (uri == null)
				continue;
			if (resources[i].getType() == IResource.FILE) {
				if (!shouldInclude(uri))
					continue;
				cFile = createFile(uri);
				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(uri)){
					if (!shouldInclude(uri))
						continue;
					cFile = createDirectory(uri);
					cFile.setLastModified(getLastModified(resources[i]));
					filesHolder.addDirectory(cFile);
					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++) {
			File cFile = null;
			if (!virtualResources[i].exists()) {
				continue;
			}
			// We have to avoid duplicates between the source and output folders (non-java
			// resources)
			IPath runtimePath = virtualResources[i].getRuntimePath();
			String uri = runtimePath == null ? null : runtimePath.toString();
			if (uri == null)
				continue;
			if (uri.charAt(0) == IPath.SEPARATOR) {
				uri = uri.substring(1);
			}
			if (filesHolder.contains(uri))
				continue;
			
			if (virtualResources[i].getType() == IVirtualResource.FILE) {
				if (!shouldInclude(uri))
					continue;
				IResource resource = virtualResources[i].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()) {
					continue;
				}
				cFile = createFile(uri);
				cFile.setLastModified(getLastModified(resource));
				filesHolder.addFile(cFile, resource);
				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(uri)){
						if (!shouldInclude(uri))
							continue;
						IResource resource = virtualResources[i].getUnderlyingResource();
						if (inJavaSrc && resource.isDerived()) {
							continue;
						}
						cFile = createDirectory(uri);
						cFile.setLastModified(getLastModified(resource));
						filesHolder.addDirectory(cFile);
						fileAdded = true;
					}
				} finally {
					inJavaSrc = inJavaSrcAtThisLevel;
				}
			}
		}
		return fileAdded;
	}
	
	/**
	 * 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();
	}

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

	public boolean isExportSource() {
		return exportSource;
	}

	protected boolean shouldInclude(IContainer aContainer) {
		return true;
	}

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

	protected boolean shouldInclude(String uri) {
		if (uri.length() == 0 || DOT_PROJECT.equals(uri) || DOT_CLASSPATH.equals(uri) || uri.endsWith(DOT_CVS_IGORE) || uri.startsWith(DOT_SETTINGS)){
			return false;
		}
		return isExportSource() || !isSource(uri);
	}

	protected boolean isSource(String uri) {
		if (uri == null)
			return false;
		return uri.endsWith(ArchiveUtil.DOT_JAVA) || uri.endsWith(ArchiveUtil.DOT_SQLJ);
	}

	protected void addExternalFile(String uri, java.io.File externalDiskFile) {
		File aFile = createFile(uri);
		filesHolder.addFile(aFile, externalDiskFile);
	}
	
	@Override
	public InputStream getInputStream(String uri) 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 (includeClasspathComponents && 
			uri.equals(J2EEConstants.MANIFEST_URI) && !javaClasspathURIs.isEmpty() &&
			manifestFile != null && manifestFile.getUnderlyingFile() != null && 
			manifestFile.getUnderlyingFile().exists()) {
			//update the manifest classpath for the component
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
	        ClasspathDependencyManifestUtil.updateManifestClasspath(manifestFile.getUnderlyingFile(), javaClasspathURIs, baos);
	        return new ByteArrayInputStream(baos.toByteArray());
		}
		
		if (filesHolder.contains(uri)) {
			return filesHolder.getInputStream(uri);
		}
		IVirtualFolder rootFolder = vComponent.getRootFolder();
		IVirtualResource vResource = rootFolder.findMember(uri);
		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);
	}

	@Override
	public Collection getLoadedMofResources() {
		Collection resources = super.getLoadedMofResources();
		Collection resourcesToRemove = new ArrayList();
		Iterator iterator = resources.iterator();
		while (iterator.hasNext()) {
			Resource res = (Resource) iterator.next();
			//only remove component files that are in the settings directory
			if (res.getURI().toString().endsWith(IModuleConstants.COMPONENT_FILE_NAME) && res.getURI().segmentsList().contains(IModuleConstants.DOT_SETTINGS))
				resourcesToRemove.add(res);
		}
		resources.removeAll(resourcesToRemove);
		return resources;
	}

	protected synchronized ArtifactEdit getArtifactEditForRead() {
		if(artifactEdit == null){
			artifactEdit = ArtifactEdit.getArtifactEditForRead(vComponent);
		}
		return artifactEdit;
	}
	
	@Override
	public Resource getMofResource(String uri) throws FileNotFoundException, ResourceLoadException {
		return getArtifactEditForRead().getResource(URI.createURI(uri));
	}

	@Override
	public boolean isClassLoaderNeeded() {
		return false;
	}

	public IVirtualComponent getComponent() {
		return vComponent;
	}

	protected IProgressMonitor monitor = null;
	
	public void setProgressMonitor(IProgressMonitor monitor){
		this.monitor = monitor;
	}
	
	protected final int FILE_SAVE_WORK = 100;
	
	@Override
	public FileIterator getFileIterator() throws IOException {
		return new FileIteratorImpl(getContainer().getFiles()){
			protected SubProgressMonitor lastSubMon = null;
			boolean firstVisit = true;
			
			@Override
			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() && ComponentLoadStrategyImpl.class.isInstance(((ContainerImpl)file).getLoadStrategy())){
						ComponentLoadStrategyImpl ls = (ComponentLoadStrategyImpl)((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;
			}
		};
		
	}
	
	@Override
	public void close() {
		if(Thread.currentThread().toString().toLowerCase().indexOf("finalizer") != -1){ //$NON-NLS-1$
			J2EEPlugin.logError(ArchiveMessages.ComponentLoadStrategyImpl_Opener_of_Archive_did_not_close_it_, exception);
		}
		
		try{
			Iterator it = zipFiles.iterator();
			while (it.hasNext()) {
				ZipFile file = (ZipFile) it.next();
				try {
					file.close();
				} catch (IOException e) {
					J2EEPlugin.logError(e);
				}
			}
		} finally{
			try{
				synchronized(this) {
					if(artifactEdit != null){
						ArtifactEditModel editModel = (ArtifactEditModel)artifactEdit.getAdapter(ArtifactEditModel.class);
						if(editModel != null && !editModel.isDisposed()){
							artifactEdit.dispose();
						}
						artifactEdit = null;
					}
				}
			} finally {
				super.close();
			}
		}
		
	}
}
