blob: e10f99157e67f065bca07ccdbffc49a3c44ebed7 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}