/*******************************************************************************
 * 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.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.jem.util.logger.proxy.Logger;
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.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.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.internal.resources.VirtualArchiveComponent;
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;

	private List zipFiles = new ArrayList();

	private List javaClasspathURIs = new ArrayList();

	protected boolean includeClasspathComponents = true;

	protected class FilesHolder {

		private Map pathsToArchiveResources = new HashMap();

		private Map pathsToWorkbenchResources = new HashMap();

		private Map workbenchResourcesToPaths = new HashMap();

		private Map pathsToDiskFiles;

		private Map pathsToZipEntry = new HashMap();

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

		public void remove(IPath path) {
			pathsToArchiveResources.remove(path);
			Object resource = pathsToWorkbenchResources.remove(path);
			if (resource != null) {
				workbenchResourcesToPaths.remove(resource);
			}
			if (pathsToDiskFiles != null) {
				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);
			if (null == pathsToDiskFiles) {
				pathsToDiskFiles = new HashMap();
			}
			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 != null && pathsToDiskFiles.containsKey(path)) {
				diskFile = (java.io.File) pathsToDiskFiles.get(path);
			} else if (pathsToWorkbenchResources != null && pathsToWorkbenchResources.containsKey(path)) {
				IResource resource = (IResource) 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);
				}
				ZipEntry entry = zipFile.getEntry(sourceFileUri);
				InputStream in = zipFile.getInputStream(entry);
				return in;
			} 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 (IArchiveResource) pathsToArchiveResources.get(path);
		}

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

			IArchiveResource file = createFile(runtimePath);

			Map fileURIMap = new HashMap();
			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();
		}
	}

	public IArchiveResource getArchiveResource(IPath resourcePath) throws FileNotFoundException {
		initArchiveResources();
		return filesHolder.getArchiveResource(resourcePath);
	}

	public boolean containsArchiveResource(IPath path) {
		initArchiveResources();
		return filesHolder.contains(path);
	}

	protected boolean archiveResourcesInitialized = false;

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

	public List<IArchiveResource> getArchiveResources() {

		initArchiveResources();
		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) {
				Logger.getLogger().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 = new ZipFile(diskFile);
					zipFiles.add(zipFile);
					Enumeration enumeration = zipFile.entries();
					while (enumeration.hasMoreElements()) {
						ZipEntry entry = (ZipEntry) enumeration.nextElement();
						filesHolder.addEntry(entry, zipFile, path);
					}
				} catch (ZipException e) {
					Logger.getLogger().logError(e);
				} catch (IOException e) {
					Logger.getLogger().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) {
			Logger.getLogger().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) {
						Logger.getLogger().logError(e);
					}
					if (null == runtimePath) {
						runtimePath = new Path(""); //$NON-NLS-1$
					}

					aggregateOutputFiles(new IResource[] { javaOutputContainer }, runtimePath, javaOutputContainer.getProjectRelativePath().segmentCount());
				}
			}
		} catch (CoreException e) {
			Logger.getLogger().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);
					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;

			IArchiveResource cFile = null;

			if (virtualResources[i].getType() == IVirtualResource.FILE) {
				if (!shouldInclude(runtimePath))
					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(runtimePath);
				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(runtimePath)) {
						if (!shouldInclude(runtimePath))
							continue;
						IResource resource = virtualResources[i].getUnderlyingResource();
						if (inJavaSrc && resource.isDerived()) {
							continue;
						}
						cFile = createDirectory(runtimePath);
						cFile.setLastModified(getLastModified(resource));
						filesHolder.addFile(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);
	}

	// 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 = (IArchiveLoadAdapter)((IArchive)archiveResource).getLoadAdapter();
			if(nestedLoadAdapter instanceof ComponentArchiveLoadAdapter){
				((ComponentArchiveLoadAdapter)nestedLoadAdapter).setExportSource(isExportSource());
			}
		}
		
		return super.getInputStream(archiveResource);
	}

	public InputStream getInputStream(IArchiveResource archiveResource) throws IOException, FileNotFoundException {
		IPath path = archiveResource.getPath();
		// 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 && path.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(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()) {
				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());
				}
			});
		}
	}

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

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

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

	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; } }; }
	 */
}
