1. /*
  2. * Copyright 2002,2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs.optional.extension;
  18. import java.util.StringTokenizer;
  19. /**
  20. * Utility class to contain version numbers in "Dewey Decimal"
  21. * syntax. Numbers in the "Dewey Decimal" syntax consist of positive
  22. * decimal integers separated by periods ".". For example, "2.0" or
  23. * "1.2.3.4.5.6.7". This allows an extensible number to be used to
  24. * represent major, minor, micro, etc versions. The version number
  25. * must begin with a number.
  26. *
  27. * @version $Revision: 1.4.2.4 $ $Date: 2004/03/09 17:01:45 $
  28. */
  29. public final class DeweyDecimal {
  30. /** Array of components that make up DeweyDecimal */
  31. private int[] components;
  32. /**
  33. * Construct a DeweyDecimal from an array of integer components.
  34. *
  35. * @param components an array of integer components.
  36. */
  37. public DeweyDecimal(final int[] components) {
  38. this.components = new int[components.length];
  39. for (int i = 0; i < components.length; i++) {
  40. this.components[i] = components[i];
  41. }
  42. }
  43. /**
  44. * Construct a DeweyDecimal from string in DeweyDecimal format.
  45. *
  46. * @param string the string in dewey decimal format
  47. * @exception NumberFormatException if string is malformed
  48. */
  49. public DeweyDecimal(final String string)
  50. throws NumberFormatException {
  51. final StringTokenizer tokenizer = new StringTokenizer(string, ".", true);
  52. final int size = tokenizer.countTokens();
  53. components = new int[ (size + 1) / 2 ];
  54. for (int i = 0; i < components.length; i++) {
  55. final String component = tokenizer.nextToken();
  56. if (component.equals("")) {
  57. throw new NumberFormatException("Empty component in string");
  58. }
  59. components[ i ] = Integer.parseInt(component);
  60. //Strip '.' token
  61. if (tokenizer.hasMoreTokens()) {
  62. tokenizer.nextToken();
  63. //If it ended in a dot, throw an exception
  64. if (!tokenizer.hasMoreTokens()) {
  65. throw new NumberFormatException("DeweyDecimal ended in a '.'");
  66. }
  67. }
  68. }
  69. }
  70. /**
  71. * Return number of components in <code>DeweyDecimal</code>.
  72. *
  73. * @return the number of components in dewey decimal
  74. */
  75. public int getSize() {
  76. return components.length;
  77. }
  78. /**
  79. * Return the component at specified index.
  80. *
  81. * @param index the index of components
  82. * @return the value of component at index
  83. */
  84. public int get(final int index) {
  85. return components[ index ];
  86. }
  87. /**
  88. * Return <code>true</code> if this <code>DeweyDecimal</code> is
  89. * equal to the other <code>DeweyDecimal</code>.
  90. *
  91. * @param other the other DeweyDecimal
  92. * @return true if equal to other DeweyDecimal, false otherwise
  93. */
  94. public boolean isEqual(final DeweyDecimal other) {
  95. final int max = Math.max(other.components.length, components.length);
  96. for (int i = 0; i < max; i++) {
  97. final int component1 = (i < components.length) ? components[ i ] : 0;
  98. final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
  99. if (component2 != component1) {
  100. return false;
  101. }
  102. }
  103. return true; // Exact match
  104. }
  105. /**
  106. * Return <code>true</code> if this <code>DeweyDecimal</code> is
  107. * less than the other <code>DeweyDecimal</code>.
  108. *
  109. * @param other the other DeweyDecimal
  110. * @return true if less than other DeweyDecimal, false otherwise
  111. */
  112. public boolean isLessThan(final DeweyDecimal other) {
  113. return !isGreaterThanOrEqual(other);
  114. }
  115. /**
  116. * Return <code>true</code> if this <code>DeweyDecimal</code> is
  117. * less than or equal to the other <code>DeweyDecimal</code>.
  118. *
  119. * @param other the other DeweyDecimal
  120. * @return true if less than or equal to other DeweyDecimal, false otherwise
  121. */
  122. public boolean isLessThanOrEqual(final DeweyDecimal other) {
  123. return !isGreaterThan(other);
  124. }
  125. /**
  126. * Return <code>true</code> if this <code>DeweyDecimal</code> is
  127. * greater than the other <code>DeweyDecimal</code>.
  128. *
  129. * @param other the other DeweyDecimal
  130. * @return true if greater than other DeweyDecimal, false otherwise
  131. */
  132. public boolean isGreaterThan(final DeweyDecimal other) {
  133. final int max = Math.max(other.components.length, components.length);
  134. for (int i = 0; i < max; i++) {
  135. final int component1 = (i < components.length) ? components[ i ] : 0;
  136. final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
  137. if (component2 > component1) {
  138. return false;
  139. }
  140. if (component2 < component1) {
  141. return true;
  142. }
  143. }
  144. return false; // Exact match
  145. }
  146. /**
  147. * Return <code>true</code> if this <code>DeweyDecimal</code> is
  148. * greater than or equal to the other <code>DeweyDecimal</code>.
  149. *
  150. * @param other the other DeweyDecimal
  151. * @return true if greater than or equal to other DeweyDecimal, false otherwise
  152. */
  153. public boolean isGreaterThanOrEqual(final DeweyDecimal other) {
  154. final int max = Math.max(other.components.length, components.length);
  155. for (int i = 0; i < max; i++) {
  156. final int component1 = (i < components.length) ? components[ i ] : 0;
  157. final int component2 = (i < other.components.length) ? other.components[ i ] : 0;
  158. if (component2 > component1) {
  159. return false;
  160. }
  161. if (component2 < component1) {
  162. return true;
  163. }
  164. }
  165. return true; // Exact match
  166. }
  167. /**
  168. * Return string representation of <code>DeweyDecimal</code>.
  169. *
  170. * @return the string representation of DeweyDecimal.
  171. */
  172. public String toString() {
  173. final StringBuffer sb = new StringBuffer();
  174. for (int i = 0; i < components.length; i++) {
  175. if (i != 0) {
  176. sb.append('.');
  177. }
  178. sb.append(components[ i ]);
  179. }
  180. return sb.toString();
  181. }
  182. }