001: package org.antmod.scm;
002:
003: import java.util.StringTokenizer;
004:
005: /**
006: * Represents the version of a module in the SCM system.
007: *
008: * @author Klaas Waslander
009: */
010: public final class ScmVersion implements Comparable {
011: public final static String VERSIONSTRING_TRUNK = "trunk";
012:
013: int major = -1;
014: int minor = -1;
015: int patch = -1;
016: String moduleName;
017:
018: /**
019: *
020: * @param versionString "modulename-revisionString", revisionString being either "trunk" or a two digit / three digit revision string.
021: */
022: public ScmVersion(String versionString) {
023: int i = versionString.indexOf("-");
024: if (i < 0) {
025: throw new IllegalArgumentException(
026: "Separator '-' missing between modulename and moduleversion");
027: }
028: this .moduleName = versionString.substring(0, i);
029: parseRevision(versionString.substring(i + 1));
030: }
031:
032: /**
033: *
034: * @param moduleName The name of the module this version applies to
035: * @param revisionString Either "trunk" or a two digit / three digit revision string.
036: */
037: public ScmVersion(String moduleName, String revisionString) {
038: this .moduleName = moduleName;
039: parseRevision(revisionString);
040: }
041:
042: /**
043: * Parses the given revision string, handling both "-" and "." as separator between the
044: * up to three digits. The revision string is also allowed to be "trunk".
045: * @param revision Either "trunk" or a two digit / three digit revision string.
046: */
047: private void parseRevision(String revision) {
048: //System.err.println("PARSE REV \"" + revision + "\"");
049: if (revision != null && !revision.equalsIgnoreCase("trunk")
050: && !revision.equalsIgnoreCase("head")) {
051: String versionSeparator = ".";
052: if (revision.indexOf("-") > 0) {
053: versionSeparator = "-";
054: }
055: StringTokenizer st = new StringTokenizer(revision,
056: versionSeparator);
057: this .major = Integer.parseInt(st.nextToken());
058: if (st.hasMoreTokens()) {
059: this .minor = Integer.parseInt(st.nextToken());
060: }
061: if (st.hasMoreTokens()) {
062: this .patch = Integer.parseInt(st.nextToken());
063: }
064: }
065: }
066:
067: public ScmVersion(String moduleName, int major, int minor, int patch) {
068: this .moduleName = moduleName;
069: this .major = major;
070: this .minor = minor;
071: this .patch = patch;
072: }
073:
074: public ScmVersion getParentBranch() {
075: if (isTrunk() || isBranch()) {
076: return getTrunkBranch();
077: } else {
078: return new ScmVersion(this .moduleName, major, minor, -1);
079: }
080: }
081:
082: public ScmVersion getTrunkBranch() {
083: return getTrunkBranch(this .moduleName);
084: }
085:
086: public static ScmVersion getTrunkBranch(String moduleName) {
087: return new ScmVersion(moduleName, -1, -1, -1);
088: }
089:
090: public ScmVersion getNextIncrement() {
091: if (this .moduleName == null
092: || this .moduleName.trim().length() == 0) {
093: throw new RuntimeException(
094: "Modulename unknown - next increment not possible.");
095: }
096:
097: if (isBranch()) {
098: return new ScmVersion(this .moduleName, major, minor + 1, -1);
099: }
100: if (isTag()) {
101: return new ScmVersion(this .moduleName, major, minor,
102: patch + 1);
103: }
104: return new ScmVersion(this .moduleName, 1, 0, -1);
105: }
106:
107: public boolean isBranch() {
108: return patch < 0 && major >= 0;
109: }
110:
111: public boolean isTag() {
112: return patch >= 0;
113: }
114:
115: public boolean isTrunk() {
116: return major < 0;
117: }
118:
119: public String getModuleName() {
120: return moduleName;
121: }
122:
123: public int getMajor() {
124: return major;
125: }
126:
127: public int getMinor() {
128: return minor;
129: }
130:
131: public int getPatch() {
132: return patch;
133: }
134:
135: public boolean equals(Object obj) {
136: if (obj instanceof ScmVersion) {
137: ScmVersion other = (ScmVersion) obj;
138: if (moduleName != null && other.getModuleName() != null) {
139: if (!moduleName.equals(other.getModuleName())) {
140: return false;
141: }
142: }
143: }
144: return toString().equals(obj.toString())
145: || (isTrunk() && obj.toString().equalsIgnoreCase(
146: "trunk"));
147: }
148:
149: public String toString() {
150: return toString('-');
151: }
152:
153: public String toString(char versionSeparator) {
154: if (major >= 0) {
155: String result = String.valueOf(major) + versionSeparator
156: + String.valueOf(minor);
157: if (patch >= 0) {
158: // String.valueOf() is very very important here: otherwise it is added as charachter value (45)...
159: result += versionSeparator + String.valueOf(patch);
160: }
161: return result;
162: } else {
163: return VERSIONSTRING_TRUNK;
164: }
165: }
166:
167: public String toFullString() {
168: return getModuleName() + "_" + toString();
169: }
170:
171: public String toFullString(char versionSeparator) {
172: return getModuleName() + "_" + toString(versionSeparator);
173: }
174:
175: public int compareTo(Object obj) {
176: if (!(obj instanceof ScmVersion)) {
177: throw new IllegalArgumentException(
178: "Cannot compare object of instance "
179: + obj.getClass() + " to ScmVersion object");
180: }
181: ScmVersion other = (ScmVersion) obj;
182: if (major > other.major)
183: return -1;
184: if (major < other.major)
185: return 1;
186: if (minor > other.minor)
187: return -1;
188: if (minor < other.minor)
189: return 1;
190: if (patch > other.patch)
191: return -1;
192: if (patch < other.patch)
193: return 1;
194: return 0;
195: }
196: }
|