/* * Copyright (C) 2013 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.customizer.android; import com.android.builder.model.AndroidProject; import com.android.builder.model.SourceProvider; import com.android.tools.idea.gradle.IdeaAndroidProject; import com.android.tools.idea.gradle.customizer.ModuleCustomizer; import com.android.tools.idea.gradle.util.Facets; import com.google.common.base.Strings; import com.intellij.facet.FacetManager; import com.intellij.facet.ModifiableFacetModel; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.android.model.impl.JpsAndroidModuleProperties; import java.io.File; import java.util.Collection; /** * Adds the Android facet to modules imported from {@link com.android.builder.model.AndroidProject}s. */ public class AndroidFacetModuleCustomizer implements ModuleCustomizer<IdeaAndroidProject> { private static final String EMPTY_PATH = ""; // It is safe to use "/" instead of File.separator. JpsAndroidModule uses it. private static final String SEPARATOR = "/"; @Override public void customizeModule(@NotNull Module module, @NotNull final Project project, @Nullable IdeaAndroidProject androidProject) { if (androidProject == null) { Facets.removeAllFacetsOfType(module, AndroidFacet.ID); } else { AndroidFacet facet = AndroidFacet.getInstance(module); if (facet != null) { configureFacet(facet, androidProject); } else { // Module does not have Android facet. Create one and add it. FacetManager facetManager = FacetManager.getInstance(module); ModifiableFacetModel model = facetManager.createModifiableModel(); try { facet = facetManager.createFacet(AndroidFacet.getFacetType(), AndroidFacet.NAME, null); model.addFacet(facet); configureFacet(facet, androidProject); } finally { model.commit(); } } } } private static void configureFacet(@NotNull AndroidFacet facet, @NotNull IdeaAndroidProject ideaAndroidProject) { JpsAndroidModuleProperties facetState = facet.getProperties(); facetState.ALLOW_USER_CONFIGURATION = false; AndroidProject delegate = ideaAndroidProject.getDelegate(); facetState.LIBRARY_PROJECT = delegate.isLibrary(); SourceProvider sourceProvider = delegate.getDefaultConfig().getSourceProvider(); syncSelectedVariant(facetState, ideaAndroidProject); // This code needs to be modified soon. Read the TODO in getRelativePath File moduleDir = VfsUtilCore.virtualToIoFile(ideaAndroidProject.getRootDir()); File manifestFile = sourceProvider.getManifestFile(); facetState.MANIFEST_FILE_RELATIVE_PATH = getRelativePath(moduleDir, manifestFile); Collection<File> resDirs = sourceProvider.getResDirectories(); facetState.RES_FOLDER_RELATIVE_PATH = getRelativePath(moduleDir, resDirs); Collection<File> assetsDirs = sourceProvider.getAssetsDirectories(); facetState.ASSETS_FOLDER_RELATIVE_PATH = getRelativePath(moduleDir, assetsDirs); facet.setIdeaAndroidProject(ideaAndroidProject); facet.syncSelectedVariant(); } private static void syncSelectedVariant(@NotNull JpsAndroidModuleProperties facetState, @NotNull IdeaAndroidProject ideaAndroidProject) { String variantStoredInFacet = facetState.SELECTED_BUILD_VARIANT; if (!Strings.isNullOrEmpty(variantStoredInFacet) && ideaAndroidProject.getVariantNames().contains(variantStoredInFacet)) { ideaAndroidProject.setSelectedVariantName(variantStoredInFacet); } } // We are only getting the relative path of the first file in the collection, because JpsAndroidModuleProperties only accepts one path. // TODO(alruiz): Change JpsAndroidModuleProperties (and callers) to use multiple paths. @NotNull private static String getRelativePath(@NotNull File basePath, @NotNull Collection<File> dirs) { return getRelativePath(basePath, ContainerUtil.getFirstItem(dirs)); } @NotNull private static String getRelativePath(@NotNull File basePath, @Nullable File file) { String relativePath = null; if (file != null) { relativePath = FileUtilRt.getRelativePath(basePath, file); } if (relativePath != null && !relativePath.startsWith(SEPARATOR)) { return SEPARATOR + FileUtilRt.toSystemIndependentName(relativePath); } return EMPTY_PATH; } }