org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl.java

Source

/*******************************************************************************
 * 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.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 = (java.io.File) referencedComponent.getAdapter(java.io.File.class);
                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();
            }
        }

    }
}