/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.google.gdt.eclipse.suite.propertytesters;
import com.google.gdt.eclipse.core.AdapterUtilities;
import com.google.gdt.eclipse.core.CorePluginLog;
import com.google.gdt.eclipse.core.ResourceUtils;
import com.google.gdt.eclipse.core.WebAppUtilities;
import com.google.gwt.eclipse.core.launch.GWTJUnitPropertyTester;
import com.google.gwt.eclipse.core.nature.GWTNature;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.IJavaElement;
/**
* A PropertyTester applied to resources to determine if they should have a Web Application launch
* shortcut applied to them.
*
* This is the case when a selection is in a project that has the webapp nature and any of the
* following apply: the selection is the project itself, it's
* <WAR>/WEB-INF/{web.xml,appengine-web.xml}, it's an html or jsp file somewhere under the war
* directory, or it's a .gwt.xml file and the containing project has GWT nature.
*
* For legacy GWT projects, launchable resources include: the project itself, a GWT module (.gwt.xml
* file), and any .html files.
*
* FIXME: Unit tests for this. We need a com.google.gdt.eclipse.suite.test plugin first, though.
*/
public class LaunchTargetTester extends PropertyTester {
@Override
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
assert (receiver != null);
IResource resource = AdapterUtilities.getAdapter(receiver, IResource.class);
if (resource == null) {
// Unexpected case; we were asked to test against something that's
// not a resource.
return false;
}
// Resolve to the actual resource (if it is linked)
resource = ResourceUtils.resolveTargetResource(resource);
try {
return (isGaeOrGwtProject(resource) && (resourceIsProject(resource)
|| receiverIsJavaButNotTestCase(receiver) || resourceIsDeploymentDescriptor(resource)
|| resourceIsHostPage(resource) || resourceIsGwtXmlAndInGwt(resource)));
} catch (CoreException ce) {
CorePluginLog.logError(ce);
return false;
}
}
private boolean isGaeOrGwtProject(IResource resource) {
return GWTNature.isGWTProject(resource.getProject());
}
/**
* @param receiver
* @return whether the receiver meets the conditions (e.g. java, not test)
*/
private boolean receiverIsJavaButNotTestCase(Object receiver) {
// Ensure it is a Java element
if (AdapterUtilities.getAdapter(receiver, IJavaElement.class) == null) {
return false;
}
// Ensure it is not a test case
GWTJUnitPropertyTester tester = new GWTJUnitPropertyTester();
return !tester.test(receiver, GWTJUnitPropertyTester.PROPERTY_IS_GWT_TEST, null, null);
}
/**
* Returns true if the resource is a web.xml or appengine-web.xml in the canonical location.
*
* @param resource
* @return whether the resource is a web.xml or appengine-web.xml file as expected.
*/
private boolean resourceIsDeploymentDescriptor(IResource resource) {
IProject project = resource.getProject();
if (WebAppUtilities.isWebApp(project)) {
IFolder webInf = WebAppUtilities.getWebInfSrc(project);
if (webInf.exists()) {
if (resource.getParent().equals(webInf)) {
String name = resource.getName();
return name.equals("web.xml") || name.equals("appengine-web.xml");
}
}
}
return false;
}
/**
* If the resource is a .gwt.xml file and we're in a gwt-enabled project, return true.
*
* @throws CoreException
*/
private boolean resourceIsGwtXmlAndInGwt(IResource resource) throws CoreException {
return GWTNature.isGWTProject(resource.getProject()) && resource.getName().endsWith(".gwt.xml");
}
/**
* WAR projects: Is this resource an html or jsp page under the war directory or one of its
* subdirectories? Legacy GWT projects: Is this resource an html file?
*
* @param resource
* @return whether the resource matches the specified conditions (a servable html/jsp page).
*/
private boolean resourceIsHostPage(IResource resource) {
IProject project = resource.getProject();
if (WebAppUtilities.isWebApp(project)) {
IFolder war = WebAppUtilities.getWarSrc(project);
if (war != null) {
if (war.getFullPath().isPrefixOf(resource.getFullPath())) {
return ResourceUtils.hasJspOrHtmlExtension(resource);
}
}
} else {
// Legacy GWT project
return "html".equalsIgnoreCase(resource.getFileExtension());
}
return false;
}
/**
* Is this resource a project?
*
* @param resource
* @return true iff the resource is a project.
*/
private boolean resourceIsProject(IResource resource) {
if (resource == null) {
return false;
}
IProject proj = resource.getProject();
boolean out = (proj == resource);
return out;
}
}