/* * 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.wizard; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import icons.AndroidIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import static com.android.tools.idea.templates.TemplateMetadata.*; import static com.android.tools.idea.wizard.ConfigureAndroidProjectStep.INVALID_FILENAME_CHARS; import static com.android.tools.idea.wizard.ScopedStateStore.Key; import static com.android.tools.idea.wizard.ScopedStateStore.Scope.STEP; import static com.android.tools.idea.wizard.ScopedStateStore.Scope.WIZARD; import static com.android.tools.idea.wizard.ScopedStateStore.createKey; import static com.android.tools.idea.wizard.FormFactorApiComboBox.AndroidTargetComboBoxItem; /** * Utility methods for dealing with Form Factors in Wizards. */ public class FormFactorUtils { public static final String INCLUDE_FORM_FACTOR = "included"; public static final String ATTR_MODULE_NAME = "projectName"; /** TODO: Turn into an enum and combine with {@link com.android.tools.idea.configurations.DeviceMenuAction.FormFactor} */ public static class FormFactor { public static final FormFactor MOBILE = new FormFactor("Mobile", AndroidIcons.Wizards.FormFactorPhoneTablet, "Phone and Tablet", 15, Lists.newArrayList("20", "Glass"), null); public static final FormFactor WEAR = new FormFactor("Wear", AndroidIcons.Wizards.FormFactorWear, "Wear", 20, null, Lists.newArrayList("20")); public static final FormFactor GLASS = new FormFactor("Glass", AndroidIcons.Wizards.FormFactorGlass, "Glass", 19, null, Lists.newArrayList("Glass")); public static final FormFactor TV = new FormFactor("TV", AndroidIcons.Wizards.FormFactorTV, "TV", 21, Lists.newArrayList("20"), null); private static final Map<String, FormFactor> myFormFactors = new ImmutableMap.Builder<String, FormFactor>() .put(MOBILE.id, MOBILE) .put(WEAR.id, WEAR) .put(GLASS.id, GLASS) .put(TV.id, TV).build(); public final String id; @Nullable private final Icon myIcon; @Nullable private String displayName; public final int defaultApi; @NotNull private final List<String> myApiBlacklist; @NotNull private final List<String> myApiWhitelist; FormFactor(@NotNull String id, @Nullable Icon icon, @Nullable String displayName, @NotNull int defaultApi, @Nullable List<String> apiBlacklist, @Nullable List<String> apiWhitelist) { this.id = id; myIcon = icon; this.displayName = displayName; this.defaultApi = defaultApi; myApiBlacklist = apiBlacklist != null ? apiBlacklist : Collections.<String>emptyList(); myApiWhitelist = apiWhitelist != null ? apiWhitelist : Collections.<String>emptyList(); } @Nullable public static FormFactor get(@NotNull String id) { if (myFormFactors.containsKey(id)) { return myFormFactors.get(id); } return new FormFactor(id, null, id, 1, null, null); } @Override public String toString() { return displayName == null ? id : displayName; } @Nullable public Icon getIcon() { return myIcon; } public static Iterator<FormFactor> iterator() { return myFormFactors.values().iterator(); } } public static Key<AndroidTargetComboBoxItem> getTargetComboBoxKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_MIN_API + "combo", STEP, AndroidTargetComboBoxItem.class); } public static Key<Integer> getMinApiLevelKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_MIN_API_LEVEL, WIZARD, Integer.class); } public static Key<String> getMinApiKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_MIN_API, WIZARD, String.class); } public static Key<String> getBuildApiKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_BUILD_API_STRING, WIZARD, String.class); } public static Key<Integer> getTargetApiLevelKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_TARGET_API, WIZARD, Integer.class); } public static Key<String> getTargetApiStringKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_TARGET_API_STRING, WIZARD, String.class); } public static Key<Integer> getBuildApiLevelKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_BUILD_API, WIZARD, Integer.class); } public static Key<String> getLanguageLevelKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_JAVA_VERSION, WIZARD, String.class); } public static Key<Boolean> getInclusionKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + INCLUDE_FORM_FACTOR, WIZARD, Boolean.class); } public static Key<String> getModuleNameKey(@NotNull FormFactor formFactor) { return createKey(formFactor.id + ATTR_MODULE_NAME, WIZARD, String.class); } public static Map<String, Object> scrubFormFactorPrefixes(@NotNull FormFactor formFactor, @NotNull Map<String, Object> values) { Map<String, Object> toReturn = Maps.newHashMapWithExpectedSize(values.size()); for (String key : values.keySet()) { if (key.startsWith(formFactor.id)) { toReturn.put(key.substring(formFactor.id.length()), values.get(key)); } else { toReturn.put(key, values.get(key)); } } return toReturn; } public static String getPropertiesComponentMinSdkKey(@NotNull FormFactor formFactor) { return formFactor.id + ATTR_MIN_API; } @NotNull public static String getModuleName(@NotNull FormFactor formFactor) { String name = formFactor.id.replaceAll(INVALID_FILENAME_CHARS, ""); name = name.replaceAll("\\s", "_"); return name.toLowerCase(); } public static Predicate<AndroidTargetComboBoxItem> getMinSdkComboBoxFilter(@NotNull final FormFactor formFactor, final int minSdkLevel) { return new Predicate<AndroidTargetComboBoxItem>() { @Override public boolean apply(@Nullable AndroidTargetComboBoxItem input) { if (input == null) { return false; } if (!formFactor.myApiWhitelist.isEmpty()) { // If a whitelist is present, only allow things on the whitelist for (String filterItem : formFactor.myApiWhitelist) { if (matches(filterItem, input)) { return true; } } return false; } // If we don't have a whitelist, let's check the blacklist for (String filterItem : formFactor.myApiBlacklist) { if (matches(filterItem, input)) { return false; } } // Finally, we'll check that the minSDK is honored return input.apiLevel >= minSdkLevel || (input.target != null && input.target.getVersion().isPreview()); } }; } /** * @return true iff the filterItem is a string which matches the string representation of the box item apiLevel, * or the target name contains the filterItem. */ private static boolean matches(@NotNull String filterItem, @NotNull AndroidTargetComboBoxItem input) { if (Integer.toString(input.apiLevel).equals(filterItem)) { return true; } if (input.target != null && input.target.getName().contains(filterItem)) { return true; } return false; } }