| /******************************************************************************* |
| * Copyright (c) 2003, 2007 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.j2ee.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.IContainer; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| 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.classpathdep.ClasspathDependencyUtil; |
| 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.util.ArchiveUtil; |
| import org.eclipse.jst.j2ee.internal.J2EEConstants; |
| import org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyVirtualComponent; |
| import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities; |
| import org.eclipse.jst.j2ee.project.EarUtilities; |
| import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities; |
| import org.eclipse.wst.common.componentcore.ComponentCore; |
| import org.eclipse.wst.common.componentcore.internal.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; |
| 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; |
| |
| public class J2EEModuleVirtualComponent extends VirtualComponent implements IComponentImplFactory { |
| |
| public static String GET_JAVA_REFS = "GET_JAVA_REFS"; |
| public static String GET_FUZZY_EAR_REFS = "GET_FUZZY_EAR_REFS"; |
| |
| public J2EEModuleVirtualComponent() { |
| super(); |
| } |
| |
| public J2EEModuleVirtualComponent(IProject aProject, IPath aRuntimePath) { |
| super(aProject, aRuntimePath); |
| } |
| |
| public IVirtualComponent createComponent(IProject aProject) { |
| return new J2EEModuleVirtualComponent(aProject, new Path("/")); //$NON-NLS-1$ |
| } |
| |
| public IVirtualComponent createArchiveComponent(IProject aProject, String archiveLocation, IPath aRuntimePath) { |
| return new J2EEModuleVirtualArchiveComponent(aProject, archiveLocation, aRuntimePath); |
| } |
| |
| public IVirtualFolder createFolder(IProject aProject, IPath aRuntimePath) { |
| return new VirtualFolder(aProject, aRuntimePath); |
| } |
| |
| /** |
| * Retrieves all references except those computed dynamically from |
| * tagged Java classpath entries. |
| * @return IVirtualReferences for all non-Java classpath entry references. |
| */ |
| public IVirtualReference[] getNonJavaReferences() { |
| return getReferences(false, false); |
| } |
| |
| @Override |
| public IVirtualReference[] getReferences(Map<String, Object> options) { |
| Object objGetJavaRefs = options.get(GET_JAVA_REFS); |
| Object objGetFuzzyEarRefs = options.get(GET_FUZZY_EAR_REFS); |
| boolean getJavaRefs = objGetJavaRefs != null ? ((Boolean)objGetJavaRefs).booleanValue() : true; |
| boolean findFuzzyEARRefs = objGetFuzzyEarRefs != null ? ((Boolean)objGetFuzzyEarRefs).booleanValue() : false; |
| return getReferences(getJavaRefs, findFuzzyEARRefs); |
| } |
| |
| public IVirtualReference[] getReferences() { |
| return getReferences(true, false); |
| } |
| |
| public IVirtualReference[] getReferences(final boolean getJavaRefs, final boolean findFuzzyEARRefs) { |
| IVirtualReference[] hardReferences = getNonManifestReferences(getJavaRefs); |
| |
| // retrieve the dynamic references specified via the MANIFEST.MF classpath |
| List dynamicReferences = J2EEModuleVirtualComponent.getManifestReferences(this, hardReferences, findFuzzyEARRefs); |
| |
| IVirtualReference[] references = null; |
| if (dynamicReferences == null) { |
| references = hardReferences; |
| } else { |
| references = new IVirtualReference[hardReferences.length + dynamicReferences.size()]; |
| System.arraycopy(hardReferences, 0, references, 0, hardReferences.length); |
| for (int i = 0; i < dynamicReferences.size(); i++) { |
| references[hardReferences.length + i] = (IVirtualReference) dynamicReferences.get(i); |
| } |
| } |
| return references; |
| } |
| |
| public IVirtualReference[] getNonManifestReferences() { |
| return getNonManifestReferences(true); |
| } |
| |
| public IVirtualReference[] getNonManifestReferences(final boolean getJavaRefs) { |
| 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 |
| if (getJavaRefs) { |
| IVirtualReference[] cpRefs = getJavaClasspathReferences(hardReferences); |
| 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) { |
| String[] manifestClasspath = null; |
| if(!moduleComponent.isBinary()){ |
| IVirtualFile vManifest = moduleComponent.getRootFolder().getFile(J2EEConstants.MANIFEST_URI); |
| if (vManifest.exists()) { |
| IFile manifestFile = vManifest.getUnderlyingFile(); |
| InputStream in = null; |
| try { |
| in = manifestFile.getContents(); |
| ArchiveManifest manifest = new ArchiveManifestImpl(in); |
| manifestClasspath = manifest.getClassPathTokenized(); |
| } catch (IOException e) { |
| Logger.getLogger().logError(e); |
| } catch (CoreException e) { |
| Logger.getLogger().logError(e); |
| } finally { |
| if (in != null) { |
| try { |
| in.close(); |
| in = null; |
| } catch (IOException e) { |
| Logger.getLogger().logError(e); |
| } |
| } |
| } |
| } |
| } else { |
| manifestClasspath = ((J2EEModuleVirtualArchiveComponent)moduleComponent).getManifestClasspath(); |
| } |
| |
| return manifestClasspath; |
| |
| } |
| |
| public IVirtualReference[] getJavaClasspathReferences() { |
| return getJavaClasspathReferences(null); |
| } |
| |
| private IVirtualReference[] getJavaClasspathReferences(IVirtualReference[] hardReferences) { |
| 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 = ClasspathDependencyUtil.getComponentClasspathDependencies(javaProject, isWebApp); |
| |
| if (referencedEntries.isEmpty()) { |
| return new IVirtualReference[0]; |
| } |
| |
| if (hardReferences == null) { |
| // only compute this not set and if we have some cp dependencies |
| hardReferences = super.getReferences(); |
| } |
| final IPath[] hardRefPaths = new IPath[hardReferences.length]; |
| 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(); |
| } |
| hardRefPaths[j] = diskPath; |
| } |
| } |
| |
| IContainer[] mappedClassFolders = null; |
| final Iterator i = referencedEntries.keySet().iterator(); |
| while (i.hasNext()) { |
| final IClasspathEntry entry = (IClasspathEntry) i.next(); |
| final IClasspathAttribute attrib = (IClasspathAttribute) referencedEntries.get(entry); |
| final boolean isClassFolder = ClasspathDependencyUtil.isClassFolderEntry(entry); |
| final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp, isClassFolder); |
| boolean add = true; |
| final IPath entryLocation = ClasspathDependencyUtil.getEntryLocation(entry); |
| if (entryLocation == null) { |
| // unable to retrieve location for cp entry, do not contribute as a virtual ref |
| add = false; |
| } else if (!isClassFolder) { // check hard archive refs |
| for (int j = 0; j < hardRefPaths.length; j++) { |
| if (entryLocation.equals(hardRefPaths[j])) { |
| // entry resolves to same file as existing hard reference, can skip |
| add = false; |
| break; |
| } |
| } |
| } else { // check class folders mapped in component file as class folders associated with mapped src folders |
| if (mappedClassFolders == null) { |
| mappedClassFolders = J2EEProjectUtilities.getAllOutputContainers(getProject()); |
| } |
| for (int j = 0; j < mappedClassFolders.length; j++) { |
| if (entryLocation.equals(mappedClassFolders[j].getFullPath())) { |
| // entry resolves to same file as existing class folder mapping, skip |
| add = false; |
| break; |
| } |
| } |
| } |
| |
| if (add) { |
| String componentPath = null; |
| ClasspathDependencyVirtualComponent entryComponent = null; |
| /* |
| if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) { |
| componentPath = VirtualArchiveComponent.CLASSPATHARCHIVETYPE; |
| final IProject cpEntryProject = ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().lastSegment()); |
| entryComponent = (VirtualArchiveComponent) ComponentCore.createArchiveComponent(cpEntryProject, componentPath); |
| } else { |
| */ |
| componentPath = VirtualArchiveComponent.CLASSPATHARCHIVETYPE + IPath.SEPARATOR + entryLocation.toPortableString(); |
| entryComponent = new ClasspathDependencyVirtualComponent(project, componentPath, isClassFolder); |
| //} |
| final IVirtualReference entryReference = ComponentCore.createReference(this, entryComponent, runtimePath); |
| entryReference.setArchiveName(ClasspathDependencyUtil.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) { |
| return getManifestReferences(moduleComponent, hardReferences, false); |
| } |
| |
| public static List getManifestReferences(IVirtualComponent moduleComponent, IVirtualReference[] hardReferences, boolean findFuzzyEARRefs) { |
| List dynamicReferences = null; |
| String [] manifestClasspath = getManifestClasspath(moduleComponent); |
| |
| IVirtualReference foundRef = null; |
| String earArchiveURI = null; //The URI for this archive in the EAR |
| boolean simplePath = false; |
| |
| if (manifestClasspath != null && manifestClasspath.length > 0) { |
| boolean [] foundRefAlready = findFuzzyEARRefs ? new boolean[manifestClasspath.length]: null; |
| if(null != foundRefAlready){ |
| for(int i=0; i<foundRefAlready.length; i++){ |
| foundRefAlready[i] = false; |
| } |
| } |
| |
| IProject [] earProjects = EarUtilities.getReferencingEARProjects(moduleComponent.getProject()); |
| for (IProject earProject : earProjects) { |
| if(!JavaEEProjectUtilities.isEARProject(earProject)){ |
| continue; |
| } |
| IVirtualReference[] earRefs = null; |
| IVirtualComponent tempEARComponent = ComponentCore.createComponent(earProject); |
| IVirtualReference[] tempEarRefs = tempEARComponent.getReferences(); |
| for (int j = 0; j < tempEarRefs.length && earRefs == null; j++) { |
| if (tempEarRefs[j].getReferencedComponent().equals(moduleComponent)) { |
| earRefs = tempEarRefs; |
| foundRef = tempEarRefs[j]; |
| earArchiveURI = foundRef.getArchiveName(); |
| simplePath = earArchiveURI != null ? earArchiveURI.lastIndexOf("/") == -1 : true; //$NON-NLS-1$ |
| } |
| } |
| if (null != earRefs) { |
| for (int manifestIndex = 0; manifestIndex < manifestClasspath.length; manifestIndex++) { |
| boolean found = false; |
| if(foundRefAlready != null && foundRefAlready[manifestIndex]){ |
| continue; |
| } |
| for (int j = 0; j < earRefs.length && !found; j++) { |
| if(foundRef != earRefs[j]){ |
| String archiveName = earRefs[j].getArchiveName(); |
| if (null != archiveName){ |
| boolean shouldAdd = false; |
| if(simplePath && manifestClasspath[manifestIndex].lastIndexOf("/") == -1){ //$NON-NLS-1$ |
| shouldAdd = archiveName.equals(manifestClasspath[manifestIndex]); |
| } else { |
| String earRelativeURI = ArchiveUtil.deriveEARRelativeURI(manifestClasspath[manifestIndex], earArchiveURI); |
| if(null != earRelativeURI){ |
| shouldAdd = earRelativeURI.equals(archiveName); |
| } |
| } |
| |
| if(shouldAdd){ |
| if(findFuzzyEARRefs){ |
| foundRefAlready[manifestIndex] = true; |
| } |
| found = true; |
| boolean shouldInclude = true; |
| IVirtualComponent dynamicComponent = earRefs[j].getReferencedComponent(); |
| if(null != hardReferences){ |
| for (int k = 0; k < hardReferences.length && shouldInclude; k++) { |
| if (hardReferences[k].getReferencedComponent().equals(dynamicComponent)) { |
| shouldInclude = false; |
| } |
| } |
| } |
| if (shouldInclude) { |
| IVirtualReference dynamicReference = ComponentCore.createReference(moduleComponent, dynamicComponent); |
| if (null == dynamicReferences) { |
| dynamicReferences = new ArrayList(); |
| } |
| dynamicReferences.add(dynamicReference); |
| } |
| } |
| } |
| } |
| } |
| |
| } |
| if(!findFuzzyEARRefs){ |
| break; |
| } else { |
| boolean foundAll = true; |
| for(int i = 0; i < foundRefAlready.length && foundAll; i++){ |
| if(!foundRefAlready[i]){ |
| foundAll = false; |
| } |
| } |
| if(foundAll){ |
| break; |
| } |
| } |
| } |
| } |
| } |
| return dynamicReferences; |
| } |
| |
| } |