### Eclipse Workspace Patch 1.0 #P org.eclipse.wst.common.modulecore Index: modulecore-src/org/eclipse/wst/common/componentcore/resources/IVirtualReference.java =================================================================== RCS file: /cvsroot/webtools/wst/components/common/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/resources/IVirtualReference.java,v retrieving revision 1.9 diff -u -r1.9 IVirtualReference.java --- modulecore-src/org/eclipse/wst/common/componentcore/resources/IVirtualReference.java 27 Mar 2006 21:49:40 -0000 1.9 +++ modulecore-src/org/eclipse/wst/common/componentcore/resources/IVirtualReference.java 9 Jan 2007 19:04:35 -0000 @@ -35,6 +35,28 @@ int DEPENDENCY_TYPE_CONSUMES = DependencyType.CONSUMES; /** + * Name of the custom Java classpath entry attribute that is used to flag + * entries which should be exposed as module dependencies via the virtual component API. Tagged classpath entries of + * dynamic web projects will be mapped to the WEB-INF/lib folder of the web project. Tagged classpath entries of + * utility, ejb and connector projects will be mapped to either the root of the EAR (if the project is referenced by an EAR) or + * to the WEB-INF/lib directory if the project is a web library for a web project. + * Only container and library entries are currently supported; for containers, only the resolved entries that are library entries are supported. + * All resolved entries are mapped (regardless of whether or not individual resolved entries also have this special attribute) except + * project entries which are not currently support and are therefore always skipped. If partial + * mapping of the resolved entries for a classpath container is desired, the {@link #CLASSPATH_COMPONENT_PARTIAL_DEPENDENCY} + * attribute must be used (see the docs for more details). + */ + String CLASSPATH_COMPONENT_DEPENDENCY = "org.eclipse.wst.component.dependency"; + + /** + * Name of the custom Java classpath entry attribute that is used to flag + * classpath container entries whose resolved entries may only be partially exposed + * via the virtual component API. When this attribute is used, individual resolved entries + * must contain the attribute {@link #CLASSPATH_COMPONENT_DEPENDENCY} if they should be exposed. + */ + String CLASSPATH_COMPONENT_PARTIAL_DEPENDENCY = "org.eclipse.wst.component.dependency.partial"; + + /** * Creates this virtual reference in model, if it doesn't already exist. * @param updateFlags Currently no update flags apply. * @param aMonitor A progress monitor to track the completion of the operation Index: modulecore-src/org/eclipse/wst/common/componentcore/internal/resources/VirtualArchiveComponent.java =================================================================== RCS file: /cvsroot/webtools/wst/components/common/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/resources/VirtualArchiveComponent.java,v retrieving revision 1.28 diff -u -r1.28 VirtualArchiveComponent.java --- modulecore-src/org/eclipse/wst/common/componentcore/internal/resources/VirtualArchiveComponent.java 30 Aug 2006 19:44:36 -0000 1.28 +++ modulecore-src/org/eclipse/wst/common/componentcore/internal/resources/VirtualArchiveComponent.java 9 Jan 2007 19:04:35 -0000 @@ -36,7 +36,8 @@ public static final Class ADAPTER_TYPE = VirtualArchiveComponent.class; public static final String LIBARCHIVETYPE = "lib"; public static final String VARARCHIVETYPE = "var"; - + public static final String CLASSPATHARCHIVETYPE = "cpe"; + private static final IVirtualReference[] NO_REFERENCES = new VirtualReference[0]; private static final IVirtualComponent[] NO_COMPONENTS = new VirtualComponent[0]; private static final IResource[] NO_RESOURCES = null; @@ -87,6 +88,16 @@ public int getType() { return IVirtualResource.COMPONENT; } + + public void setBinary(final boolean binary) { + if (binary) { + flag |= BINARY; + } else if ((flag & BINARY) == 1) { + flag ^= BINARY; + } else { + flag |= 0; + } + } public boolean isBinary() { boolean ret = (flag & BINARY) == 1 ? true : false; @@ -254,7 +265,7 @@ File diskFile = new File(osPath); return diskFile; } - + public String toString() { if(archivePath != null){ return componentProject + " " +archivePath; #P org.eclipse.jst.j2ee.jca Index: jcaedit/org/eclipse/jst/j2ee/internal/jca/archive/operations/ConnectorComponentLoadStrategyImpl.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.jca/jcaedit/org/eclipse/jst/j2ee/internal/jca/archive/operations/ConnectorComponentLoadStrategyImpl.java,v retrieving revision 1.7 diff -u -r1.7 ConnectorComponentLoadStrategyImpl.java --- jcaedit/org/eclipse/jst/j2ee/internal/jca/archive/operations/ConnectorComponentLoadStrategyImpl.java 23 Aug 2006 13:16:47 -0000 1.7 +++ jcaedit/org/eclipse/jst/j2ee/internal/jca/archive/operations/ConnectorComponentLoadStrategyImpl.java 9 Jan 2007 19:04:36 -0000 @@ -56,7 +56,11 @@ }; public ConnectorComponentLoadStrategyImpl(IVirtualComponent vComponent) { - super(vComponent); + this(vComponent, true); + } + + public ConnectorComponentLoadStrategyImpl(IVirtualComponent vComponent, boolean includeClasspathComponents) { + super(vComponent, includeClasspathComponents); knownDD = vComponent.getRootFolder().getFile(J2EEConstants.RAR_DD_URI).getUnderlyingFile(); } Index: rarproject/org/eclipse/jst/j2ee/jca/modulecore/util/ConnectorArtifactEdit.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.jca/rarproject/org/eclipse/jst/j2ee/jca/modulecore/util/ConnectorArtifactEdit.java,v retrieving revision 1.23 diff -u -r1.23 ConnectorArtifactEdit.java --- rarproject/org/eclipse/jst/j2ee/jca/modulecore/util/ConnectorArtifactEdit.java 28 Jul 2006 20:59:16 -0000 1.23 +++ rarproject/org/eclipse/jst/j2ee/jca/modulecore/util/ConnectorArtifactEdit.java 9 Jan 2007 19:04:36 -0000 @@ -380,11 +380,11 @@ return getConnectorArtifactEditForWrite(aComponent); } - public Archive asArchive(boolean includeSource) throws OpenFailureException { + public Archive asArchive(boolean includeSource, boolean includeClasspathComponents) throws OpenFailureException { if (isBinary()) { return ((EnterpriseBinaryComponentHelper) getBinaryComponentHelper()).accessArchive(); } else { - ConnectorComponentLoadStrategyImpl loader = new ConnectorComponentLoadStrategyImpl(getComponent()); + ConnectorComponentLoadStrategyImpl loader = new ConnectorComponentLoadStrategyImpl(getComponent(), includeClasspathComponents); loader.setExportSource(includeSource); String uri = ModuleURIUtil.getHandleString(getComponent()); return CommonarchiveFactory.eINSTANCE.openRARFile(loader, uri); #P org.eclipse.wst.web Index: static_web_project/org/eclipse/wst/web/internal/deployables/ComponentDeployable.java =================================================================== RCS file: /cvsroot/webtools/wst/components/web/plugins/org.eclipse.wst.web/static_web_project/org/eclipse/wst/web/internal/deployables/ComponentDeployable.java,v retrieving revision 1.18 diff -u -r1.18 ComponentDeployable.java --- static_web_project/org/eclipse/wst/web/internal/deployables/ComponentDeployable.java 18 Oct 2006 22:14:31 -0000 1.18 +++ static_web_project/org/eclipse/wst/web/internal/deployables/ComponentDeployable.java 9 Jan 2007 19:04:38 -0000 @@ -39,6 +39,7 @@ import org.eclipse.wst.server.core.ServerUtil; import org.eclipse.wst.server.core.internal.ModuleFile; import org.eclipse.wst.server.core.internal.ModuleFolder; +import org.eclipse.wst.server.core.model.IModuleFile; import org.eclipse.wst.server.core.model.IModuleFolder; import org.eclipse.wst.server.core.model.IModuleResource; import org.eclipse.wst.server.core.util.ProjectModule; @@ -177,13 +178,13 @@ // Handle the default package case if (path.equals(javaPath)) { ModuleFolder mFolder = (ModuleFolder) getExistingModuleResource(members,javaPath); - ModuleFile mFile = new ModuleFile(f, f.getName(), javaPath, f.getModificationStamp() + f.getLocalTimeStamp()); + IModuleFile mFile = createModuleFile(f, javaPath); if (mFolder != null) addMembersToModuleFolder(mFolder,new IModuleResource[]{mFile}); else list.add(mFile); } else { - ModuleFile mf = new ModuleFile(f, f.getName(), path, f.getModificationStamp() + f.getLocalTimeStamp()); + IModuleFile mf = createModuleFile(f, path); list.add(mf); } } @@ -193,6 +194,10 @@ return mr; } + protected IModuleFile createModuleFile(final IFile file, final IPath path) { + return new ModuleFile(file, file.getName(), path, file.getModificationStamp() + file.getLocalTimeStamp()); + } + protected IModuleResource[] getMembers(IVirtualContainer cont, IPath path) throws CoreException { IVirtualResource[] res = cont.members(); int size2 = res.length; @@ -217,8 +222,9 @@ addMembersToModuleFolder(mf, mr); } else { IFile f = (IFile) res[j].getUnderlyingResource(); + IModuleFile mf = null; if (shouldAddComponentFile(f)) { - ModuleFile mf = new ModuleFile(f, f.getName(), path, f.getModificationStamp() + f.getLocalTimeStamp()); + mf = createModuleFile(f, path); list.add(mf); } } @@ -342,37 +348,10 @@ edit = getComponentArtifactEditForRead(); IVirtualReference[] components = vc.getReferences(); for (int i = 0; i < components.length; i++) { - IVirtualReference reference = components[i]; + IVirtualReference reference = components[i]; IVirtualComponent virtualComp = reference.getReferencedComponent(); if (shouldIncludeUtilityComponent(virtualComp,components,edit)) { - ModuleFile mf = null; - String archiveName = reference.getArchiveName(); - IPath archivePath = ((VirtualArchiveComponent)virtualComp).getWorkspaceRelativePath(); - if (archivePath != null) { //In Workspace - IFile utilFile = ResourcesPlugin.getWorkspace().getRoot().getFile(archivePath); - String name = null != archiveName ? archiveName : utilFile.getName(); - mf = new ModuleFile(utilFile, name, reference.getRuntimePath().makeRelative()); - } - else { - File extFile = ((VirtualArchiveComponent)virtualComp).getUnderlyingDiskFile(); - String name = null != archiveName ? archiveName : extFile.getName(); - mf = new ModuleFile(extFile, name, reference.getRuntimePath().makeRelative()); - } - if (mf == null) - continue; - IModuleResource moduleParent = getExistingModuleResource(members, mf.getModuleRelativePath()); - - if (moduleParent != null && moduleParent instanceof ModuleFolder) - addMembersToModuleFolder((ModuleFolder)moduleParent, new IModuleResource[]{mf}); - else { - if (mf.getModuleRelativePath().isEmpty()) - members.add(mf); - else { - if (moduleParent == null) - moduleParent = ensureParentExists(mf.getModuleRelativePath(), (IContainer)vc.getRootFolder().getUnderlyingResource()); - addMembersToModuleFolder((ModuleFolder)moduleParent, new IModuleResource[] {mf}); - } - } + addUtilMember(vc, reference, reference.getRuntimePath()); } } } finally { @@ -381,6 +360,38 @@ } } + protected void addUtilMember(IVirtualComponent parent, IVirtualReference reference, IPath runtimePath) { + IModuleFile mf = null; + final String archiveName = reference.getArchiveName(); + final IVirtualComponent virtualComp = reference.getReferencedComponent(); + final IPath archivePath = ((VirtualArchiveComponent)virtualComp).getWorkspaceRelativePath(); + if (archivePath != null) { //In Workspace + IFile utilFile = ResourcesPlugin.getWorkspace().getRoot().getFile(archivePath); + String name = null != archiveName ? archiveName : utilFile.getName(); + mf = new ModuleFile(utilFile, name, runtimePath.makeRelative()); + } else { + File extFile = ((VirtualArchiveComponent)virtualComp).getUnderlyingDiskFile(); + String name = null != archiveName ? archiveName : extFile.getName(); + mf = new ModuleFile(extFile, name, runtimePath.makeRelative()); + } + if (mf == null) { + return; + } + IModuleResource moduleParent = getExistingModuleResource(members, mf.getModuleRelativePath()); + if (moduleParent != null && moduleParent instanceof ModuleFolder) { + addMembersToModuleFolder((ModuleFolder)moduleParent, new IModuleResource[]{mf}); + } else { + if (mf.getModuleRelativePath().isEmpty()) { + members.add(mf); + } else { + if (moduleParent == null) { + moduleParent = ensureParentExists(mf.getModuleRelativePath(), (IContainer)parent.getRootFolder().getUnderlyingResource()); + } + addMembersToModuleFolder((ModuleFolder)moduleParent, new IModuleResource[] {mf}); + } + } + } + protected ArtifactEdit getComponentArtifactEditForRead() { return null; } #P org.eclipse.jst.j2ee.web Index: webproject/org/eclipse/jst/j2ee/web/componentcore/util/WebArtifactEdit.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.web/webproject/org/eclipse/jst/j2ee/web/componentcore/util/WebArtifactEdit.java,v retrieving revision 1.34 diff -u -r1.34 WebArtifactEdit.java --- webproject/org/eclipse/jst/j2ee/web/componentcore/util/WebArtifactEdit.java 13 Sep 2006 20:57:24 -0000 1.34 +++ webproject/org/eclipse/jst/j2ee/web/componentcore/util/WebArtifactEdit.java 9 Jan 2007 19:04:40 -0000 @@ -633,11 +633,11 @@ return getWebArtifactEditForWrite(aComponent); } - public Archive asArchive(boolean includeSource) throws OpenFailureException { + public Archive asArchive(boolean includeSource, boolean includeClasspathComponents) throws OpenFailureException { if (isBinary()) { return ((EnterpriseBinaryComponentHelper) getBinaryComponentHelper()).accessArchive(); } else { - WebComponentLoadStrategyImpl loader = new WebComponentLoadStrategyImpl(getComponent()); + WebComponentLoadStrategyImpl loader = new WebComponentLoadStrategyImpl(getComponent(), includeClasspathComponents); loader.setExportSource(includeSource); String uri = ModuleURIUtil.getHandleString(getComponent()); return CommonarchiveFactory.eINSTANCE.openWARFile(loader, uri); Index: war-validation/org/eclipse/jst/j2ee/internal/web/validation/UIWarValidator.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.web/war-validation/org/eclipse/jst/j2ee/internal/web/validation/UIWarValidator.java,v retrieving revision 1.35 diff -u -r1.35 UIWarValidator.java --- war-validation/org/eclipse/jst/j2ee/internal/web/validation/UIWarValidator.java 20 Jul 2006 23:25:29 -0000 1.35 +++ war-validation/org/eclipse/jst/j2ee/internal/web/validation/UIWarValidator.java 9 Jan 2007 19:04:40 -0000 @@ -12,19 +12,34 @@ +import java.io.File; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.internal.J2EEConstants; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.jst.j2ee.model.internal.validation.WarValidator; +import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit; import org.eclipse.wst.common.componentcore.ComponentCore; +import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; +import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; 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; +import org.eclipse.wst.validation.internal.core.Message; import org.eclipse.wst.validation.internal.core.ValidationException; import org.eclipse.wst.validation.internal.operations.IWorkbenchContext; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; import org.eclipse.wst.validation.internal.provisional.core.IValidationContext; @@ -87,13 +102,98 @@ IProject proj = ((IWorkbenchContext) warHelper).getProject(); IVirtualComponent wbModule = ComponentCore.createComponent(proj); if( wbModule != null && J2EEProjectUtilities.isDynamicWebProject(proj)) { - IVirtualFile webFile = wbModule.getRootFolder().getFile(J2EEConstants.WEBAPP_DD_URI); + IVirtualFile webFile = wbModule.getRootFolder().getFile(J2EEConstants.WEBAPP_DD_URI); if( webFile.exists()) { - status = super.validateInJob(inHelper, inReporter); + status = super.validateInJob(inHelper, inReporter); + validateWebInfLibs(wbModule); } } return status; } + + /* + * For web projects, need to validate that the classpath component dependencies (both + * from this project's classpath and from the exported classpath entries of referenced + * utility projects) do not conflict. + */ + private void validateWebInfLibs(final IVirtualComponent component) { + + final Set webLibMappings = new HashSet(); + + // get the libs currently in the WEB-INF/lib folder + final IVirtualFolder folder = component.getRootFolder().getFolder(WebArtifactEdit.WEBLIB); + try { + IVirtualResource[] resources = folder.members(); + for (int i = 0; i < resources.length; i++) { + if (resources[i] instanceof IVirtualFile) { + IResource[] underlyingResources = resources[i].getUnderlyingResources(); + for (int j = 0; j < resources.length; j++) { + webLibMappings.add(underlyingResources[j].getName()); + } + } + } + } catch (CoreException ce) { + // swallow + } + + final IVirtualReference[] webLibs = getWebInfLibModules(component); + for (int i = 0; i < webLibs.length; i++) { + IVirtualComponent comp = webLibs[i].getReferencedComponent(); + String name = null; + if (comp.isBinary()) { + VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp; + java.io.File diskFile = archiveComp.getUnderlyingDiskFile(); + if (!diskFile.exists()) { + IFile wbFile = archiveComp.getUnderlyingWorkbenchFile(); + diskFile = new File(wbFile.getLocation().toOSString()); + } + checkLibName(diskFile.getName(), null, webLibMappings); + } else { + String archiveName = webLibs[i].getArchiveName(); + if (archiveName != null && archiveName.length() > 0) { + name = archiveName; + } else { + name = comp.getName() + ".jar"; //$NON-NLS-1$ + } + checkLibName(name, comp.getProject(), webLibMappings); + if (comp instanceof J2EEModuleVirtualComponent) { + final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) comp).getJavaClasspathReferences(); + for (int j = 0; j < cpRefs.length; j++) { + final IVirtualReference ref = cpRefs[j]; + if (ref.getReferencedComponent() instanceof VirtualArchiveComponent) { + checkLibName(ref.getArchiveName(), comp.getProject(), webLibMappings); + } + } + } + } + } + } + + private void checkLibName(final String name, final IProject project, final Set webLibNames) { + if (webLibNames.contains(name)) { + if (project != null) { + _reporter.addMessage(this, new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_DUPLICATE_WEB_INF_LIB_OTHER_PROJECT, new String[]{name, project.getName()})); + } else { + _reporter.addMessage(this, new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_DUPLICATE_WEB_INF_LIB, new String[]{name})); + } + } else { + webLibNames.add(name); + } + } + + private IVirtualReference[] getWebInfLibModules(final IVirtualComponent comp) { + WebArtifactEdit webArtifactEdit = null; + try { + webArtifactEdit = (WebArtifactEdit) ComponentUtilities.getArtifactEditForRead(comp); + if (webArtifactEdit != null) { + return webArtifactEdit.getLibModules(); + } + } finally { + if (webArtifactEdit != null) + webArtifactEdit.dispose(); + } + return new IVirtualReference[0]; + } /** * Insert the method's description here. Creation date: (10/2/2001 6:49:26 PM) Index: plugin.xml =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.web/plugin.xml,v retrieving revision 1.68 diff -u -r1.68 plugin.xml --- plugin.xml 11 Apr 2006 20:38:16 -0000 1.68 +++ plugin.xml 9 Jan 2007 19:04:40 -0000 @@ -33,6 +33,14 @@ objectClass="org.eclipse.core.resources.IFile" nameFilter=".websettings"> + + + + Index: webproject/org/eclipse/jst/j2ee/internal/web/archive/operations/WebComponentLoadStrategyImpl.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.web/webproject/org/eclipse/jst/j2ee/internal/web/archive/operations/WebComponentLoadStrategyImpl.java,v retrieving revision 1.13 diff -u -r1.13 WebComponentLoadStrategyImpl.java --- webproject/org/eclipse/jst/j2ee/internal/web/archive/operations/WebComponentLoadStrategyImpl.java 21 Apr 2006 19:19:29 -0000 1.13 +++ webproject/org/eclipse/jst/j2ee/internal/web/archive/operations/WebComponentLoadStrategyImpl.java 9 Jan 2007 19:04:40 -0000 @@ -14,8 +14,10 @@ import java.util.List; import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Path; import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.jst.j2ee.internal.project.ProjectSupportResourceHandler; @@ -30,6 +32,10 @@ public WebComponentLoadStrategyImpl(IVirtualComponent vComponent) { super(vComponent); } + + public WebComponentLoadStrategyImpl(IVirtualComponent vComponent, boolean includeClasspathComponents) { + super(vComponent, includeClasspathComponents); + } public List getFiles() { super.getFiles(); @@ -78,6 +84,8 @@ prefix += "/"; //$NON-NLS-1$ } + addClasspathComponentDependencies(looseComponent); + String uri = prefix + name; try { Archive utilJAR = J2EEProjectUtilities.asArchive(uri, looseComponent.getProject(), isExportSource()); @@ -91,5 +99,24 @@ } } } + + private void addClasspathComponentDependencies(final IVirtualComponent referencedComponent) { + // retrieve all Java classpath component dependencies + if (includeClasspathComponents && referencedComponent instanceof J2EEModuleVirtualComponent) { + final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) referencedComponent).getJavaClasspathReferences(); + for (int j = 0; j < cpRefs.length; j++) { + final IVirtualReference ref = cpRefs[j]; + if (ref.getReferencedComponent() instanceof VirtualArchiveComponent) { + final VirtualArchiveComponent comp = (VirtualArchiveComponent) ref.getReferencedComponent(); + File cpEntryFile = comp.getUnderlyingDiskFile(); + if (!cpEntryFile.exists()) { + final IFile wbFile = comp.getUnderlyingWorkbenchFile(); + cpEntryFile = new File(wbFile.getLocation().toOSString()); + } + addExternalFile("WEB-INF/lib/" + ref.getArchiveName(), cpEntryFile); + } + } + } + } } Index: property_files/warvalidation.properties =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.web/property_files/warvalidation.properties,v retrieving revision 1.3 diff -u -r1.3 warvalidation.properties --- property_files/warvalidation.properties 24 Nov 2004 13:00:19 -0000 1.3 +++ property_files/warvalidation.properties 9 Jan 2007 19:04:40 -0000 @@ -225,6 +225,10 @@ #EXPLANATION None. #USERACTION None. +ERROR_DUPLICATE_WEB_INF_LIB_OTHER_PROJECT=Web library project archive {0} from project {1} conflicts with another archive also mapped to the WEB-INF/lib folder. +ERROR_DUPLICATE_WEB_INF_LIB=Web library project archive {0} conflicts with another archive also mapped to the WEB-INF/lib folder. + + of_Type_Security_Role_Name_6=of Type Security Role Name Web_Archive_Validator_8=Web Archive Validator of_Type_Role_Name_19=of Type Role Name #P org.eclipse.jst.j2ee Index: j2eecreation/org/eclipse/jst/j2ee/internal/project/J2EEProjectUtilities.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/j2eecreation/org/eclipse/jst/j2ee/internal/project/J2EEProjectUtilities.java,v retrieving revision 1.49 diff -u -r1.49 J2EEProjectUtilities.java --- j2eecreation/org/eclipse/jst/j2ee/internal/project/J2EEProjectUtilities.java 21 Sep 2006 21:30:13 -0000 1.49 +++ j2eecreation/org/eclipse/jst/j2ee/internal/project/J2EEProjectUtilities.java 9 Jan 2007 19:04:47 -0000 @@ -34,12 +34,15 @@ import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.URI; +import org.eclipse.jdt.core.IClasspathAttribute; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jem.java.JavaClass; import org.eclipse.jem.java.JavaRefFactory; import org.eclipse.jem.util.emf.workbench.ProjectUtilities; @@ -77,6 +80,7 @@ import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualFolder; +import org.eclipse.wst.common.componentcore.resources.IVirtualReference; import org.eclipse.wst.common.componentcore.resources.IVirtualResource; import org.eclipse.wst.common.frameworks.datamodel.DataModelFactory; import org.eclipse.wst.common.frameworks.datamodel.IDataModel; @@ -518,7 +522,11 @@ } public static Archive asArchive(String jarUri, IProject project, boolean exportSource) throws OpenFailureException { - JavaComponentLoadStrategyImpl strat = new JavaComponentLoadStrategyImpl(ComponentCore.createComponent(project)); + return asArchive(jarUri, project, exportSource, true); + } + + public static Archive asArchive(String jarUri, IProject project, boolean exportSource, boolean includeClasspathComponents) throws OpenFailureException { + JavaComponentLoadStrategyImpl strat = new JavaComponentLoadStrategyImpl(ComponentCore.createComponent(project), includeClasspathComponents); strat.setExportSource(exportSource); return CommonarchiveFactoryImpl.getActiveFactory().primOpenArchive(strat, jarUri); } Index: j2eeplugin/org/eclipse/jst/j2ee/internal/validation/UIEarValidator.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/j2eeplugin/org/eclipse/jst/j2ee/internal/validation/UIEarValidator.java,v retrieving revision 1.49 diff -u -r1.49 UIEarValidator.java --- j2eeplugin/org/eclipse/jst/j2ee/internal/validation/UIEarValidator.java 30 Aug 2006 17:04:00 -0000 1.49 +++ j2eeplugin/org/eclipse/jst/j2ee/internal/validation/UIEarValidator.java 9 Jan 2007 19:04:48 -0000 @@ -50,6 +50,7 @@ import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveConstants; import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; import org.eclipse.jst.j2ee.internal.J2EEConstants; import org.eclipse.jst.j2ee.internal.J2EEVersionConstants; @@ -60,6 +61,7 @@ import org.eclipse.osgi.util.NLS; import org.eclipse.wst.common.componentcore.ComponentCore; import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil; +import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualFile; import org.eclipse.wst.common.componentcore.resources.IVirtualReference; @@ -218,9 +220,10 @@ status = super.validateInJob(inHelper, inReporter); validateModuleMaps(earModule); validateManifests(); + validateDuplicateClasspathComponentURIs(earModule); // validateUtilJarMaps(earEdit,earModule); // validateUriAlreadyExistsInEar(earEdit,earModule); - // validateDocType(earEdit,earModule); + // validateDocType(earEdit,earModule); } } return IValidatorJob.OK_STATUS; @@ -239,14 +242,54 @@ return appDeploymentDescriptor; } + public void validateDuplicateClasspathComponentURIs(IVirtualComponent earComponent) { + if (earFile == null) { + return; + } + Set moduleURIs = new HashSet(); + List archives = earFile.getArchiveFiles(); + for (int i = 0; i < archives.size(); i++) { + final Archive anArchive = (Archive) archives.get(i); + moduleURIs.add(anArchive.getURI()); + } + + Set cpURIs = new HashSet(); + IVirtualReference[] components = earComponent.getReferences(); + for (int i = 0; i < components.length; i++) { + IVirtualReference reference = components[i]; + IVirtualComponent referencedComponent = reference.getReferencedComponent(); + + // retrieve all Java classpath component dependencies + if (referencedComponent instanceof J2EEModuleVirtualComponent) { + final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) referencedComponent).getJavaClasspathReferences(); + for (int j = 0; j < cpRefs.length; j++) { + final IVirtualReference ref = cpRefs[j]; + // only / runtime paths contribute to the EAR + if (ref.getRuntimePath().equals(Path.ROOT)) { + String archiveName = ref.getArchiveName(); + String[] params = {referencedComponent.getProject().getName(), archiveName}; + if (moduleURIs.contains(archiveName)) { + String msg = NLS.bind(EARValidationMessageResourceHandler.CLASSPATH_COMPONENT_URI_MATCHES_ARCHIVE_URI, params); + addLocalizedError(msg, project); + } else if (archives.contains(archiveName)) { + String msg = NLS.bind(EARValidationMessageResourceHandler.DUPLICATE_CLASSPATH_COMPONENT_URI, params); + addLocalizedError(msg, project); + } else { + archives.add(archiveName); + } + } + } + } + } + } + public void validateManifests() throws ValidationException { if (earFile == null) return; List archives = earFile.getArchiveFiles(); for (int i = 0; i < archives.size(); i++) { - Archive anArchive = (Archive) archives.get(i); - + final Archive anArchive = (Archive) archives.get(i); IFile target = getManifestFile(anArchive); if (target != null) _reporter.removeMessageSubset(this, target, MANIFEST_GROUP_NAME); Index: j2eeplugin/org/eclipse/jst/j2ee/internal/validation/EarHelper.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/j2eeplugin/org/eclipse/jst/j2ee/internal/validation/EarHelper.java,v retrieving revision 1.12 diff -u -r1.12 EarHelper.java --- j2eeplugin/org/eclipse/jst/j2ee/internal/validation/EarHelper.java 12 Apr 2006 14:22:39 -0000 1.12 +++ j2eeplugin/org/eclipse/jst/j2ee/internal/validation/EarHelper.java 9 Jan 2007 19:04:48 -0000 @@ -83,7 +83,7 @@ edit = ComponentUtilities.getArtifactEditForRead(comp); try { - Archive archive = ((EARArtifactEdit) edit).asArchive(false); + Archive archive = ((EARArtifactEdit) edit).asArchive(false, false); earFile = (EARFile)archive; return archive; } catch (OpenFailureException e1) { Index: earproject/org/eclipse/jst/j2ee/application/internal/operations/ClassPathSelection.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/earproject/org/eclipse/jst/j2ee/application/internal/operations/ClassPathSelection.java,v retrieving revision 1.26 diff -u -r1.26 ClassPathSelection.java --- earproject/org/eclipse/jst/j2ee/application/internal/operations/ClassPathSelection.java 10 Oct 2006 13:28:13 -0000 1.26 +++ earproject/org/eclipse/jst/j2ee/application/internal/operations/ClassPathSelection.java 9 Jan 2007 19:04:45 -0000 @@ -18,14 +18,17 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; 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.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jem.util.emf.workbench.ProjectUtilities; @@ -40,12 +43,15 @@ import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.LoadStrategy; import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl; import org.eclipse.jst.j2ee.commonarchivecore.internal.util.ArchiveUtil; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; import org.eclipse.jst.j2ee.internal.archive.operations.ComponentLoadStrategyImpl; import org.eclipse.jst.j2ee.internal.archive.operations.EARComponentLoadStrategyImpl; +import org.eclipse.jst.j2ee.internal.common.ClasspathModel; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.wst.common.componentcore.UnresolveableURIException; import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil; +import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualReference; @@ -177,7 +183,39 @@ element.setText(name); element.setEarProject(earProject); return element; - } + } + + public ClasspathElement[] createClasspathComponentDependencyElements(final IVirtualComponent comp) { + List elements = new ArrayList(); + if (comp != null && comp instanceof J2EEModuleVirtualComponent) { + J2EEModuleVirtualComponent j2eeComp = (J2EEModuleVirtualComponent) comp; + IVirtualReference[] cpRefs = j2eeComp.getJavaClasspathReferences(); + + for (int i = 0; i < cpRefs.length; i++) { + String unresolvedURI = null; + // only / mappings supported at this level + if (!cpRefs[i].getRuntimePath().equals(Path.ROOT)) { + continue; + } + + IVirtualComponent referencedComponent = cpRefs[i].getReferencedComponent(); + URI archiveURI = URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)); + try { + unresolvedURI = ModuleURIUtil.getArchiveName(archiveURI); + } catch (UnresolveableURIException e) { + e.printStackTrace(); + } + if (unresolvedURI != null) { + //URI archiveURI = URI.createURI(unresolvedURI); + ClasspathElement element = createClasspathArchiveElement(referencedComponent, archiveURI, unresolvedURI); + element.setClasspathDependency(true); + addClasspathElement(element, unresolvedURI); + elements.add(element); + } + } + } + return (ClasspathElement[]) elements.toArray(new ClasspathElement[elements.size()]); + } /** * @param element @@ -299,9 +337,17 @@ } protected IProject getProject(Archive anArchive) { + IVirtualComponent comp = getComponent(anArchive); + if (comp != null) { + return comp.getProject(); + } + return null; + } + + protected IVirtualComponent getComponent(Archive anArchive) { LoadStrategy loader = anArchive.getLoadStrategy(); if (loader instanceof ComponentLoadStrategyImpl) - return ((ComponentLoadStrategyImpl) loader).getComponent().getProject(); + return ((ComponentLoadStrategyImpl) loader).getComponent(); return null; } @@ -330,6 +376,7 @@ clientToEJBJARs = reverse(ejbToClientJARs); classpathElements = new ArrayList(); urisToElements = new HashMap(); + String[] cp = new String[0]; try { cp = archive.getManifest().getClassPathTokenized(); @@ -337,11 +384,12 @@ Logger.getLogger().logError(ex); } List archives = getEARFile().getArchiveFiles(); - Archive other = null; ClasspathElement element = null; + Archive other = null; for (int i = 0; i < cp.length; i++) { String cpEntry = cp[i]; String uri = ArchiveUtil.deriveEARRelativeURI(cpEntry, archive); + other = getArchive(uri, archives); if (other != null && ArchiveUtil.isValidDependency(other, archive)) { element = createElement(archive, other, cpEntry); @@ -370,11 +418,17 @@ } addClasspathElement(element, uri); } + + // Add referenced classpath entries + IVirtualComponent comp = getComponent(archive); + createClasspathComponentDependencyElements(comp); + Collections.sort(archives, comparator); //Anything that remains in the list of available archives that is valid should be //available for selection for (int i = 0; i < archives.size(); i++) { other = (Archive) archives.get(i); + if (other != archive && ArchiveUtil.isValidDependency(other, archive)) { IProject project = getProject(other); if (null == targetProjectName || null == project || !project.getName().equals(targetProjectName)) { @@ -392,11 +446,10 @@ IVirtualComponent referencedComponent = ref.getReferencedComponent(); boolean isBinary = referencedComponent.isBinary(); if( isBinary ){ - - - /** - * Warning clean-up 12/05/2005 - */ + + /** + * Warning clean-up 12/05/2005 + */ //String uri = J2EEProjectUtilities.getResolvedPathForArchiveComponent(referencedComponent.getName()).toString(); String unresolvedURI = ref.getArchiveName(); if(unresolvedURI == null){ @@ -406,10 +459,10 @@ e.printStackTrace(); } } - + if(unresolvedURI != null){ URI archiveURI = URI.createURI(unresolvedURI); - + boolean alreadyInList = false; Iterator iter = getClasspathElements().iterator(); while(iter.hasNext()){ @@ -419,7 +472,7 @@ break; } } - + if( !alreadyInList ){ if( inManifest(cp, archiveURI.lastSegment())){ element = createArchiveElement(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)), archiveURI.lastSegment(), archiveURI.lastSegment()); @@ -434,6 +487,11 @@ } } } + + public ClasspathElement createClasspathArchiveElement(final IVirtualComponent archiveComponent, URI archiveURI, String unresolvedURI) { + // TODO resourcify + return createArchiveElement(archiveURI, "(Classpath) " + unresolvedURI, archiveURI.lastSegment()); + } boolean inManifest(String[] cp, String archiveName ){ boolean result = false; @@ -627,7 +685,7 @@ StringBuffer sb = new StringBuffer(); for (int i = 0; i < classpathElements.size(); i++) { ClasspathElement element = (ClasspathElement) classpathElements.get(i); - if (element.isSelected()) { + if (element.isSelected() && !element.isClasspathDependency()) { sb.append(element.getRelativeText()); sb.append(" "); //$NON-NLS-1$ } Index: earproject/org/eclipse/jst/j2ee/application/internal/operations/ClasspathElement.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/earproject/org/eclipse/jst/j2ee/application/internal/operations/ClasspathElement.java,v retrieving revision 1.13 diff -u -r1.13 ClasspathElement.java --- earproject/org/eclipse/jst/j2ee/application/internal/operations/ClasspathElement.java 10 May 2006 02:47:09 -0000 1.13 +++ earproject/org/eclipse/jst/j2ee/application/internal/operations/ClasspathElement.java 9 Jan 2007 19:04:45 -0000 @@ -58,6 +58,9 @@ /** Indicates if this is selected in the view */ protected boolean selected; protected boolean valid; + /** Indicates if this element represents a Java classpath-based component dependency */ + protected boolean classpathDependency = false; + /** * The text that is an actual Class-Path entry in the Manifest; in the case of multi-segment * uris, might look like ../xxx @@ -196,6 +199,24 @@ } /** + * Determines if this ClasspathElement is associated with a Java classpath entry + * that is tagged as a component dependency. + * @return True if a classpath component dependency. + */ + public boolean isClasspathDependency() { + return classpathDependency; + } + + /** + * Sets whether this ClasspathElement is associated with a Java classpath entry + * that is tagged as a component dependency. + * @param classpathDependency True if a classpath component dependency. + */ + public void setClasspathDependency(final boolean classpathDependency) { + this.classpathDependency = classpathDependency; + } + + /** * Insert the method's description here. Creation date: (8/27/2001 1:04:35 PM) * * @return boolean Index: j2eecreation/org/eclipse/jst/j2ee/componentcore/J2EEModuleVirtualComponent.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/j2eecreation/org/eclipse/jst/j2ee/componentcore/J2EEModuleVirtualComponent.java,v retrieving revision 1.6 diff -u -r1.6 J2EEModuleVirtualComponent.java --- j2eecreation/org/eclipse/jst/j2ee/componentcore/J2EEModuleVirtualComponent.java 13 Dec 2006 19:51:19 -0000 1.6 +++ j2eecreation/org/eclipse/jst/j2ee/componentcore/J2EEModuleVirtualComponent.java 9 Jan 2007 19:04:46 -0000 @@ -10,16 +10,26 @@ *******************************************************************************/ package org.eclipse.jst.j2ee.componentcore; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import java.util.Map; 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.IClasspathAttribute; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jem.util.logger.proxy.Logger; import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl; @@ -27,6 +37,9 @@ import org.eclipse.jst.j2ee.internal.J2EEConstants; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.wst.common.componentcore.ComponentCore; +import org.eclipse.wst.common.componentcore.UnresolveableURIException; +import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil; +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.util.IComponentImplFactory; @@ -59,8 +72,10 @@ public IVirtualReference[] getReferences() { IVirtualReference[] hardReferences = getNonManifestReferences(); + + // retrieve the dynamic references specified via the MANIFEST.MF classpath List dynamicReferences = J2EEModuleVirtualComponent.getManifestReferences(this, hardReferences); - + IVirtualReference[] references = null; if (dynamicReferences == null) { references = hardReferences; @@ -75,7 +90,21 @@ } public IVirtualReference[] getNonManifestReferences() { - return super.getReferences(); + final List allRefs = new ArrayList(); + + // add component file references + IVirtualReference[] hardReferences = super.getReferences(); + for (int i = 0; i < hardReferences.length; i++) { + allRefs.add(hardReferences[i]); + } + + // add the dynamic references specified via specially tagged JDT classpath entries + IVirtualReference[] cpRefs = getJavaClasspathReferences(); + for (int i = 0; i < cpRefs.length; i++) { + allRefs.add(cpRefs[i]); + } + + return (IVirtualReference[]) allRefs.toArray(new IVirtualReference[allRefs.size()]); } public static String [] getManifestClasspath(IVirtualComponent moduleComponent) { @@ -112,6 +141,73 @@ } + public IVirtualReference[] getJavaClasspathReferences() { + IVirtualReference[] hardReferences = super.getReferences(); + final IProject project = getProject(); + final List cpRefs = new ArrayList(); + final boolean isWebApp = J2EEProjectUtilities.isDynamicWebComponent(this); + + try { + if (project == null || !project.isAccessible() || !project.hasNature(JavaCore.NATURE_ID)) { + return new IVirtualReference[0]; + } + + final IJavaProject javaProject = JavaCore.create(project); + if (javaProject == null) { + return new IVirtualReference[0]; + } + + // retrieve all referenced classpath entries + final Map referencedEntries = ClasspathComponentDependencyUtil.getComponentClasspathDependencies(javaProject, isWebApp); + + if (referencedEntries.isEmpty()) { + return new IVirtualReference[0]; + } + + final Iterator i = referencedEntries.keySet().iterator(); + final IPath runtimePath = isWebApp ? new Path("/WEB-INF/lib") : Path.ROOT; // $NON-NLS-1$ + while (i.hasNext()) { + final IClasspathEntry entry = (IClasspathEntry) i.next(); + boolean add = true; + final IClasspathAttribute attrib = (IClasspathAttribute) referencedEntries.get(entry); + final IPath entryLocation = ClasspathComponentDependencyUtil.getEntryLocation(entry); + + for (int j = 0; j < hardReferences.length; j++) { + final IVirtualComponent comp = hardReferences[j].getReferencedComponent(); + if (comp.isBinary()) { + final VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp; + final File diskFile = archiveComp.getUnderlyingDiskFile(); + IPath diskPath = null; + if (diskFile.exists()) { + diskPath =new Path(diskFile.getAbsolutePath()); + } else { + final IFile iFile = archiveComp.getUnderlyingWorkbenchFile(); + diskPath = iFile.getFullPath(); + } + + if (entryLocation.equals(diskPath)) { + // entry resolves to same file as existing hard reference, can skip + add = false; + break; + } + } + } + + if (add) { + final String componentPath = VirtualArchiveComponent.CLASSPATHARCHIVETYPE + IPath.SEPARATOR + entryLocation.toPortableString(); + final VirtualArchiveComponent entryComponent = (VirtualArchiveComponent) ComponentCore.createArchiveComponent(project, componentPath); + final IVirtualReference entryReference = ComponentCore.createReference(this, entryComponent, runtimePath); + entryReference.setArchiveName(ClasspathComponentDependencyUtil.getArchiveName(entry)); + cpRefs.add(entryReference); + } + } + + } catch (CoreException jme) { + Logger.getLogger().logError(jme); + } + + return (IVirtualReference[]) cpRefs.toArray(new IVirtualReference[cpRefs.size()]); + } public static List getManifestReferences(IVirtualComponent moduleComponent, IVirtualReference[] hardReferences) { List dynamicReferences = null; Index: j2eecreation/org/eclipse/jst/j2ee/componentcore/EnterpriseArtifactEdit.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/j2eecreation/org/eclipse/jst/j2ee/componentcore/EnterpriseArtifactEdit.java,v retrieving revision 1.16 diff -u -r1.16 EnterpriseArtifactEdit.java --- j2eecreation/org/eclipse/jst/j2ee/componentcore/EnterpriseArtifactEdit.java 22 May 2006 21:27:49 -0000 1.16 +++ j2eecreation/org/eclipse/jst/j2ee/componentcore/EnterpriseArtifactEdit.java 9 Jan 2007 19:04:46 -0000 @@ -234,8 +234,11 @@ public abstract EObject createModelRoot(int version); - public Archive asArchive(boolean includeSource) throws OpenFailureException{ + return asArchive(includeSource, true); + } + + public Archive asArchive(boolean includeSource, boolean includeClasspathComponents) throws OpenFailureException { return null; } } Index: common/org/eclipse/jst/j2ee/internal/common/ClasspathModel.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/common/org/eclipse/jst/j2ee/internal/common/ClasspathModel.java,v retrieving revision 1.38 diff -u -r1.38 ClasspathModel.java --- common/org/eclipse/jst/j2ee/internal/common/ClasspathModel.java 18 Aug 2006 12:35:48 -0000 1.38 +++ common/org/eclipse/jst/j2ee/internal/common/ClasspathModel.java 9 Jan 2007 19:04:44 -0000 @@ -45,6 +45,7 @@ import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException; import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; import org.eclipse.jst.j2ee.internal.J2EEConstants; import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater; @@ -174,7 +175,7 @@ return; } try { - earFile = (EARFile) getEARArtifactEdit().asArchive(false); + earFile = (EARFile) getEARArtifactEdit().asArchive(false, false); } catch (OpenFailureException ex) { handleOpenFailureException(ex); } @@ -640,13 +641,17 @@ for (Iterator it = hs.iterator(); it.hasNext();) { Object item = it.next(); IProject utilProject = null; + IVirtualComponent comp = null; if (item instanceof IProject) { utilProject = (IProject) item; + comp = ComponentCore.createComponent(utilProject); if (utilProject.getName().startsWith(".")) { //$NON-NLS-1$ continue; } - } else if (item instanceof IVirtualComponent) + } else if (item instanceof IVirtualComponent) { utilProject = ((IVirtualComponent) item).getProject(); + comp = (IVirtualComponent) item; + } boolean existingEntry = false; if (containerEntries != null) { for (int j = 0; j < containerEntries.length; j++) { @@ -677,6 +682,12 @@ } } } + + if (existingEntry) { + // add elements for all exported classpath component dependencies + classPathWLPSelection.createClasspathComponentDependencyElements(comp); + } + classPathWLPSelection.createProjectElement(utilProject, existingEntry); classPathWLPSelection.setFilterLevel(ClassPathSelection.FILTER_NONE); } @@ -720,10 +731,12 @@ } } + boolean inClasspath = false; if( !inContainer ){ IJavaProject javaProject = JavaCore.create( component.getProject() ); if( javaProject != null ){ VirtualArchiveComponent vComp = (VirtualArchiveComponent) referencedComponent; + java.io.File diskFile = vComp.getUnderlyingDiskFile(); IPath path = null; if ( diskFile.exists() ) { @@ -732,12 +745,19 @@ IFile iFile = vComp.getUnderlyingWorkbenchFile(); path = iFile.getFullPath(); } - inContainer = inClassPath(javaProject, path ); + inClasspath = inClassPath(javaProject, path ); } } if (inContainer) { element = classPathWLPSelection.createArchiveElement(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)), referencedComponent.getName(), archiveURI.lastSegment()); classPathWLPSelection.addClasspathElement(element, unresolvedURI); + } else if (inClasspath) { + // if a classpath component dependency, need to ensure that the runtime path is + // /WEB-INF/lib + if (ref.getRuntimePath().equals(libPath)) { + element = classPathWLPSelection.createClasspathArchiveElement(referencedComponent, archiveURI, unresolvedURI); + classPathWLPSelection.addClasspathElement(element, unresolvedURI); + } } else { element = classPathWLPSelection.createArchiveElement(URI.createURI(ModuleURIUtil.getHandleString(referencedComponent)), archiveURI.lastSegment(), null); classPathWLPSelection.addClasspathElement(element, unresolvedURI); @@ -764,18 +784,15 @@ boolean existingEntry = false; IClasspathEntry[] entry = null; try { - entry = javaProject.getRawClasspath(); + entry = javaProject.getResolvedClasspath(true); } catch (JavaModelException e) { Logger.getLogger().logError(e); } for (int j = 0; j < entry.length; j++) { IClasspathEntry eachEntry = entry[j]; - if (eachEntry.getEntryKind() == IClasspathEntry.CPE_LIBRARY || eachEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE ) { - IClasspathEntry classPathEntry = JavaCore.getResolvedClasspathEntry( eachEntry ); - if( classPathEntry != null && classPathEntry.getPath().equals(path) ){ - existingEntry = true; - break; - } + if (eachEntry.getPath().equals(path)) { + existingEntry = true; + break; } } return existingEntry; Index: archiveops/org/eclipse/jst/j2ee/internal/archive/operations/ComponentLoadStrategyImpl.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/archiveops/org/eclipse/jst/j2ee/internal/archive/operations/ComponentLoadStrategyImpl.java,v retrieving revision 1.45 diff -u -r1.45 ComponentLoadStrategyImpl.java --- archiveops/org/eclipse/jst/j2ee/internal/archive/operations/ComponentLoadStrategyImpl.java 13 Dec 2006 19:57:22 -0000 1.45 +++ archiveops/org/eclipse/jst/j2ee/internal/archive/operations/ComponentLoadStrategyImpl.java 9 Jan 2007 19:04:43 -0000 @@ -10,6 +10,8 @@ *******************************************************************************/ 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; @@ -44,11 +46,16 @@ import org.eclipse.jem.util.logger.proxy.Logger; 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.ArchiveManifest; +import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl; 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.ClasspathComponentDependencyUtil; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; +import org.eclipse.jst.j2ee.internal.J2EEConstants; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.jst.j2ee.internal.project.ProjectSupportResourceHandler; import org.eclipse.wst.common.componentcore.ArtifactEdit; @@ -57,10 +64,12 @@ 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.impl.ModuleURIUtil; 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; @@ -76,6 +85,8 @@ protected boolean exportSource; private ArtifactEdit artifactEdit; private List zipFiles = new ArrayList(); + private List javaClasspathURIs = new ArrayList(); + protected boolean includeClasspathComponents = true; protected class FilesHolder { @@ -187,10 +198,21 @@ 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) { + this.manifestFile = vComponent.getRootFolder().getFile(new Path(J2EEConstants.MANIFEST_URI)); + saveJavaClasspathReferences(); + } } public boolean contains(String uri) { @@ -212,6 +234,21 @@ addUtilities(); return filesHolder.getFiles(); } + + 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(Path.ROOT)) { + javaClasspathURIs.add(refs[i].getArchiveName()); + } + } + } + } protected void addUtilities() { IVirtualReference[] components = vComponent.getReferences(); @@ -485,8 +522,21 @@ File aFile = createFile(uri); filesHolder.addFile(aFile, externalDiskFile); } - + 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(); + ClasspathComponentDependencyUtil.updateManifestClasspath(manifestFile.getUnderlyingFile(), javaClasspathURIs, baos); + return new ByteArrayInputStream(baos.toByteArray()); + } + if (filesHolder.contains(uri)) { return filesHolder.getInputStream(uri); } Index: archiveops/org/eclipse/jst/j2ee/internal/archive/operations/JavaComponentLoadStrategyImpl.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/archiveops/org/eclipse/jst/j2ee/internal/archive/operations/JavaComponentLoadStrategyImpl.java,v retrieving revision 1.1 diff -u -r1.1 JavaComponentLoadStrategyImpl.java --- archiveops/org/eclipse/jst/j2ee/internal/archive/operations/JavaComponentLoadStrategyImpl.java 13 Jun 2005 16:19:13 -0000 1.1 +++ archiveops/org/eclipse/jst/j2ee/internal/archive/operations/JavaComponentLoadStrategyImpl.java 9 Jan 2007 19:04:44 -0000 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.jst.j2ee.internal.archive.operations; +import java.util.List; + import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; public class JavaComponentLoadStrategyImpl extends ComponentLoadStrategyImpl { @@ -17,5 +19,8 @@ public JavaComponentLoadStrategyImpl(IVirtualComponent vComponent) { super(vComponent); } - + + public JavaComponentLoadStrategyImpl(IVirtualComponent vComponent, boolean includeClasspathComponents) { + super(vComponent, includeClasspathComponents); + } } Index: archiveops/org/eclipse/jst/j2ee/internal/archive/operations/J2EEComponentLoadStrategyImpl.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/archiveops/org/eclipse/jst/j2ee/internal/archive/operations/J2EEComponentLoadStrategyImpl.java,v retrieving revision 1.1 diff -u -r1.1 J2EEComponentLoadStrategyImpl.java --- archiveops/org/eclipse/jst/j2ee/internal/archive/operations/J2EEComponentLoadStrategyImpl.java 12 Jul 2005 16:01:28 -0000 1.1 +++ archiveops/org/eclipse/jst/j2ee/internal/archive/operations/J2EEComponentLoadStrategyImpl.java 9 Jan 2007 19:04:44 -0000 @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.jst.j2ee.internal.archive.operations; +import java.util.List; + import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; public class J2EEComponentLoadStrategyImpl extends ComponentLoadStrategyImpl{ Index: archiveops/org/eclipse/jst/j2ee/internal/archive/operations/EARComponentLoadStrategyImpl.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/archiveops/org/eclipse/jst/j2ee/internal/archive/operations/EARComponentLoadStrategyImpl.java,v retrieving revision 1.22 diff -u -r1.22 EARComponentLoadStrategyImpl.java --- archiveops/org/eclipse/jst/j2ee/internal/archive/operations/EARComponentLoadStrategyImpl.java 10 Oct 2006 13:28:13 -0000 1.22 +++ archiveops/org/eclipse/jst/j2ee/internal/archive/operations/EARComponentLoadStrategyImpl.java 9 Jan 2007 19:04:44 -0000 @@ -22,6 +22,7 @@ import java.util.Map; import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Path; import org.eclipse.jem.util.logger.proxy.Logger; import org.eclipse.jst.j2ee.applicationclient.componentcore.util.AppClientArtifactEdit; import org.eclipse.jst.j2ee.commonarchivecore.internal.Archive; @@ -29,6 +30,7 @@ import org.eclipse.jst.j2ee.commonarchivecore.internal.exception.OpenFailureException; import org.eclipse.jst.j2ee.commonarchivecore.internal.strategy.ZipFileLoadStrategyImpl; import org.eclipse.jst.j2ee.componentcore.EnterpriseArtifactEdit; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.wst.common.componentcore.ArtifactEdit; @@ -45,6 +47,10 @@ public EARComponentLoadStrategyImpl(IVirtualComponent vComponent) { super(vComponent); } + + public EARComponentLoadStrategyImpl(IVirtualComponent vComponent, boolean includeClasspathComponents) { + super(vComponent, includeClasspathComponents); + } public List getFiles() { aggregateSourceFiles(); @@ -59,7 +65,7 @@ } return super.getInputStream(uri); } - + public void addModulesAndUtilities() { EARArtifactEdit earArtifactEdit = null; try { @@ -79,19 +85,22 @@ } boolean isModule = false; + boolean addClasspathComponentDependencies = false; ArtifactEdit componentArtifactEdit = null; try { if (J2EEProjectUtilities.isApplicationClientComponent(referencedComponent)) { componentArtifactEdit = AppClientArtifactEdit.getAppClientArtifactEditForRead(referencedComponent); } else if (J2EEProjectUtilities.isEJBComponent(referencedComponent)) { + addClasspathComponentDependencies = true; componentArtifactEdit = ArtifactEditRegistryReader.instance().getArtifactEdit(J2EEProjectUtilities.EJB).createArtifactEditForRead(referencedComponent); } else if (J2EEProjectUtilities.isDynamicWebComponent(referencedComponent)) { componentArtifactEdit = ArtifactEditRegistryReader.instance().getArtifactEdit(J2EEProjectUtilities.DYNAMIC_WEB).createArtifactEditForRead(referencedComponent); } else if (J2EEProjectUtilities.isJCAComponent(referencedComponent)) { + addClasspathComponentDependencies = true; componentArtifactEdit = ArtifactEditRegistryReader.instance().getArtifactEdit(J2EEProjectUtilities.JCA).createArtifactEditForRead(referencedComponent); } if (null != componentArtifactEdit) { - Archive archive = ((EnterpriseArtifactEdit) componentArtifactEdit).asArchive(exportSource); + Archive archive = ((EnterpriseArtifactEdit) componentArtifactEdit).asArchive(exportSource, includeClasspathComponents); if (referencedComponent.isBinary()) { artifactEditsToDispose.add(componentArtifactEdit); archive.setLoadingContainer(getContainer()); @@ -100,6 +109,9 @@ archive.setURI(earArtifactEdit.getModuleURI(referencedComponent)); filesHolder.addFile(archive); isModule = true; + if (addClasspathComponentDependencies) { + addClasspathComponentDependencies(referencedComponent); + } } } catch (OpenFailureException oe) { Logger.getLogger().logError(oe); @@ -116,9 +128,10 @@ try { if (!referencedComponent.isBinary()) { String uri = earArtifactEdit.getModuleURI(referencedComponent); - Archive archive = J2EEProjectUtilities.asArchive(uri, referencedComponent.getProject(), exportSource); + Archive archive = J2EEProjectUtilities.asArchive(uri, referencedComponent.getProject(), exportSource, includeClasspathComponents); archive.setURI(uri); filesHolder.addFile(archive); + addClasspathComponentDependencies(referencedComponent); } else { @@ -137,6 +150,28 @@ } } + private void addClasspathComponentDependencies(final IVirtualComponent referencedComponent) { + // retrieve all Java classpath component dependencies + if (includeClasspathComponents && referencedComponent instanceof J2EEModuleVirtualComponent) { + final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) referencedComponent).getJavaClasspathReferences(); + for (int j = 0; j < cpRefs.length; j++) { + final IVirtualReference ref = cpRefs[j]; + // only / runtime paths contribute to the EAR + if (ref.getRuntimePath().equals(Path.ROOT)) { + if (ref.getReferencedComponent() instanceof VirtualArchiveComponent) { + final VirtualArchiveComponent comp = (VirtualArchiveComponent) ref.getReferencedComponent(); + File cpEntryFile = comp.getUnderlyingDiskFile(); + if (!cpEntryFile.exists()) { + final IFile wbFile = comp.getUnderlyingWorkbenchFile(); + cpEntryFile = new File(wbFile.getLocation().toOSString()); + } + addExternalFile(ref.getArchiveName(), cpEntryFile); + } + } + } + } + } + public void close() { super.close(); Iterator it = artifactEditsToDispose.iterator(); Index: plugin.xml =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/plugin.xml,v retrieving revision 1.105 diff -u -r1.105 plugin.xml --- plugin.xml 9 Jan 2007 14:50:03 -0000 1.105 +++ plugin.xml 9 Jan 2007 19:04:43 -0000 @@ -327,6 +327,10 @@ objectClass="org.eclipse.core.resources.IFile" nameFilter=".modulemaps"> + + @@ -368,6 +372,28 @@ + + + + + + + + + + + + + + Index: plugin.properties =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/plugin.properties,v retrieving revision 1.6 diff -u -r1.6 plugin.properties --- plugin.properties 15 May 2006 18:12:42 -0000 1.6 +++ plugin.properties 9 Jan 2007 19:04:42 -0000 @@ -23,4 +23,5 @@ APPCLIENT_FACET_LABEL=Application Client module APPCLIENT_FACET_DESCRIPTION=Enables the project to be deployed as a J2EE Application Client module. APPCLIENT_FACET_TEMPLATE=Application Client Project -differentRuntimesDetectedMarkerName = Faceted Project Problem (Mismatched Runtimes) \ No newline at end of file +differentRuntimesDetectedMarkerName = Faceted Project Problem (Mismatched Runtimes) +classpath_component_dependency_validator_UI_=Classpath Component Dependency Validator \ No newline at end of file Index: j2eeplugin/org/eclipse/jst/j2ee/internal/deployables/J2EEFlexProjDeployable.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/j2eeplugin/org/eclipse/jst/j2ee/internal/deployables/J2EEFlexProjDeployable.java,v retrieving revision 1.65 diff -u -r1.65 J2EEFlexProjDeployable.java --- j2eeplugin/org/eclipse/jst/j2ee/internal/deployables/J2EEFlexProjDeployable.java 18 Oct 2006 22:14:20 -0000 1.65 +++ j2eeplugin/org/eclipse/jst/j2ee/internal/deployables/J2EEFlexProjDeployable.java 9 Jan 2007 19:04:47 -0000 @@ -11,6 +11,8 @@ package org.eclipse.jst.j2ee.internal.deployables; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -25,10 +27,12 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jem.workbench.utility.JemProjectUtilities; import org.eclipse.jst.j2ee.application.Application; +import org.eclipse.jst.j2ee.componentcore.ClasspathComponentDependencyUtil; import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualArchiveComponent; import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; @@ -37,6 +41,7 @@ import org.eclipse.jst.j2ee.internal.IEJBModelExtenderManager; import org.eclipse.jst.j2ee.internal.J2EEConstants; import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants; +import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.jst.server.core.IApplicationClientModule; import org.eclipse.jst.server.core.IConnectorModule; @@ -49,15 +54,19 @@ import org.eclipse.wst.common.componentcore.internal.ComponentResource; import org.eclipse.wst.common.componentcore.internal.StructureEdit; import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent; +import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities; 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.IVirtualFolder; import org.eclipse.wst.common.componentcore.resources.IVirtualReference; +import org.eclipse.wst.common.componentcore.resources.IVirtualResource; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.ServerUtil; import org.eclipse.wst.server.core.internal.ModuleFile; import org.eclipse.wst.server.core.internal.ModuleFolder; +import org.eclipse.wst.server.core.model.IModuleFile; import org.eclipse.wst.server.core.model.IModuleFolder; import org.eclipse.wst.server.core.model.IModuleResource; import org.eclipse.wst.web.internal.deployables.ComponentDeployable; @@ -66,11 +75,13 @@ */ public class J2EEFlexProjDeployable extends ComponentDeployable implements IJ2EEModule, IEnterpriseApplication, IApplicationClientModule, IConnectorModule, IEJBModule, IWebModule { private static final IPath WEB_CLASSES_PATH = new Path(J2EEConstants.WEB_INF_CLASSES); + private static final IPath MANIFEST_PATH = new Path(J2EEConstants.MANIFEST_URI); private static IPath WEBLIB = new Path(J2EEConstants.WEB_INF_LIB).makeAbsolute(); private IPackageFragmentRoot[] cachedSourceContainers; private IContainer[] cachedOutputContainers; private HashMap cachedOutputMappings; private HashMap cachedSourceOutputPairs; + private List classpathComponentDependencyURIs = new ArrayList(); /** * Constructor for J2EEFlexProjDeployable. @@ -152,14 +163,40 @@ public IModuleResource[] members() throws CoreException { members.clear(); - + classpathComponentDependencyURIs.clear(); + // Handle binary components if (component instanceof J2EEModuleVirtualArchiveComponent) return getBinaryModuleMembers(); + + if (J2EEProjectUtilities.isEARProject(component.getProject())) { + // If an EAR, add classpath contributions for all referenced modules + addReferencedComponentClasspathDependencies(component, false); + } else if (J2EEProjectUtilities.isDynamicWebProject(component.getProject())) { + // If a web, add classpath contributions for all WEB-INF/lib modules + addReferencedComponentClasspathDependencies(component, true); + } else if (canExportClasspathComponentDependencies(component)){ + saveClasspathDependencyURIs(component); + } // If j2ee project structure is a single root structure, just return optimized members - if (isSingleRootStructure()) - return getOptimizedMembers(); + if (isSingleRootStructure()) { + final IModuleResource[] resources = getOptimizedMembers(); + if (!classpathComponentDependencyURIs.isEmpty()) { + for (int i = 0; i < resources.length; i++) { + if (resources[i] instanceof IModuleFolder) { + IModuleFolder folder = (IModuleFolder) resources[i]; + if (folder.getName().equals(J2EEConstants.META_INF)) { + IModuleResource[] files = folder.members(); + for (int j = 0; j < files.length; j++) { + resources[i] = replaceManifestFile((IModuleFile) files[j]); + } + } + } + } + } + return resources; + } cachedSourceContainers = J2EEProjectUtilities.getSourceContainers(getProject()); try { @@ -207,6 +244,44 @@ } } + protected IModuleFile createModuleFile(IFile file, IPath path) { + // if this is the MANIFEST.MF file and we have have classpath component dependencies, + // update it + return replaceManifestFile(super.createModuleFile(file, path)); + } + + protected IModuleFile replaceManifestFile(IModuleFile moduleFile) { + final IFile file = (IFile) moduleFile.getAdapter(IFile.class); + final IPath path = moduleFile.getModuleRelativePath(); + // if the MANIFEST.MF is being requested and we have classpath component dependencies, + // dynamically generate a customized MANIFEST.MF and return that + if (path.append(file.getName()).equals(MANIFEST_PATH) && !classpathComponentDependencyURIs.isEmpty()) { + final IProject project = file.getProject(); + final IPath workingLocation = project.getWorkingLocation(J2EEPlugin.PLUGIN_ID); + // create path to temp MANIFEST.MF + final IPath tempManifestPath = workingLocation.append(MANIFEST_PATH); + final File fsFile = tempManifestPath.toFile(); + if (!fsFile.exists()) { + // create parent dirs for temp MANIFEST.MF + final File parent = fsFile.getParentFile(); + if (!parent.exists()) { + if (!parent.mkdirs()) { + return moduleFile; + } + } + } + // create temp MANIFEST.MF using util method + try { + ClasspathComponentDependencyUtil.updateManifestClasspath(file, classpathComponentDependencyURIs, new FileOutputStream(fsFile)); + // create new ModuleFile that points to temp MANIFEST.MF + return new ModuleFile(fsFile, file.getName(), path); + } catch (IOException ioe) { + return moduleFile; + } + } + return moduleFile; + } + protected IModuleResource[] handleJavaPath(IPath path, IPath javaPath, IPath curPath, IContainer[] javaCont, IModuleResource[] mr, IContainer cc) throws CoreException { if (curPath.equals(javaPath)) { int size = javaCont.length; @@ -559,23 +634,89 @@ } /** - * This method will return the list of dependent modules which are utility jars in the web lib - * folder of the deployed path of the module. It will not return null. - * - * @return array of the web library dependent modules - */ + * This method will return the list of dependent modules which are utility jars in the web lib + * folder of the deployed path of the module. It will not return null. + * + * @return array of the web library dependent modules + */ private IVirtualReference[] getWebLibModules(J2EEModuleVirtualComponent comp) { List result = new ArrayList(); IVirtualReference[] refComponents = comp.getNonManifestReferences(); // Check the deployed path to make sure it has a lib parent folder and matchs the web.xml // base path for (int i = 0; i < refComponents.length; i++) { - if (refComponents[i].getRuntimePath().equals(WEBLIB)) + IVirtualReference ref = refComponents[i]; + if (ref.getRuntimePath().equals(WEBLIB)) { result.add(refComponents[i]); + } } return (IVirtualReference[]) result.toArray(new IVirtualReference[result.size()]); } + /* + * Add any classpath component dependencies from this component + */ + private void addReferencedComponentClasspathDependencies(final IVirtualComponent component, final boolean web) { + final IVirtualReference[] refs = component.getReferences(); + final IPath runtimePath = web ? WEBLIB : Path.ROOT; + for (int i = 0; i < refs.length; i++) { + final IVirtualReference reference = refs[i]; + final IVirtualComponent referencedComponent = reference.getReferencedComponent(); + + // if we are adding to a web project, only process references with the WEB-INF/lib runtime path + if (web && !reference.getRuntimePath().equals(WEBLIB)) { + continue; + } + + if (!canExportClasspathComponentDependencies(referencedComponent)) { + continue; + } + + if (!referencedComponent.isBinary() && referencedComponent instanceof J2EEModuleVirtualComponent) { + final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) referencedComponent).getJavaClasspathReferences(); + for (int j = 0; j < cpRefs.length; j++) { + final IVirtualReference cpRef = cpRefs[j]; + // if we are adding to an EAR project, only process references with the root mapping + if (!web && !cpRef.getRuntimePath().equals(Path.ROOT)) { + // fails the runtime path test + continue; + } + if (cpRef.getReferencedComponent() instanceof VirtualArchiveComponent) { + addUtilMember(component, cpRef, runtimePath); + } + } + } + } + } + + private boolean canExportClasspathComponentDependencies(IVirtualComponent component) { + final IProject project = component.getProject(); + // check for valid project type + if (J2EEProjectUtilities.isEJBProject(project) + || J2EEProjectUtilities.isJCAProject(project) + || J2EEProjectUtilities.isUtilityProject(project)) { + return true; + } + return false; + } + + private void saveClasspathDependencyURIs(IVirtualComponent component) { + if (!component.isBinary() && component instanceof J2EEModuleVirtualComponent) { + final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) component).getJavaClasspathReferences(); + for (int j = 0; j < cpRefs.length; j++) { + final IVirtualReference cpRef = cpRefs[j]; + // if we are adding to an EAR project, only process references with the root mapping + if (!cpRef.getRuntimePath().equals(Path.ROOT)) { + // fails the runtime path test + continue; + } + if (cpRef.getReferencedComponent() instanceof VirtualArchiveComponent) { + classpathComponentDependencyURIs.add(cpRef.getArchiveName()); + } + } + } + } + /** * Returns true if this module has a simple structure based on a * single root folder, and false otherwise. @@ -740,18 +881,19 @@ * @throws CoreException */ private IModuleResource[] getOptimizedMembers() throws CoreException { + IModuleResource[] resources = new IModuleResource[]{}; if (component != null) { // For java utility modules, we can just use the output container, at this point we know there is only one if (J2EEProjectUtilities.isUtilityProject(getProject())) { - return getModuleResources(Path.EMPTY, getJavaOutputFolders()[0]); + resources = getModuleResources(Path.EMPTY, getJavaOutputFolders()[0]); } // For J2EE modules, we use the contents of the content root else { IVirtualFolder vFolder = component.getRootFolder(); - return getModuleResources(Path.EMPTY, vFolder.getUnderlyingFolder()); + resources = getModuleResources(Path.EMPTY, vFolder.getUnderlyingFolder()); } } - return new IModuleResource[] {}; + return resources; } /** Index: earproject/org/eclipse/jst/j2ee/componentcore/util/EARArtifactEdit.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee/earproject/org/eclipse/jst/j2ee/componentcore/util/EARArtifactEdit.java,v retrieving revision 1.49 diff -u -r1.49 EARArtifactEdit.java --- earproject/org/eclipse/jst/j2ee/componentcore/util/EARArtifactEdit.java 6 Jun 2006 20:35:18 -0000 1.49 +++ earproject/org/eclipse/jst/j2ee/componentcore/util/EARArtifactEdit.java 9 Jan 2007 19:04:45 -0000 @@ -574,7 +574,11 @@ } public Archive asArchive(boolean includeSource) throws OpenFailureException { - EARComponentLoadStrategyImpl loader = new EARComponentLoadStrategyImpl(getComponent()); + return asArchive(includeSource, true); + } + + public Archive asArchive(boolean includeSource, boolean includeClasspathComponents) throws OpenFailureException { + EARComponentLoadStrategyImpl loader = new EARComponentLoadStrategyImpl(getComponent(), includeClasspathComponents); loader.setExportSource(includeSource); String uri = ModuleURIUtil.getHandleString(getComponent()); return CommonarchiveFactory.eINSTANCE.openEARFile(loader, uri); Index: j2eecreation/org/eclipse/jst/j2ee/componentcore/ClasspathComponentDependencyUtil.java =================================================================== RCS file: j2eecreation/org/eclipse/jst/j2ee/componentcore/ClasspathComponentDependencyUtil.java diff -N j2eecreation/org/eclipse/jst/j2ee/componentcore/ClasspathComponentDependencyUtil.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ j2eecreation/org/eclipse/jst/j2ee/componentcore/ClasspathComponentDependencyUtil.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,297 @@ +/******************************************************************************* + * Copyright (c) 2006 BEA Systems, Inc. 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: + * BEA Systems, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.j2ee.componentcore; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.resources.IFile; +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.IClasspathAttribute; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.JavaProject; +import org.eclipse.jem.util.logger.proxy.Logger; +import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; +import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifestImpl; +import org.eclipse.jst.j2ee.internal.validation.ClasspathComponentDependencyValidator; +import org.eclipse.wst.common.componentcore.UnresolveableURIException; +import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil; +import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; +import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; +import org.eclipse.wst.common.componentcore.resources.IVirtualFile; +import org.eclipse.wst.common.componentcore.resources.IVirtualReference; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; + +/** + * Contains utility code for working with Java classpath entries that are + * tagged as virtual components. + */ +public class ClasspathComponentDependencyUtil { + + /** + * Returns all unresolved classpath entries for the specified Java project that + * have one of the special WTP classpath component dependency attributes. + * + * @param javaProject Java project whose component classpath dependencies are being retrieved. + * @param isWebApp True if the target project is associated with a web project. + * @return Map from IClasspathEntry to IClasspathAttribute for special component dependency attribute. + * @throws CoreException Thrown if an error is encountered accessing the unresolved classpath. + */ + public static Map getRawComponentClasspathDependencies(final IJavaProject javaProject, final boolean isWebApp) throws CoreException { + final Map referencedRawEntries = new HashMap(); + + if (javaProject == null) { + return referencedRawEntries; + } + + IClasspathEntry[] entries = javaProject.getRawClasspath(); + for (int i = 0; i < entries.length; i++) { + final IClasspathEntry entry = entries[i]; + final IClasspathAttribute attrib = checkForComponentDependencyAttribute(entry); + if (attrib != null) { + referencedRawEntries.put(entry, attrib); + } + } + return referencedRawEntries; + } + /** + * Returns all resolved classpath entries for the specified Java project that + * have one of the special WTP classpath component dependency attributes. + * + * @param javaProject Java project whose component classpath dependencies are being retrieved. + * @param isWebApp True if the target project is associated with a web project. + * @return Map from IClasspathEntry to IClasspathAttribute for classpath component dependencies. + * @throws CoreException Thrown if an error is encountered accessing the unresolved classpath. + */ + public static Map getComponentClasspathDependencies(final IJavaProject javaProject, final boolean isWebApp) throws CoreException { + final Map referencedEntries = new HashMap(); + + // get the raw entries + final Map referencedRawEntries = getRawComponentClasspathDependencies(javaProject, isWebApp); + + // filter out non-valid referenced raw entries + Iterator i = referencedRawEntries.keySet().iterator(); + while (i.hasNext()) { + final IClasspathEntry entry = (IClasspathEntry) i.next(); + final IClasspathAttribute attrib = (IClasspathAttribute) referencedRawEntries.get(entry); + IMessage[] msgs = ClasspathComponentDependencyValidator.validateVirtualComponentEntry(entry, attrib, isWebApp, javaProject.getProject()); + boolean valid = true; + for (int j = 0; j < msgs.length; j++) { + if (msgs[j].getSeverity() == IMessage.HIGH_SEVERITY) { + valid = false; + break; + } + } + if (!valid) { + i.remove(); + } + } + + // NOTE: if, despite the prohibition listed in the API, it is in fact OK to make a call directly into + // IClasspathContainer.getClasspathEntries() in this context (and we can be certain that the container + // implementations will support necessary caching), we can remove the internal API usage + + IClasspathEntry[] entries = javaProject.getResolvedClasspath(true); + final JavaProject jProject = (JavaProject) javaProject; + final JavaModelManager.PerProjectInfo perProjectInfo = jProject.getPerProjectInfo(); + final Map resolvedPathToRawEntries = perProjectInfo.resolvedPathToRawEntries; + + // if the resolved-to-raw map is null or empty for some reason, return + if (resolvedPathToRawEntries == null || resolvedPathToRawEntries.isEmpty()) { + return referencedEntries; + } + + // collect the paths for all resolved entries that are associated with a raw dependent + // entry + for (int j = 0; j < entries.length; j++) { + final IClasspathEntry entry = entries[j]; + final IClasspathEntry rawEntry = (IClasspathEntry) perProjectInfo.resolvedPathToRawEntries.get(entry.getPath()); + if (rawEntry == null) { + continue; + } + final IClasspathAttribute parentAttrib = (IClasspathAttribute) referencedRawEntries.get(rawEntry); + // missing entry from referencedRawEntries, skip + if (parentAttrib == null) { + continue; + } + IClasspathAttribute attrib = checkForComponentDependencyAttribute(entry); + if (attrib == null) { + attrib = parentAttrib; + } + + // attribute for either the resolved or parent raw entry must be the non-partial + // dependency attribute for it to be included + if (attrib.getName().equals(IVirtualReference.CLASSPATH_COMPONENT_DEPENDENCY)) { + referencedEntries.put(entry, attrib); + continue; + } + } + + return referencedEntries; + } + + /** + * Retrieves the location (as a absolute file system path) for the specified classpath entry. + * @param entry Classpath entry. + * @return Absolute file system path. + */ + public static IPath getEntryLocation(final IClasspathEntry entry) { + final IPath entryPath = entry.getPath(); + IPath entryLocation = entryPath; + final IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath); + if (resource != null) { + entryLocation = resource.getLocation(); + } + return entryLocation; + } + + /** + * Retrieves the archive name for the specified classpath entry + * @param entry The entry. + * @return The archive name. + */ + public static String getArchiveName(final IClasspathEntry entry) { + final IPath entryLocation = getEntryLocation(entry); + return entryLocation.lastSegment(); + } + + /** + * Checks if the specified IClasspathEntry has one of the special WTP component dependency + * attributes that indicate it should be mapped into the virtual component for the associated project. + * + * @param entry The IClasspathEntry. + * @return The IClasspathAttribute that holds the special WTP attribute or null if one was not found. + */ + public static IClasspathAttribute checkForComponentDependencyAttribute(final IClasspathEntry entry) { + if (entry == null) { + return null; + } + final IClasspathAttribute[] attributes = entry.getExtraAttributes(); + for (int i = 0; i < attributes.length; i++) { + final IClasspathAttribute attribute = attributes[i]; + final String name = attribute.getName(); + if (name.equals(IVirtualReference.CLASSPATH_COMPONENT_DEPENDENCY) + || name.equals(IVirtualReference.CLASSPATH_COMPONENT_PARTIAL_DEPENDENCY)) { + return attribute; + } + } + return null; + } + + /** + * Determines if the specified virtual component represents a classpath component dependency. + * @param component + * @return + */ + public static boolean isClasspathComponentDependency(final IVirtualComponent component) { + if (component == null) { + return false; + } + if (component instanceof VirtualArchiveComponent) { + final VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) component; + return archiveComp.getArchiveType().equals(VirtualArchiveComponent.CLASSPATHARCHIVETYPE); + } + return false; + } + + public static String getClasspathComponentDependencyDisplayString(final IVirtualComponent component) { + URI archiveURI = URI.createURI(ModuleURIUtil.getHandleString(component)); + String unresolvedURI = null; + try { + unresolvedURI = ModuleURIUtil.getArchiveName(archiveURI); + } catch (UnresolveableURIException e) { + e.printStackTrace(); + } + if (!isClasspathComponentDependency(component)) { + archiveURI.lastSegment(); + } + // TODO resourcify + return "(Classpath) " + unresolvedURI; // $NON-NLS-1$ + } + + /** + * Generates new MANIFEST.MF with a dynamically updated classpath that is written to the specified + * output stream. + * @param manifestFile The current MANIFEST.MF file. + * @param dynamicURIs Is List of URIs to dynamically add to the manifest classpath. + * @param outputStream Stream to which the modified entry should be written. + * @throws IOException + * @throws FileNotFoundException + */ + public static void updateManifestClasspath(final IFile manifestFile, final List dynamicURIs, final OutputStream outputStream) throws IOException, FileNotFoundException { + InputStream in = null; + ArchiveManifest manifest = null; + try { + in = manifestFile.getContents(); + manifest = new ArchiveManifestImpl(in); + } catch (CoreException ce) { + throw new IOException(ce.getLocalizedMessage()); + } finally { + if (in != null) { + try { + in.close(); + in = null; + } catch (IOException e) { + Logger.getLogger().logError(e); + } + } + } + final String[] manifestClasspath = manifest.getClassPathTokenized(); + final List updatedCP = new ArrayList(); + for (int i = 0; i < manifestClasspath.length; i++) { + updatedCP.add(manifestClasspath[i]); + } + // update manifest classpath to include dynamic entries + for (int j = 0; j < dynamicURIs.size(); j++) { + final String containerURI = (String) dynamicURIs.get(j); + // need to check existing entries to ensure it doesn't are exist on the classpath + boolean exists = false; + for (int i = 0; i < manifestClasspath.length; i++) { + if (manifestClasspath[i].equals(containerURI)) { + exists = true; + break; + } + } + if (!exists) { + updatedCP.add(containerURI); + } + } + final StringBuffer cpBuffer = new StringBuffer(); + boolean first = true; + for (int j = 0; j < updatedCP.size(); j++) { + if (!first) { + cpBuffer.append(" "); + } else { + first = false; + } + cpBuffer.append((String) updatedCP.get(j)); + } + manifest.setClassPath(cpBuffer.toString()); + manifest.write(outputStream); + outputStream.flush(); + } +} Index: j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidator.java =================================================================== RCS file: j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidator.java diff -N j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidator.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidator.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,236 @@ +/******************************************************************************* + * Copyright (c) 2006 BEA Systems, Inc. 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: + * BEA Systems, Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jst.j2ee.internal.validation; + + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +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.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.ISchedulingRule; +import org.eclipse.jdt.core.IClasspathAttribute; +import org.eclipse.jdt.core.IClasspathEntry; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jst.j2ee.componentcore.ClasspathComponentDependencyUtil; +import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; +import org.eclipse.wst.common.componentcore.ComponentCore; +import org.eclipse.wst.common.componentcore.ModuleCoreNature; +import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; +import org.eclipse.wst.common.componentcore.resources.IVirtualReference; +import org.eclipse.wst.validation.internal.core.Message; +import org.eclipse.wst.validation.internal.core.ValidationException; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; +import org.eclipse.wst.validation.internal.provisional.core.IValidationContext; +import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob; + +/** + * Validates classpath entries that have been tagged as component dependencies. + */ +public class ClasspathComponentDependencyValidator implements IValidatorJob { + + protected IReporter _reporter; + + public ClasspathComponentDependencyValidator() { + super(); + } + + public IStatus validateInJob(IValidationContext helper, IReporter reporter) + throws ValidationException { + _reporter = reporter; + //Remove all markers related to this validator + _reporter.removeAllMessages(this); + //Using the helper class, load the module model + final Set archiveNames = new HashSet(); + final IProject proj = ((ClasspathComponentDependencyValidatorHelper) helper).getProject(); + try { + if (proj.isAccessible() + && proj.hasNature(ModuleCoreNature.MODULE_NATURE_ID) + && proj.hasNature(JavaCore.NATURE_ID)) { + + final IJavaProject javaProject = JavaCore.create(proj); + final boolean isWebApp = J2EEProjectUtilities.isDynamicWebProject(proj); + final Map referencedRawEntries = ClasspathComponentDependencyUtil.getRawComponentClasspathDependencies(javaProject, isWebApp); + final IVirtualComponent component = ComponentCore.createComponent(proj); + if (!isWebApp) { + if (referencedRawEntries.size() > 0) { + boolean referencedFromEARorWAR = false; + if (component != null) { + List earWarRefs = new ArrayList(); + final IVirtualComponent[] refComponents = component.getReferencingComponents(); + for (int i = 0; i < refComponents.length; i++) { + if (J2EEProjectUtilities.isEARProject(refComponents[i].getProject()) + || J2EEProjectUtilities.isDynamicWebProject(refComponents[i].getProject())) { + referencedFromEARorWAR = true; + earWarRefs.add(refComponents[i]); + } + } + if (!referencedFromEARorWAR) { + + // root mappings are only supported if the project is referenced by an EAR or a WAR + + _reporter.addMessage(this, new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "RootMappingNonEARWARRef", null, proj)); // $NON-NLS-1$ + } + } + + if (J2EEProjectUtilities.isApplicationClientProject(proj)) { + + // classpath component dependencies are not supported for application client projects + + _reporter.addMessage(this, new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "AppClientProject", null, proj)); // $NON-NLS-1$ + } + } + } + + // validate the raw container entries + Iterator i = referencedRawEntries.keySet().iterator(); + while (i.hasNext()) { + final IClasspathEntry entry = (IClasspathEntry) i.next(); + final IClasspathAttribute attrib = (IClasspathAttribute) referencedRawEntries.get(entry); + IMessage[] msgs = validateVirtualComponentEntry(entry, attrib, isWebApp, proj); + reportMessages(msgs); + } + + // validate all resolved entries + Map referencedResolvedEntries = ClasspathComponentDependencyUtil.getComponentClasspathDependencies(javaProject, isWebApp); + i = referencedResolvedEntries.keySet().iterator(); + while (i.hasNext()) { + final IClasspathEntry entry = (IClasspathEntry) i.next(); + final IClasspathAttribute attrib = (IClasspathAttribute) referencedResolvedEntries.get(entry); + // compute the archive name + final String archivePath = ClasspathComponentDependencyUtil.getArchiveName(entry); + if (archiveNames.contains(archivePath)) { + // Project cp entry + _reporter.addMessage(this, new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "DuplicateArchiveName", new String[]{entry.getPath().toString()}, proj)); // $NON-NLS-1$ + } else { + archiveNames.add(archivePath); + } + IMessage[] msgs = validateVirtualComponentEntry(entry, attrib, isWebApp, proj); + reportMessages(msgs); + } + } + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return Status.OK_STATUS; + } + + + + private void reportMessages(final IMessage[] msgs) { + for (int i = 0; i < msgs.length; i++) { + _reporter.addMessage(this, msgs[i]); + } + } + + /** + * Checks if the specified Java classpath entry is a valid WTP virtual component reference. + * Does not check the runtime path. + * @param entry Raw or resolved classpath entry to validate. + * @param attrib The component dependency attribute for the entry. + * @param isWebApp True if the target project is associated with a web project. + * @return IMessages representing validation results. + */ + public static IMessage[] validateVirtualComponentEntry(final IClasspathEntry entry, final IClasspathAttribute attrib, final boolean isWebApp, final IProject project) { + List results = new ArrayList(); + if (entry == null || attrib == null) { + return (IMessage[]) results.toArray(new IMessage[results.size()]); + } + + final int kind = entry.getEntryKind(); + if (kind == IClasspathEntry.CPE_PROJECT) { + + // Project cp entry + + results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "ProjectClasspathEntry", new String[]{entry.getPath().toString()}, project)); // $NON-NLS-1$ + + return (IMessage[]) results.toArray(new IMessage[results.size()]); + } else if (kind == IClasspathEntry.CPE_SOURCE) { + + // Source cp entry + + results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "SourceEntry", new String[]{entry.getPath().toString()}, project)); // $NON-NLS-1$ + return (IMessage[]) results.toArray(new IMessage[results.size()]); + } + + // does the path refer to a file or a folder? + final IPath entryPath = entry.getPath(); + IPath entryLocation = entryPath; + final IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath); + if (resource != null) { + entryLocation = resource.getLocation(); + } + boolean isFile = true; // by default, assume a jar file + if (entryLocation.toFile().isDirectory()) { + isFile = false; + } + + if (!isFile) { + + // Class folder reference + + results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "ClassFolderEntry", new String[]{entry.getPath().toString()}, project)); // $NON-NLS-1$ + } + + if (attrib.getName().equals(IVirtualReference.CLASSPATH_COMPONENT_PARTIAL_DEPENDENCY) + && kind != IClasspathEntry.CPE_CONTAINER) { + + // Partial component dependency for non-container + + results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "NonContainerPartialDependency", new String[]{entry.getPath().toString()}, project)); // $NON-NLS-1$ + } + + if (!isWebApp && !entry.isExported()) { + + // if not a web app, associated cp entry must be exported + + results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$ + IMessage.HIGH_SEVERITY, "NonWebNonExported", new String[]{entry.getPath().toString()}, project)); // $NON-NLS-1$ + } + + return (IMessage[]) results.toArray(new IMessage[results.size()]); + } + + public ISchedulingRule getSchedulingRule(IValidationContext helper) { + return null; + } + + public void cleanup(IReporter reporter) { + _reporter = null; + + } + + public void validate(IValidationContext helper, IReporter reporter) + throws ValidationException { + // Forwarding to job method + validateInJob(helper, reporter); + } +} Index: j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidatorHelper.java =================================================================== RCS file: j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidatorHelper.java diff -N j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidatorHelper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ j2eeplugin/org/eclipse/jst/j2ee/internal/validation/ClasspathComponentDependencyValidatorHelper.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,11 @@ +package org.eclipse.jst.j2ee.internal.validation; + +import org.eclipse.wst.validation.internal.operations.WorkbenchContext; + + +public class ClasspathComponentDependencyValidatorHelper extends WorkbenchContext { + + public ClasspathComponentDependencyValidatorHelper() { + super(); + } +} Index: j2eeplugin/classpathdependencyvalidator.properties =================================================================== RCS file: j2eeplugin/classpathdependencyvalidator.properties diff -N j2eeplugin/classpathdependencyvalidator.properties --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ j2eeplugin/classpathdependencyvalidator.properties 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,18 @@ +############################################################################### +# Copyright (c) 2006 BEA Systems, Inc. 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: +# BEA Systems, Inc. - initial API and implementation +############################################################################### +ClassFolderEntry=Invalid classpath component dependency {0}. Class folders not supported. +NonContainerPartialDependency=Invalid classpath component dependency {0}. Partial component dependencies can only be specified for classpath container entries. +NonWebNonExported=Invalid classpath component dependency {0}. Classpath component dependencies for non-web projects must be exported. +DuplicateArchiveName=Invalid classpath component dependency {0}. The project contains another classpath component dependency the same archive name. +RootMappingNonEARWARRef=Non-web projects must be referenced by an EAR or a WAR to use classpath component dependencies. +AppClientProject=Classpath component dependencies are not supported for Application Client projects. +ProjectClasspathEntry=Invalid classpath component dependency {0}. Project entries not supported. +SourceEntry=Invalid classpath component dependency {0}. Source entries not supported. #P org.eclipse.jst.j2ee.core Index: j2ee-validation/warvalidation.properties =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/warvalidation.properties,v retrieving revision 1.3 diff -u -r1.3 warvalidation.properties --- j2ee-validation/warvalidation.properties 1 Dec 2005 22:25:31 -0000 1.3 +++ j2ee-validation/warvalidation.properties 9 Jan 2007 19:04:50 -0000 @@ -41,7 +41,6 @@ #EXPLANATION None. #USERACTION None. - # -------------------------------- ERROR_EAR_DUPLICATE_ROLES=CHKJ1002E: Duplicate security role named {0}. MESSAGE_WAR_VALIDATION_MISSING_JSP=CHKJ3001E: The JSP file, {0}, for the servlet \"{1}\" is missing. Index: j2ee-validation/earvalidation.properties =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/earvalidation.properties,v retrieving revision 1.3 diff -u -r1.3 earvalidation.properties --- j2ee-validation/earvalidation.properties 11 May 2006 18:29:12 -0000 1.3 +++ j2ee-validation/earvalidation.properties 9 Jan 2007 19:04:50 -0000 @@ -112,6 +112,10 @@ MODULE_DD_PARSE_NOINFO_ERROR_=IWAE0021E The deployment descriptor of module {0} could not be loaded. EJB_BEAN_EJB_LINK_INTEFACE_MISMATCH_ERROR_=IWAE0037E The interfaces of the linked enterprise bean {0} do not match those in EJB ref {1} in module {2}. +CLASSPATH_COMPONENT_URI_MATCHES_ARCHIVE_URI=URI {1} for classpath component dependency from project {0} clashes with existing archive in EAR. +DUPLICATE_CLASSPATH_COMPONENT_URI=URI {1} for classpath component dependency from project {0} clashes with another classpath component dependency URI. + + # warnings ---------------------------- WARNING_METAFOLDER_MISSING=IWAJ0000W: Meta folder {0} must exist in project {1}. WARNING_FILE_MISSING=IWAJ0001W: {0} must exist in project {1}. Index: j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/EARValidationMessageResourceHandler.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/EARValidationMessageResourceHandler.java,v retrieving revision 1.1 diff -u -r1.1 EARValidationMessageResourceHandler.java --- j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/EARValidationMessageResourceHandler.java 21 Feb 2006 16:43:42 -0000 1.1 +++ j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/EARValidationMessageResourceHandler.java 9 Jan 2007 19:04:50 -0000 @@ -64,6 +64,8 @@ public static String MESSAGE_INCOMPATIBLE_13_SPEC_WARNING_; public static String MESSAGE_INCOMPATIBLE_14_SPEC_WARNING_; public static String EAR_VALIDATION_INTERNAL_ERROR_UI_; + public static String CLASSPATH_COMPONENT_URI_MATCHES_ARCHIVE_URI; + public static String DUPLICATE_CLASSPATH_COMPONENT_URI; static { Index: j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/WARMessageConstants.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.core/j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/WARMessageConstants.java,v retrieving revision 1.1 diff -u -r1.1 WARMessageConstants.java --- j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/WARMessageConstants.java 24 Nov 2004 04:35:57 -0000 1.1 +++ j2ee-validation/org/eclipse/jst/j2ee/model/internal/validation/WARMessageConstants.java 9 Jan 2007 19:04:50 -0000 @@ -52,6 +52,8 @@ public static final String ERROR_EAR_DUPLICATE_ROLES = "ERROR_EAR_DUPLICATE_ROLES"; //$NON-NLS-1$ public static final String ERROR_EAR_UNCONTAINED_MODULE_FILE_EXCEPTION = "ERROR_EAR_UNCONTAINED_MODULE_FILE_EXCEPTION"; //$NON-NLS-1$ public static final String ERROR_INVALID_WAR_FILE = "ERROR_INVALID_WAR_FILE"; //$NON-NLS-1$ + public static final String ERROR_DUPLICATE_WEB_INF_LIB= "ERROR_DUPLICATE_WEB_INF_LIB"; //$NON-NLS-1$ + public static final String ERROR_DUPLICATE_WEB_INF_LIB_OTHER_PROJECT = "ERROR_DUPLICATE_WEB_INF_LIB_OTHER_PROJECT"; //$NON-NLS-1$ public static final String WAR_DD_PARSE_LINECOL = "WAR_DD_PARSE_LINECOL"; //$NON-NLS-1$ public static final String WAR_DD_PARSE_LINE = "WAR_DD_PARSE_LINE"; //$NON-NLS-1$ public static final String WAR_DD_CANNOT_OPEN_DD = "WAR_DD_CANNOT_OPEN_DD"; //$NON-NLS-1$ #P org.eclipse.jst.j2ee.ui Index: j2ee_ui/org/eclipse/jst/j2ee/internal/AvailableJ2EEComponentsForEARContentProvider.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.ui/j2ee_ui/org/eclipse/jst/j2ee/internal/AvailableJ2EEComponentsForEARContentProvider.java,v retrieving revision 1.12 diff -u -r1.12 AvailableJ2EEComponentsForEARContentProvider.java --- j2ee_ui/org/eclipse/jst/j2ee/internal/AvailableJ2EEComponentsForEARContentProvider.java 10 May 2006 17:01:14 -0000 1.12 +++ j2ee_ui/org/eclipse/jst/j2ee/internal/AvailableJ2EEComponentsForEARContentProvider.java 9 Jan 2007 19:04:52 -0000 @@ -22,17 +22,21 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; import org.eclipse.jem.util.logger.proxy.Logger; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jst.j2ee.componentcore.ClasspathComponentDependencyUtil; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.componentcore.util.EARArtifactEdit; import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil; import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; import org.eclipse.swt.graphics.Image; import org.eclipse.wst.common.componentcore.ComponentCore; import org.eclipse.wst.common.componentcore.ModuleCoreNature; +import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualComponent; import org.eclipse.wst.common.componentcore.resources.IVirtualReference; @@ -87,7 +91,9 @@ validCompList.add(referencedcomp); //validCompList.add(referencedcomp.getProject()); //IPath path = ComponentUtilities.getResolvedPathForArchiveComponent(name); - } + } else { + addClasspathComponentDependencies(validCompList, referencedcomp); + } } } } @@ -104,6 +110,21 @@ return validCompList.toArray(); } + public static void addClasspathComponentDependencies(final List componentList, final IVirtualComponent referencedComponent) { + if (referencedComponent instanceof J2EEModuleVirtualComponent) { + J2EEModuleVirtualComponent j2eeComp = (J2EEModuleVirtualComponent) referencedComponent; + IVirtualReference[] cpRefs = j2eeComp.getJavaClasspathReferences(); + for (int j=0; j < cpRefs.length; j++) { + String unresolvedURI = null; + // only / mappings supported at this level + if (!cpRefs[j].getRuntimePath().equals(Path.ROOT)) { + continue; + } + componentList.add(cpRefs[j].getReferencedComponent()); + } + } + } + /* * (non-Javadoc) * @@ -123,6 +144,9 @@ IVirtualComponent comp = (IVirtualComponent)element; String name = ""; //$NON-NLS-1$ if( columnIndex == 0 ){ + if (ClasspathComponentDependencyUtil.isClasspathComponentDependency(comp)) { + return ClasspathComponentDependencyUtil.getClasspathComponentDependencyDisplayString(comp); + } EARArtifactEdit earEdit = null; try{ earEdit = EARArtifactEdit.getEARArtifactEditForRead(earComponent.getProject()); Index: j2ee_ui/org/eclipse/jst/j2ee/internal/AddModulestoEARPropertiesPage.java =================================================================== RCS file: /cvsroot/webtools/jst/components/j2ee/plugins/org.eclipse.jst.j2ee.ui/j2ee_ui/org/eclipse/jst/j2ee/internal/AddModulestoEARPropertiesPage.java,v retrieving revision 1.27 diff -u -r1.27 AddModulestoEARPropertiesPage.java --- j2ee_ui/org/eclipse/jst/j2ee/internal/AddModulestoEARPropertiesPage.java 6 Nov 2006 21:36:11 -0000 1.27 +++ j2ee_ui/org/eclipse/jst/j2ee/internal/AddModulestoEARPropertiesPage.java 9 Jan 2007 19:04:52 -0000 @@ -35,6 +35,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; +import org.eclipse.emf.common.util.URI; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.ui.wizards.BuildPathDialogAccess; import org.eclipse.jem.util.logger.proxy.Logger; @@ -45,10 +46,13 @@ import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jst.j2ee.application.internal.operations.AddComponentToEnterpriseApplicationDataModelProvider; +import org.eclipse.jst.j2ee.application.internal.operations.ClasspathElement; import org.eclipse.jst.j2ee.application.internal.operations.RemoveComponentFromEnterpriseApplicationDataModelProvider; import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProperties; import org.eclipse.jst.j2ee.application.internal.operations.UpdateManifestDataModelProvider; import org.eclipse.jst.j2ee.commonarchivecore.internal.helpers.ArchiveManifest; +import org.eclipse.jst.j2ee.componentcore.ClasspathComponentDependencyUtil; +import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent; import org.eclipse.jst.j2ee.internal.common.J2EEVersionUtil; import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater; import org.eclipse.jst.j2ee.internal.plugin.J2EEUIMessages; @@ -69,8 +73,10 @@ import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.wst.common.componentcore.ComponentCore; +import org.eclipse.wst.common.componentcore.UnresolveableURIException; import org.eclipse.wst.common.componentcore.datamodel.properties.ICreateReferenceComponentsDataModelProperties; import org.eclipse.wst.common.componentcore.internal.builder.DependencyGraphManager; +import org.eclipse.wst.common.componentcore.internal.impl.ModuleURIUtil; import org.eclipse.wst.common.componentcore.internal.operation.CreateReferenceComponentsDataModelProvider; import org.eclipse.wst.common.componentcore.internal.operation.RemoveReferenceComponentsDataModelProvider; import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent; @@ -171,6 +177,9 @@ if (j2eeComponentList != null && !j2eeComponentList.isEmpty()){ for (int i = 0; i < j2eeComponentList.size(); i++){ IVirtualComponent handle = (IVirtualComponent)j2eeComponentList.get(i); + if (ClasspathComponentDependencyUtil.isClasspathComponentDependency(handle)) { + continue; + } if( !inEARAlready(handle)) newComps.add(handle); } @@ -543,7 +552,9 @@ IVirtualReference refs[] = earComponent.getReferences(); for( int i=0; i< refs.length; i++){ IVirtualReference ref = refs[i]; - list.add(ref.getReferencedComponent()); + IVirtualComponent comp = ref.getReferencedComponent(); + list.add(comp); + AvailableJ2EEComponentsForEARContentProvider.addClasspathComponentDependencies(list, comp); } return list.toArray(); } #P org.eclipse.jst.common.frameworks Index: src/org/eclipse/jst/common/jdt/internal/classpath/FlexibleProjectContainer.java =================================================================== RCS file: /cvsroot/webtools/jst/components/common/plugins/org.eclipse.jst.common.frameworks/src/org/eclipse/jst/common/jdt/internal/classpath/FlexibleProjectContainer.java,v retrieving revision 1.33 diff -u -r1.33 FlexibleProjectContainer.java --- src/org/eclipse/jst/common/jdt/internal/classpath/FlexibleProjectContainer.java 6 Nov 2006 17:52:37 -0000 1.33 +++ src/org/eclipse/jst/common/jdt/internal/classpath/FlexibleProjectContainer.java 9 Jan 2007 19:04:53 -0000 @@ -196,6 +196,10 @@ IPath newPath = null; if (comp.isBinary()) { VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp; + if (archiveComp.getArchiveType().equals(VirtualArchiveComponent.CLASSPATHARCHIVETYPE)) { + // do not process components dynamically computed from the Java classpath + continue; + } java.io.File diskFile = archiveComp.getUnderlyingDiskFile(); if (diskFile.exists()) { newPath =new Path(diskFile.getAbsolutePath());