blob: a624b644fc7180ab460e321c1e707a10fdf05c11 [file] [log] [blame]
/*
* 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
*
* https://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.ivy.plugins.conflict;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.plugins.latest.ArtifactInfo;
import org.apache.ivy.plugins.latest.LatestStrategy;
import org.apache.ivy.util.Message;
public class LatestConflictManager extends AbstractConflictManager {
@SuppressWarnings("serial")
public static class NoConflictResolvedYetException extends RuntimeException {
}
protected static final class IvyNodeArtifactInfo implements ArtifactInfo {
private final IvyNode node;
private IvyNodeArtifactInfo(IvyNode dep) {
node = dep;
}
public long getLastModified() {
long lastModified = node.getLastModified();
if (lastModified == 0) {
// if the last modified timestamp is unknown, we can't resolve
// the conflicts now, and trigger an exception which will be caught
// in the main resolveConflicts method
throw new NoConflictResolvedYetException();
} else {
return lastModified;
}
}
public String getRevision() {
return node.getResolvedId().getRevision();
}
public IvyNode getNode() {
return node;
}
}
private LatestStrategy strategy;
private String strategyName;
public LatestConflictManager() {
}
public LatestConflictManager(LatestStrategy strategy) {
this.strategy = strategy;
}
public LatestConflictManager(String name, LatestStrategy strategy) {
setName(name);
this.strategy = strategy;
}
public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
if (conflicts.size() < 2) {
return conflicts;
}
for (IvyNode node : conflicts) {
DependencyDescriptor dd = node.getDependencyDescriptor(parent);
if (dd != null && dd.isForce()
&& parent.getResolvedId().equals(dd.getParentRevisionId())) {
return Collections.singleton(node);
}
}
/*
* If the list of conflicts contains dynamic revisions, delay the conflict calculation until
* they are resolved. TODO: we probably could already evict some of the dynamic revisions!
*/
for (IvyNode node : conflicts) {
ModuleRevisionId modRev = node.getResolvedId();
if (getSettings().getVersionMatcher().isDynamic(modRev)) {
return null;
}
}
List<IvyNode> unevicted = new ArrayList<>();
for (IvyNode node : conflicts) {
if (!node.isCompletelyEvicted()) {
unevicted.add(node);
}
}
if (unevicted.size() > 0) {
conflicts = unevicted;
}
try {
IvyNodeArtifactInfo latest = (IvyNodeArtifactInfo) getStrategy().findLatest(
toArtifactInfo(conflicts), null);
if (latest != null) {
return Collections.singleton(latest.getNode());
} else {
return conflicts;
}
} catch (NoConflictResolvedYetException ex) {
// we have not enough information in the nodes to resolve conflict
// according to the resolveConflicts contract, we must return null
return null;
}
}
protected ArtifactInfo[] toArtifactInfo(Collection<IvyNode> conflicts) {
List<ArtifactInfo> artifacts = new ArrayList<>(conflicts.size());
for (IvyNode node : conflicts) {
artifacts.add(new IvyNodeArtifactInfo(node));
}
return artifacts.toArray(new ArtifactInfo[artifacts.size()]);
}
public LatestStrategy getStrategy() {
if (strategy == null) {
if (strategyName != null) {
strategy = getSettings().getLatestStrategy(strategyName);
if (strategy == null) {
Message.error("unknown latest strategy: " + strategyName);
strategy = getSettings().getDefaultLatestStrategy();
}
} else {
strategy = getSettings().getDefaultLatestStrategy();
}
}
return strategy;
}
/**
* To conform to configurator API
*
* @param strategyName ditto
*/
public void setLatest(String strategyName) {
this.strategyName = strategyName;
}
public void setStrategy(LatestStrategy strategy) {
this.strategy = strategy;
}
@Override
public String toString() {
return strategy != null ? String.valueOf(strategy) : strategyName;
}
}