/* * Copyright 2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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 org.gradle.plugins.ide.eclipse.model; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import groovy.lang.Closure; import org.gradle.api.Action; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; import org.gradle.plugins.ide.api.XmlFileContentMerger; import org.gradle.plugins.ide.eclipse.model.internal.FileReferenceFactory; import org.gradle.plugins.ide.eclipse.model.internal.WtpComponentFactory; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import static org.gradle.util.ConfigureUtil.configure; /** * Enables fine-tuning wtp component details of the Eclipse plugin * <p> * Example of use with a blend of all possible properties. * Bear in mind that usually you don't have to configure them directly because Gradle configures it for free! * * <pre autoTested=''> * apply plugin: 'war' //or 'ear' or 'java' * apply plugin: 'eclipse-wtp' * * configurations { * someInterestingConfiguration * anotherConfiguration * } * * eclipse { * * //if you want parts of paths in resulting file(s) to be replaced by variables (files): * pathVariables 'GRADLE_HOME': file('/best/software/gradle'), 'TOMCAT_HOME': file('../tomcat') * * wtp { * component { * //you can configure the context path: * contextPath = 'someContextPath' * * //you can configure the deployName: * deployName = 'killerApp' * * //you can alter the wb-resource elements. sourceDirs is a ConventionProperty. * //non-existing source dirs won't be added to the component file. * sourceDirs += file('someExtraFolder') * * // dependencies to mark as deployable with lib folder deploy path * libConfigurations += [ configurations.someInterestingConfiguration ] * * // dependencies to mark as deployable with root folder deploy path * rootConfigurations += [ configurations.someInterestingConfiguration ] * * // dependencies to exclude from wtp deployment * minusConfigurations << configurations.anotherConfiguration * * //you can add a wb-resource elements; mandatory keys: 'sourcePath', 'deployPath': * //if sourcePath points to non-existing folder it will *not* be added. * resource sourcePath: 'extra/resource', deployPath: 'deployment/resource' * * //you can add a wb-property elements; mandatory keys: 'name', 'value': * property name: 'moodOfTheDay', value: ':-D' * } * } * } * </pre> * * For tackling edge cases users can perform advanced configuration on resulting XML file. * It is also possible to affect the way eclipse plugin merges the existing configuration * via beforeMerged and whenMerged closures. * <p> * beforeMerged and whenMerged closures receive {@link WtpComponent} object * <p> * Examples of advanced configuration: * * <pre autoTested=''> * apply plugin: 'war' * apply plugin: 'eclipse-wtp' * * eclipse { * * wtp { * component { * file { * //if you want to mess with the resulting XML in whatever way you fancy * withXml { * def node = it.asNode() * node.appendNode('xml', 'is what I love') * } * * //closure executed after wtp component file content is loaded from existing file * //but before gradle build information is merged * beforeMerged { wtpComponent -> * //tinker with {@link WtpComponent} here * } * * //closure executed after wtp component file content is loaded from existing file * //and after gradle build information is merged * whenMerged { wtpComponent -> * //you can tinker with the {@link WtpComponent} here * } * } * } * } * } * </pre> */ public class EclipseWtpComponent { private final Project project; private final XmlFileContentMerger file; private Set<File> sourceDirs; private Set<Configuration> rootConfigurations = Sets.newHashSet(); private Set<Configuration> libConfigurations; private Set<Configuration> minusConfigurations; private String deployName; private List<WbResource> resources = Lists.newArrayList(); private List<WbProperty> properties = Lists.newArrayList(); private String contextPath; private String classesDeployPath = "/WEB-INF/classes"; private String libDeployPath; private Map<String, File> pathVariables = Maps.newHashMap(); public EclipseWtpComponent(org.gradle.api.Project project, XmlFileContentMerger file) { this.project = project; this.file = file; } public Project getProject() { return project; } /** * See {@link #file(Action) } */ public XmlFileContentMerger getFile() { return file; } /** * Enables advanced configuration like tinkering with the output XML * or affecting the way existing wtp component file content is merged with gradle build information * <p> * The object passed to whenMerged{} and beforeMerged{} closures is of type {@link WtpComponent} * <p> * For example see docs for {@link EclipseWtpComponent} */ public void file(Closure closure) { configure(closure, file); } /** * Enables advanced configuration like tinkering with the output XML * or affecting the way existing wtp component file content is merged with gradle build information. * <p> * For example see docs for {@link EclipseWtpComponent} * * @since 3.5 */ public void file(Action<? super XmlFileContentMerger> action) { action.execute(file); } /** * {@link org.gradle.api.dsl.ConventionProperty} for the source directories to be transformed into wb-resource elements. * <p> * For examples see docs for {@link EclipseWtp} * <p> * Only source dirs that exist will be added to the wtp component file. * Non-existing resource directory declarations lead to errors when project is imported into Eclipse. */ public Set<File> getSourceDirs() { return sourceDirs; } public void setSourceDirs(Set<File> sourceDirs) { this.sourceDirs = sourceDirs; } /** * The configurations whose files are to be marked to be deployed with a deploy path of '/'. * <p> * For examples see docs for {@link EclipseWtp} */ public Set<Configuration> getRootConfigurations() { return rootConfigurations; } public void setRootConfigurations(Set<Configuration> rootConfigurations) { this.rootConfigurations = rootConfigurations; } /** * The configurations whose files are to be marked to be deployed with a deploy path of {@link #getLibDeployPath()}. * <p> * For examples see docs for {@link EclipseWtp} */ public Set<Configuration> getLibConfigurations() { return libConfigurations; } public void setLibConfigurations(Set<Configuration> libConfigurations) { this.libConfigurations = libConfigurations; } /** * Synonym for {@link #getLibConfigurations()}. */ public Set<Configuration> getPlusConfigurations() { return getLibConfigurations(); } /** * Synonym for {@link #setLibConfigurations(Set)}. */ public void setPlusConfigurations(Set<Configuration> plusConfigurations) { setLibConfigurations(plusConfigurations); } /** * The configurations whose files are to be excluded from wtp deployment. * <p> * For examples see docs for {@link EclipseWtp} */ public Set<Configuration> getMinusConfigurations() { return minusConfigurations; } public void setMinusConfigurations(Set<Configuration> minusConfigurations) { this.minusConfigurations = minusConfigurations; } /** * The deploy name to be used. * <p> * For examples see docs for {@link EclipseWtp} */ public String getDeployName() { return deployName; } public void setDeployName(String deployName) { this.deployName = deployName; } /** * {@link org.gradle.api.dsl.ConventionProperty} for additional wb-resource elements. * <p> * For examples see docs for {@link EclipseWtp} * <p> * Only resources that link to an existing directory ({@link WbResource#getSourcePath()}) * will be added to the wtp component file. * The reason is that non-existing resource directory declarations * lead to errors when project is imported into Eclipse. */ public List<WbResource> getResources() { return resources; } public void setResources(List<WbResource> resources) { this.resources = resources; } /** * Adds a wb-resource. * <p> * For examples see docs for {@link EclipseWtp} * * @param args A map that must contain a deployPath and sourcePath key with corresponding values. */ public void resource(Map<String, String> args) { resources = Lists.newArrayList(Iterables.concat(getResources(), Collections.singleton(new WbResource(args.get("deployPath"), args.get("sourcePath"))))); } /** * Additional property elements. * <p> * For examples see docs for {@link EclipseWtp} */ public List<WbProperty> getProperties() { return properties; } public void setProperties(List<WbProperty> properties) { this.properties = properties; } /** * Adds a property. * <p> * For examples see docs for {@link EclipseWtp} * * @param args A map that must contain a 'name' and 'value' key with corresponding values. */ public void property(Map<String, String> args) { properties = Lists.newArrayList(Iterables.concat(getProperties(), Collections.singleton(new WbProperty(args.get("name"), args.get("value"))))); } /** * The context path for the web application * <p> * For examples see docs for {@link EclipseWtp} */ public String getContextPath() { return contextPath; } public void setContextPath(String contextPath) { this.contextPath = contextPath; } /** * The deploy path for classes. * <p> * For examples see docs for {@link EclipseWtp} */ public String getClassesDeployPath() { return classesDeployPath; } public void setClassesDeployPath(String classesDeployPath) { this.classesDeployPath = classesDeployPath; } /** * The deploy path for libraries. * <p> * For examples see docs for {@link EclipseWtp} */ public String getLibDeployPath() { return libDeployPath; } public void setLibDeployPath(String libDeployPath) { this.libDeployPath = libDeployPath; } /** * The variables to be used for replacing absolute path in dependent-module elements. * <p> * For examples see docs for {@link EclipseModel} */ public Map<String, File> getPathVariables() { return pathVariables; } public void setPathVariables(Map<String, File> pathVariables) { this.pathVariables = pathVariables; } public FileReferenceFactory getFileReferenceFactory() { FileReferenceFactory referenceFactory = new FileReferenceFactory(); for (Map.Entry<String, File> pathVariable : pathVariables.entrySet()) { referenceFactory.addPathVariable(pathVariable.getKey(), pathVariable.getValue()); } return referenceFactory; } public void mergeXmlComponent(WtpComponent xmlComponent) { file.getBeforeMerged().execute(xmlComponent); new WtpComponentFactory(project).configure(this, xmlComponent); file.getWhenMerged().execute(xmlComponent); } }