blob: 653f1af1f18aee449de8581e030cc4fdc3a132c5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 Red Hat 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:
* Red Hat - Initial API and implementation
*******************************************************************************/
package org.eclipse.jst.j2ee.internal.common.exportmodel;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jst.common.internal.modulecore.ISingleRootStatus;
import org.eclipse.jst.common.internal.modulecore.SingleRootUtil;
import org.eclipse.jst.common.internal.modulecore.SingleRootExportParticipant.SingleRootParticipantCallback;
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.internal.J2EEConstants;
import org.eclipse.jst.j2ee.project.JavaEEProjectUtilities;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.flat.AbstractFlattenParticipant;
import org.eclipse.wst.common.componentcore.internal.flat.FilterResourceParticipant;
import org.eclipse.wst.common.componentcore.internal.flat.IFlatResource;
import org.eclipse.wst.common.componentcore.internal.flat.IFlattenParticipant;
import org.eclipse.wst.common.componentcore.internal.flat.FlatVirtualComponent.FlatComponentTaskModel;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
public class JavaEESingleRootCallback implements SingleRootParticipantCallback {
public static final int EAR_PROJECT_FOUND = 10100;
public static final int ATLEAST_1_RESOURCE_MAP_MISSING = 10101;
public static final int JAVA_OUTPUT_NOT_WEBINF_CLASSES = 10102;
public static final int RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES = 10103;
public static final int ONLY_1_CONTENT_ROOT_ALLOWED = 10104;
public static final int ONE_CONTENT_ROOT_REQUIRED = 10105;
public static final int ATLEAST_1_JAVA_SOURCE_REQUIRED = 10106;
public static final int CLASSPATH_DEPENDENCIES_FOUND = 10107;
private String[] filteredSuffixes = new String[]{};
public JavaEESingleRootCallback() {
// intentionally blank
}
public JavaEESingleRootCallback(String[] filtered) {
this.filteredSuffixes = filtered;
}
public void setFilteredSuffixes(String[] filtered) {
this.filteredSuffixes = filtered;
}
public boolean canValidate(IProject project) {
return JavaEEProjectUtilities.isEARProject(project) ||
JavaEEProjectUtilities.isDynamicWebProject(project);
}
public void validate(SingleRootUtil util, IVirtualComponent vc, IProject project, List resourceMaps) {
// Always return false for EARs so that members for EAR are always calculated and j2ee modules are filtered out
if (JavaEEProjectUtilities.isEARProject(project))
util.reportStatus(EAR_PROJECT_FOUND);
//validate web projects for single root
if (JavaEEProjectUtilities.isDynamicWebProject(project))
validateWebProject(util, vc, resourceMaps);
// If we have classpath dependencies we can't be single root
if( hasClasspathDependencies(vc))
util.reportStatus(CLASSPATH_DEPENDENCIES_FOUND);
}
protected boolean hasClasspathDependencies(IVirtualComponent component) {
try {
final Map entriesToAttrib = ClasspathDependencyUtil.getRawComponentClasspathDependencies(
JavaCoreLite.create(component.getProject()),
DependencyAttributeType.CLASSPATH_COMPONENT_DEPENDENCY);
return entriesToAttrib != null && entriesToAttrib.size() > 0;
} catch( CoreException ce ) {}
return false;
}
private void validateWebProject(SingleRootUtil util, IVirtualComponent vc, List resourceMaps) {
// Ensure there are only basic component resource mappings -- one for the content folder
// and any for src folders mapped to WEB-INF/classes
if (hasDefaultWebResourceMappings(util, resourceMaps)) {
IContainer[] javaOutputFolders = util.getJavaOutputFolders();
// Verify only one java output folder
if (javaOutputFolders.length == 1) {
// Verify the java output folder is to <content root>/WEB-INF/classes
IPath javaOutputPath = util.getJavaOutputFolders()[0].getProjectRelativePath();
IContainer rootContainer = vc.getRootFolder().getUnderlyingFolder();
IPath compRootPath = rootContainer.getProjectRelativePath();
if (compRootPath.append(J2EEConstants.WEB_INF_CLASSES).equals(javaOutputPath)) {
util.reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, rootContainer);
return;
}
util.reportStatus(JAVA_OUTPUT_NOT_WEBINF_CLASSES);
}
else {
util.reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
}
}
}
/**
* Ensure the default web setup is correct with one resource map and any number of java
* resource maps to WEB-INF/classes
*
* @param resourceMaps
* @return boolean
*/
private boolean hasDefaultWebResourceMappings(SingleRootUtil util, List resourceMaps) {
int rootValidMaps = 0;
IPath webInfClasses = new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
for (int i = 0; i < resourceMaps.size(); i++) {
ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
IPath sourcePath = resourceMap.getSourcePath();
IPath runtimePath = resourceMap.getRuntimePath();
IResource sourceResource = util.getProject().findMember(sourcePath);
// Verify if the map is for the content root
if (util.isRootMapping(resourceMap)) {
rootValidMaps++;
}
// Verify if the map is for a java src folder and is mapped to "WEB-INF/classes"
else if (runtimePath.equals(webInfClasses)) {
if (sourceResource != null && sourceResource.exists()) {
if (sourceResource instanceof IContainer && !util.isSourceContainer((IContainer) sourceResource)) {
util.reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, sourcePath);
return false;
}
}
else {
util.reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, sourcePath);
return false;
}
}
else {
util.reportStatus(RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES, runtimePath);
return false;
}
}
// Make sure only one of the maps is the content root, and that at least one is for the java folder
if (rootValidMaps != 1) {
if (rootValidMaps < 1) {
util.reportStatus(ONE_CONTENT_ROOT_REQUIRED);
return false;
}
else if (rootValidMaps > 1) {
util.reportStatus(ONLY_1_CONTENT_ROOT_ALLOWED);
return false;
}
}
return true;
}
public IFlattenParticipant[] getDelegateParticipants() {
return new IFlattenParticipant[] {
createManifestFinalizer(),
FilterResourceParticipant.createSuffixFilterParticipant(filteredSuffixes)
};
}
public IFlattenParticipant createManifestFinalizer() {
return new AbstractFlattenParticipant() {
@Override
public void finalize(IVirtualComponent component,
FlatComponentTaskModel dataModel, List<IFlatResource> resources) {
new ReplaceManifestExportParticipant().forceUpdate(component, dataModel, resources);
}
};
}
}