org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2015 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.componentcore;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
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.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyComponent;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyProvider;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyReceiver;
import org.eclipse.jst.common.internal.modulecore.util.ManifestUtilities;
import org.eclipse.jst.common.jdt.internal.javalite.IJavaProjectLite;
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
import org.eclipse.jst.common.jdt.internal.javalite.JavaLiteUtilities;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent;
import org.eclipse.jst.j2ee.internal.common.J2EEDependencyListener;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.project.EarUtilities;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraph;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualFolder;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualReference;
import org.eclipse.wst.common.componentcore.internal.util.IComponentImplFactory;
import org.eclipse.wst.common.componentcore.internal.util.VirtualReferenceUtilities;
import org.eclipse.wst.common.componentcore.resources.ITaggedVirtualResource;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;

public class J2EEModuleVirtualComponent extends VirtualComponent
        implements IComponentImplFactory, IClasspathDependencyProvider, IClasspathDependencyReceiver {

    public static final String DD_FOLDER_TAG = org.eclipse.wst.common.componentcore.internal.WorkbenchComponent.DEFAULT_ROOT_SOURCE_TAG;
    public static String GET_JAVA_REFS = "GET_JAVA_REFS"; //$NON-NLS-1$
    public static String GET_FUZZY_EAR_REFS = "GET_FUZZY_EAR_REFS"; //$NON-NLS-1$
    public static String GET_EXPANDED_LIB_REFS = "GET_EXPANDED_LIB_REFS"; //$NON-NLS-1$
    /**
     * Use this value to retrieve references consisting of only META-INF/MANIFEST.MF classpath
     * attributes.  Do this as follows:
     * <code>
     * IVirtualCompoment component = a virtual component
     * Map<String, Object> onlyManifestRefs = new HashMap<String, Object>();
     * onlyManifestRefs.put(IVirtualComponent.REQUESTED_REFERENCE_TYPE, J2EEModuleVirtualComponent.ONLY_MANIFEST_REFERENCES);
     * IVirtualReference[] refs = component.getReferences(onlyManifestRefs); 
     * </code> 
     */
    public static String ONLY_MANIFEST_REFERENCES = "ONLY_MANIFEST_REFERENCES"; //$NON-NLS-1$

    private long depGraphModStamp;
    private long jeeModStamp;

    /**
     * Accessors of this field should always use getHardReferences()
     */
    private IVirtualReference[] hardReferences = null;
    private IVirtualReference[] javaReferences = null;
    private IVirtualReference[] parentEarManifestReferences = null;
    private IVirtualReference[] fuzzyEarManifestReferences = null;

    public J2EEModuleVirtualComponent() {
        super();
    }

    public J2EEModuleVirtualComponent(IProject aProject, IPath aRuntimePath) {
        super(aProject, aRuntimePath);
    }

    public IVirtualComponent createComponent(IProject aProject) {
        return new J2EEModuleVirtualComponent(aProject, new Path("/")); //$NON-NLS-1$
    }

    public IVirtualComponent createArchiveComponent(IProject aProject, String archiveLocation, IPath aRuntimePath) {
        return new J2EEModuleVirtualArchiveComponent(aProject, archiveLocation, aRuntimePath);
    }

    public IVirtualFolder createFolder(IProject aProject, IPath aRuntimePath) {
        return new VirtualFolder(aProject, aRuntimePath);
    }

    /**
     * Retrieves all references except those computed dynamically from
     * tagged Java classpath entries.
     * @return IVirtualReferences for all non-Java classpath entry references.
     */
    public IVirtualReference[] getNonJavaReferences() {
        return getReferences(false, false);
    }

    protected IVirtualReference[] getHardReferences() {
        if (!checkIfStillValid() || hardReferences == null) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put(REQUESTED_REFERENCE_TYPE, HARD_REFERENCES);
            hardReferences = super.getReferences(map);
        }
        return hardReferences;
    }

    protected static IVirtualReference[] getHardReferences(IVirtualComponent component) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(REQUESTED_REFERENCE_TYPE, HARD_REFERENCES);
        return component.getReferences(map);
    }

    public IVirtualReference[] getJavaClasspathReferences() {
        //broken by cache
        //if (javaReferences == null || !checkIfStillValid())
        javaReferences = getJavaClasspathReferences(getHardReferences());
        return javaReferences;
    }

    @Override
    public IVirtualReference[] getReferences(Map<String, Object> options) {
        Object val = options.get(REQUESTED_REFERENCE_TYPE);
        if (val != null) {
            if (HARD_REFERENCES.equals(val) || NON_DERIVED_REFERENCES.equals(val)
                    || DISPLAYABLE_REFERENCES.equals(val)) {
                return getHardReferences();
            } else if (DISPLAYABLE_REFERENCES_ALL.equals(val)) {
                checkIfStillValid(); // This will clear the cache of raw references if needed.
                return getAllReferences();
            } else if (ONLY_MANIFEST_REFERENCES.equals(val)) {
                ArrayList<IVirtualReference> all = new ArrayList<IVirtualReference>();
                checkIfStillValid();
                cacheManifestReferences();
                all.addAll(Arrays.asList(parentEarManifestReferences));
                all.addAll(Arrays.asList(fuzzyEarManifestReferences));
                IVirtualReference[] refs = all.toArray(new IVirtualReference[all.size()]);
                VirtualReferenceUtilities.INSTANCE.ensureReferencesHaveNames(refs);
                return refs;
            }
        }
        Boolean objGetJavaRefs = (Boolean) options.get(GET_JAVA_REFS);
        Boolean objGetFuzzyEarRefs = (Boolean) options.get(GET_FUZZY_EAR_REFS);
        Boolean objGetExpandRefs = (Boolean) options.get(GET_EXPANDED_LIB_REFS);
        boolean getJavaRefs = objGetJavaRefs != null ? objGetJavaRefs.booleanValue() : true;
        boolean findFuzzyEARRefs = objGetFuzzyEarRefs != null ? objGetFuzzyEarRefs.booleanValue() : false;
        boolean getExpandRefs = objGetExpandRefs != null ? objGetExpandRefs.booleanValue() : false;

        IVirtualReference[] nonManifestRefs = getNonManifestRefs(getJavaRefs);
        if (val != null && FLATTENABLE_REFERENCES.equals(val)) {
            if (getExpandRefs) {
                return JavaEEProjectUtilities.getExpandedReferences(this, nonManifestRefs);
            }
            return nonManifestRefs;
        }
        ArrayList<IVirtualReference> all = new ArrayList<IVirtualReference>();
        all.addAll(Arrays.asList(nonManifestRefs));
        // retrieve the dynamic references specified via the MANIFEST.MF classpath
        cacheManifestReferences();
        ArrayList<IVirtualReference> dynamicRefs = new ArrayList<IVirtualReference>();
        dynamicRefs.addAll(Arrays.asList(parentEarManifestReferences));
        if (findFuzzyEARRefs)
            dynamicRefs.addAll(Arrays.asList(fuzzyEarManifestReferences));

        for (Iterator<IVirtualReference> iterator = dynamicRefs.iterator(); iterator.hasNext();) {
            IVirtualReference reference = iterator.next();
            IVirtualComponent dynamicComponent = reference.getReferencedComponent();
            boolean shouldInclude = true;
            for (IVirtualReference hardRef : getHardReferences()) {
                if (hardRef.getReferencedComponent().equals(dynamicComponent)) {
                    shouldInclude = false;
                    break;
                }
            }
            if (shouldInclude) {
                all.add(reference);
            }
        }
        IVirtualReference[] refs = all.toArray(new IVirtualReference[all.size()]);
        VirtualReferenceUtilities.INSTANCE.ensureReferencesHaveNames(refs);

        if (getExpandRefs) {
            return JavaEEProjectUtilities.getExpandedReferences(this, refs);
        }
        return refs;
    }

    @Override
    public IVirtualReference[] getReferences() {
        return getReferences(true, false);
    }

    public IVirtualReference[] getReferences(final boolean getJavaRefs, final boolean findFuzzyEARRefs) {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put(GET_JAVA_REFS, new Boolean(getJavaRefs));
        options.put(GET_FUZZY_EAR_REFS, new Boolean(findFuzzyEARRefs));
        return getReferences(options);
    }

    /**
     * Non-manifest references are hard references *OR* java classpath
     * references
     * 
     * @return
     */
    public IVirtualReference[] getNonManifestReferences() {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put(IVirtualComponent.REQUESTED_REFERENCE_TYPE, IVirtualComponent.FLATTENABLE_REFERENCES);
        return getReferences(options);
    }

    @Deprecated
    public IVirtualReference[] getNonManifestReferences(final boolean getJavaRefs) {
        Map<String, Object> options = new HashMap<String, Object>();
        options.put(IVirtualComponent.REQUESTED_REFERENCE_TYPE, IVirtualComponent.FLATTENABLE_REFERENCES);
        options.put(GET_JAVA_REFS, new Boolean(getJavaRefs));
        return getReferences(options);
    }

    private IVirtualReference[] getNonManifestRefs(final boolean getJavaRefs) {
        ArrayList<IVirtualReference> allRefs = new ArrayList<IVirtualReference>();
        IVirtualReference[] hardRefs = getHardReferences();
        allRefs.addAll(Arrays.asList(hardRefs));
        if (getJavaRefs)
            allRefs.addAll(Arrays.asList(getJavaClasspathReferences(hardRefs)));
        return allRefs.toArray(new IVirtualReference[allRefs.size()]);
    }

    public static String[] getManifestClasspath(IVirtualComponent moduleComponent) {
        return ManifestUtilities.getManifestClasspath(moduleComponent, new Path(J2EEConstants.MANIFEST_URI));
    }

    public IVirtualReference[] getJavaClasspathReferences(IVirtualReference[] hardReferences) {
        final boolean isLegacyJ2EE = JavaEEProjectUtilities.isLegacyJ2EEComponent(this);
        final boolean isWebApp = JavaEEProjectUtilities.isDynamicWebComponent(this);

        final IProject project = getProject();
        final List cpRefs = new ArrayList();

        try {
            if (project == null || !project.isAccessible() || !project.hasNature(JavaCoreLite.NATURE_ID)) {
                return new IVirtualReference[0];
            }

            final IJavaProjectLite javaProjectLite = JavaCoreLite.create(project);
            if (javaProjectLite == null)
                return new IVirtualReference[0];

            // retrieve all referenced classpath entries
            final Map referencedEntries = ClasspathDependencyUtil.getComponentClasspathDependencies(javaProjectLite,
                    isLegacyJ2EE);

            if (referencedEntries.isEmpty())
                return new IVirtualReference[0];

            IVirtualReference[] innerHardReferences = hardReferences == null ? getHardReferences() : hardReferences;
            final IPath[] hardRefPaths = new IPath[innerHardReferences.length];
            for (int j = 0; j < innerHardReferences.length; j++) {
                final IVirtualComponent comp = innerHardReferences[j].getReferencedComponent();
                if (comp.isBinary()) {
                    hardRefPaths[j] = (IPath) comp.getAdapter(IPath.class);
                }
            }

            IContainer[] mappedClassFolders = null;
            final Iterator i = referencedEntries.keySet().iterator();
            while (i.hasNext()) {
                final IClasspathEntry entry = (IClasspathEntry) i.next();
                final IClasspathAttribute attrib = (IClasspathAttribute) referencedEntries.get(entry);
                final boolean isClassFolder = ClasspathDependencyUtil.isClassFolderEntry(entry);
                final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp, isClassFolder);
                boolean add = true;
                final IPath entryLocation = ClasspathDependencyUtil.getEntryLocation(entry);
                if (entryLocation == null) {
                    // unable to retrieve location for cp entry, do not
                    // contribute as a virtual ref
                    add = false;
                } else if (!isClassFolder) { // check hard archive refs
                    for (int j = 0; j < hardRefPaths.length; j++) {
                        if (entryLocation.equals(hardRefPaths[j])) {
                            // entry resolves to same file as existing hard
                            // reference, can skip
                            add = false;
                            break;
                        }
                    }
                } else { // check class folders mapped in component file as
                    // class folders associated with mapped src folders
                    if (mappedClassFolders == null) {
                        List<IContainer> containers = JavaLiteUtilities.getJavaOutputContainers(this);
                        mappedClassFolders = containers.toArray(new IContainer[containers.size()]);
                    }
                    for (int j = 0; j < mappedClassFolders.length; j++) {
                        if (entryLocation.equals(mappedClassFolders[j].getFullPath())) {
                            // entry resolves to same file as existing class
                            // folder mapping, skip
                            add = false;
                            break;
                        }
                    }
                }

                if (add && entryLocation != null) {
                    final IVirtualReference entryReference;
                    String componentPath = null;

                    if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
                        final IProject cpEntryProject = ResourcesPlugin.getWorkspace().getRoot()
                                .getProject(entry.getPath().lastSegment());
                        IVirtualComponent entryComponent = ComponentCore.createComponent(cpEntryProject);
                        entryReference = ComponentCore.createReference(this, entryComponent, runtimePath);
                        entryReference.setArchiveName(
                                VirtualReferenceUtilities.INSTANCE.getDefaultProjectArchiveName(entryComponent));
                    } else {
                        componentPath = VirtualArchiveComponent.CLASSPATHARCHIVETYPE + IPath.SEPARATOR
                                + entryLocation.toPortableString();
                        ClasspathDependencyVirtualComponent entryComponent = new ClasspathDependencyVirtualComponent(
                                project, componentPath, isClassFolder);
                        entryReference = ComponentCore.createReference(this, entryComponent, runtimePath);
                        ((VirtualReference) entryReference).setDerived(true);
                        entryReference.setArchiveName(ClasspathDependencyUtil.getArchiveName(entry));
                    }
                    cpRefs.add(entryReference);
                }
            }

        } catch (CoreException jme) {
            J2EEPlugin.logError(jme);
        }

        return (IVirtualReference[]) cpRefs.toArray(new IVirtualReference[cpRefs.size()]);
    }

    private void cacheManifestReferences() {
        if (parentEarManifestReferences == null || fuzzyEarManifestReferences == null) {
            IVirtualReference[][] refs = calculateManifestReferences(this, true);
            parentEarManifestReferences = refs[0];
            fuzzyEarManifestReferences = refs[1];
        }
    }

    private static IVirtualReference[][] calculateManifestReferences(IVirtualComponent moduleComponent,
            boolean checkFuzzyRefs) {
        String[] manifestClasspath = getManifestClasspath(moduleComponent);
        IProject[] earProjects = EarUtilities.getReferencingEARProjects(moduleComponent.getProject());
        // Early aborts
        if (manifestClasspath == null || manifestClasspath.length == 0 || earProjects.length == 0) {
            return new IVirtualReference[][] { new IVirtualReference[0], new IVirtualReference[0] };
        }

        // Get our found cache going
        boolean[] foundRefAlready = new boolean[manifestClasspath.length];
        for (int i = 0; i < foundRefAlready.length; i++)
            foundRefAlready[i] = false;

        // Get the true parent references
        IProject firstEar = earProjects[earProjects.length - 1];
        ArrayList<IVirtualReference> tmp = cacheOneEarProjectManifestRefs(moduleComponent, firstEar,
                manifestClasspath, foundRefAlready);
        IVirtualReference[] parentEarManifestReferences = tmp.toArray(new IVirtualReference[tmp.size()]);

        ArrayList<IVirtualReference> dynamicReferences = new ArrayList<IVirtualReference>();
        // get the fuzzy references
        if (checkFuzzyRefs) {
            if (earProjects.length > 1) {
                for (int earIndex = earProjects.length - 2; earIndex > -1; earIndex--) {
                    if (earProjects[earIndex] != null) {
                        tmp = cacheOneEarProjectManifestRefs(moduleComponent, earProjects[earIndex],
                                manifestClasspath, foundRefAlready);
                        dynamicReferences.addAll(tmp);
                    }
                }
            }
        }
        IVirtualReference[] fuzzyEarManifestReferences = dynamicReferences
                .toArray(new IVirtualReference[dynamicReferences.size()]);

        // return our two creatures
        return new IVirtualReference[][] { parentEarManifestReferences, fuzzyEarManifestReferences };
    }

    protected static ArrayList<IVirtualReference> cacheOneEarProjectManifestRefs(IVirtualComponent moduleComponent,
            IProject earProject, String[] manifestClasspath, boolean[] foundRefAlready) {
        ArrayList<IVirtualReference> dynamicReferences = new ArrayList<IVirtualReference>();

        IVirtualReference foundRef = null;
        String earArchiveURI = null; // The URI for this archive in the EAR
        boolean simplePath = false;
        IVirtualReference[] earRefs = null;
        IVirtualComponent tempEARComponent = ComponentCore.createComponent(earProject);
        IVirtualReference[] tempEarRefs = tempEARComponent.getReferences();
        for (int j = 0; j < tempEarRefs.length && earRefs == null; j++) {
            if (tempEarRefs[j].getReferencedComponent().equals(moduleComponent)) {
                earRefs = tempEarRefs;
                foundRef = tempEarRefs[j];
                earArchiveURI = foundRef.getRuntimePath() == null ? foundRef.getArchiveName()
                        : foundRef.getRuntimePath().append(foundRef.getArchiveName()).makeRelative().toString();
                simplePath = earArchiveURI != null ? earArchiveURI.lastIndexOf("/") == -1 : true; //$NON-NLS-1$
            }
        }
        if (null != earRefs) {
            for (int manifestIndex = 0; manifestIndex < manifestClasspath.length; manifestIndex++) {
                boolean found = false;
                if (foundRefAlready != null && foundRefAlready[manifestIndex]) {
                    continue;
                }
                for (int j = 0; j < earRefs.length && !found; j++) {
                    if (foundRef != earRefs[j]) {
                        String archiveName = earRefs[j].getArchiveName();
                        if (null != archiveName) {
                            boolean shouldAdd = false;
                            String manifestEntryString = manifestClasspath[manifestIndex];
                            if (manifestEntryString != null) {
                                IPath manifestPath = new Path(manifestEntryString);
                                manifestEntryString = manifestPath.toPortableString();
                            }

                            if (simplePath && manifestEntryString != null
                                    && manifestEntryString.lastIndexOf("/") == -1) { //$NON-NLS-1$
                                shouldAdd = archiveName.equals(manifestEntryString);
                            } else {
                                String earRelativeURI = ArchiveUtil.deriveEARRelativeURI(manifestEntryString,
                                        earArchiveURI);
                                if (null != earRelativeURI) {
                                    IPath earRefPath = earRefs[j].getRuntimePath().makeRelative();
                                    shouldAdd = earRelativeURI.equals(earRefPath.append(archiveName).toString());
                                }
                            }

                            if (shouldAdd) {
                                if (foundRefAlready != null) {
                                    foundRefAlready[manifestIndex] = true;
                                }
                                found = true;
                                IVirtualComponent dynamicComponent = earRefs[j].getReferencedComponent();
                                IVirtualReference dynamicReference = ComponentCore.createReference(moduleComponent,
                                        dynamicComponent);
                                ((VirtualReference) dynamicReference).setDerived(true);
                                dynamicReferences.add(dynamicReference);
                            }
                        }
                    }
                }
            }
        }
        return dynamicReferences;
    }

    public static List getManifestReferences(IVirtualComponent moduleComponent,
            IVirtualReference[] hardReferences) {
        return getManifestReferences(moduleComponent, hardReferences, false);
    }

    public static List getManifestReferences(IVirtualComponent moduleComponent, IVirtualReference[] hardReferences,
            boolean findFuzzyEARRefs) {
        IVirtualReference[][] refs = calculateManifestReferences(moduleComponent, findFuzzyEARRefs);
        ArrayList<IVirtualReference> tmp = new ArrayList<IVirtualReference>();
        tmp.addAll(Arrays.asList(refs[0]));
        if (findFuzzyEARRefs)
            tmp.addAll(Arrays.asList(refs[1]));
        return tmp;
    }

    private boolean checkIfStillValid() {
        boolean valid = IDependencyGraph.INSTANCE.getModStamp() == depGraphModStamp;
        valid = valid && J2EEDependencyListener.INSTANCE.getModStamp() == jeeModStamp;
        if (!valid) {
            clearCache();
        }
        return valid;
    }

    @Override
    protected void clearCache() {
        super.clearCache();
        depGraphModStamp = IDependencyGraph.INSTANCE.getModStamp();
        jeeModStamp = J2EEDependencyListener.INSTANCE.getModStamp();
        hardReferences = null;
        javaReferences = null;
        parentEarManifestReferences = null;
        fuzzyEarManifestReferences = null;
    }

    public boolean canReceiveClasspathDependencies() {
        return J2EEProjectUtilities.isDynamicWebProject(getProject());
    }

    public IPath getClasspathFolderPath(IClasspathDependencyComponent component) {
        if (J2EEProjectUtilities.isDynamicWebProject(getProject())) {
            return new Path(J2EEConstants.WEB_INF_LIB).makeAbsolute();
        }
        return new Path("/"); //$NON-NLS-1$
    }

    public static void setDefaultDeploymentDescriptorFolder(IVirtualFolder folder, IPath aProjectRelativeLocation,
            IProgressMonitor monitor) {
        if (folder instanceof ITaggedVirtualResource) {
            ITaggedVirtualResource taggedFolder = (ITaggedVirtualResource) folder;
            //First, remove tag is there is already one folder already tagged 
            IPath[] paths = taggedFolder.getTaggedResources(DD_FOLDER_TAG);
            for (IPath path : paths) {
                taggedFolder.tagResource(path, null, monitor);
            }
            // Now, tag the correct path
            ((ITaggedVirtualResource) folder).tagResource(aProjectRelativeLocation, DD_FOLDER_TAG, monitor);
        }
    }

    public static IPath getDefaultDeploymentDescriptorFolder(IVirtualFolder folder) {
        IPath returnValue = null;
        if (folder instanceof ITaggedVirtualResource) {
            returnValue = ((ITaggedVirtualResource) folder).getFirstTaggedResource(DD_FOLDER_TAG);
        }
        return returnValue;
    }

}