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 org.apache.ivy.Ivy;
021: import org.apache.ivy.core.module.id.ModuleId;
022: import org.apache.ivy.core.module.id.ModuleRevisionId;
023: import org.apache.ivy.core.resolve.ResolvedModuleRevision;
024: import org.apache.ivy.core.settings.IvySettings;
025: import org.apache.tools.ant.BuildException;
026:
027: /**
028: * Look for the latest module in the repository matching the given criteria, and sets a set of
029: * properties according to what was found.
030: */
031: public class IvyBuildNumber extends IvyTask {
032: private String organisation;
033:
034: private String module;
035:
036: private String branch;
037:
038: private String revision;
039:
040: private String revSep = ".";
041:
042: private String prefix = "ivy.";
043:
044: private String defaultValue = "0";
045:
046: private String defaultBuildNumber = "0";
047:
048: public String getModule() {
049: return module;
050: }
051:
052: public void setModule(String module) {
053: this .module = module;
054: }
055:
056: public String getOrganisation() {
057: return organisation;
058: }
059:
060: public void setOrganisation(String organisation) {
061: this .organisation = organisation;
062: }
063:
064: public String getRevision() {
065: return revision;
066: }
067:
068: public void setRevision(String revision) {
069: this .revision = revision;
070: }
071:
072: public String getBranch() {
073: return branch;
074: }
075:
076: public void setBranch(String branch) {
077: this .branch = branch;
078: }
079:
080: public String getDefault() {
081: return defaultValue;
082: }
083:
084: public void setDefault(String default1) {
085: defaultValue = default1;
086: }
087:
088: public String getPrefix() {
089: return prefix;
090: }
091:
092: public void setPrefix(String prefix) {
093: this .prefix = prefix;
094: }
095:
096: public void doExecute() throws BuildException {
097: if (organisation == null) {
098: throw new BuildException(
099: "no organisation provided for ivy findmodules");
100: }
101: if (module == null) {
102: throw new BuildException(
103: "no module name provided for ivy findmodules");
104: }
105: if (prefix == null) {
106: throw new BuildException("null prefix not allowed");
107: }
108:
109: Ivy ivy = getIvyInstance();
110: IvySettings settings = ivy.getSettings();
111: if (branch == null) {
112: settings
113: .getDefaultBranch(new ModuleId(organisation, module));
114: }
115: if (revision == null || revision.length() == 0) {
116: revision = "latest.integration";
117: } else if (!revision.endsWith("+")) {
118: revision = revision + "+";
119: }
120: if (!prefix.endsWith(".") && prefix.length() > 0) {
121: prefix = prefix + ".";
122: }
123: ResolvedModuleRevision rmr = ivy.findModule(ModuleRevisionId
124: .newInstance(organisation, module, branch, revision));
125: String revision = rmr == null ? null : rmr.getId()
126: .getRevision();
127: NewRevision newRevision = computeNewRevision(revision);
128: setProperty("revision", newRevision.revision);
129: setProperty("new.revision", newRevision.newRevision);
130: setProperty("build.number", newRevision.buildNumber);
131: setProperty("new.build.number", newRevision.newBuildNumber);
132: }
133:
134: private void setProperty(String propertyName, String value) {
135: if (value != null) {
136: getProject().setProperty(prefix + propertyName, value);
137: }
138: }
139:
140: private NewRevision computeNewRevision(String revision) {
141: String revPrefix = "latest.integration".equals(this .revision) ? ""
142: : this .revision
143: .substring(0, this .revision.length() - 1);
144: if (revision != null && !revision.startsWith(revPrefix)) {
145: throw new BuildException(
146: "invalid exception found in repository: '"
147: + revision + "' for '" + revPrefix + "'");
148: }
149: if (revision == null) {
150: if (revPrefix.length() > 0) {
151: return new NewRevision(
152: revision,
153: revPrefix
154: + (revPrefix.endsWith(revSep) ? defaultBuildNumber
155: : revSep + defaultBuildNumber),
156: null, defaultBuildNumber);
157: } else {
158: Range r = findLastNumber(defaultValue);
159: if (r == null) { // no number found
160: return new NewRevision(revision, defaultValue,
161: null, null);
162: } else {
163: long n = Long.parseLong(defaultValue.substring(
164: r.startIndex, r.endIndex));
165: return new NewRevision(revision, defaultValue,
166: null, String.valueOf(n));
167: }
168: }
169: }
170: Range r;
171: if (revPrefix.length() == 0) {
172: r = findLastNumber(revision);
173: if (r == null) {
174: return new NewRevision(revision, revision
175: + (revision.endsWith(revSep) ? "1" : revSep
176: + "1"), null, "1");
177: }
178: } else {
179: r = findFirstNumber(revision, revPrefix.length());
180: if (r == null) {
181: return new NewRevision(revision, revPrefix
182: + (revPrefix.endsWith(revSep) ? "1" : revSep
183: + "1"), null, "1");
184: }
185: }
186: long n = Long.parseLong(revision.substring(r.startIndex,
187: r.endIndex)) + 1;
188: return new NewRevision(revision, revision.substring(0,
189: r.startIndex)
190: + n, String.valueOf(n - 1), String.valueOf(n));
191: }
192:
193: private Range findFirstNumber(String str, int startIndex) {
194: // let's find the first digit in the string
195: int startNumberIndex = startIndex;
196: while (startNumberIndex < str.length()
197: && !Character.isDigit(str.charAt(startNumberIndex))) {
198: startNumberIndex++;
199: }
200: if (startNumberIndex == str.length()) {
201: return null;
202: }
203: // let's find the end of the number
204: int endNumberIndex = startNumberIndex + 1;
205: while (endNumberIndex < str.length()
206: && Character.isDigit(str.charAt(endNumberIndex))) {
207: endNumberIndex++;
208: }
209: return new Range(startNumberIndex, endNumberIndex);
210: }
211:
212: private Range findLastNumber(String str) {
213: int endNumberIndex = str.length() - 1;
214: while (endNumberIndex >= 0
215: && !Character.isDigit(str.charAt(endNumberIndex))) {
216: endNumberIndex--;
217: }
218: int startNumberIndex = endNumberIndex == -1 ? -1
219: : endNumberIndex - 1;
220: while (startNumberIndex >= 0
221: && Character.isDigit(str.charAt(startNumberIndex))) {
222: startNumberIndex--;
223: }
224: endNumberIndex++;
225: startNumberIndex++;
226: if (startNumberIndex == endNumberIndex) { // no number found
227: return null;
228: } else {
229: return new Range(startNumberIndex, endNumberIndex);
230: }
231: }
232:
233: private static class Range {
234: private int startIndex;
235:
236: private int endIndex;
237:
238: public Range(int startIndex, int endIndex) {
239: this .startIndex = startIndex;
240: this .endIndex = endIndex;
241: }
242: }
243:
244: private static class NewRevision {
245: private String revision;
246:
247: private String newRevision;
248:
249: private String buildNumber;
250:
251: private String newBuildNumber;
252:
253: public NewRevision(String revision, String newRevision,
254: String buildNumber, String newBuildNumber) {
255: this .revision = revision;
256: this .newRevision = newRevision;
257: this .buildNumber = buildNumber;
258: this .newBuildNumber = newBuildNumber;
259: }
260: }
261:
262: public String getRevSep() {
263: return revSep;
264: }
265:
266: public void setRevSep(String revSep) {
267: this .revSep = revSep;
268: }
269:
270: public String getDefaultBuildNumber() {
271: return defaultBuildNumber;
272: }
273:
274: public void setDefaultBuildNumber(String defaultBuildNumber) {
275: this.defaultBuildNumber = defaultBuildNumber;
276: }
277: }
|