KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > jayasoft > ivy > latest > LatestRevisionStrategy


1 /*
2  * This file is subject to the license found in LICENCE.TXT in the root directory of the project.
3  *
4  * #SNAPSHOT#
5  */

6 package fr.jayasoft.ivy.latest;
7
8 import java.util.Comparator JavaDoc;
9 import java.util.HashMap JavaDoc;
10 import java.util.Map JavaDoc;
11
12 import fr.jayasoft.ivy.ArtifactInfo;
13
14
15 public class LatestRevisionStrategy extends ComparatorLatestStrategy {
16     public static class SpecialMeaning {
17         private String JavaDoc _name;
18         private Integer JavaDoc _value;
19         public String JavaDoc getName() {
20             return _name;
21         }
22         public void setName(String JavaDoc name) {
23             _name = name;
24         }
25         public Integer JavaDoc getValue() {
26             return _value;
27         }
28         public void setValue(Integer JavaDoc value) {
29             _value = value;
30         }
31         public void validate() {
32             if (_name == null) {
33                 throw new IllegalStateException JavaDoc("a special meaning should have a name");
34             }
35             if (_value == null) {
36                 throw new IllegalStateException JavaDoc("a special meaning should have a value");
37             }
38         }
39     }
40
41     private static final Map JavaDoc DEFAULT_SPECIAL_MEANINGS;
42     static {
43         DEFAULT_SPECIAL_MEANINGS = new HashMap JavaDoc();
44         DEFAULT_SPECIAL_MEANINGS.put("dev", new Integer JavaDoc(-1));
45         DEFAULT_SPECIAL_MEANINGS.put("rc", new Integer JavaDoc(1));
46         DEFAULT_SPECIAL_MEANINGS.put("final", new Integer JavaDoc(2));
47     }
48
49     
50     /**
51      * Compares two revisions.
52      * Revisions are compared using an algorithm inspired by PHP
53      * version_compare one, unless
54      * a 'latest' revision is found. If the latest revision found
55      * is an absolute latest (latest. like), then it is assumed to be the greater.
56      * If a partial latest is found, then it is assumed to be greater
57      * than any matching fixed revision.
58      */

59     public Comparator JavaDoc COMPARATOR = new Comparator JavaDoc() {
60
61         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
62             String JavaDoc rev1 = ((ArtifactInfo)o1).getRevision();
63             String JavaDoc rev2 = ((ArtifactInfo)o2).getRevision();
64             if (rev1.startsWith("latest")) {
65                 return 1;
66             }
67             if (rev1.endsWith("+") && rev2.startsWith(rev1.substring(0, rev1.length() - 1))) {
68                 return 1;
69             }
70             if (rev2.startsWith("latest")) {
71                 return -1;
72             }
73             if (rev2.endsWith("+") && rev1.startsWith(rev2.substring(0, rev2.length() - 1))) {
74                 return -1;
75             }
76             
77             rev1 = rev1.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
78             rev1 = rev1.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
79             rev2 = rev2.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
80             rev2 = rev2.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
81             
82             String JavaDoc[] parts1 = rev1.split("[\\._\\-\\+]");
83             String JavaDoc[] parts2 = rev2.split("[\\._\\-\\+]");
84             
85             int i = 0;
86             for (; i < parts1.length && i <parts2.length; i++) {
87                 if (parts1[i].equals(parts2[i])) {
88                     continue;
89                 }
90                 boolean is1Number = isNumber(parts1[i]);
91                 boolean is2Number = isNumber(parts2[i]);
92                 if (is1Number && !is2Number) {
93                     return 1;
94                 }
95                 if (is2Number && !is1Number) {
96                     return -1;
97                 }
98                 if (is1Number && is2Number) {
99                     return Long.valueOf(parts1[i]).compareTo(Long.valueOf(parts2[i]));
100                 }
101                 // both are strings, we compare them taking into account special meaning
102
Map JavaDoc specialMeanings = getSpecialMeanings();
103                 Integer JavaDoc sm1 = (Integer JavaDoc)specialMeanings.get(parts1[i].toLowerCase());
104                 Integer JavaDoc sm2 = (Integer JavaDoc)specialMeanings.get(parts2[i].toLowerCase());
105                 if (sm1 != null) {
106                     sm2 = sm2==null?new Integer JavaDoc(0):sm2;
107                     return sm1.compareTo(sm2);
108                 }
109                 if (sm2 != null) {
110                     return new Integer JavaDoc(0).compareTo(sm2);
111                 }
112                 return parts1[i].compareTo(parts2[i]);
113             }
114             if (i < parts1.length) {
115                 return isNumber(parts1[i])?1:-1;
116             }
117             if (i < parts2.length) {
118                 return isNumber(parts2[i])?-1:1;
119             }
120             return 0;
121         }
122
123         private boolean isNumber(String JavaDoc str) {
124             return str.matches("\\d+");
125         }
126     
127     };
128     
129     private Map JavaDoc _specialMeanings = null;
130     private boolean _usedefaultspecialmeanings = true;
131     
132     public LatestRevisionStrategy() {
133         setComparator(COMPARATOR);
134         setName("latest-revision");
135     }
136     
137     public void addConfiguredSpecialMeaning(SpecialMeaning meaning) {
138         meaning.validate();
139         getSpecialMeanings().put(meaning.getName().toLowerCase(), meaning.getValue());
140     }
141
142     public synchronized Map JavaDoc getSpecialMeanings() {
143         if (_specialMeanings == null) {
144             _specialMeanings = new HashMap JavaDoc();
145             if (isUsedefaultspecialmeanings()) {
146                 _specialMeanings.putAll(DEFAULT_SPECIAL_MEANINGS);
147             }
148         }
149         return _specialMeanings;
150     }
151
152     public boolean isUsedefaultspecialmeanings() {
153         return _usedefaultspecialmeanings;
154     }
155
156     public void setUsedefaultspecialmeanings(boolean usedefaultspecialmeanings) {
157         _usedefaultspecialmeanings = usedefaultspecialmeanings;
158     }
159 }
160
Popular Tags