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.Date;
022:
023: import org.apache.ivy.Ivy;
024: import org.apache.ivy.core.deliver.DefaultPublishingDRResolver;
025: import org.apache.ivy.core.deliver.DeliverOptions;
026: import org.apache.ivy.core.deliver.PublishingDependencyRevisionResolver;
027: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
028: import org.apache.ivy.core.module.id.ModuleRevisionId;
029: import org.apache.ivy.core.module.status.StatusManager;
030: import org.apache.ivy.core.settings.IvySettings;
031: import org.apache.ivy.util.Message;
032: import org.apache.tools.ant.BuildException;
033: import org.apache.tools.ant.taskdefs.CallTarget;
034: import org.apache.tools.ant.taskdefs.Echo;
035: import org.apache.tools.ant.taskdefs.Input;
036: import org.apache.tools.ant.taskdefs.Property;
037:
038: /**
039: * Trigger the delivery of a module, which may consist in a recursive delivery of dependencies and
040: * on the replacement in the ivy file of dynamic revisions (like latest.integration) by static ones.
041: */
042: public class IvyDeliver extends IvyTask {
043: private final class DeliverDRResolver extends
044: DefaultPublishingDRResolver {
045: public String resolve(ModuleDescriptor published,
046: String publishedStatus, ModuleRevisionId depMrid,
047: String depStatus) {
048: if (StatusManager.getCurrent().isIntegration(
049: publishedStatus)) {
050: // published status is integration one, nothing to ask
051: return super .resolve(published, publishedStatus,
052: depMrid, depStatus);
053: }
054:
055: // we are publishing a delivery (a non integration module)
056:
057: if (!StatusManager.getCurrent().isIntegration(depStatus)) {
058: // dependency is already a delivery, nothing to ask
059: return super .resolve(published, publishedStatus,
060: depMrid, depStatus);
061: }
062:
063: // the dependency is not a delivery
064:
065: String statusProperty = depMrid.getName() + "."
066: + depMrid.getRevision() + ".status";
067: String versionProperty = depMrid.getName() + "."
068: + depMrid.getRevision() + ".version";
069: String deliveredProperty = depMrid.getName() + "."
070: + depMrid.getRevision() + ".delivered";
071:
072: String version = getProject().getProperty(versionProperty);
073: String status = getProject().getProperty(statusProperty);
074: String delivered = getProject().getProperty(
075: deliveredProperty);
076: Message.debug("found version = " + version + " status="
077: + status + " delivered=" + delivered);
078: if (version != null && status != null) {
079: if ("true".equals(delivered)) {
080: // delivery has already been done : just return the value
081: return version;
082: } else {
083: deliverDependency(depMrid, version, status,
084: depStatus);
085: loadDeliveryList();
086: return version;
087: }
088: }
089:
090: /**
091: * By setting these properties: recursive.delivery.status and
092: * recursive.delivery.version, then if the specific status/version is not found, then we
093: * will use the status/version set in these global properties. This will apply to all
094: * artifacts in the system. This patch is meant to be used for recursive deliveries so
095: * that all deliveries will use the global status/version unless a more specific one is
096: * set.
097: */
098: String globalStatusProperty = "recursive.delivery.status";
099: String globalVersionProperty = "recursive.delivery.version";
100: version = getProject().getProperty(globalVersionProperty);
101: status = getProject().getProperty(globalStatusProperty);
102: if (version != null && status != null) {
103: // found global delivery properties
104: delivered = getProject()
105: .getProperty(
106: "recursive." + depMrid.getName()
107: + ".delivered");
108: Message.debug("found global version = " + version
109: + " and global status=" + status
110: + " - delivered = " + delivered);
111: if ("true".equals(delivered)) {
112: // delivery has already been done : just return the value
113: return version;
114: } else {
115: getProject().setProperty(statusProperty, status);
116: deliverDependency(depMrid, version, status,
117: depStatus);
118: loadDeliveryList();
119: return version;
120: }
121: }
122:
123: // we must ask the user what version and status he want to have
124: // for the dependency
125: Input input = (Input) getProject().createTask("input");
126: input.setOwningTarget(getOwningTarget());
127: input.init();
128:
129: // ask status
130: input.setMessage(depMrid.getName() + " "
131: + depMrid.getRevision()
132: + ": please enter a status: ");
133: input.setValidargs(StatusManager.getCurrent()
134: .getDeliveryStatusListString());
135: input.setAddproperty(statusProperty);
136: input.perform();
137: status = getProject().getProperty(statusProperty);
138: appendDeliveryList(statusProperty + " = " + status);
139:
140: // ask version
141: input.setMessage(depMrid.getName() + " "
142: + depMrid.getRevision()
143: + ": please enter a version: ");
144: input.setValidargs(null);
145: input.setAddproperty(versionProperty);
146: input.perform();
147:
148: version = getProject().getProperty(versionProperty);
149: appendDeliveryList(versionProperty + " = " + version);
150: deliverDependency(depMrid, version, status, depStatus);
151:
152: loadDeliveryList();
153:
154: return version;
155: }
156:
157: public void deliverDependency(ModuleRevisionId depMrid,
158: String version, String status, String depStatus) {
159: // call deliver target if any
160: if (deliverTarget != null
161: && deliverTarget.trim().length() > 0) {
162:
163: CallTarget ct = (CallTarget) getProject().createTask(
164: "antcall");
165: ct.setOwningTarget(getOwningTarget());
166: ct.init();
167: ct.setTarget(deliverTarget);
168: ct.setInheritAll(true);
169: ct.setInheritRefs(true);
170: Property param = ct.createParam();
171: param.setName("dependency.name");
172: param.setValue(depMrid.getName());
173: param = ct.createParam();
174: param.setName("dependency.published.status");
175: param.setValue(status);
176: param = ct.createParam();
177: param.setName("dependency.published.version");
178: param.setValue(version);
179: param = ct.createParam();
180: param.setName("dependency.version");
181: param.setValue(depMrid.getRevision());
182: param = ct.createParam();
183: param.setName("dependency.status");
184: param.setValue(depStatus == null ? "null" : depStatus);
185:
186: ct.perform();
187:
188: String deliveredProperty = depMrid.getName() + "."
189: + depMrid.getRevision() + ".delivered";
190: getProject().setProperty(deliveredProperty, "true");
191: appendDeliveryList(deliveredProperty + " = true");
192:
193: getProject()
194: .setProperty(
195: "recursive." + depMrid.getName()
196: + ".delivered", "true");
197: appendDeliveryList("recursive." + depMrid.getName()
198: + ".delivered" + " = true");
199: }
200: }
201:
202: }
203:
204: private String organisation;
205:
206: private String module;
207:
208: private String revision;
209:
210: private String pubRevision;
211:
212: private String deliverpattern;
213:
214: private String status;
215:
216: private String pubdate;
217:
218: private String deliverTarget;
219:
220: private File deliveryList;
221:
222: private boolean replacedynamicrev = true;
223:
224: private String resolveId;
225:
226: private String conf;
227:
228: public void setCache(File cache) {
229: cacheAttributeNotSupported();
230: }
231:
232: public String getDeliverpattern() {
233: return deliverpattern;
234: }
235:
236: public void setDeliverpattern(String destivypattern) {
237: this .deliverpattern = destivypattern;
238: }
239:
240: public String getModule() {
241: return module;
242: }
243:
244: public void setModule(String module) {
245: this .module = module;
246: }
247:
248: public String getOrganisation() {
249: return organisation;
250: }
251:
252: public void setOrganisation(String organisation) {
253: this .organisation = organisation;
254: }
255:
256: public String getPubdate() {
257: return pubdate;
258: }
259:
260: public void setPubdate(String pubdate) {
261: this .pubdate = pubdate;
262: }
263:
264: public String getPubrevision() {
265: return pubRevision;
266: }
267:
268: public void setPubrevision(String pubRevision) {
269: this .pubRevision = pubRevision;
270: }
271:
272: public String getRevision() {
273: return revision;
274: }
275:
276: public void setRevision(String revision) {
277: this .revision = revision;
278: }
279:
280: public String getStatus() {
281: return status;
282: }
283:
284: public void setStatus(String status) {
285: this .status = status;
286: }
287:
288: public void setDelivertarget(String deliverTarget) {
289: this .deliverTarget = deliverTarget;
290: }
291:
292: public void setDeliveryList(File deliveryList) {
293: this .deliveryList = deliveryList;
294: }
295:
296: public boolean isReplacedynamicrev() {
297: return replacedynamicrev;
298: }
299:
300: public void setReplacedynamicrev(boolean replacedynamicrev) {
301: this .replacedynamicrev = replacedynamicrev;
302: }
303:
304: public String getResolveId() {
305: return resolveId;
306: }
307:
308: public void setResolveId(String resolveId) {
309: this .resolveId = resolveId;
310: }
311:
312: public String getConf() {
313: return conf;
314: }
315:
316: public void setConf(String confs) {
317: conf = confs;
318: }
319:
320: public void doExecute() throws BuildException {
321: Ivy ivy = getIvyInstance();
322: IvySettings settings = ivy.getSettings();
323:
324: organisation = getProperty(organisation, settings,
325: "ivy.organisation", resolveId);
326: module = getProperty(module, settings, "ivy.module", resolveId);
327: revision = getProperty(revision, settings, "ivy.revision",
328: resolveId);
329: pubRevision = getProperty(pubRevision, settings,
330: "ivy.deliver.revision");
331: deliverpattern = getProperty(deliverpattern, settings,
332: "ivy.deliver.ivy.pattern");
333: status = getProperty(status, settings, "ivy.status");
334: if (deliveryList == null) {
335: String deliveryListPath = getProperty(settings,
336: "ivy.delivery.list.file");
337: if (deliveryListPath == null) {
338: deliveryList = new File(System
339: .getProperty("java.io.tmpdir")
340: + "/delivery.properties");
341: } else {
342: deliveryList = getProject().resolveFile(
343: settings.substitute(deliveryListPath));
344: }
345: }
346: if (resolveId == null) {
347: if (organisation == null) {
348: throw new BuildException(
349: "no organisation provided for ivy deliver task: "
350: + "It can either be set explicitely via the attribute 'organisation' "
351: + "or via 'ivy.organisation' property or a prior call to <resolve/>");
352: }
353: if (module == null) {
354: throw new BuildException(
355: "no module name provided for ivy deliver task: "
356: + "It can either be set explicitely via the attribute 'module' "
357: + "or via 'ivy.module' property or a prior call to <resolve/>");
358: }
359: }
360: if (revision == null) {
361: revision = Ivy.getWorkingRevision();
362: }
363: Date pubdate = getPubDate(this .pubdate, new Date());
364: if (pubRevision == null) {
365: if (revision.startsWith("working@")) {
366: pubRevision = Ivy.DATE_FORMAT.format(pubdate);
367: } else {
368: pubRevision = revision;
369: }
370: }
371: if (deliverpattern == null) {
372: throw new BuildException(
373: "deliver ivy pattern is missing: either provide it as parameters "
374: + "or through ivy.deliver.ivy.pattern properties");
375: }
376: if (status == null) {
377: throw new BuildException(
378: "no status provided: either provide it as parameter or through "
379: + "the ivy.status.default property");
380: }
381:
382: ModuleRevisionId mrid = null;
383: if (resolveId == null) {
384: mrid = ModuleRevisionId.newInstance(organisation, module,
385: revision);
386: }
387: boolean isLeading = false;
388: try {
389: if (!deliveryList.exists()) {
390: isLeading = true;
391: }
392:
393: loadDeliveryList();
394:
395: PublishingDependencyRevisionResolver drResolver;
396: if (deliverTarget != null
397: && deliverTarget.trim().length() > 0) {
398: drResolver = new DeliverDRResolver();
399: } else {
400: drResolver = new DefaultPublishingDRResolver();
401: }
402:
403: DeliverOptions options = new DeliverOptions(status,
404: pubdate, drResolver, doValidate(settings),
405: replacedynamicrev, splitConfs(conf))
406: .setResolveId(resolveId);
407: if (mrid == null) {
408: ivy.deliver(pubRevision, deliverpattern, options);
409: } else {
410: ivy.deliver(mrid, pubRevision, deliverpattern, options);
411: }
412: } catch (Exception e) {
413: throw new BuildException(
414: "impossible to deliver " + mrid == null ? resolveId
415: : mrid + ": " + e, e);
416: } finally {
417: if (isLeading) {
418: if (deliveryList.exists()) {
419: deliveryList.delete();
420: }
421: }
422: }
423: }
424:
425: private void loadDeliveryList() {
426: Property property = (Property) getProject().createTask(
427: "property");
428: property.setOwningTarget(getOwningTarget());
429: property.init();
430: property.setFile(deliveryList);
431: property.perform();
432: }
433:
434: private void appendDeliveryList(String msg) {
435: Echo echo = (Echo) getProject().createTask("echo");
436: echo.setOwningTarget(getOwningTarget());
437: echo.init();
438: echo.setFile(deliveryList);
439: echo.setMessage(msg + "\n");
440: echo.setAppend(true);
441: echo.perform();
442: }
443:
444: }
|