Search in sources :

Example 1 with SchemaTypeInfo

use of com.intellij.xml.index.SchemaTypeInfo in project intellij-community by JetBrains.

the class SchemaDefinitionsSearch method execute.

@Override
public boolean execute(@NotNull final PsiElement queryParameters, @NotNull final Processor<PsiElement> consumer) {
    if (queryParameters instanceof XmlTagImpl) {
        final XmlTagImpl xml = (XmlTagImpl) queryParameters;
        if (ReadAction.compute(() -> isTypeElement(xml))) {
            final Collection<SchemaTypeInfo> infos = ApplicationManager.getApplication().runReadAction(new Computable<Collection<SchemaTypeInfo>>() {

                @Override
                public Collection<SchemaTypeInfo> compute() {
                    return gatherInheritors(xml);
                }
            });
            if (infos != null && !infos.isEmpty()) {
                final XmlFile file = XmlUtil.getContainingFile(xml);
                final Project project = file.getProject();
                final Module module = ModuleUtilCore.findModuleForPsiElement(queryParameters);
                //if (module == null) return false;
                final VirtualFile vf = file.getVirtualFile();
                String thisNs = ApplicationManager.getApplication().runReadAction(new Computable<String>() {

                    @Override
                    public String compute() {
                        return XmlNamespaceIndex.getNamespace(vf, project, file);
                    }
                });
                thisNs = thisNs == null ? getDefaultNs(file) : thisNs;
                // so thisNs can be null
                if (thisNs == null)
                    return false;
                final ArrayList<SchemaTypeInfo> infosLst = new ArrayList<>(infos);
                Collections.sort(infosLst);
                final Map<String, Set<XmlFile>> nsMap = new HashMap<>();
                for (final SchemaTypeInfo info : infosLst) {
                    Set<XmlFile> targetFiles = nsMap.get(info.getNamespaceUri());
                    if (targetFiles == null) {
                        targetFiles = new HashSet<>();
                        if (Comparing.equal(info.getNamespaceUri(), thisNs)) {
                            targetFiles.add(file);
                        }
                        final Collection<XmlFile> files = ApplicationManager.getApplication().runReadAction(new Computable<Collection<XmlFile>>() {

                            @Override
                            public Collection<XmlFile> compute() {
                                return XmlUtil.findNSFilesByURI(info.getNamespaceUri(), project, module);
                            }
                        });
                        if (files != null) {
                            targetFiles.addAll(files);
                        }
                        nsMap.put(info.getNamespaceUri(), targetFiles);
                    }
                    if (!targetFiles.isEmpty()) {
                        for (final XmlFile targetFile : targetFiles) {
                            ApplicationManager.getApplication().runReadAction(() -> {
                                final String prefixByURI = XmlUtil.findNamespacePrefixByURI(targetFile, info.getNamespaceUri());
                                if (prefixByURI == null)
                                    return;
                                final PsiElementProcessor processor = new PsiElementProcessor() {

                                    @Override
                                    public boolean execute(@NotNull PsiElement element) {
                                        if (element instanceof XmlTagImpl) {
                                            if (isCertainTypeElement((XmlTagImpl) element, info.getTagName(), prefixByURI) || isElementWithEmbeddedType((XmlTagImpl) element, info.getTagName(), prefixByURI)) {
                                                consumer.process(element);
                                                return false;
                                            }
                                        }
                                        return true;
                                    }
                                };
                                XmlUtil.processXmlElements(targetFile, processor, true);
                            });
                        }
                    }
                }
            }
        }
    }
    return true;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) XmlTagImpl(com.intellij.psi.impl.source.xml.XmlTagImpl) HashSet(com.intellij.util.containers.hash.HashSet) XmlFile(com.intellij.psi.xml.XmlFile) HashMap(com.intellij.util.containers.hash.HashMap) NotNull(org.jetbrains.annotations.NotNull) PsiElementProcessor(com.intellij.psi.search.PsiElementProcessor) Project(com.intellij.openapi.project.Project) SchemaTypeInfo(com.intellij.xml.index.SchemaTypeInfo) Module(com.intellij.openapi.module.Module) PsiElement(com.intellij.psi.PsiElement)

Example 2 with SchemaTypeInfo

use of com.intellij.xml.index.SchemaTypeInfo in project intellij-community by JetBrains.

the class SchemaDefinitionsSearch method gatherInheritors.

private Collection<SchemaTypeInfo> gatherInheritors(XmlTagImpl xml) {
    XmlAttribute name = getNameAttr(xml);
    if (name == null || StringUtil.isEmptyOrSpaces(name.getValue()))
        return null;
    String localName = name.getValue();
    final boolean hasPrefix = localName.contains(":");
    localName = hasPrefix ? localName.substring(localName.indexOf(':') + 1) : localName;
    final String nsPrefix = hasPrefix ? name.getValue().substring(0, name.getValue().indexOf(':')) : null;
    final XmlFile file = XmlUtil.getContainingFile(xml);
    if (file == null)
        return null;
    final Project project = file.getProject();
    if (project == null)
        return null;
    final Set<SchemaTypeInfo> result = new HashSet<>();
    final ArrayDeque<SchemaTypeInfo> queue = new ArrayDeque<>();
    String nsUri;
    if (!hasPrefix) {
        nsUri = getDefaultNs(file);
    } else {
        nsUri = XmlUtil.findNamespaceByPrefix(nsPrefix, file.getRootTag());
    }
    if (nsUri == null)
        return null;
    queue.add(new SchemaTypeInfo(localName, true, nsUri));
    final BiFunction<String, String, List<Set<SchemaTypeInfo>>> worker = SchemaTypeInheritanceIndex.getWorker(project, file.getContainingFile().getVirtualFile());
    while (!queue.isEmpty()) {
        final SchemaTypeInfo info = queue.removeFirst();
        final List<Set<SchemaTypeInfo>> childrenOfType = worker.apply(info.getNamespaceUri(), info.getTagName());
        for (Set<SchemaTypeInfo> infos : childrenOfType) {
            for (SchemaTypeInfo typeInfo : infos) {
                if (typeInfo.isIsTypeName()) {
                    queue.add(typeInfo);
                }
                result.add(typeInfo);
            }
        }
    }
    return result;
}
Also used : XmlAttribute(com.intellij.psi.xml.XmlAttribute) HashSet(com.intellij.util.containers.hash.HashSet) XmlFile(com.intellij.psi.xml.XmlFile) Project(com.intellij.openapi.project.Project) SchemaTypeInfo(com.intellij.xml.index.SchemaTypeInfo) HashSet(com.intellij.util.containers.hash.HashSet)

Aggregations

Project (com.intellij.openapi.project.Project)2 XmlFile (com.intellij.psi.xml.XmlFile)2 HashSet (com.intellij.util.containers.hash.HashSet)2 SchemaTypeInfo (com.intellij.xml.index.SchemaTypeInfo)2 Module (com.intellij.openapi.module.Module)1 VirtualFile (com.intellij.openapi.vfs.VirtualFile)1 PsiElement (com.intellij.psi.PsiElement)1 XmlTagImpl (com.intellij.psi.impl.source.xml.XmlTagImpl)1 PsiElementProcessor (com.intellij.psi.search.PsiElementProcessor)1 XmlAttribute (com.intellij.psi.xml.XmlAttribute)1 HashMap (com.intellij.util.containers.hash.HashMap)1 NotNull (org.jetbrains.annotations.NotNull)1