blob: 7f97c12f0f74dbb12053959023da12852f9fa10e [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.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyComponent;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyReceiver;
import org.eclipse.jst.common.jdt.internal.javalite.JavaCoreLite;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants.DependencyAttributeType;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualArchiveComponent;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathInitializer;
import org.eclipse.jst.j2ee.internal.common.classpath.J2EEComponentClasspathUpdater;
import org.eclipse.jst.j2ee.internal.modulecore.util.DummyClasspathDependencyContainerVirtualComponent;
import org.eclipse.jst.j2ee.internal.plugin.IJ2EEModuleConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.jee.application.ICommonModule;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.builder.IDependencyGraph;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualComponent;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualFolder;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualReference;
import org.eclipse.wst.common.componentcore.internal.util.IComponentImplFactory;
import org.eclipse.wst.common.componentcore.internal.util.VirtualReferenceUtilities;
import org.eclipse.wst.common.componentcore.resources.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;
public class EARVirtualComponent extends VirtualComponent implements IComponentImplFactory, IClasspathDependencyReceiver {
public static String [] EXTENSIONS_TO_IGNORE = new String [] {IJ2EEModuleConstants.JAR_EXT, ".zip", IJ2EEModuleConstants.RAR_EXT, IJ2EEModuleConstants.WAR_EXT }; //$NON-NLS-1$
private IVirtualReference[] cachedReferences;
private long depGraphModStamp;
public EARVirtualComponent() {
super();
}
public EARVirtualComponent(IProject aProject, IPath aRuntimePath) {
super(aProject, aRuntimePath);
}
public IVirtualComponent createArchiveComponent(IProject aProject, String archiveLocation, IPath aRuntimePath) {
return new J2EEModuleVirtualArchiveComponent(aProject, archiveLocation, aRuntimePath);
}
public IVirtualComponent createComponent(IProject aProject) {
return new EARVirtualComponent(aProject, new Path("/")); //$NON-NLS-1$
}
public IVirtualFolder createFolder(IProject aProject, IPath aRuntimePath) {
return new VirtualFolder(aProject, aRuntimePath);
}
@Override
protected boolean shouldCacheReferences() {
return true;
}
private List<IVirtualReference> getHardReferences(IVirtualComponent earComponent) {
IVirtualReference[] comparison = super.getReferences(new HashMap<String, Object>());
ArrayList<IVirtualReference> refs2 = new ArrayList<IVirtualReference>();
refs2.addAll(Arrays.asList(comparison));
return refs2;
}
@Override
protected void customizeCreatedReference(IVirtualReference reference, Object dependentObject) {
if( dependentObject instanceof ICommonModule )
reference.setArchiveName(((ICommonModule) dependentObject).getUri());
else
VirtualReferenceUtilities.INSTANCE.ensureReferencesHaveNames(new IVirtualReference[]{reference});
}
/**
* Returns the resulting list of referenced components based off the hard references and archives mapping to the root folder.
*
* @param earComponent
* @param hardReferences
* @param membersToIgnore
* @return
*/
private static List getLooseArchiveReferences(EARVirtualComponent earComponent, List hardReferences) {
return getLooseArchiveReferences(earComponent, hardReferences, null, earComponent.getRootFolder());
}
private static List getLooseArchiveReferences(EARVirtualComponent earComponent, List hardReferences, List dynamicReferences, IVirtualFolder folder) {
Map<EARVirtualComponent, List> cache = J2EEComponentClasspathInitializer.getLooseConfigCache();
if (cache != null) {
List list = cache.get(earComponent);
if (list != null) {
return list;
}
}
List list = getLooseArchiveReferences2(earComponent, hardReferences, null, folder);
if (cache != null) {
cache.put(earComponent, list);
}
return list;
}
private static List getLooseArchiveReferences2(EARVirtualComponent earComponent, List hardReferences, List dynamicReferences, IVirtualFolder folder) {
List innerDynamicReferences = dynamicReferences;
try {
IVirtualResource[] members = folder.members();
for (int i = 0; i < members.length; i++) {
if (IVirtualResource.FILE == members[i].getType()) {
if(isDynamicComponent((IVirtualFile)members[i])){
IPath archiveFullPath = new Path(members[i].getRuntimePath().toString());
boolean shouldInclude = true;
for (int j = 0; j < hardReferences.size() && shouldInclude; j++) {
IVirtualReference tmpRef = ((IVirtualReference) hardReferences.get(j));
IPath tmpFullPath = tmpRef.getRuntimePath().append(tmpRef.getArchiveName());
if( tmpFullPath.equals(archiveFullPath))
shouldInclude = false;
}
if (shouldInclude) {
IResource iResource = members[i].getUnderlyingResource();
IVirtualComponent dynamicComponent = ComponentCore.createArchiveComponent(earComponent.getProject(), VirtualArchiveComponent.LIBARCHIVETYPE + iResource.getFullPath().toString());
IVirtualReference dynamicRef = ComponentCore.createReference(earComponent, dynamicComponent);
((VirtualReference)dynamicRef).setDerived(true);
dynamicRef.setArchiveName(archiveFullPath.lastSegment());
dynamicRef.setRuntimePath(archiveFullPath.removeLastSegments(1));
if (null == innerDynamicReferences) {
innerDynamicReferences = new ArrayList();
}
innerDynamicReferences.add(dynamicRef);
}
}
} else if(IVirtualResource.FOLDER == members[i].getType()){
innerDynamicReferences = getLooseArchiveReferences2(earComponent, hardReferences, innerDynamicReferences, (IVirtualFolder)members[i]);
}
}
} catch (CoreException e) {
J2EEPlugin.logError(e);
}
return innerDynamicReferences;
}
public static boolean isDynamicComponent(IVirtualFile vFile){
String archiveName = vFile.getName();
for(int j = 0; j<EXTENSIONS_TO_IGNORE.length; j++){
if(J2EEComponentClasspathUpdater.endsWithIgnoreCase(archiveName, EXTENSIONS_TO_IGNORE[j])){
return true;
}
}
return false;
}
@Override
public IVirtualReference[] getReferences() {
IVirtualReference[] cached = getCachedReferences();
if (cached != null)
return cached;
List hardReferences = getHardReferences(this);
List dynamicReferences = getLooseArchiveReferences(this, hardReferences);
if (dynamicReferences != null) {
hardReferences.addAll(dynamicReferences);
}
cachedReferences = (IVirtualReference[]) hardReferences.toArray(new IVirtualReference[hardReferences.size()]);
return cachedReferences;
}
@Override
public IVirtualReference[] getReferences(Map<String, Object> options) {
Object refType = options.get(IVirtualComponent.REQUESTED_REFERENCE_TYPE);
if( refType != null && IVirtualComponent.DISPLAYABLE_REFERENCES.equals(refType)) {
List<IVirtualReference> hardReferences = getHardReferences(this);
if( shouldAddClasspathDependencyDerivedReference()) {
IVirtualComponent imported =
new DummyClasspathDependencyContainerVirtualComponent(getProject(), this);
VirtualReference importedRef = new VirtualReference(this, imported);
importedRef.setDependencyType(IVirtualReference.DEPENDENCY_TYPE_CONSUMES);
importedRef.setDerived(true);
hardReferences.add(importedRef);
}
return hardReferences.toArray(new IVirtualReference[hardReferences.size()]);
}
if( refType != null && (IVirtualComponent.NON_DERIVED_REFERENCES.equals(refType) ||
IVirtualComponent.HARD_REFERENCES.equals(refType))) {
List<IVirtualReference> hardReferences = getHardReferences(this);
return hardReferences.toArray(new IVirtualReference[hardReferences.size()]);
}
return getReferences();
}
protected boolean shouldAddClasspathDependencyDerivedReference() {
IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
for( int i = 0; i < projects.length; i++ ) {
try {
if( projects[i].hasNature(JavaCoreLite.NATURE_ID) && ModuleCoreNature.isFlexibleProject(projects[i])) {
Map <IClasspathEntry, IClasspathAttribute> results =
ClasspathDependencyUtil.getRawComponentClasspathDependencies(
JavaCoreLite.create(projects[i]),
DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
if( !results.isEmpty())
return true;
}
} catch(CoreException ce) {
}
}
return false;
}
// Returns cache if still valid or null
public IVirtualReference[] getCachedReferences() {
if (cachedReferences != null && checkIfStillValid())
return cachedReferences;
depGraphModStamp = IDependencyGraph.INSTANCE.getModStamp();
return null;
}
private boolean checkIfStillValid() {
return IDependencyGraph.INSTANCE.getModStamp() == depGraphModStamp;
}
@Override
protected void clearCache() {
super.clearCache();
depGraphModStamp = IDependencyGraph.INSTANCE.getModStamp();
cachedReferences = null;
}
public boolean canReceiveClasspathDependencies() {
return true;
}
public IPath getClasspathFolderPath(IClasspathDependencyComponent component) {
return Path.EMPTY;
}
}