text: // Copyright (c) 2009 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  package org.chromium.sdk;
  
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.List;
  
  /**
   * An object that describes a number-based version. A version consists of dot-separated
   * integers and an optional string addendum.
   */
  public class Version implements Comparable<Version> {
    private final List<Integer> components;
    private final String textComponent;
  
    /**
     * Constructs an immutable Version instance given the numeric components of version.
     */
    public Version(Integer ... components) {
      this(Arrays.asList(components), null);
    }
    /**
     * Constructs an immutable Version instance given the numeric components of version and optional
     * text component.
     */
    public Version(List<Integer> components, String textComponent) {
      this.components = Collections.unmodifiableList(new ArrayList<Integer>(components));
      this.textComponent = textComponent;
    }
  
  
    /**
     * @return numeric components of version in form of list of integers
     */
    public List<Integer> getComponents() {
      return components;
    }
  
    @Override
    public boolean equals(Object obj) {
      if (obj == null || !(obj instanceof Version)) {
        return false;
      }
      Version that = (Version) obj;
      return this.components.equals(that.components);
    }
  
    @Override
    public int hashCode() {
      return components.hashCode();
    }
  
    @Override
    public int compareTo(Version other) {
      for (int i = 0; i < this.components.size(); i++) {
        if (other.components.size() <= i) {
          // shorter version is less
          return +1;
        }
        int res = this.components.get(i).compareTo(other.components.get(i));
        if (res != 0) {
          return res;
        }
      }
      if (this.components.size() < other.components.size()) {
        return -1;
      } else {
        return 0;
      }
    }
  
    @Override
    public String toString() {
      if (textComponent == null) {
        return components.toString();
      } else {
        return components.toString() + textComponent;
      }
    }
  
    /**
     * Parses string as version as far as it is dot-delimited integer numbers.
     * @param text string representation of version; not null
     * @return new instance of version or null if text is not version.
     */
    public static Version parseString(String text) {
      int i = 0;
      List<Integer> components = new ArrayList<Integer>(4);
      while (i < text.length()) {
        int num = Character.digit(text.charAt(i), 10);
        if (num < 0) {
          break;
        }
        i++;
        while (i < text.length() && Character.digit(text.charAt(i), 10) >= 0) {
          num = num * 10 + Character.digit(text.charAt(i), 10);
          i++;
        }
        components.add(num);
        if (i < text.length() && text.charAt(i) == '.') {
          i++;
          continue;
        } else {
          break;
        }
      }
      String suffix;
      if (i < text.length()) {
        suffix = text.substring(i);
      } else {
        suffix = null;
      }
      if (components.isEmpty()) {
        return null;
      }
      return new Version(components, suffix);
    }
  }
  