001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.ivy.ant;
019:
020: import java.io.File;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Iterator;
024: import java.util.Map;
025:
026: import org.apache.ivy.core.IvyContext;
027: import org.apache.ivy.core.IvyPatternHelper;
028: import org.apache.ivy.core.event.IvyEvent;
029: import org.apache.ivy.plugins.trigger.AbstractTrigger;
030: import org.apache.ivy.plugins.trigger.Trigger;
031: import org.apache.ivy.util.Message;
032: import org.apache.tools.ant.BuildException;
033: import org.apache.tools.ant.Project;
034: import org.apache.tools.ant.taskdefs.Ant;
035: import org.apache.tools.ant.taskdefs.Property;
036:
037: /**
038: * Triggers an ant build on an event occurence.
039: * <p>
040: * Example of use:
041: *
042: * <pre>
043: * <ant-build-trigger event="pre-resolve-dependency"
044: * filter="revision=latest.integration"
045: * antfile="/path/to/[module]/build.xml"
046: * target="compile"/>
047: * </pre>
048: *
049: * Triggers an ant build for any dependency in asked in latest.integration, just before resolving
050: * the dependency.
051: *
052: * @see AntCallTrigger
053: * @since 1.4
054: */
055: public class AntBuildTrigger extends AbstractTrigger implements Trigger {
056: private boolean onlyOnce = true;
057:
058: private String target = null;
059:
060: private Collection builds = new ArrayList();
061:
062: private String buildFilePattern;
063:
064: private String prefix;
065:
066: public void progress(IvyEvent event) {
067: File f = getBuildFile(event);
068: if (f.exists()) {
069: if (onlyOnce && isBuilt(f)) {
070: Message
071: .verbose("target build file already built, skipping: "
072: + f);
073: } else {
074: Ant ant = new Ant();
075: Project project = (Project) IvyContext
076: .peekInContextStack(IvyTask.ANT_PROJECT_CONTEXT_KEY);
077: if (project == null) {
078: project = new Project();
079: project.init();
080: }
081:
082: ant.setProject(project);
083: ant.setTaskName("ant");
084:
085: ant.setAntfile(f.getAbsolutePath());
086: ant.setInheritAll(false);
087: String target = getTarget();
088: if (target != null) {
089: ant.setTarget(target);
090: }
091: Map atts = event.getAttributes();
092: for (Iterator iter = atts.keySet().iterator(); iter
093: .hasNext();) {
094: String key = (String) iter.next();
095: String value = (String) atts.get(key);
096: Property p = ant.createProperty();
097: p.setName(prefix == null ? key : prefix + key);
098: p.setValue(value);
099: }
100:
101: Message.verbose("triggering build: " + f + " target="
102: + target + " for " + event);
103: try {
104: ant.execute();
105: } catch (BuildException e) {
106: Message
107: .verbose("Exception occurred while executing target "
108: + target);
109: e.printStackTrace(); // TODO: remove when finished debugging
110: throw e;
111: }
112: markBuilt(f);
113:
114: Message.debug("triggered build finished: " + f
115: + " target=" + target + " for " + event);
116: }
117: } else {
118: Message
119: .verbose("no build file found for dependency, skipping: "
120: + f);
121: }
122: }
123:
124: private void markBuilt(File f) {
125: builds.add(f.getAbsolutePath());
126: }
127:
128: private boolean isBuilt(File f) {
129: return builds.contains(f.getAbsolutePath());
130: }
131:
132: private File getBuildFile(IvyEvent event) {
133: return new File(IvyPatternHelper.substituteTokens(
134: getBuildFilePattern(), event.getAttributes()));
135: }
136:
137: public String getBuildFilePattern() {
138: return buildFilePattern;
139: }
140:
141: public void setAntfile(String pattern) {
142: buildFilePattern = pattern;
143: }
144:
145: public String getTarget() {
146: return target;
147: }
148:
149: public void setTarget(String target) {
150: this .target = target;
151: }
152:
153: public boolean isOnlyonce() {
154: return onlyOnce;
155: }
156:
157: public void setOnlyonce(boolean onlyonce) {
158: onlyOnce = onlyonce;
159: }
160:
161: public String getPrefix() {
162: return prefix;
163: }
164:
165: public void setPrefix(String prefix) {
166: this .prefix = prefix;
167: if (!prefix.endsWith(".")) {
168: this .prefix += ".";
169: }
170: }
171: }
|