/*
* Copyright 2014 Red Hat, Inc. and/or its affiliates.
*
* 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 org.jbpm.kie.services.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.jbpm.services.api.model.DeployedUnit;
import org.kie.internal.runtime.manager.RuntimeManagerIdFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Deployment id resolver that allows to find out latest version of given deployment id. To be able
* to find it deployment id needs to be done with valid group and artifact id and version must be
* set to <code>latest</code> (case insensitive):<br/>
* <code>org.jbpm:HR:latest</code><br/>
* then available deployment units will be scanned and based on Maven version comparison latest will
* be returned.
* <br/>
* Primary method to be used {@link DeploymentIdResolver#matchAndReturnLatest}
*/
public class DeploymentIdResolver implements RuntimeManagerIdFilter {
private static final Logger logger = LoggerFactory.getLogger(DeploymentIdResolver.class);
public static String matchAndReturnLatest(String deploymentId, Collection<String> availableDeployments) {
try {
GAVInfo gav = new GAVInfo(deploymentId);
if (deploymentId != null && gav.getVersion().equalsIgnoreCase("latest")) {
Collection<String> matched = matchDeployments(deploymentId, availableDeployments);
if (matched != null && !matched.isEmpty()) {
return findLatest(matched);
}
}
} catch (Exception e) {
logger.debug("Unable to resolve latest version of deployment {} due to {}", deploymentId, e.getMessage());
}
return deploymentId;
}
@SuppressWarnings("unchecked")
public static Collection<String> matchDeployments(String deploymentId, Collection<String> availableDeployments) {
Collection<String> matched = CollectionUtils.select(availableDeployments, new GroupAndArtifactMatchPredicate(deploymentId));
return matched;
}
public static String findLatest(Collection<String> deploymentIds) {
List<ComparableVersion> comparableVersions = new ArrayList<ComparableVersion>();
Map<String, String> versionToIdentifier = new HashMap<String, String>();
for (String deploymentId : deploymentIds) {
GAVInfo gav = new GAVInfo(deploymentId);
comparableVersions.add(new ComparableVersion(gav.getVersion()));
versionToIdentifier.put(gav.getVersion(), deploymentId);
}
ComparableVersion latest = Collections.max(comparableVersions);
return versionToIdentifier.get(latest.toString());
}
private static class GroupAndArtifactMatchPredicate implements Predicate {
private GAVInfo gavInfo;
private String groupArtifact;
private GroupAndArtifactMatchPredicate(String deploymentId) {
this.gavInfo = new GAVInfo(deploymentId);
this.groupArtifact = gavInfo.getGroupId() + ":" + gavInfo.getArtifactId();
}
@Override
public boolean evaluate(Object object) {
if (object instanceof String) {
if (((String) object).startsWith(groupArtifact)) {
return true;
}
} else if (object instanceof DeployedUnit) {
String identifier = ((DeployedUnit) object).getDeploymentUnit().getIdentifier();
if (identifier.startsWith(groupArtifact)) {
return true;
}
}
return false;
}
}
private static class GAVInfo {
private String groupId;
private String artifactId;
private String version;
GAVInfo(String deploymentId) {
String[] details = deploymentId.split(":");
this.groupId = details[0];
this.artifactId = details[1];
this.version = details[2];
}
public String getGroupId() {
return groupId;
}
public String getArtifactId() {
return artifactId;
}
public String getVersion() {
return version;
}
}
@Override
public Collection<String> filter(String pattern, Collection<String> identifiers) {
Collection<String> filtered = new ArrayList<String>();
String found = DeploymentIdResolver.matchAndReturnLatest(pattern, identifiers);
if (found != null && !found.equals(pattern)) {
filtered.add(found);
}
return filtered;
}
}