@Nullable protected XmlElementDescriptor computeElementDescriptor() { for (XmlElementDescriptorProvider provider : Extensions.getExtensions(XmlElementDescriptorProvider.EP_NAME)) { XmlElementDescriptor elementDescriptor = provider.getDescriptor(this); if (elementDescriptor != null) { return elementDescriptor; } } final String namespace = getNamespace(); if (XmlUtil.EMPTY_URI.equals(namespace)) { // nonqualified items final XmlTag parent = getParentTag(); if (parent != null) { final XmlElementDescriptor descriptor = parent.getDescriptor(); if (descriptor != null) { XmlElementDescriptor fromParent = descriptor.getElementDescriptor(this, parent); if (fromParent != null && !(fromParent instanceof AnyXmlElementDescriptor)) { return fromParent; } } } } XmlElementDescriptor elementDescriptor = null; final XmlNSDescriptor nsDescriptor = getNSDescriptor(namespace, false); LOG.debug( "Descriptor for namespace " + namespace + " is " + (nsDescriptor != null ? nsDescriptor.getClass().getCanonicalName() : "NULL")); if (nsDescriptor != null) { if (!DumbService.getInstance(getProject()).isDumb() || DumbService.isDumbAware(nsDescriptor)) { elementDescriptor = nsDescriptor.getElementDescriptor(this); } } if (elementDescriptor == null) { return XmlUtil.findXmlDescriptorByType(this); } return elementDescriptor; }
@Nullable private XmlNSDescriptor getNsDescriptorFormDocType( final XmlDoctype doctype, final XmlFile containingFile, final boolean forHtml) { XmlNSDescriptor descriptor = getNSDescriptorFromMetaData(doctype.getMarkupDecl(), true); final String filePath = getFilePathForLogging(containingFile); final String dtdUri = XmlUtil.getDtdUri(doctype); LOG.debug( "DTD url for doctype " + doctype.getText() + " in file " + filePath + " is " + dtdUri); if (dtdUri != null && !dtdUri.isEmpty()) { XmlFile xmlFile = XmlUtil.findNamespace(containingFile, dtdUri); if (xmlFile == null) { // try to auto-detect it xmlFile = XmlNamespaceIndex.guessDtd(dtdUri, containingFile); } final String schemaFilePath = getFilePathForLogging(xmlFile); LOG.debug("Schema file for " + filePath + " is " + schemaFilePath); XmlNSDescriptor descriptorFromDtd = getNSDescriptorFromMetaData(xmlFile == null ? null : xmlFile.getDocument(), forHtml); LOG.debug( "Descriptor from meta data for schema file " + schemaFilePath + " is " + (descriptorFromDtd != null ? descriptorFromDtd.getClass().getCanonicalName() : "NULL")); if (descriptor != null && descriptorFromDtd != null) { descriptor = new XmlNSDescriptorSequence(new XmlNSDescriptor[] {descriptor, descriptorFromDtd}); } else if (descriptorFromDtd != null) { descriptor = descriptorFromDtd; } } return descriptor; }
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; }