587
|
1 |
/*
|
|
2 |
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
* All rights reserved.
|
|
4 |
* This component and the accompanying materials are made available
|
|
5 |
* under the terms of the License "Eclipse Public License v1.0"
|
|
6 |
* which accompanies this distribution, and is available
|
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
*
|
|
9 |
* Initial Contributors:
|
|
10 |
* Nokia Corporation - initial contribution.
|
|
11 |
*
|
|
12 |
* Contributors:
|
|
13 |
*
|
|
14 |
* Description:
|
|
15 |
*
|
|
16 |
*/
|
|
17 |
|
|
18 |
|
|
19 |
package com.nokia.helium.scm.ant.types;
|
|
20 |
|
|
21 |
import java.util.ArrayList;
|
|
22 |
import java.util.Collections;
|
|
23 |
import java.util.Comparator;
|
|
24 |
import java.util.List;
|
|
25 |
import java.util.regex.Matcher;
|
|
26 |
import java.util.regex.Pattern;
|
|
27 |
|
|
28 |
import org.apache.tools.ant.BuildException;
|
|
29 |
import org.apache.tools.ant.Project;
|
|
30 |
|
|
31 |
/**
|
|
32 |
* The latestTag element will help you to find the latest revision based
|
|
33 |
* on a pattern.
|
|
34 |
*
|
|
35 |
* <pre>
|
|
36 |
* <latestTag name="1.0.*">
|
|
37 |
* <tagSet id="set.of.tags"/>
|
|
38 |
* latestTag
|
|
39 |
* </pre>
|
|
40 |
*
|
|
41 |
* @ant.type name="latestTag" category="SCM"
|
|
42 |
*/
|
|
43 |
public class LatestTag extends Tag {
|
|
44 |
|
|
45 |
private String pattern;
|
|
46 |
private List<TagSet> tagSets = new ArrayList<TagSet>();
|
|
47 |
|
|
48 |
/**
|
|
49 |
* Defines the pattern.
|
|
50 |
* @ant.required
|
|
51 |
*/
|
|
52 |
public void setPattern(String pattern) {
|
|
53 |
this.pattern = pattern;
|
|
54 |
}
|
|
55 |
|
|
56 |
/**
|
|
57 |
* Add a set of release to search the latest release in.
|
|
58 |
* @param tagSet
|
|
59 |
*/
|
|
60 |
public void add(TagSet tagSet) {
|
|
61 |
tagSets.add(tagSet);
|
|
62 |
}
|
|
63 |
|
|
64 |
|
|
65 |
/**
|
|
66 |
* {@inheritDoc}
|
|
67 |
*/
|
|
68 |
@Override
|
|
69 |
public String getName() {
|
628
|
70 |
if (pattern == null) {
|
587
|
71 |
throw new BuildException("'pattern' attribute has not been defined.");
|
628
|
72 |
}
|
587
|
73 |
|
|
74 |
List<Tag> tags = getCleanedList();
|
|
75 |
Collections.sort(tags, new TagComparator<Tag>(getPattern()));
|
|
76 |
|
628
|
77 |
if (tags.isEmpty()) {
|
587
|
78 |
throw new BuildException("No tag found.");
|
628
|
79 |
}
|
587
|
80 |
|
|
81 |
getProject().log("Latest tag: " + tags.get(0).getName());
|
|
82 |
return tags.get(0).getName();
|
|
83 |
}
|
|
84 |
|
|
85 |
/**
|
|
86 |
* Get a reduce set of tags, only tag matching the pattern will be
|
|
87 |
* included.
|
|
88 |
* @return the reduce list of tags.
|
|
89 |
*/
|
|
90 |
protected List<Tag> getCleanedList() {
|
|
91 |
Pattern pVer = getPattern();
|
|
92 |
List<Tag> tags = new ArrayList<Tag>();
|
|
93 |
for (Tag tag : getTags()) {
|
|
94 |
if (pVer.matcher(tag.getName()).matches()) {
|
|
95 |
tags.add(tag);
|
|
96 |
}
|
|
97 |
}
|
|
98 |
return tags;
|
|
99 |
}
|
|
100 |
|
|
101 |
/**
|
|
102 |
* Get the pattern as a regular expression.
|
|
103 |
* '*' will be transformed into (\d+) (which means only numbers
|
|
104 |
* will be considered). Other character will be quoted.
|
|
105 |
* For example:
|
|
106 |
* 1.0.* => 1\.0\.(\d+)
|
|
107 |
*
|
|
108 |
* @return the transformed pattern.
|
|
109 |
*/
|
|
110 |
protected Pattern getPattern() {
|
|
111 |
// Quoting the current pattern
|
|
112 |
getProject().log("pattern: " + pattern, Project.MSG_DEBUG);
|
|
113 |
String qVer = pattern.replaceAll("([.\\:_()])", "\\\\$1");
|
|
114 |
getProject().log("quoted: " + qVer, Project.MSG_DEBUG);
|
|
115 |
// Replacing quoted \* into \d+
|
|
116 |
qVer = qVer.replaceAll("\\*", "(\\\\d+)");
|
|
117 |
qVer = "^" + qVer + "$";
|
|
118 |
getProject().log("final: " + qVer, Project.MSG_DEBUG);
|
|
119 |
return Pattern.compile(qVer);
|
|
120 |
}
|
|
121 |
|
|
122 |
/**
|
|
123 |
* Get the list of tags, from the tagSets.
|
|
124 |
* @return a list of Tags objects.
|
|
125 |
*/
|
|
126 |
protected List<Tag> getTags() {
|
|
127 |
List<Tag> tags = new ArrayList<Tag>();
|
|
128 |
for (TagSet ts : tagSets) {
|
|
129 |
if (ts.isReference()) {
|
|
130 |
ts = (TagSet)ts.getRefid().getReferencedObject(getProject());
|
|
131 |
}
|
|
132 |
for (Tag tag : ts.getTags()) {
|
|
133 |
tags.add(tag);
|
|
134 |
}
|
|
135 |
}
|
|
136 |
return tags;
|
|
137 |
}
|
|
138 |
|
|
139 |
/**
|
|
140 |
* This class implements the comparator interface, which will help to
|
|
141 |
* order the tag compare to the pattern. For example:
|
|
142 |
* 1.0.2 > 1.0.1 (for pattern 1.0.*)
|
|
143 |
* 1.1.1 > 1.0.2 (for pattern 1.*.*)
|
|
144 |
*
|
|
145 |
* @param <T> A Tag kind of class.
|
|
146 |
*/
|
|
147 |
public class TagComparator<T extends Tag> implements Comparator<T> {
|
|
148 |
|
|
149 |
// Pattern to match for the comparison
|
|
150 |
private Pattern pVer;
|
|
151 |
|
|
152 |
/**
|
|
153 |
* Configure the Comparator with the pattern.
|
|
154 |
* @param pattern
|
|
155 |
*/
|
|
156 |
public TagComparator(Pattern pattern) {
|
|
157 |
pVer = pattern;
|
|
158 |
}
|
|
159 |
|
|
160 |
/**
|
|
161 |
* {@inheritDoc}
|
|
162 |
*/
|
|
163 |
@Override
|
|
164 |
public int compare(T o1, T o2) {
|
|
165 |
getProject().log("Comparing: " + o1.getName() + ">" + o2.getName(), Project.MSG_DEBUG);
|
|
166 |
|
628
|
167 |
if (o1.getName().equals(o2.getName())) {
|
587
|
168 |
return 0;
|
628
|
169 |
}
|
587
|
170 |
Matcher m1 = pVer.matcher(o1.getName());
|
|
171 |
Matcher m2 = pVer.matcher(o2.getName());
|
|
172 |
m1.matches();
|
|
173 |
m2.matches();
|
|
174 |
int max = (m1.groupCount() > m2.groupCount()) ? m2.groupCount() : m1.groupCount();
|
|
175 |
int i = 1;
|
|
176 |
while (i <= max) {
|
|
177 |
int i1 = Integer.decode(m1.group(i)).intValue();
|
|
178 |
int i2 = Integer.decode(m2.group(i)).intValue();
|
|
179 |
getProject().log("Comparing index " + i + ": " + i1 + " < " + i2, Project.MSG_DEBUG);
|
|
180 |
if (i1 != i2) {
|
|
181 |
return i2 - i1;
|
|
182 |
}
|
|
183 |
i++;
|
|
184 |
}
|
|
185 |
return 0;
|
|
186 |
}
|
|
187 |
}
|
|
188 |
|
|
189 |
}
|