public XmlNSDescriptor getNSDescriptor(final String namespace, boolean strict) { final XmlTag parentTag = getParentTag(); if (parentTag == null && namespace.equals(XmlUtil.XHTML_URI)) { final XmlNSDescriptor descriptor = getDtdDescriptor(XmlUtil.getContainingFile(this)); if (descriptor != null) { return descriptor; } } Map<String, CachedValue<XmlNSDescriptor>> map = initNSDescriptorsMap(); final CachedValue<XmlNSDescriptor> descriptor = map.get(namespace); if (descriptor != null) { final XmlNSDescriptor value = descriptor.getValue(); if (value != null) { return value; } } if (parentTag == null) { final XmlDocument parentOfType = PsiTreeUtil.getParentOfType(this, XmlDocument.class); if (parentOfType == null) { return null; } return parentOfType.getDefaultNSDescriptor(namespace, strict); } return parentTag.getNSDescriptor(namespace, strict); }
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); } }
@Override public void visitXmlDocument(final XmlDocument document) { if (document.getLanguage() == DTDLanguage.INSTANCE) { final PsiMetaData psiMetaData = document.getMetaData(); if (psiMetaData instanceof Validator) { //noinspection unchecked ((Validator<XmlDocument>) psiMetaData).validate(document, this); } } }
public static void handleError( SAXParseException ex, PsiFile file, Document document, ValidationMessageConsumer consumer) { final String systemId = ex.getSystemId(); if (LOG.isDebugEnabled()) { LOG.debug("RNG Schema error: " + ex.getMessage() + " [" + systemId + "]"); } if (systemId != null) { final VirtualFile virtualFile = findVirtualFile(systemId); if (!Comparing.equal(virtualFile, file.getVirtualFile())) { return; } } final PsiElement at; final int line = ex.getLineNumber(); if (line > 0) { final int column = ex.getColumnNumber(); final int startOffset = document.getLineStartOffset(line - 1); if (column > 0) { if (file.getFileType() == RncFileType.getInstance()) { final PsiElement e = file.findElementAt(startOffset + column); if (e == null) { at = e; } else { at = file.findElementAt(startOffset + column - 1); } } else { at = file.findElementAt(startOffset + column - 2); } } else { final PsiElement e = file.findElementAt(startOffset); at = e != null ? PsiTreeUtil.nextLeaf(e) : null; } } else { final XmlDocument d = ((XmlFile) file).getDocument(); assert d != null; final XmlTag rootTag = d.getRootTag(); assert rootTag != null; at = rootTag.getFirstChild(); } final PsiElement host; if (file instanceof RncFile) { host = at; } else { host = PsiTreeUtil.getParentOfType(at, XmlAttribute.class, XmlTag.class); } if (at != null && host != null) { consumer.onMessage(host, ex.getMessage()); } else { consumer.onMessage(file, ex.getMessage()); } }
@Nullable private static XmlNSDescriptor getDtdDescriptor(@NotNull XmlFile containingFile) { final XmlDocument document = containingFile.getDocument(); if (document == null) { return null; } final String url = XmlUtil.getDtdUri(document); if (url == null) { return null; } return document.getDefaultNSDescriptor(url, true); }
@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; }
private XmlNSDescriptor getDefaultNSDescriptorInner( final String namespace, final boolean strict) { final XmlFile containingFile = XmlUtil.getContainingFile(this); if (containingFile == null) return null; final XmlProlog prolog = getProlog(); final XmlDoctype doctype = prolog != null ? prolog.getDoctype() : null; boolean dtdUriFromDocTypeIsNamespace = false; if (XmlUtil.HTML_URI.equals(namespace)) { XmlNSDescriptor nsDescriptor = doctype != null ? getNsDescriptorFormDocType(doctype, containingFile, true) : null; if (doctype != null) { LOG.debug( "Descriptor from doctype " + doctype + " is " + (nsDescriptor != null ? nsDescriptor.getClass().getCanonicalName() : "NULL")); } if (nsDescriptor == null) { String htmlns = ExternalResourceManagerEx.getInstanceEx().getDefaultHtmlDoctype(getProject()); if (htmlns.isEmpty()) { htmlns = Html5SchemaProvider.getHtml5SchemaLocation(); } nsDescriptor = getDefaultNSDescriptor(htmlns, false); } return new HtmlNSDescriptorImpl(nsDescriptor); } else if (XmlUtil.XHTML_URI.equals(namespace)) { String xhtmlNamespace = XmlUtil.getDefaultXhtmlNamespace(getProject()); if (xhtmlNamespace == null || xhtmlNamespace.isEmpty()) { xhtmlNamespace = Html5SchemaProvider.getXhtml5SchemaLocation(); } return getDefaultNSDescriptor(xhtmlNamespace, false); } else if (namespace != null && namespace != XmlUtil.EMPTY_URI) { if (doctype == null || !namespace.equals(XmlUtil.getDtdUri(doctype))) { boolean documentIsSchemaThatDefinesNs = namespace.equals(XmlUtil.getTargetSchemaNsFromTag(getRootTag())); final XmlFile xmlFile = documentIsSchemaThatDefinesNs ? containingFile : XmlUtil.findNamespace(containingFile, namespace); if (xmlFile != null) { final XmlDocument document = xmlFile.getDocument(); if (document != null) { return (XmlNSDescriptor) document.getMetaData(); } } } else { dtdUriFromDocTypeIsNamespace = true; } } if (strict && !dtdUriFromDocTypeIsNamespace) return null; if (doctype != null) { XmlNSDescriptor descr = getNsDescriptorFormDocType(doctype, containingFile, false); if (descr != null) { return XmlExtension.getExtension(containingFile) .getDescriptorFromDoctype(containingFile, descr); } } if (strict) return null; if (namespace == XmlUtil.EMPTY_URI) { final XmlFile xmlFile = XmlUtil.findNamespace(containingFile, namespace); if (xmlFile != null) { return (XmlNSDescriptor) xmlFile.getDocument().getMetaData(); } } try { final PsiFile fileFromText = PsiFileFactory.getInstance(getProject()) .createFileFromText( containingFile.getName() + ".dtd", DTDLanguage.INSTANCE, XmlUtil.generateDocumentDTD(this, false), false, false); if (fileFromText instanceof XmlFile) { fileFromText.putUserData(AUTO_GENERATED, Boolean.TRUE); return (XmlNSDescriptor) ((XmlFile) fileFromText).getDocument().getMetaData(); } } catch (ProcessCanceledException ex) { throw ex; } catch (RuntimeException ignored) { } // e.g. dtd isn't mapped to xml type return null; }
@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()); } }; }