@NotNull public PsiReference[] getReferences() { ProgressManager.checkCanceled(); final ASTNode startTagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(this); if (startTagName == null) return PsiReference.EMPTY_ARRAY; final ASTNode endTagName = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(this); List<PsiReference> refs = new ArrayList<PsiReference>(); String prefix = getNamespacePrefix(); TagNameReference startTagRef = TagNameReference.createTagNameReference(this, startTagName, true); refs.add(startTagRef); if (prefix.length() > 0) { refs.add(createPrefixReference(startTagName, prefix, startTagRef)); } if (endTagName != null) { TagNameReference endTagRef = TagNameReference.createTagNameReference(this, endTagName, false); refs.add(endTagRef); prefix = XmlUtil.findPrefixByQualifiedName(endTagName.getText()); if (StringUtil.isNotEmpty(prefix)) { refs.add(createPrefixReference(endTagName, prefix, endTagRef)); } } // ArrayList.addAll() makes a clone of the collection //noinspection ManualArrayToCollectionCopy for (PsiReference ref : ReferenceProvidersRegistry.getReferencesFromProviders(this, XmlTag.class)) { refs.add(ref); } return ContainerUtil.toArray(refs, new PsiReference[refs.size()]); }
@NotNull public XmlTag[] findSubTags(final String name, final String namespace) { final XmlTag[] subTags = getSubTags(); final List<XmlTag> result = new ArrayList<XmlTag>(); for (final XmlTag subTag : subTags) { if (namespace == null) { if (name.equals(subTag.getName())) result.add(subTag); } else if (name.equals(subTag.getLocalName()) && namespace.equals(subTag.getNamespace())) { result.add(subTag); } } return ContainerUtil.toArray(result, new XmlTag[result.size()]); }
@SuppressWarnings("ForLoopReplaceableByForEach") public static <T extends DomElement> List<T> getChildrenOf( DomElement parent, final Class<T> type) { final List<T> list = new SmartList<>(); List<? extends AbstractDomChildrenDescription> descriptions = parent.getGenericInfo().getChildrenDescriptions(); for (int i = 0, descriptionsSize = descriptions.size(); i < descriptionsSize; i++) { AbstractDomChildrenDescription description = descriptions.get(i); if (description.getType() instanceof Class && type.isAssignableFrom((Class<?>) description.getType())) { List<T> values = (List<T>) description.getValues(parent); for (int j = 0, valuesSize = values.size(); j < valuesSize; j++) { T value = values.get(j); if (value.exists()) { list.add(value); } } } } return list; }
@NotNull public XmlTagValue getValue() { XmlTagValue tagValue = myValue; if (tagValue == null) { final PsiElement[] elements = getElements(); final List<XmlTagChild> bodyElements = new ArrayList<XmlTagChild>(elements.length); boolean insideBody = false; for (final PsiElement element : elements) { final ASTNode treeElement = element.getNode(); if (insideBody) { if (treeElement.getElementType() == XmlTokenType.XML_END_TAG_START) break; if (!(element instanceof XmlTagChild)) continue; bodyElements.add((XmlTagChild) element); } else if (treeElement.getElementType() == XmlTokenType.XML_TAG_END) insideBody = true; } XmlTagChild[] tagChildren = ContainerUtil.toArray(bodyElements, new XmlTagChild[bodyElements.size()]); myValue = tagValue = new XmlTagValueImpl(tagChildren, this); } return tagValue; }
@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()); } }; }
private void fetchDtd( final Project project, final String dtdUrl, final String url, final ProgressIndicator indicator) throws IOException { final String extResourcesPath = getExternalResourcesPath(); final File extResources = new File(extResourcesPath); LOG.assertTrue(extResources.mkdirs() || extResources.exists(), extResources); final PsiManager psiManager = PsiManager.getInstance(project); ApplicationManager.getApplication() .invokeAndWait( () -> { @SuppressWarnings("deprecation") final AccessToken token = ApplicationManager.getApplication() .acquireWriteActionLock(FetchExtResourceAction.class); try { final String path = FileUtil.toSystemIndependentName(extResources.getAbsolutePath()); final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(path); LOG.assertTrue(vFile != null, path); } finally { token.finish(); } }, indicator.getModalityState()); final List<String> downloadedResources = new LinkedList<>(); final List<String> resourceUrls = new LinkedList<>(); final IOException[] nestedException = new IOException[1]; try { final String resPath = fetchOneFile(indicator, url, project, extResourcesPath, null); if (resPath == null) return; resourceUrls.add(dtdUrl); downloadedResources.add(resPath); VirtualFile virtualFile = findFileByPath(resPath, dtdUrl, indicator); Set<String> linksToProcess = new HashSet<>(); Set<String> processedLinks = new HashSet<>(); Map<String, String> baseUrls = new HashMap<>(); VirtualFile contextFile = virtualFile; linksToProcess.addAll(extractEmbeddedFileReferences(virtualFile, null, psiManager, url)); while (!linksToProcess.isEmpty()) { String s = linksToProcess.iterator().next(); linksToProcess.remove(s); processedLinks.add(s); final boolean absoluteUrl = s.startsWith(HTTP_PROTOCOL); String resourceUrl; if (absoluteUrl) { resourceUrl = s; } else { String baseUrl = baseUrls.get(s); if (baseUrl == null) baseUrl = url; resourceUrl = baseUrl.substring(0, baseUrl.lastIndexOf('/') + 1) + s; } String resourcePath; String refname = s.substring(s.lastIndexOf('/') + 1); if (absoluteUrl) refname = Integer.toHexString(s.hashCode()) + "_" + refname; try { resourcePath = fetchOneFile(indicator, resourceUrl, project, extResourcesPath, refname); } catch (IOException e) { nestedException[0] = new FetchingResourceIOException(e, resourceUrl); break; } if (resourcePath == null) break; virtualFile = findFileByPath(resourcePath, absoluteUrl ? s : null, indicator); downloadedResources.add(resourcePath); if (absoluteUrl) { resourceUrls.add(s); } final Set<String> newLinks = extractEmbeddedFileReferences(virtualFile, contextFile, psiManager, resourceUrl); for (String u : newLinks) { baseUrls.put(u, resourceUrl); if (!processedLinks.contains(u)) linksToProcess.add(u); } } } catch (IOException ex) { nestedException[0] = ex; } if (nestedException[0] != null) { cleanup(resourceUrls, downloadedResources); throw nestedException[0]; } }