com.metaeffekt.artifact.analysis.version.token.VersionToken Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2021-2024 the original author or authors.
*
* 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.
*/
package com.metaeffekt.artifact.analysis.version.token;
import com.metaeffekt.artifact.analysis.utils.StringUtils;
import com.metaeffekt.artifact.analysis.version.VersionModifier;
import com.metaeffekt.artifact.analysis.vulnerability.enrichment.VersionComparator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class VersionToken {
private final String value;
private final VersionTokenType type;
private List subTokens = null;
public VersionToken(String value, VersionTokenType type) {
this(value, type, null);
}
public VersionToken(String value, VersionTokenType type, VersionToken subToken) {
if (value == null) {
throw new IllegalArgumentException("Value must not be null.");
} else if (type == null) {
throw new IllegalArgumentException("Type must not be null.");
}
this.value = value;
this.type = type;
this.addSubToken(subToken);
}
public String getValue() {
return value;
}
public VersionTokenType getType() {
return type;
}
public List getSubTokens() {
return subTokens;
}
public int getSubTokenCount() {
return subTokens != null ? subTokens.size() : 0;
}
public void addSubToken(VersionToken subToken) {
if (subToken == null) {
return;
} else if (subTokens == null) {
subTokens = new ArrayList<>();
}
subTokens.add(subToken);
}
public boolean isComparableByString() {
return isDateNumberOrSemver() || isLetteredSubversion();
}
public boolean isDateNumberOrSemver() {
return type == VersionTokenType.NUMBER_OR_SEMVER || type == VersionTokenType.DATE;
}
public boolean isLetteredSubversion() {
return type == VersionTokenType.STRING && (value.length() == 1 || value.length() == 2 && value.startsWith("z"));
}
public boolean isLettersOnly() {
for (int i = 0; i < value.length(); i++) {
if (!Character.isLetter(value.charAt(i))) {
return false;
}
}
return true;
}
public VersionToken deriveToken(String newValue) {
return new VersionToken(newValue, type);
}
@Override
public String toString() {
return value + (subTokens != null && !subTokens.isEmpty() ? " " + subTokens.stream().map(VersionToken::toString).collect(Collectors.joining(" ")) : "");
}
public static boolean isEmpty(VersionToken token) {
return token == null || StringUtils.isEmpty(token.getValue());
}
public final static Comparator VERSION_MODIFIER_COMPARATOR = new VersionModifierComparator(false);
public final static Comparator VERSION_MODIFIER_COMPARATOR_COMMON_PARTS = new VersionModifierComparator(true);
private static class VersionModifierComparator implements Comparator {
private final boolean useOnlyCommonParts;
private VersionModifierComparator(boolean useOnlyCommonParts) {
this.useOnlyCommonParts = useOnlyCommonParts;
}
public int compare(VersionToken o1, VersionToken o2) {
if (o1 == null && o2 == null) {
return 0;
} else if (o1 == null) {
return -1;
} else if (o2 == null) {
return 1;
} else {
final VersionModifier m1 = VersionModifier.fromStringName(o1.getValue());
final VersionModifier m2 = VersionModifier.fromStringName(o2.getValue());
final int m1Value = m1 != null ? m1.getValue() : 0;
final int m2Value = m2 != null ? m2.getValue() : 0;
final int modifierComparison = Integer.compare(m1Value, m2Value);
if (modifierComparison != 0) {
return modifierComparison;
} else {
final List subTokens1 = o1.getSubTokens();
final List subTokens2 = o2.getSubTokens();
final boolean isNullOrEmpty1 = subTokens1 == null || subTokens1.isEmpty();
final boolean isNullOrEmpty2 = subTokens2 == null || subTokens2.isEmpty();
if (useOnlyCommonParts && (isNullOrEmpty1 || isNullOrEmpty2)) {
return 0;
}
if (isNullOrEmpty1 && isNullOrEmpty2) {
return 0;
} else if (isNullOrEmpty1) {
return -1;
} else if (isNullOrEmpty2) {
return 1;
}
final int limit = useOnlyCommonParts ? Math.min(subTokens1.size(), subTokens2.size()) : Math.max(subTokens1.size(), subTokens2.size());
for (int i = 0; i < limit; i++) {
if (i >= subTokens1.size()) {
return -1;
} else if (i >= subTokens2.size()) {
return 1;
}
final String value1 = subTokens1.get(i).getValue();
final String value2 = subTokens2.get(i).getValue();
final boolean isLettersOnly1 = subTokens1.get(i).isLettersOnly();
final boolean isLettersOnly2 = subTokens2.get(i).isLettersOnly();
final int subTokenComparison;
if (!isLettersOnly1 && !isLettersOnly2) {
subTokenComparison = (useOnlyCommonParts ? VersionComparator.INSTANCE_COMMON_PARTS : VersionComparator.INSTANCE).compare(value1, value2);
} else {
subTokenComparison = value1.compareTo(value2);
}
if (subTokenComparison != 0) {
return subTokenComparison;
}
}
}
}
return 0;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy