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 Set<String> extractEmbeddedFileReferences( XmlFile file, XmlFile context, final String url) { final Set<String> result = new LinkedHashSet<>(); if (context != null) { XmlEntityCache.copyEntityCaches(file, context); } XmlUtil.processXmlElements( file, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiElement element) { if (element instanceof XmlEntityDecl) { String candidateName = null; for (PsiElement e = element.getLastChild(); e != null; e = e.getPrevSibling()) { if (e instanceof XmlAttributeValue && candidateName == null) { candidateName = e.getText().substring(1, e.getTextLength() - 1); } else if (e instanceof XmlToken && candidateName != null && (((XmlToken) e).getTokenType() == XmlTokenType.XML_DOCTYPE_PUBLIC || ((XmlToken) e).getTokenType() == XmlTokenType.XML_DOCTYPE_SYSTEM)) { if (!result.contains(candidateName)) { result.add(candidateName); } break; } } } else if (element instanceof XmlTag) { final XmlTag tag = (XmlTag) element; String schemaLocation = tag.getAttributeValue(XmlUtil.SCHEMA_LOCATION_ATT); if (schemaLocation != null) { // processing xsd:import && xsd:include final PsiReference[] references = tag.getAttribute(XmlUtil.SCHEMA_LOCATION_ATT).getValueElement().getReferences(); if (references.length > 0) { String extension = FileUtilRt.getExtension(new File(url).getName()); final String namespace = tag.getAttributeValue("namespace"); if (namespace != null && schemaLocation.indexOf('/') == -1 && !extension.equals(FileUtilRt.getExtension(schemaLocation))) { result.add( namespace.substring(0, namespace.lastIndexOf('/') + 1) + schemaLocation); } else { result.add(schemaLocation); } } } else { schemaLocation = tag.getAttributeValue( XmlUtil.SCHEMA_LOCATION_ATT, XmlUtil.XML_SCHEMA_INSTANCE_URI); if (schemaLocation != null) { final StringTokenizer tokenizer = new StringTokenizer(schemaLocation); while (tokenizer.hasMoreTokens()) { tokenizer.nextToken(); if (!tokenizer.hasMoreTokens()) break; String location = tokenizer.nextToken(); result.add(location); } } } } return true; } }, true, true); return result; }