001: /*
002: * Copyright 2007 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.workflow;
017:
018: import org.outerj.daisy.util.ObjectUtils;
019: import org.outerj.daisy.repository.*;
020:
021: import java.util.regex.Pattern;
022: import java.util.regex.Matcher;
023:
024: /**
025: * A pointer to a specific version of a document variant.
026: *
027: * <p>This object is immutable.
028: */
029: public class WfVersionKey implements Comparable {
030: private final String documentId;
031: private final long branchId;
032: private final long languageId;
033: private final String version;
034: private static final Pattern VERSION_PATTERN = Pattern
035: .compile("^([0-9]*)|(last)|(LAST)|(live)|(LIVE)$");
036:
037: /**
038: *
039: * @param version a version number, or the strings live/LIVE or last/LAST
040: */
041: public WfVersionKey(String documentId, long branchId,
042: long languageId, String version) {
043: if (documentId == null)
044: throw new IllegalArgumentException(
045: "documentId can not be null");
046: this .documentId = documentId;
047: this .branchId = branchId;
048: this .languageId = languageId;
049: if (version != null) {
050: Matcher matcher = VERSION_PATTERN.matcher(version);
051: if (!matcher.matches())
052: throw new IllegalArgumentException(
053: "Invalid version: \"" + version + "\".");
054: // normalize version representation
055: if (version.equalsIgnoreCase("last")) {
056: version = "last";
057: } else if (version.equalsIgnoreCase("live")) {
058: version = "live";
059: } else {
060: version = String.valueOf(Long.parseLong(version));
061: }
062: }
063: this .version = version;
064: }
065:
066: public String getDocumentId() {
067: return documentId;
068: }
069:
070: public long getBranchId() {
071: return branchId;
072: }
073:
074: public long getLanguageId() {
075: return languageId;
076: }
077:
078: /**
079: * Version (number or live/last), can be null.
080: */
081: public String getVersion() {
082: return version;
083: }
084:
085: public int compareTo(Object o) {
086: WfVersionKey otherKey = (WfVersionKey) o;
087: int docCompareResult = documentId
088: .compareTo(otherKey.documentId);
089: if (docCompareResult == 0) {
090: if (branchId == otherKey.branchId) {
091: if (languageId == otherKey.languageId) {
092: if (ObjectUtils.safeEquals(version,
093: otherKey.version)) {
094: return 0;
095: } else if (version == null) {
096: return -1;
097: } else if (otherKey.version == null) {
098: return 1;
099: } else {
100: return version.compareTo(otherKey.version);
101: }
102: } else if (languageId < otherKey.languageId) {
103: return -1;
104: } else {
105: return 1;
106: }
107: } else if (branchId < otherKey.branchId) {
108: return -1;
109: } else {
110: return 1;
111: }
112: } else {
113: return docCompareResult;
114: }
115: }
116:
117: public boolean equals(Object obj) {
118: if (obj == this ) {
119: return true;
120: } else if (obj instanceof WfVersionKey) {
121: WfVersionKey otherKey = (WfVersionKey) obj;
122: return (this .documentId.equals(otherKey.documentId)
123: && this .branchId == otherKey.branchId
124: && this .languageId == otherKey.languageId && ObjectUtils
125: .safeEquals(this .version, otherKey.version));
126: }
127:
128: return false;
129: }
130:
131: public int hashCode() {
132: // The calculation technique for this hashcode is taken from the HashCodeBuilder
133: // of Jakarta Commons Lang, which in itself is based on techniques from the
134: // "Effective Java" book by Joshua Bloch.
135: final int iConstant = 159;
136: int iTotal = 615;
137:
138: iTotal = iTotal * iConstant + documentId.hashCode();
139: iTotal = appendHash(branchId, iTotal, iConstant);
140: iTotal = appendHash(languageId, iTotal, iConstant);
141: if (version != null)
142: iTotal = iTotal * iConstant + version.hashCode();
143: else
144: iTotal = iTotal * iConstant;
145:
146: return iTotal;
147: }
148:
149: private int appendHash(long value, int iTotal, int iConstant) {
150: return iTotal * iConstant + ((int) (value ^ (value >> 32)));
151: }
152:
153: public String toString() {
154: return " {document ID " + documentId + ", branch ID "
155: + branchId + ", language ID " + languageId
156: + ", version " + version + "}";
157: }
158:
159: /**
160: * Gets a VariantKey equivalent to this WfVersionKey (missing the version
161: * information of course).
162: */
163: public VariantKey getVariantKey() {
164: return new VariantKey(documentId, branchId, languageId);
165: }
166:
167: /**
168: * Retrieve the document version pointed to by this key from the given repository.
169: * If the version component of this WfVersionKey is null, the last version will
170: * be returned.
171: */
172: public Version getVersion(Repository repository)
173: throws RepositoryException {
174: Document document = repository.getDocument(documentId,
175: branchId, languageId, true);
176: if (version == null || version.equalsIgnoreCase("last")) {
177: return document.getLastVersion();
178: } else if (version.equalsIgnoreCase("live")) {
179: Version version = document.getLiveVersion();
180: if (version == null)
181: throw new RepositoryException(
182: "Document does not have a live version.");
183: return version;
184: } else {
185: return document.getVersion(Long.parseLong(version));
186: }
187: }
188:
189: /**
190: * Convenience method to construct a WfVersionKey object from the given document and version string.
191: */
192: public static WfVersionKey get(Document document, String version) {
193: return new WfVersionKey(document.getId(), document
194: .getBranchId(), document.getLanguageId(), version);
195: }
196: }
|