public Object[] get(final PsiElement context, CompletionContext completionContext) { XmlFile containingFile = null; XmlFile descriptorFile = null; final XmlTag tag = PsiTreeUtil.getParentOfType(context, XmlTag.class); if (tag != null) { containingFile = (XmlFile) tag.getContainingFile(); descriptorFile = findDescriptorFile(tag, containingFile); } else { final XmlDocument document = PsiTreeUtil.getParentOfType(context, XmlDocument.class); if (document != null) { containingFile = (XmlFile) document.getContainingFile(); final FileType ft = containingFile.getFileType(); if (ft != StdFileTypes.XML) { final String namespace = ft == StdFileTypes.XHTML || ft == StdFileTypes.JSPX ? XmlUtil.XHTML_URI : XmlUtil.HTML_URI; final XmlNSDescriptor nsDescriptor = document.getDefaultNSDescriptor(namespace, true); if (nsDescriptor != null) { descriptorFile = nsDescriptor.getDescriptorFile(); } } } } if (descriptorFile != null) { final List<Object> results = new ArrayList<Object>(); final boolean acceptSystemEntities = containingFile.getFileType() == StdFileTypes.XML; final PsiElementProcessor processor = new PsiElementProcessor() { public boolean execute(@NotNull final PsiElement element) { if (element instanceof XmlEntityDecl) { final XmlEntityDecl xmlEntityDecl = (XmlEntityDecl) element; if (xmlEntityDecl.isInternalReference() || acceptSystemEntities) { final String name = xmlEntityDecl.getName(); final Object _item = getLookupItem(xmlEntityDecl); results.add(_item == null ? name : _item); } } return true; } }; XmlUtil.processXmlElements(descriptorFile, processor, true); if (descriptorFile != containingFile && containingFile.getFileType() == StdFileTypes.XML) { final XmlProlog element = containingFile.getDocument().getProlog(); if (element != null) XmlUtil.processXmlElements(element, processor, true); } return ArrayUtil.toObjectArray(results); } return ArrayUtil.EMPTY_OBJECT_ARRAY; }
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); } }
@Nullable private XmlNSDescriptor getNSDescriptorFromMetaData( @Nullable PsiMetaOwner metaOwner, boolean nonEmpty) { if (metaOwner == null) return null; XmlNSDescriptor descriptor = (XmlNSDescriptor) metaOwner.getMetaData(); if (descriptor == null) return null; if (nonEmpty && descriptor.getRootElementsDescriptors(this).length == 0) { return null; } return descriptor; }
@Nullable private <T> T processSchema(String schema, SchemaProcessor<T> processor) { VirtualFile file = MavenSchemaProvider.getSchemaFile(schema); PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); if (!(psiFile instanceof XmlFile)) return null; XmlFile xmlFile = (XmlFile) psiFile; XmlDocument document = xmlFile.getDocument(); XmlNSDescriptor desc = (XmlNSDescriptor) document.getMetaData(); XmlElementDescriptor[] descriptors = desc.getRootElementsDescriptors(document); return doProcessSchema(descriptors, null, processor, new THashSet<XmlElementDescriptor>()); }
public static XmlFile findDescriptorFile(final XmlTag tag, final XmlFile containingFile) { final XmlElementDescriptor descriptor = tag.getDescriptor(); final XmlNSDescriptor nsDescriptor = descriptor != null ? descriptor.getNSDescriptor() : null; XmlFile descriptorFile = nsDescriptor != null ? nsDescriptor.getDescriptorFile() : containingFile.getDocument().getProlog().getDoctype() != null ? containingFile : null; if (nsDescriptor != null && (descriptorFile == null || descriptorFile.getName().equals(containingFile.getName() + ".dtd"))) { descriptorFile = containingFile; } return descriptorFile; }
@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; }
private boolean isGeneratedFromDtd(XmlNSDescriptor defaultNSDescriptorInner) { if (defaultNSDescriptorInner == null) { return false; } XmlFile descriptorFile = defaultNSDescriptorInner.getDescriptorFile(); if (descriptorFile == null) { return false; } @NonNls String otherName = XmlUtil.getContainingFile(this).getName() + ".dtd"; return descriptorFile.getName().equals(otherName); }
@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; }