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.text.DateFormat;
021: import java.text.SimpleDateFormat;
022: import java.util.Date;
023: import java.util.Locale;
024:
025: import org.apache.ivy.Ivy;
026: import org.apache.ivy.core.IvyContext;
027: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
028: import org.apache.ivy.core.report.ResolveReport;
029: import org.apache.ivy.core.settings.IvySettings;
030: import org.apache.ivy.util.Message;
031: import org.apache.ivy.util.StringUtils;
032: import org.apache.tools.ant.BuildException;
033: import org.apache.tools.ant.Task;
034: import org.apache.tools.ant.types.Reference;
035:
036: /**
037: * Base class for all ivy ant tasks, deal particularly with ivy instance storage in ant project.
038: */
039: public abstract class IvyTask extends Task {
040: public static final String ANT_PROJECT_CONTEXT_KEY = "ant-project";
041:
042: private Boolean validate = null;
043:
044: private Reference antIvyEngineRef = null;
045:
046: protected boolean doValidate(IvySettings ivy) {
047: if (validate != null) {
048: return validate.booleanValue();
049: }
050: return ivy.doValidate();
051: }
052:
053: public boolean isValidate() {
054: return validate == null ? true : validate.booleanValue();
055: }
056:
057: public void setValidate(boolean validate) {
058: this .validate = Boolean.valueOf(validate);
059: }
060:
061: public void setSettingsRef(Reference ref) {
062: antIvyEngineRef = ref;
063: }
064:
065: public Reference getSettingsRef() {
066: return antIvyEngineRef;
067: }
068:
069: protected IvySettings getSettings() {
070: return getIvyInstance().getSettings();
071: }
072:
073: protected Ivy getIvyInstance() {
074: Object antIvyEngine;
075: if (antIvyEngineRef != null) {
076: antIvyEngine = antIvyEngineRef
077: .getReferencedObject(getProject());
078: if (!antIvyEngine.getClass().getName().equals(
079: IvyAntSettings.class.getName())) {
080: throw new BuildException(antIvyEngineRef.getRefId()
081: + " doesn't reference an ivy:settings",
082: getLocation());
083: }
084: if (!(antIvyEngine instanceof IvyAntSettings)) {
085: throw new BuildException(
086: antIvyEngineRef.getRefId()
087: + " has been defined in a different classloader. "
088: + "Please use the same loader when defining your task, or "
089: + "redeclare your ivy:settings in this classloader",
090: getLocation());
091: }
092: } else {
093: antIvyEngine = IvyAntSettings
094: .getDefaultInstance(getProject());
095: }
096: Ivy ivy = ((IvyAntSettings) antIvyEngine)
097: .getConfiguredIvyInstance();
098: AntMessageLogger.register(this , ivy);
099: return ivy;
100: }
101:
102: protected void setResolved(ResolveReport report, boolean keep) {
103: ModuleDescriptor md = report.getModuleDescriptor();
104: String[] confs = report.getConfigurations();
105: if (keep) {
106: getProject().addReference("ivy.resolved.report", report);
107: getProject().addReference(
108: "ivy.resolved.configurations.ref", confs);
109: getProject().addReference("ivy.resolved.descriptor", md);
110: }
111: String suffix = md.getModuleRevisionId().getModuleId()
112: .getOrganisation()
113: + "."
114: + md.getModuleRevisionId().getModuleId().getName();
115: getProject().addReference("ivy.resolved.report." + suffix,
116: report);
117: getProject().addReference("ivy.resolved.descriptor." + suffix,
118: md);
119: getProject().addReference(
120: "ivy.resolved.configurations.ref." + suffix, confs);
121: }
122:
123: protected void setResolved(ResolveReport report, String resolveId,
124: boolean keep) {
125: setResolved(report, keep);
126: if (resolveId != null) {
127: ModuleDescriptor md = report.getModuleDescriptor();
128: String[] confs = report.getConfigurations();
129: getProject().addReference(
130: "ivy.resolved.report." + resolveId, report);
131: getProject().addReference(
132: "ivy.resolved.descriptor." + resolveId, md);
133: getProject().addReference(
134: "ivy.resolved.configurations.ref." + resolveId,
135: confs);
136: }
137: }
138:
139: protected String[] getResolvedConfigurations(String org,
140: String module, boolean strict) {
141: return (String[]) getReference(
142: "ivy.resolved.configurations.ref", org, module, strict);
143: }
144:
145: protected Object getResolvedDescriptor(String resolveId) {
146: return getResolvedDescriptor(resolveId, true);
147: }
148:
149: protected Object getResolvedDescriptor(String resolveId,
150: boolean strict) {
151: Object result = getProject().getReference(
152: "ivy.resolved.descriptor." + resolveId);
153: if (strict && (result == null)) {
154: throw new BuildException(
155: "ModuleDescriptor for resolve with id '"
156: + resolveId + "' not found.");
157: }
158: return result;
159: }
160:
161: protected Object getResolvedDescriptor(String org, String module) {
162: return getResolvedDescriptor(org, module, false);
163: }
164:
165: protected Object getResolvedDescriptor(String org, String module,
166: boolean strict) {
167: return getReference("ivy.resolved.descriptor", org, module,
168: strict);
169: }
170:
171: private Object getReference(String prefix, String org,
172: String module, boolean strict) {
173: Object reference = null;
174: if (org != null && module != null) {
175: reference = getProject().getReference(
176: prefix + "." + org + "." + module);
177: }
178: if (!strict && reference == null) {
179: reference = getProject().getReference(prefix);
180: }
181: return reference;
182: }
183:
184: protected ResolveReport getResolvedReport(String org,
185: String module, String resolveId) {
186: ResolveReport result = null;
187:
188: if (resolveId == null) {
189: result = (ResolveReport) getReference(
190: "ivy.resolved.report", org, module, false);
191: } else {
192: result = (ResolveReport) getReference(
193: "ivy.resolved.report." + resolveId, null, null,
194: false);
195: }
196:
197: return result;
198: }
199:
200: protected String[] splitConfs(String conf) {
201: if (conf == null) {
202: return null;
203: }
204: String[] confs = conf.split(",");
205: for (int i = 0; i < confs.length; i++) {
206: confs[i] = confs[i].trim();
207: }
208: return confs;
209: }
210:
211: protected String mergeConfs(String[] conf) {
212: return StringUtils.join(conf, ", ");
213: }
214:
215: private static final DateFormat DATE_FORMAT = new SimpleDateFormat(
216: "yyyyMMddHHmmss");
217:
218: protected Date getPubDate(String date, Date def) {
219: if (date != null) {
220: if ("now".equals(date.toLowerCase(Locale.US))) {
221: return new Date();
222: }
223: try {
224: return DATE_FORMAT.parse(date);
225: } catch (Exception ex) {
226: throw new BuildException(
227: "publication date provided in bad format. should be yyyyMMddHHmmss and not "
228: + date);
229: }
230: } else {
231: return def;
232: }
233: }
234:
235: protected String getProperty(String value, IvySettings ivy,
236: String name) {
237: if (value == null) {
238: return getProperty(ivy, name);
239: } else {
240: value = ivy.substitute(value);
241: Message.debug("parameter found as attribute value: " + name
242: + "=" + value);
243: return value;
244: }
245: }
246:
247: protected String getProperty(String value, IvySettings ivy,
248: String name, String resolveId) {
249: if (resolveId == null) {
250: return getProperty(value, ivy, name);
251: } else {
252: return getProperty(value, ivy, name + "." + resolveId);
253: }
254: }
255:
256: protected String getProperty(IvySettings ivy, String name,
257: String resolveId) {
258: if (resolveId == null) {
259: return getProperty(ivy, name);
260: } else {
261: return getProperty(ivy, name + "." + resolveId);
262: }
263: }
264:
265: protected String getProperty(IvySettings ivy, String name) {
266: String val = ivy.getVariable(name);
267: if (val == null) {
268: val = ivy.substitute(getProject().getProperty(name));
269: if (val != null) {
270: Message
271: .debug("parameter found as ant project property: "
272: + name + "=" + val);
273: } else {
274: Message.debug("parameter not found: " + name);
275: }
276: } else {
277: val = ivy.substitute(val);
278: Message.debug("parameter found as ivy variable: " + name
279: + "=" + val);
280: }
281: return val;
282: }
283:
284: /**
285: * Called when task starts its execution.
286: */
287: protected void prepareTask() {
288: // push current project and Ivy on the stack in context
289: IvyContext.pushNewCopyContext();
290: IvyContext.getContext().setIvy(getIvyInstance());
291: IvyContext.getContext().push(ANT_PROJECT_CONTEXT_KEY,
292: getProject());
293: }
294:
295: /**
296: * Called when task is about to finish Should clean up all state related information (stacks for
297: * example)
298: */
299: protected void finalizeTask() {
300: if (!IvyContext.getContext().pop(ANT_PROJECT_CONTEXT_KEY,
301: getProject())) {
302: Message
303: .error("ANT project poped from stack not equals current !. Ignoring");
304: }
305: IvyContext.popContext();
306: }
307:
308: /**
309: * Ant task execute. Calls prepareTask, doExecute, finalzeTask
310: */
311: public final void execute() throws BuildException {
312: try {
313: prepareTask();
314: doExecute();
315: } finally {
316: finalizeTask();
317: }
318: }
319:
320: /**
321: * The real logic of task execution after project has been set in the context. MUST be
322: * implemented by subclasses
323: *
324: * @throws BuildException
325: */
326: public abstract void doExecute() throws BuildException;
327:
328: public String toString() {
329: return getClass().getName() + ":" + getTaskName();
330: }
331:
332: /**
333: * Informs the user that the cache attribute is not supported any more.
334: */
335: protected void cacheAttributeNotSupported() {
336: throw new BuildException(
337: "cache attribute is not supported any more. See IVY-685 for details.");
338: }
339:
340: }
|