blob: 25041fd33f18e4f04f4aa2e20d17f74b037d206b [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* 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.intellij.lang.ant.dom;
import com.intellij.openapi.util.Pair;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author Eugene Zhuravlev
* Date: Apr 22, 2010
*/
public class TargetResolver extends PropertyProviderFinder {
private List<String> myDeclaredTargetRefs;
private @Nullable AntDomTarget myContextTarget;
private Result myResult;
public static class Result {
private String myRefsString;
private Map<String, Pair<AntDomTarget, String>> myMap = new HashMap<String, Pair<AntDomTarget, String>>(); // declared target name -> pair[target, effective name]
private Map<String, AntDomTarget> myVariants;
void add(String declaredTargetRef, Pair<AntDomTarget, String> pair) {
myMap.put(declaredTargetRef, pair);
}
void setVariants(Map<String, AntDomTarget> variants) {
myVariants = variants;
}
public String getRefsString() {
return myRefsString;
}
public void setRefsString(String refsString) {
myRefsString = refsString;
}
@NotNull
public Collection<String> getTargetReferences() {
return Collections.unmodifiableSet(myMap.keySet());
}
@Nullable
public Pair<AntDomTarget, String> getResolvedTarget(String declaredTargetRef) {
return myMap.get(declaredTargetRef);
}
@NotNull
public Map<String, AntDomTarget> getVariants() {
return myVariants != null? myVariants : Collections.<String, AntDomTarget>emptyMap();
}
}
private TargetResolver(@NotNull Collection<String> declaredDependencyRefs, @Nullable AntDomTarget contextElement) {
super(contextElement);
myResult = new Result();
myDeclaredTargetRefs = new ArrayList<String>(declaredDependencyRefs);
myContextTarget = contextElement;
}
@NotNull
public static Result resolve(@NotNull AntDomProject project, @Nullable AntDomTarget contextTarget, @NotNull String declaredTargetRef) {
return resolve(project, contextTarget, Arrays.asList(declaredTargetRef));
}
public static Result resolve(AntDomProject project, AntDomTarget contextTarget, @NotNull Collection<String> declaredTargetRefs) {
final TargetResolver resolver = new TargetResolver(declaredTargetRefs, contextTarget);
resolver.execute(project, null);
final Result result = resolver.getResult();
result.setVariants(resolver.getDiscoveredTargets());
return result;
}
public interface TargetSink {
void duplicateTargetDetected(AntDomTarget existingTarget, AntDomTarget duplicatingTarget, String targetEffectiveName);
}
public static void validateDuplicateTargets(AntDomProject project, final TargetSink sink) {
final TargetResolver resolver = new TargetResolver(Collections.<String>emptyList(), null) {
protected void duplicateTargetFound(AntDomTarget existingTarget, AntDomTarget duplicatingTarget, String taregetEffectiveName) {
sink.duplicateTargetDetected(existingTarget, duplicatingTarget, taregetEffectiveName);
}
protected void stageCompleted(Stage completedStage, Stage startingStage) {
if (Stage.RESOLVE_MAP_BUILDING_STAGE.equals(completedStage)) {
stop();
}
}
};
resolver.execute(project, null);
}
protected void targetDefined(AntDomTarget target, String targetEffectiveName, Map<String, Pair<AntDomTarget, String>> dependenciesMap) {
if (myContextTarget != null && myDeclaredTargetRefs.size() > 0 && target.equals(myContextTarget)) {
for (Iterator<String> it = myDeclaredTargetRefs.iterator(); it.hasNext();) {
final String declaredRef = it.next();
final Pair<AntDomTarget, String> result = dependenciesMap.get(declaredRef);
if (result != null) {
myResult.add(declaredRef, result);
it.remove();
}
}
stop();
}
}
protected void stageCompleted(Stage completedStage, Stage startingStage) {
if (completedStage == Stage.RESOLVE_MAP_BUILDING_STAGE) {
if (myDeclaredTargetRefs.size() > 0) {
for (Iterator<String> it = myDeclaredTargetRefs.iterator(); it.hasNext();) {
final String declaredRef = it.next();
final AntDomTarget result = getTargetByName(declaredRef);
if (result != null) {
myResult.add(declaredRef, Pair.create(result, declaredRef)); // treat declared name as effective name
it.remove();
}
}
}
stop();
}
}
@NotNull
public Result getResult() {
return myResult;
}
@Override
protected void propertyProviderFound(PropertiesProvider propertiesProvider) {
}
}