| /* |
| * 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) { |
| } |
| } |