예제 #1
0
  @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()]);
  }
예제 #2
0
 @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()]);
 }
예제 #3
0
 @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;
 }
예제 #4
0
  @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];
    }
  }