private static void fillFromSchema(PsiFile file, ElementNames names) { if (!(file instanceof XmlFile)) return; final XmlFile f = (XmlFile) file; final XmlDocument d = f.getDocument(); if (d == null) return; final XmlTag rootTag = d.getRootTag(); if (rootTag == null) return; //noinspection unchecked names.dependencies.add(new NSDeclTracker(rootTag)); try { final Map<String, String> namespaceDeclarations = rootTag.getLocalNamespaceDeclarations(); final Collection<String> prefixes = namespaceDeclarations.keySet(); //noinspection unchecked final Set<XmlElementDescriptor> history = new THashSet<XmlElementDescriptor>(); final XmlElementFactory ef = XmlElementFactory.getInstance(file.getProject()); int noSchemaNamespaces = 0; for (String prefix : prefixes) { final String namespace = namespaceDeclarations.get(prefix); if (isIgnoredNamespace(prefix, namespace)) continue; final XmlTag tag = ef.createTagFromText("<dummy-tag xmlns='" + namespace + "' />", XMLLanguage.INSTANCE); final XmlDocument document = PsiTreeUtil.getParentOfType(tag, XmlDocument.class); final XmlNSDescriptor rootDescriptor = tag.getNSDescriptor(tag.getNamespace(), true); if (rootDescriptor == null || (rootDescriptor instanceof XmlNSDescriptorImpl && ((XmlNSDescriptorImpl) rootDescriptor).getTag() == null) || !rootDescriptor.getDeclaration().isPhysical()) { final QName any = QNameUtil.createAnyLocalName(namespace); names.elementNames.add(any); names.attributeNames.add(any); noSchemaNamespaces++; continue; } //noinspection unchecked names.dependencies.add(rootDescriptor.getDescriptorFile()); final XmlElementDescriptor[] e = rootDescriptor.getRootElementsDescriptors(document); for (XmlElementDescriptor descriptor : e) { processElementDescriptors(descriptor, tag, names, history); } } names.validateNames = names.elementNames.size() > noSchemaNamespaces; // final QName any = QNameUtil.createAnyLocalName(""); // names.elementNames.add(any); // names.attributeNames.add(any); } catch (IncorrectOperationException e) { Logger.getInstance(XsltContextProvider.class.getName()).error(e); } }
private CachedValue<ElementNames> createCachedValue(final PsiFile file) { return CachedValuesManager.getManager(file.getProject()) .createCachedValue( new CachedValueProvider<ElementNames>() { public Result<ElementNames> compute() { final ElementNames names = new ElementNames(); final PsiFile[] associations = myFileAssociationsManager.getAssociationsFor( file, FileAssociationsManager.XML_FILES); if (associations.length == 0) { fillFromSchema(file, names); } else { names.validateNames = true; //noinspection unchecked ContainerUtil.addAll(names.dependencies, associations); } //noinspection unchecked names.dependencies.add(myFileAssociationsManager); for (PsiFile file : associations) { if (!(file instanceof XmlFile)) continue; file.accept( new XmlRecursiveElementVisitor() { @Override public void visitXmlTag(XmlTag tag) { names.elementNames.add(QNameUtil.createQName(tag)); super.visitXmlTag(tag); } @Override public void visitXmlAttribute(XmlAttribute attribute) { if (!attribute.isNamespaceDeclaration()) { names.attributeNames.add(QNameUtil.createQName(attribute)); } super.visitXmlAttribute(attribute); } }); } //noinspection unchecked return new Result<ElementNames>(names, ArrayUtil.toObjectArray(names.dependencies)); } }, false); }
@Nullable @Override public MyValidationMessageConsumer collectInformation(@NotNull final PsiFile file) { final FileType type = file.getFileType(); if (type != StdFileTypes.XML && type != RncFileType.getInstance()) { return null; } final XmlFile xmlfile = (XmlFile) file; final XmlDocument document = xmlfile.getDocument(); if (document == null) { return null; } if (type == StdFileTypes.XML) { final XmlTag rootTag = document.getRootTag(); if (rootTag == null) { return null; } if (!ApplicationLoader.RNG_NAMESPACE.equals(rootTag.getNamespace())) { return null; } } else { if (!ApplicationManager.getApplication().isUnitTestMode() && MyErrorFinder.hasError(xmlfile)) { return null; } } final Document doc = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); final MyValidationMessageConsumer consumer = new MyValidationMessageConsumer(); ErrorHandler eh = new DefaultHandler() { @Override public void warning(SAXParseException e) { handleError(e, file, doc, consumer.warning()); } @Override public void error(SAXParseException e) { handleError(e, file, doc, consumer.error()); } }; RngParser.parsePattern(file, eh, true); return consumer; }
@NotNull @Override public Runnable processFile(final PsiFile file) { VirtualFile vFile = file.getVirtualFile(); if (vFile instanceof VirtualFileWindow) vFile = ((VirtualFileWindow) vFile).getDelegate(); final Project project = file.getProject(); if (vFile == null || !ProjectRootManager.getInstance(project).getFileIndex().isInSourceContent(vFile)) { return EmptyRunnable.INSTANCE; } final List<Pair<String, Boolean>> names = new ArrayList<Pair<String, Boolean>>(); final Set<String> demandedForNested = new HashSet<>(); collectNamesToImport(names, demandedForNested, (XmlFile) file); Collections.sort(names, (o1, o2) -> StringUtil.compare(o1.first, o2.first, true)); final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(project); final List<Pair<String, Boolean>> sortedNames = ImportHelper.sortItemsAccordingToSettings(names, settings); final HashSet<String> onDemand = new HashSet<String>(); ImportHelper.collectOnDemandImports(sortedNames, onDemand, settings); onDemand.addAll(demandedForNested); final Set<String> imported = new HashSet<String>(); final List<String> imports = new ArrayList<String>(); for (Pair<String, Boolean> pair : sortedNames) { final String qName = pair.first; final String packageName = StringUtil.getPackageName(qName); if (imported.contains(packageName) || imported.contains(qName)) { continue; } if (onDemand.contains(packageName)) { imported.add(packageName); imports.add("<?import " + packageName + ".*?>"); } else { imported.add(qName); imports.add("<?import " + qName + "?>"); } } final PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject()); final XmlFile dummyFile = (XmlFile) factory.createFileFromText( "_Dummy_.fxml", StdFileTypes.XML, StringUtil.join(imports, "\n")); final XmlDocument document = dummyFile.getDocument(); final XmlProlog newImportList = document != null ? document.getProlog() : null; if (newImportList == null) return EmptyRunnable.getInstance(); return () -> { final XmlDocument xmlDocument = ((XmlFile) file).getDocument(); final XmlProlog prolog = xmlDocument != null ? xmlDocument.getProlog() : null; if (prolog != null) { final Collection<XmlProcessingInstruction> instructions = PsiTreeUtil.findChildrenOfType(prolog, XmlProcessingInstruction.class); for (final XmlProcessingInstruction instruction : instructions) { final ASTNode node = instruction.getNode(); final ASTNode nameNode = node.findChildByType(XmlTokenType.XML_NAME); if (nameNode != null && nameNode.getText().equals("import")) { instruction.delete(); } } prolog.add(newImportList); } else { document.addBefore(newImportList, document.getRootTag()); } }; }