/*
* $Header: /home/cvs/jakarta-slide/src/share/org/apache/slide/content/NodeRevisionNumber.java,v 1.7.2.1 2004/02/05 16:05:08 mholz Exp $
* $Revision: 1.7.2.1 $
* $Date: 2004/02/05 16:05:08 $
*
* ====================================================================
*
* Copyright 1999-2002 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.slide.content;
import java.io.Serializable;
import java.util.StringTokenizer;
import org.apache.slide.common.ObjectValidationFailedException;
import org.apache.slide.util.Messages;
/**
* Node Revision Number class.
*
* @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
* @version $Revision: 1.7.2.1 $
*/
public final class NodeRevisionNumber implements Serializable, Cloneable {
// -------------------------------------------------------------- Constants
public static final int MAJOR = 0;
public static final int MINOR = 1;
// The hidden revision number is used for DeltaV-related system data
// ("version-history" and "backup" branches in VHR and VCR resources)
public static final NodeRevisionNumber HIDDEN_0_0 =
new NodeRevisionNumber( 0, 0 ); // major=0, minor=0
// ----------------------------------------------------------- Constructors
/**
* Create a new revision number.
*/
public NodeRevisionNumber() {
number = new int[2];
number[MAJOR] = 1;
number[MINOR] = 0;
}
/**
* Create a new revision number.
*
* @param major
* @param minor
*/
public NodeRevisionNumber(int major, int minor) {
number = new int[2];
number[MAJOR] = major;
number[MINOR] = minor;
}
/**
* Create a new revision number.
*
* @param revisionNumberStr String representation of the revision number
*/
public NodeRevisionNumber(String revisionNumberStr) {
parseString(revisionNumberStr);
}
/**
* Create a new revision number based on a previous revision number.
*
* @param revisionNumber Previous revision number
*/
public NodeRevisionNumber(NodeRevisionNumber revisionNumber) {
this(revisionNumber, false);
}
/**
* Create a new revision number based on a previous revision number.
*
* @param revisionNumber Previous revision number
* @param createBranch True if a new branch is to be created
*/
public NodeRevisionNumber(NodeRevisionNumber revisionNumber,
boolean createBranch) {
if (revisionNumber != null) {
if (createBranch) {
parseString(revisionNumber.toString() + ".1");
} else {
parseString(revisionNumber.toString());
next();
}
} else {
number = new int[2];
number[MAJOR] = 1;
number[MINOR] = 0;
}
}
// ----------------------------------------------------- Instance Variables
/**
* Number storage.
* <b>Note: when this array or it's content is modified, you must reset
* {@link #cachedToString} to null!</b>
*/
private int[] number;
// --------------------------------------------------------- Public Methods
/**
* Get the first number in the revision number.
*
* @return int
*/
public int getMajor() {
return number[MAJOR];
}
/**
* Get the second number in the revision number.
*
* @return int
*/
public int getMinor() {
return number[MINOR];
}
/**
* Get a number by specifying its order.
*
* @param pos Position of the number
* @return int
*/
public int getNumber(int pos) {
return number[pos];
}
/**
* Return number of digits if the revision number.
*
* @return int
*/
public int getNbDigits() {
return number.length;
}
// -------------------------------------------------------- Private Methods
/**
* Parse a String.
*
* @param revisionNumberStr String representation of the revision number
*/
private void parseString(String revisionNumberStr) {
// We tokenize the string using "." as a delimiter.
StringTokenizer tokenizer =
new StringTokenizer(revisionNumberStr, ".");
int nbDigits = tokenizer.countTokens();
if (nbDigits > 0) {
number = new int[nbDigits];
for (int i=0; i<nbDigits; i++) {
number[i] = (new Integer(tokenizer.nextToken())).intValue();
}
cachedToString=null; // reset cache
} else {
number = new int[2];
number[MAJOR] = 1;
number[MINOR] = 0;
cachedToString=null; // reset cache
}
}
/**
* Next revision.
*/
private void next() {
if (number.length > 0) {
number[number.length - 1] += 1;
cachedToString=null; // reset cache
}
}
// --------------------------------------------------------- Public Methods
/**
* Caches the result of last toString()-call. This will also heavily improve
* hashCode() as the String.hashCode() method is also buffered.
* This imust be resetet to null whenever the {@link #number} array changes.
*/
private String cachedToString;
/**
* Get a String representation of the revision number.
*
* @return String
*/
public String toString() {
if(cachedToString!=null) return cachedToString;
int count=number.length;
if(count==2) cachedToString=(number[MAJOR]+"."+number[MINOR]);
else
{
StringBuffer buf = new StringBuffer();
buf.append(number[MAJOR]);
for (int i=1; i<count; i++) {
buf.append('.').append(number[i]);
}
cachedToString=buf.toString();
}
return cachedToString;
/* old code being replaced by the cached one
StringBuffer buf = new StringBuffer();
buf.append(number[MAJOR]);
for (int i=1; i<number.length; i++) {
buf.append(".").append(number[i]);
}
return buf.toString();*/
}
/**
* HashCode.
*
* @return int
*/
public int hashCode() {
return toString().hashCode();
}
/**
* Equals.
*
* @param obj Object to test
* @return boolean True if the two object are equal :
* <li>obj is of type NodeRevisionNumber and is not null</li>
* <li>The string representations are equal are equal</li>
*/
public boolean equals(Object obj) {
boolean result = false;
if ((obj != null) && (obj instanceof NodeRevisionNumber)) {
result = (this.toString().equals(obj.toString()));
}
return result;
}
/**
* Clone.
*
* @return Object clone
*/
NodeRevisionNumber cloneObject() {
NodeRevisionNumber result = null;
try {
result = (NodeRevisionNumber) super.clone();
} catch(CloneNotSupportedException e) {
}
return result;
}
/**
* Validate.
*/
public void validate() {
if (number == null)
throw new ObjectValidationFailedException
(Messages.message
(NodeRevisionNumber.class.getName() + ".nullNumber"));
if (number.length < 2)
throw new ObjectValidationFailedException
(Messages.message
(NodeRevisionNumber.class.getName() + ".invalidNumber"));
}
}