Search in sources :

Example 46 with AndroidFacet

use of org.jetbrains.android.facet.AndroidFacet in project android by JetBrains.

the class MigrateDrawableToMipmapFix method apply.

@Override
public void apply(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull AndroidQuickfixContexts.Context context) {
    Project project = startElement.getProject();
    AndroidFacet facet = AndroidFacet.getInstance(startElement);
    if (facet == null) {
        return;
    }
    final List<PsiFile> bitmaps = Lists.newArrayList();
    final Set<PsiElement> references = Sets.newHashSet();
    GlobalSearchScope useScope = GlobalSearchScope.projectScope(project);
    ProjectResourceRepository projectResources = facet.getProjectResources(true);
    List<ResourceItem> resourceItems = projectResources.getResourceItem(myUrl.type, myUrl.name);
    if (resourceItems != null) {
        for (ResourceItem item : resourceItems) {
            PsiFile file = LocalResourceRepository.getItemPsiFile(project, item);
            if (file == null) {
                continue;
            }
            bitmaps.add(file);
            Iterable<PsiReference> allReferences = SearchUtils.findAllReferences(file, useScope);
            for (PsiReference next : allReferences) {
                PsiElement element = next.getElement();
                if (element != null) {
                    references.add(element);
                }
            }
        }
    }
    PsiField[] resourceFields = AndroidResourceUtil.findResourceFields(facet, ResourceType.DRAWABLE.getName(), myUrl.name, true);
    if (resourceFields.length == 1) {
        Iterable<PsiReference> allReferences = SearchUtils.findAllReferences(resourceFields[0], useScope);
        for (PsiReference next : allReferences) {
            PsiElement element = next.getElement();
            if (element != null) {
                references.add(element);
            }
        }
    }
    Set<PsiFile> applicableFiles = Sets.newHashSet();
    applicableFiles.addAll(bitmaps);
    for (PsiElement element : references) {
        PsiFile containingFile = element.getContainingFile();
        if (containingFile != null) {
            applicableFiles.add(containingFile);
        }
    }
    WriteCommandAction<Void> action = new WriteCommandAction<Void>(project, "Migrate Drawable to Bitmap", applicableFiles.toArray(new PsiFile[applicableFiles.size()])) {

        @Override
        protected void run(@NotNull Result<Void> result) throws Throwable {
            // Move each drawable bitmap from drawable-my-qualifiers to bitmap-my-qualifiers
            for (PsiFile bitmap : bitmaps) {
                VirtualFile file = bitmap.getVirtualFile();
                if (file == null) {
                    continue;
                }
                VirtualFile parent = file.getParent();
                if (parent == null) {
                    // shouldn't happen for bitmaps found in the resource repository
                    continue;
                }
                if (file.getFileType() == StdFileTypes.XML && parent.getName().startsWith(FD_RES_VALUES)) {
                    // Resource alias rather than an actual drawable XML file: update the type reference instead
                    XmlFile xmlFile = (XmlFile) bitmap;
                    XmlTag root = xmlFile.getRootTag();
                    if (root != null) {
                        for (XmlTag item : root.getSubTags()) {
                            String name = item.getAttributeValue(ATTR_NAME);
                            if (myUrl.name.equals(name)) {
                                if (ResourceType.DRAWABLE.getName().equals(item.getName())) {
                                    item.setName(ResourceType.MIPMAP.getName());
                                } else if (ResourceType.DRAWABLE.getName().equals(item.getAttributeValue(ATTR_TYPE))) {
                                    item.setAttribute(ATTR_TYPE, ResourceType.MIPMAP.getName());
                                }
                            }
                        }
                    }
                    // Don't move the file
                    continue;
                }
                VirtualFile res = parent.getParent();
                if (res == null) {
                    // shouldn't happen for bitmaps found in the resource repository
                    continue;
                }
                FolderConfiguration configuration = FolderConfiguration.getConfigForFolder(parent.getName());
                if (configuration == null) {
                    continue;
                }
                String targetFolderName = configuration.getFolderName(ResourceFolderType.MIPMAP);
                VirtualFile targetFolder = res.findChild(targetFolderName);
                if (targetFolder == null) {
                    targetFolder = res.createChildDirectory(this, targetFolderName);
                }
                file.move(this, targetFolder);
            }
            // Update references
            for (PsiElement reference : references) {
                if (reference instanceof XmlAttributeValue) {
                    // Convert @drawable/foo references to @mipmap/foo
                    XmlAttributeValue value = (XmlAttributeValue) reference;
                    XmlAttribute attribute = (XmlAttribute) value.getParent();
                    attribute.setValue(ResourceUrl.create(ResourceType.MIPMAP, myUrl.name, false, false).toString());
                } else if (reference instanceof PsiReferenceExpression) {
                    // Convert R.drawable.foo references to R.mipmap.foo
                    PsiReferenceExpression inner = (PsiReferenceExpression) reference;
                    PsiExpression qualifier = inner.getQualifierExpression();
                    if (qualifier instanceof PsiReferenceExpression) {
                        PsiReferenceExpression outer = (PsiReferenceExpression) qualifier;
                        if (outer.getReferenceNameElement() instanceof PsiIdentifier) {
                            PsiIdentifier identifier = (PsiIdentifier) outer.getReferenceNameElement();
                            if (ResourceType.DRAWABLE.getName().equals(identifier.getText())) {
                                Project project = reference.getProject();
                                final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
                                PsiIdentifier newIdentifier = elementFactory.createIdentifier(ResourceType.MIPMAP.getName());
                                identifier.replace(newIdentifier);
                            }
                        }
                    }
                }
            }
        }
    };
    action.execute();
}
Also used : WriteCommandAction(com.intellij.openapi.command.WriteCommandAction) VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlAttribute(com.intellij.psi.xml.XmlAttribute) NotNull(org.jetbrains.annotations.NotNull) Result(com.intellij.openapi.application.Result) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) ProjectResourceRepository(com.android.tools.idea.res.ProjectResourceRepository) XmlFile(com.intellij.psi.xml.XmlFile) FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) XmlAttributeValue(com.intellij.psi.xml.XmlAttributeValue) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) Project(com.intellij.openapi.project.Project) ResourceItem(com.android.ide.common.res2.ResourceItem) XmlTag(com.intellij.psi.xml.XmlTag)

Example 47 with AndroidFacet

use of org.jetbrains.android.facet.AndroidFacet in project android by JetBrains.

the class GenerateBackupDescriptorFix method apply.

@Override
public void apply(@NotNull final PsiElement startElement, @NotNull PsiElement endElement, @NotNull AndroidQuickfixContexts.Context context) {
    final Project project = startElement.getProject();
    final AndroidFacet facet = AndroidFacet.getInstance(startElement);
    if (facet == null) {
        return;
    }
    // Find all classes that extend the SQLiteOpenHelper
    GlobalSearchScope allScope = GlobalSearchScope.allScope(project);
    GlobalSearchScope useScope = GlobalSearchScope.projectScope(project);
    // All necessary PsiClassType's
    PsiClassType stringType = PsiType.getJavaLangString(PsiManager.getInstance(project), allScope);
    JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
    PsiClass psiOpenHelperClass = javaPsiFacade.findClass("android.database.sqlite.SQLiteOpenHelper", allScope);
    assert psiOpenHelperClass != null;
    PsiClass psiContext = javaPsiFacade.findClass(CLASS_CONTEXT, allScope);
    assert psiContext != null;
    final Set<String> databaseNames = findDatabasesInProject(useScope, psiOpenHelperClass, stringType, javaPsiFacade);
    final Set<String> sharedPreferenceFiles = findSharedPrefsInProject(useScope, psiContext, facet, stringType, javaPsiFacade);
    WriteCommandAction.runWriteCommandAction(project, "Create Backup Descriptor", null, () -> {
        try {
            @SuppressWarnings("deprecation") VirtualFile primaryResourceDir = facet.getPrimaryResourceDir();
            assert primaryResourceDir != null;
            VirtualFile xmlDir = createChildDirectoryIfNotExist(project, primaryResourceDir, FD_RES_XML);
            VirtualFile resFile = xmlDir.createChildData(project, myUrl.name + DOT_XML);
            VfsUtil.saveText(resFile, generateBackupDescriptorContents(databaseNames, sharedPreferenceFiles));
            TemplateUtils.reformatAndRearrange(project, resFile);
            TemplateUtils.openEditor(project, resFile);
            TemplateUtils.selectEditor(project, resFile);
        } catch (IOException e) {
            String error = String.format("Failed to create file: %1$s", e.getMessage());
            Messages.showErrorDialog(project, error, "Create Backup Resource");
        }
    });
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Project(com.intellij.openapi.project.Project) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) IOException(java.io.IOException) AndroidFacet(org.jetbrains.android.facet.AndroidFacet)

Example 48 with AndroidFacet

use of org.jetbrains.android.facet.AndroidFacet in project android by JetBrains.

the class LintIdeProject method createModuleProject.

/** Creates a new module project */
@Nullable
private static LintModuleProject createModuleProject(@NonNull LintClient client, @NonNull Module module) {
    AndroidFacet facet = AndroidFacet.getInstance(module);
    File dir = getLintProjectDirectory(module, facet);
    if (dir == null)
        return null;
    LintModuleProject project = null;
    if (facet == null) {
        project = new LintModuleProject(client, dir, dir, module);
        AndroidFacet f = findAndroidFacetInProject(module.getProject());
        if (f != null) {
            project.gradleProject = f.requiresAndroidModel();
        }
    } else if (facet.requiresAndroidModel()) {
        AndroidModel androidModel = facet.getAndroidModel();
        if (androidModel instanceof AndroidModuleModel) {
            project = new LintGradleProject(client, dir, dir, facet, (AndroidModuleModel) androidModel);
        } else {
            project = new LintAndroidModelProject(client, dir, dir, facet, androidModel);
        }
    } else {
        project = new LintAndroidProject(client, dir, dir, facet);
    }
    if (project != null) {
        client.registerProject(dir, project);
    }
    return project;
}
Also used : AndroidModel(com.android.tools.idea.model.AndroidModel) AndroidModuleModel(com.android.tools.idea.gradle.project.model.AndroidModuleModel) VirtualFile(com.intellij.openapi.vfs.VirtualFile) File(java.io.File) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) Nullable(org.jetbrains.annotations.Nullable)

Example 49 with AndroidFacet

use of org.jetbrains.android.facet.AndroidFacet in project android by JetBrains.

the class LintIdeProject method addProjects.

/**
   * Recursively add lint projects for the given module, and any other module or library it depends on, and also
   * populate the reverse maps so we can quickly map from a lint project to a corresponding module/library (used
   * by the lint client
   */
private static void addProjects(@NonNull LintClient client, @NonNull Module module, @Nullable List<VirtualFile> files, @NonNull Map<Module, Project> moduleMap, @NonNull Map<AndroidLibrary, Project> libraryMap, @NonNull Map<Project, Module> projectMap, @NonNull List<Project> projects) {
    if (moduleMap.containsKey(module)) {
        return;
    }
    LintModuleProject project = createModuleProject(client, module);
    if (project == null) {
        // It's possible for the module to *depend* on Android code, e.g. in a Gradle
        // project there will be a top-level non-Android module
        List<AndroidFacet> dependentFacets = AndroidUtils.getAllAndroidDependencies(module, false);
        for (AndroidFacet dependentFacet : dependentFacets) {
            addProjects(client, dependentFacet.getModule(), files, moduleMap, libraryMap, projectMap, projects);
        }
        return;
    }
    projects.add(project);
    moduleMap.put(module, project);
    projectMap.put(project, module);
    if (processFileFilter(module, files, project)) {
        // No need to process dependencies when doing single file analysis
        return;
    }
    List<Project> dependencies = Lists.newArrayList();
    // No, this shouldn't use getAllAndroidDependencies; we may have non-Android dependencies that this won't include
    // (e.g. Java-only modules)
    List<AndroidFacet> dependentFacets = AndroidUtils.getAllAndroidDependencies(module, true);
    for (AndroidFacet dependentFacet : dependentFacets) {
        Project p = moduleMap.get(dependentFacet.getModule());
        if (p != null) {
            dependencies.add(p);
        } else {
            addProjects(client, dependentFacet.getModule(), files, moduleMap, libraryMap, projectMap, dependencies);
        }
    }
    AndroidFacet facet = AndroidFacet.getInstance(module);
    if (facet != null) {
        AndroidModuleModel androidModuleModel = AndroidModuleModel.get(facet);
        if (androidModuleModel != null) {
            addGradleLibraryProjects(client, files, libraryMap, projects, facet, androidModuleModel, project, projectMap, dependencies);
        }
    }
    project.setDirectLibraries(dependencies);
}
Also used : Project(com.android.tools.lint.detector.api.Project) AndroidModuleModel(com.android.tools.idea.gradle.project.model.AndroidModuleModel) AndroidFacet(org.jetbrains.android.facet.AndroidFacet)

Example 50 with AndroidFacet

use of org.jetbrains.android.facet.AndroidFacet in project android by JetBrains.

the class LintIdeProject method addAndroidModules.

private static void addAndroidModules(Set<AndroidFacet> androidFacets, Set<Module> seen, Graph<Module> graph, Module module) {
    Iterator<Module> iterator = graph.getOut(module);
    while (iterator.hasNext()) {
        Module dep = iterator.next();
        AndroidFacet facet = AndroidFacet.getInstance(dep);
        if (facet != null) {
            androidFacets.add(facet);
        }
        if (!seen.contains(dep)) {
            seen.add(dep);
            addAndroidModules(androidFacets, seen, graph, dep);
        }
    }
}
Also used : Module(com.intellij.openapi.module.Module) AndroidFacet(org.jetbrains.android.facet.AndroidFacet)

Aggregations

AndroidFacet (org.jetbrains.android.facet.AndroidFacet)299 Module (com.intellij.openapi.module.Module)122 VirtualFile (com.intellij.openapi.vfs.VirtualFile)73 NotNull (org.jetbrains.annotations.NotNull)61 Nullable (org.jetbrains.annotations.Nullable)51 Project (com.intellij.openapi.project.Project)39 File (java.io.File)29 AndroidModuleModel (com.android.tools.idea.gradle.project.model.AndroidModuleModel)28 PsiFile (com.intellij.psi.PsiFile)24 XmlFile (com.intellij.psi.xml.XmlFile)20 PsiElement (com.intellij.psi.PsiElement)17 FolderConfiguration (com.android.ide.common.resources.configuration.FolderConfiguration)16 XmlTag (com.intellij.psi.xml.XmlTag)16 ArrayList (java.util.ArrayList)16 Manifest (org.jetbrains.android.dom.manifest.Manifest)14 IAndroidTarget (com.android.sdklib.IAndroidTarget)13 ResourceFolderType (com.android.resources.ResourceFolderType)11 Configuration (com.android.tools.idea.configurations.Configuration)10 PsiClass (com.intellij.psi.PsiClass)10 XmlAttributeValue (com.intellij.psi.xml.XmlAttributeValue)10