/* * 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.apache.ivyde.internal.eclipse.workspaceresolver; import java.util.Comparator; import org.apache.ivy.core.IvyContext; import org.apache.ivy.core.module.id.ModuleRevisionId; import org.apache.ivy.plugins.latest.ArtifactInfo; import org.apache.ivy.plugins.latest.ComparatorLatestStrategy; import org.apache.ivy.plugins.version.VersionMatcher; /** * A dumb copy of the {@link org.apache.ivy.plugins.latest.LatestRevisionStrategy} but that take * into account the latest and working revision as superior to any other revision. */ public class IvyDEStrategy extends ComparatorLatestStrategy { final class MridComparator implements Comparator { public int compare(Object o1, Object o2) { String rev1 = ((ModuleRevisionId) o1).getRevision(); String rev2 = ((ModuleRevisionId) o2).getRevision(); boolean latestRev1 = rev1.startsWith("latest") || rev1.startsWith("working"); boolean latestRev2 = rev2.startsWith("latest") || rev2.startsWith("working"); if (latestRev1 && !latestRev2) { return 1; } else if (latestRev2 && !latestRev1) { return -1; } rev1 = rev1.replaceAll("([a-zA-Z])(\\d)", "$1.$2"); rev1 = rev1.replaceAll("(\\d)([a-zA-Z])", "$1.$2"); rev2 = rev2.replaceAll("([a-zA-Z])(\\d)", "$1.$2"); rev2 = rev2.replaceAll("(\\d)([a-zA-Z])", "$1.$2"); String[] parts1 = rev1.split("[\\._\\-\\+]"); String[] parts2 = rev2.split("[\\._\\-\\+]"); int i = 0; for (; i < parts1.length && i < parts2.length; i++) { if (parts1[i].equals(parts2[i])) { continue; } boolean is1Number = isNumber(parts1[i]); boolean is2Number = isNumber(parts2[i]); if (is1Number && !is2Number) { return 1; } if (is2Number && !is1Number) { return -1; } if (is1Number && is2Number) { return Long.valueOf(parts1[i]).compareTo(Long.valueOf(parts2[i])); } return parts1[i].compareTo(parts2[i]); } if (i < parts1.length) { return isNumber(parts1[i]) ? 1 : -1; } if (i < parts2.length) { return isNumber(parts2[i]) ? -1 : 1; } return 0; } private boolean isNumber(String str) { return str.matches("\\d+"); } } /** * Compares two ArtifactInfo by their revision. Revisions are compared using an algorithm * inspired by PHP version_compare one, unless a dynamic revision is given, in which case the * version matcher is used to perform the comparison. */ final class ArtifactInfoComparator implements Comparator { public int compare(Object o1, Object o2) { String rev1 = ((ArtifactInfo) o1).getRevision(); String rev2 = ((ArtifactInfo) o2).getRevision(); /* * The revisions can still be not resolved, so we use the current version matcher to * know if one revision is dynamic, and in this case if it should be considered greater * or lower than the other one. Note that if the version matcher compare method returns * 0, it's because it's not possible to know which revision is greater. In this case we * consider the dynamic one to be greater, because most of the time it will then be * actually resolved and a real comparison will occur. */ VersionMatcher vmatcher = IvyContext.getContext().getSettings().getVersionMatcher(); ModuleRevisionId mrid1 = ModuleRevisionId.newInstance("", "", rev1); ModuleRevisionId mrid2 = ModuleRevisionId.newInstance("", "", rev2); if (vmatcher.isDynamic(mrid1)) { int c = vmatcher.compare(mrid1, mrid2, mridComparator); return c >= 0 ? 1 : -1; } else if (vmatcher.isDynamic(mrid2)) { int c = vmatcher.compare(mrid2, mrid1, mridComparator); return c >= 0 ? -1 : 1; } return mridComparator.compare(mrid1, mrid2); } } private final Comparator mridComparator = new MridComparator(); private final Comparator artifactInfoComparator = new ArtifactInfoComparator(); public IvyDEStrategy() { setComparator(artifactInfoComparator); setName("ivyde-latest-revision"); } }