All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.aether.util.version.GenericVersionRange Maven / Gradle / Ivy

There is a newer version: 2.0.5
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.eclipse.aether.util.version;

import java.util.Objects;

import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionRange;
import org.eclipse.aether.version.VersionScheme;

import static java.util.Objects.requireNonNull;

/**
 * A version range inspired by mathematical range syntax. For example, "[1.0,2.0)", "[1.0,)" or "[1.0]".
 * 

* Despite its name, this class is generic in a sense it works with any {@link Version} */ final class GenericVersionRange implements VersionRange { private final VersionScheme versionScheme; private final Bound lowerBound; private final Bound upperBound; /** * Creates a version range from the specified range specification. * * @param range The range specification to parse, must not be {@code null}. * @throws InvalidVersionSpecificationException If the range could not be parsed. */ GenericVersionRange(VersionScheme versionScheme, String range) throws InvalidVersionSpecificationException { this.versionScheme = requireNonNull(versionScheme, "versionScheme cannot be null"); String process = requireNonNull(range, "version range cannot be null"); boolean lowerBoundInclusive, upperBoundInclusive; Version lowerBound, upperBound; if (range.startsWith("[")) { lowerBoundInclusive = true; } else if (range.startsWith("(")) { lowerBoundInclusive = false; } else { throw new InvalidVersionSpecificationException( range, "Invalid version range " + range + ", a range must start with either [ or ("); } if (range.endsWith("]")) { upperBoundInclusive = true; } else if (range.endsWith(")")) { upperBoundInclusive = false; } else { throw new InvalidVersionSpecificationException( range, "Invalid version range " + range + ", a range must end with either [ or ("); } process = process.substring(1, process.length() - 1); int index = process.indexOf(","); if (index < 0) { if (!lowerBoundInclusive || !upperBoundInclusive) { throw new InvalidVersionSpecificationException( range, "Invalid version range " + range + ", single version must be surrounded by []"); } String version = process.trim(); if (version.endsWith(".*")) { String prefix = version.substring(0, version.length() - 1); lowerBound = parse(prefix + "min"); upperBound = parse(prefix + "max"); } else { lowerBound = parse(version); upperBound = lowerBound; } } else { String parsedLowerBound = process.substring(0, index).trim(); String parsedUpperBound = process.substring(index + 1).trim(); // more than two bounds, e.g. (1,2,3) if (parsedUpperBound.contains(",")) { throw new InvalidVersionSpecificationException( range, "Invalid version range " + range + ", bounds may not contain additional ','"); } lowerBound = !parsedLowerBound.isEmpty() ? parse(parsedLowerBound) : null; upperBound = !parsedUpperBound.isEmpty() ? parse(parsedUpperBound) : null; if (upperBound != null && lowerBound != null) { if (upperBound.compareTo(lowerBound) < 0) { throw new InvalidVersionSpecificationException( range, "Invalid version range " + range + ", lower bound must not be greater than upper bound"); } } } this.lowerBound = (lowerBound != null) ? new Bound(lowerBound, lowerBoundInclusive) : null; this.upperBound = (upperBound != null) ? new Bound(upperBound, upperBoundInclusive) : null; } private Version parse(String version) throws InvalidVersionSpecificationException { return versionScheme.parseVersion(version); } @Override public Bound getLowerBound() { return lowerBound; } @Override public Bound getUpperBound() { return upperBound; } @Override public boolean containsVersion(Version version) { if (lowerBound != null) { int comparison = lowerBound.getVersion().compareTo(version); if (comparison == 0 && !lowerBound.isInclusive()) { return false; } if (comparison > 0) { return false; } } if (upperBound != null) { int comparison = upperBound.getVersion().compareTo(version); if (comparison == 0 && !upperBound.isInclusive()) { return false; } if (comparison < 0) { return false; } } return true; } @Override public boolean equals(Object obj) { if (obj == this) { return true; } else if (obj == null || !getClass().equals(obj.getClass())) { return false; } VersionRange that = (VersionRange) obj; return Objects.equals(upperBound, that.getUpperBound()) && Objects.equals(lowerBound, that.getLowerBound()); } @Override public int hashCode() { int hash = 17; hash = hash * 31 + hash(upperBound); hash = hash * 31 + hash(lowerBound); return hash; } private static int hash(Object obj) { return obj != null ? obj.hashCode() : 0; } @Override public String toString() { StringBuilder buffer = new StringBuilder(64); if (lowerBound != null) { buffer.append(lowerBound.isInclusive() ? '[' : '('); buffer.append(lowerBound.getVersion()); } else { buffer.append('('); } buffer.append(','); if (upperBound != null) { buffer.append(upperBound.getVersion()); buffer.append(upperBound.isInclusive() ? ']' : ')'); } else { buffer.append(')'); } return buffer.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy