src/jdk.jpackage/share/classes/jdk/jpackage/internal/DottedVersion.java
branchJDK-8200758-branch
changeset 58890 6539ad1d90aa
parent 58696 61c44899b4eb
equal deleted inserted replaced
58889:f04c0704a006 58890:6539ad1d90aa
    26 package jdk.jpackage.internal;
    26 package jdk.jpackage.internal;
    27 
    27 
    28 import java.util.ArrayList;
    28 import java.util.ArrayList;
    29 import java.util.List;
    29 import java.util.List;
    30 import java.util.Objects;
    30 import java.util.Objects;
       
    31 import java.util.regex.Pattern;
    31 
    32 
    32 /**
    33 /**
    33  * Dotted numeric version string.
    34  * Dotted numeric version string.
    34  * E.g.: 1.0.37, 10, 0.5
    35  * E.g.: 1.0.37, 10, 0.5
    35  */
    36  */
    36 class DottedVersion implements Comparable<String> {
    37 class DottedVersion implements Comparable<String> {
    37 
    38 
    38     public DottedVersion(String version) {
    39     public DottedVersion(String version) {
    39         components = parseVersionString(version);
    40         greedy = true;
       
    41         components = parseVersionString(version, greedy);
    40         value = version;
    42         value = version;
       
    43     }
       
    44 
       
    45     private DottedVersion(String version, boolean greedy) {
       
    46         this.greedy = greedy;
       
    47         components = parseVersionString(version, greedy);
       
    48         value = version;
       
    49     }
       
    50 
       
    51     public static DottedVersion greedy(String version) {
       
    52         return new DottedVersion(version);
       
    53     }
       
    54 
       
    55     public static DottedVersion lazy(String version) {
       
    56         return new DottedVersion(version, false);
    41     }
    57     }
    42 
    58 
    43     @Override
    59     @Override
    44     public int compareTo(String o) {
    60     public int compareTo(String o) {
    45         int result = 0;
    61         int result = 0;
    46         int[] otherComponents = parseVersionString(o);
    62         int[] otherComponents = parseVersionString(o, greedy);
    47         for (int i = 0; i < Math.min(components.length, otherComponents.length)
    63         for (int i = 0; i < Math.min(components.length, otherComponents.length)
    48                 && result == 0; ++i) {
    64                 && result == 0; ++i) {
    49             result = components[i] - otherComponents[i];
    65             result = components[i] - otherComponents[i];
    50         }
    66         }
    51 
    67 
    54         }
    70         }
    55 
    71 
    56         return result;
    72         return result;
    57     }
    73     }
    58 
    74 
    59     private static int[] parseVersionString(String version) {
    75     private static int[] parseVersionString(String version, boolean greedy) {
    60         Objects.requireNonNull(version);
    76         Objects.requireNonNull(version);
    61         if (version.isEmpty()) {
    77         if (version.isEmpty()) {
       
    78             if (!greedy) {
       
    79                 return new int[] {0};
       
    80             }
    62             throw new IllegalArgumentException("Version may not be empty string");
    81             throw new IllegalArgumentException("Version may not be empty string");
    63         }
    82         }
    64 
    83 
    65         int lastNotZeroIdx = -1;
    84         int lastNotZeroIdx = -1;
    66         List<Integer> components = new ArrayList<>();
    85         List<Integer> components = new ArrayList<>();
    67         for (var component : version.split("\\.", -1)) {
    86         for (var component : version.split("\\.", -1)) {
    68             if (component.isEmpty()) {
    87             if (component.isEmpty()) {
       
    88                 if (!greedy) {
       
    89                     break;
       
    90                 }
       
    91 
    69                 throw new IllegalArgumentException(String.format(
    92                 throw new IllegalArgumentException(String.format(
    70                         "Version [%s] contains a zero lenght component", version));
    93                         "Version [%s] contains a zero lenght component", version));
    71             }
    94             }
    72 
    95 
    73             int num = Integer.parseInt(component);
    96             if (!DIGITS.matcher(component).matches()) {
    74             if (num < 0) {
    97                 // Catch "+N" and "-N"  cases.
       
    98                 if (!greedy) {
       
    99                     break;
       
   100                 }
       
   101 
    75                 throw new IllegalArgumentException(String.format(
   102                 throw new IllegalArgumentException(String.format(
    76                         "Version [%s] contains invalid component [%s]", version,
   103                         "Version [%s] contains invalid component [%s]", version,
    77                         component));
   104                         component));
       
   105             }
       
   106 
       
   107             final int num;
       
   108             try {
       
   109                 num = Integer.parseInt(component);
       
   110             } catch (NumberFormatException ex) {
       
   111                 if (!greedy) {
       
   112                     break;
       
   113                 }
       
   114 
       
   115                 throw ex;
    78             }
   116             }
    79 
   117 
    80             if (num != 0) {
   118             if (num != 0) {
    81                 lastNotZeroIdx = components.size();
   119                 lastNotZeroIdx = components.size();
    82             }
   120             }
    86         if (lastNotZeroIdx + 1 != components.size()) {
   124         if (lastNotZeroIdx + 1 != components.size()) {
    87             // Strip trailing zeros.
   125             // Strip trailing zeros.
    88             components = components.subList(0, lastNotZeroIdx + 1);
   126             components = components.subList(0, lastNotZeroIdx + 1);
    89         }
   127         }
    90 
   128 
       
   129         if (components.isEmpty()) {
       
   130             components.add(0);
       
   131         }
    91         return components.stream().mapToInt(Integer::intValue).toArray();
   132         return components.stream().mapToInt(Integer::intValue).toArray();
    92     }
   133     }
    93 
   134 
    94     @Override
   135     @Override
    95     public String toString() {
   136     public String toString() {
    96         return value;
   137         return value;
    97     }
   138     }
    98 
   139 
    99     final private int[] components;
   140     final private int[] components;
   100     final private String value;
   141     final private String value;
       
   142     final private boolean greedy;
       
   143 
       
   144     private static final Pattern DIGITS = Pattern.compile("\\d+");
   101 }
   145 }