| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * 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.android.tools.idea.gradle.variant.conflict; |
| |
| import com.google.common.collect.ArrayListMultimap; |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Multimap; |
| import com.intellij.openapi.module.Module; |
| import com.intellij.util.containers.ContainerUtil; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| public class Conflict { |
| @NotNull private final Module mySource; |
| @NotNull private final String mySelectedVariant; |
| |
| // Key: variant expected by module, Value: all modules expecting the variant used as key. |
| @NotNull private final Multimap<String, AffectedModule> myAffectedModulesByExpectedVariant = ArrayListMultimap.create(); |
| |
| @NotNull private final List<AffectedModule> myAffectedModules = Lists.newArrayList(); |
| |
| private boolean myResolved; |
| |
| public Conflict(@NotNull Module source, @NotNull String selectedVariant) { |
| mySource = source; |
| mySelectedVariant = selectedVariant; |
| } |
| |
| public void addAffectedModule(@NotNull Module target, @NotNull String expectedVariant) { |
| AffectedModule affected = new AffectedModule(this, target, expectedVariant); |
| myAffectedModules.add(affected); |
| myAffectedModulesByExpectedVariant.put(expectedVariant, affected); |
| } |
| |
| @NotNull |
| public Collection<String> getVariants() { |
| return myAffectedModulesByExpectedVariant.keySet(); |
| } |
| |
| @NotNull |
| public Collection<AffectedModule> getModulesExpectingVariant(@NotNull String variant) { |
| return myAffectedModulesByExpectedVariant.get(variant); |
| } |
| |
| @NotNull |
| public Module getSource() { |
| return mySource; |
| } |
| |
| @NotNull |
| public String getSelectedVariant() { |
| return mySelectedVariant; |
| } |
| |
| @NotNull |
| public List<AffectedModule> getAffectedModules() { |
| return myAffectedModules; |
| } |
| |
| public void refreshStatus() { |
| int selectedVariantCount = 0; |
| for (String variant : myAffectedModulesByExpectedVariant.keySet()) { |
| for (AffectedModule affected : getModulesExpectingVariant(variant)) { |
| if (affected.isSelected()) { |
| selectedVariantCount++; |
| break; |
| } |
| } |
| } |
| setResolved(selectedVariantCount <= 1); |
| } |
| |
| public boolean isResolved() { |
| return myResolved; |
| } |
| |
| public void setResolved(boolean resolved) { |
| this.myResolved = resolved; |
| } |
| |
| @Override |
| public String toString() { |
| String text = String.format("Module '%1$s' has variant '%2$s' selected, but", mySource.getName(), mySelectedVariant); |
| |
| List<String> expectedVariants = Lists.newArrayList(getVariants()); |
| if (expectedVariants.size() == 1) { |
| String expectedVariant = expectedVariants.get(0); |
| Collection<Conflict.AffectedModule> modules = getModulesExpectingVariant(expectedVariant); |
| String moduleNames = getModuleNames(modules); |
| String format = modules.size() == 1 ? " the module '%1$s' depends on variant '%2$s'" : " the modules %1$s depend on variant '%2$s'"; |
| text += String.format(format, moduleNames, expectedVariant); |
| } |
| else { |
| Collections.sort(expectedVariants); |
| for (String expectedVariant : expectedVariants) { |
| Collection<Conflict.AffectedModule> modules = getModulesExpectingVariant(expectedVariant); |
| String moduleNames = getModuleNames(modules); |
| text += "\n- "; |
| String format = modules.size() == 1 ? "Module '%1$s' depends on variant '%2$s'" : "Modules %1$s depend on variant '%2$s'"; |
| text += String.format(format, moduleNames, expectedVariant); |
| } |
| } |
| return text; |
| } |
| |
| @NotNull |
| private static String getModuleNames(@NotNull Collection<Conflict.AffectedModule> modules) { |
| if (modules.size() == 1) { |
| Conflict.AffectedModule module = ContainerUtil.getFirstItem(modules); |
| assert module != null; |
| return "'" + module.getTarget().getName() + "'"; |
| } |
| List<String> names = Lists.newArrayList(); |
| for (Conflict.AffectedModule module : modules) { |
| names.add("'" + module.getTarget().getName() + "'"); |
| } |
| Collections.sort(names); |
| return names.toString(); |
| } |
| |
| public static class AffectedModule { |
| @NotNull private final Conflict myConflict; |
| @NotNull private final Module myTarget; |
| @NotNull private final String myExpectedVariant; |
| private boolean mySelected = true; |
| |
| AffectedModule(@NotNull Conflict conflict, @NotNull Module target, @NotNull String expectedVariant) { |
| myConflict = conflict; |
| myTarget = target; |
| myExpectedVariant = expectedVariant; |
| } |
| |
| @NotNull |
| public Conflict getConflict() { |
| return myConflict; |
| } |
| |
| @NotNull |
| public Module getTarget() { |
| return myTarget; |
| } |
| |
| @NotNull |
| public String getExpectedVariant() { |
| return myExpectedVariant; |
| } |
| |
| public boolean isSelected() { |
| return mySelected; |
| } |
| |
| public void setSelected(boolean selected) { |
| mySelected = selected; |
| myConflict.refreshStatus(); |
| } |
| } |
| } |