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

org.owasp.dependencycheck.utils.DependencyVersion Maven / Gradle / Ivy

/*
 * This file is part of dependency-check-core.
 *
 * 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.
 *
 * Copyright (c) 2013 Jeremy Long. All Rights Reserved.
 */
package org.owasp.dependencycheck.utils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.concurrent.NotThreadSafe;
import org.apache.commons.lang3.StringUtils;

/**
 * 

* Simple object to track the parts of a version number. The parts are contained * in a List such that version 1.2.3 will be stored as: versionParts[0] = 1; * versionParts[1] = 2; * versionParts[2] = 3; *

*

* Note, the parser contained in this class expects the version numbers to be * separated by periods. If a different separator is used the parser will likely * fail.

* * @author Jeremy Long */ @NotThreadSafe public class DependencyVersion implements Iterable, Comparable { /** * A list of the version parts. */ private List versionParts; /** * Constructor for a empty DependencyVersion. */ public DependencyVersion() { } /** * Constructor for a DependencyVersion that will parse a version string. * Note, this should only be used when the version passed in is * already known to be a well formatted version number. Otherwise, * DependencyVersionUtil.parseVersion() should be used instead. * * @param version the well formatted version number to parse */ public DependencyVersion(String version) { parseVersion(version); } /** * Parses a version string into its sub parts: major, minor, revision, * build, etc. Note, this should only be used to parse something that * is already known to be a version number. * * @param version the version string to parse */ public final void parseVersion(String version) { versionParts = new ArrayList<>(); if (version != null) { final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)"); final Matcher matcher = rx.matcher(version.toLowerCase()); while (matcher.find()) { versionParts.add(matcher.group()); } if (versionParts.isEmpty()) { versionParts.add(version); } } } /** * Get the value of versionParts. * * @return the value of versionParts */ public List getVersionParts() { return versionParts; } /** * Set the value of versionParts. * * @param versionParts new value of versionParts */ public void setVersionParts(List versionParts) { this.versionParts = versionParts; } /** * Retrieves an iterator for the version parts. * * @return an iterator for the version parts */ @Override public Iterator iterator() { return versionParts.iterator(); } /** * Reconstructs the version string from the split version parts. * * @return a string representing the version. */ @Override public String toString() { return StringUtils.join(versionParts, '.'); } /** * Compares the equality of this object to the one passed in as a parameter. * * @param obj the object to compare equality * @return returns true only if the two objects are equal, otherwise false */ @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instanceof DependencyVersion)) { return false; } final DependencyVersion other = (DependencyVersion) obj; final int minVersionMatchLength = (this.versionParts.size() < other.versionParts.size()) ? this.versionParts.size() : other.versionParts.size(); final int maxVersionMatchLength = (this.versionParts.size() > other.versionParts.size()) ? this.versionParts.size() : other.versionParts.size(); if (minVersionMatchLength == 1 && maxVersionMatchLength >= 3) { return false; } //TODO steal better version of code from compareTo for (int i = 0; i < minVersionMatchLength; i++) { final String thisPart = this.versionParts.get(i); final String otherPart = other.versionParts.get(i); if (!thisPart.equals(otherPart)) { return false; } } if (this.versionParts.size() > minVersionMatchLength) { for (int i = minVersionMatchLength; i < this.versionParts.size(); i++) { if (!"0".equals(this.versionParts.get(i))) { return false; } } } if (other.versionParts.size() > minVersionMatchLength) { for (int i = minVersionMatchLength; i < other.versionParts.size(); i++) { if (!"0".equals(other.versionParts.get(i))) { return false; } } } /* * if (this.versionParts != other.versionParts && (this.versionParts == null || !this.versionParts.equals(other.versionParts))) { * return false; * } */ return true; } /** * Calculates the hashCode for this object. * * @return the hashCode */ @Override public int hashCode() { int hash = 5; hash = 71 * hash + (this.versionParts != null ? this.versionParts.hashCode() : 0); return hash; } /** * Determines if the three most major major version parts are identical. For * instances, if version 1.2.3.4 was compared to 1.2.3 this function would * return true. * * @param version the version number to compare * @return true if the first three major parts of the version are identical */ public boolean matchesAtLeastThreeLevels(DependencyVersion version) { if (version == null) { return false; } if (Math.abs(this.versionParts.size() - version.versionParts.size()) >= 3) { return false; } final int max = (this.versionParts.size() < version.versionParts.size()) ? this.versionParts.size() : version.versionParts.size(); boolean ret = true; for (int i = 0; i < max; i++) { final String thisVersion = this.versionParts.get(i); final String otherVersion = version.getVersionParts().get(i); if (i >= 3) { if (thisVersion.compareToIgnoreCase(otherVersion) >= 0) { ret = false; break; } } else if (!thisVersion.equals(otherVersion)) { ret = false; break; } } return ret; } @Override public int compareTo(DependencyVersion version) { if (version == null) { return 1; } final List left = this.getVersionParts(); final List right = version.getVersionParts(); final int max = left.size() < right.size() ? left.size() : right.size(); for (int i = 0; i < max; i++) { final String lStr = left.get(i); final String rStr = right.get(i); if (lStr.equals(rStr)) { continue; } try { final int l = Integer.parseInt(lStr); final int r = Integer.parseInt(rStr); if (l < r) { return -1; } else if (l > r) { return 1; } } catch (NumberFormatException ex) { final int comp = left.get(i).compareTo(right.get(i)); if (comp < 0) { return -1; } else if (comp > 0) { return 1; } } } if (left.size() < right.size()) { return -1; } else if (left.size() > right.size()) { return 1; } else { return 0; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy