package com.intellij.flex.uiDesigner; import com.intellij.flex.uiDesigner.mxml.ProjectComponentReferenceCounter; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.lang.javascript.flex.JSFlexFileReference; import com.intellij.lang.javascript.psi.ecmal4.JSClass; import com.intellij.lang.properties.ResourceBundleReference; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.roots.ModuleFileIndex; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference; import com.intellij.psi.xml.XmlFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public final class InjectionUtil { public static boolean isSwf(VirtualFile source, String mimeType) { return mimeType == null ? source.getName().endsWith(".swf") : mimeType.equals("application/x-shockwave-flash"); } public static boolean isImage(VirtualFile source, String mimeType) { if (mimeType == null) { String extension = source.getExtension(); if (extension != null) { extension = extension.toLowerCase(); if (extension.equals("png") || extension.equals("gif") || extension.equals("jpg") || extension.equals("jpeg")) { return true; } } } else if (mimeType.equals("image/png") || mimeType.equals("image/gif") || mimeType.equals("image/jpeg")) { return true; } return false; } public static int getProjectComponentFactoryId(JSClass jsClass, ProjectComponentReferenceCounter referenceCounter) throws InvalidPropertyException { PsiFile psiFile = jsClass.getContainingFile(); VirtualFile virtualFile = psiFile.getVirtualFile(); assert virtualFile != null; if (checkSupportedProjectComponentFile(virtualFile, psiFile, jsClass.getQualifiedName())) { return DocumentFactoryManager.getInstance().getId(virtualFile, (XmlFile)psiFile, referenceCounter); } else { return -1; } } private static boolean checkSupportedProjectComponentFile(VirtualFile virtualFile, PsiFile psiFile, String qualifiedClassName) throws InvalidPropertyException { boolean inSourceContent = ProjectRootManager.getInstance(psiFile.getProject()).getFileIndex().isInSourceContent(virtualFile); if (psiFile instanceof XmlFile) { if (inSourceContent) { return true; } } else if (inSourceContent) { throw new InvalidPropertyException("support.only.mxml.based.component", qualifiedClassName); } return false; } public static boolean isProjectComponent(JSClass jsClass) throws InvalidPropertyException { PsiFile psiFile = jsClass.getContainingFile(); VirtualFile virtualFile = psiFile.getVirtualFile(); assert virtualFile != null; return checkSupportedProjectComponentFile(virtualFile, psiFile, jsClass.getQualifiedName()); } @Nullable public static JSClass getJsClassFromPackageAndLocalClassNameReferences(PsiElement element) { return getJsClassFromPackageAndLocalClassNameReferences(element.getReferences()); } @Nullable public static JSClass getJsClassFromPackageAndLocalClassNameReferences(PsiReference[] references) { if (references.length > 0) { PsiElement element = references[references.length - 1].resolve(); if (element instanceof JSClass) { return (JSClass)element; } } return null; } @NotNull public static VirtualFile getReferencedFile(PsiElement element) throws InvalidPropertyException { //noinspection ConstantConditions return getReferencedPsiFile(element, false).getVirtualFile(); } @NotNull public static PsiFileSystemItem getReferencedPsiFile(PsiElement element) throws InvalidPropertyException { return getReferencedPsiFile(element, false); } @NotNull public static PsiFileSystemItem getReferencedPsiFile(PsiElement element, boolean resolveToFirstIfMulti) throws InvalidPropertyException { final PsiReference[] references = element.getReferences(); final PsiPolyVariantReference fileReference; int i = references.length - 1; // injection in mxml has JSAttributeNameValuePairImpl$NameReference as last reference while (true) { final PsiReference reference = i < 0 ? null : references[i]; if (reference instanceof JSFlexFileReference || reference instanceof ResourceBundleReference) { fileReference = (PsiPolyVariantReference)reference; break; } else if (--i < 0) { throw new InvalidPropertyException(element, "cannot.find.file.reference"); } } // IDEA-68144 ResolveResult[] resolveResults = fileReference.multiResolve(false); final PsiFileSystemItem psiFile; if (resolveResults.length == 0) { psiFile = null; } else if (resolveResults.length == 1 || resolveToFirstIfMulti) { psiFile = (PsiFileSystemItem)resolveResults[0].getElement(); } else { psiFile = resolveResult(element, resolveResults); } if (psiFile == null) { if (fileReference instanceof FileReference) { throw new InvalidPropertyException(((FileReference)fileReference).getUnresolvedMessagePattern(), element); } else { throw new InvalidPropertyException(element, "unresolved.resource.bundle", fileReference.getCanonicalText()); } } else if (psiFile.isDirectory()) { throw new InvalidPropertyException(element, "embed.source.is.directory", fileReference.getCanonicalText()); } else { return psiFile; } } @Nullable private static PsiFileSystemItem resolveResult(PsiElement element, ResolveResult[] resolveResults) { InjectedLanguageManager manager = InjectedLanguageManager.getInstance(element.getProject()); final PsiFile currentTopLevelFile = manager.getTopLevelFile(element); // find equal files for (ResolveResult resolveResult : resolveResults) { PsiElement resolvedElement = resolveResult.getElement(); assert resolvedElement != null; if (manager.getTopLevelFile(resolvedElement).equals(currentTopLevelFile)) { return (PsiFileSystemItem)resolvedElement; } } final Module module = ModuleUtilCore.findModuleForPsiElement(element); if (module != null) { final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex(); // return if is local file for (ResolveResult resolveResult : resolveResults) { PsiFileSystemItem resolvedElement = (PsiFileSystemItem)resolveResult.getElement(); assert resolvedElement != null; VirtualFile virtualFile = resolvedElement.getVirtualFile(); if (virtualFile != null && fileIndex.isInSourceContent(virtualFile)) { return resolvedElement; } } } return (PsiFileSystemItem)resolveResults[0].getElement(); } }