Ejemplo n.º 1
0
  public XmlNSDescriptor getNSDescriptor(final String namespace, boolean strict) {
    final XmlTag parentTag = getParentTag();

    if (parentTag == null && namespace.equals(XmlUtil.XHTML_URI)) {
      final XmlNSDescriptor descriptor = getDtdDescriptor(XmlUtil.getContainingFile(this));
      if (descriptor != null) {
        return descriptor;
      }
    }

    Map<String, CachedValue<XmlNSDescriptor>> map = initNSDescriptorsMap();
    final CachedValue<XmlNSDescriptor> descriptor = map.get(namespace);
    if (descriptor != null) {
      final XmlNSDescriptor value = descriptor.getValue();
      if (value != null) {
        return value;
      }
    }

    if (parentTag == null) {
      final XmlDocument parentOfType = PsiTreeUtil.getParentOfType(this, XmlDocument.class);
      if (parentOfType == null) {
        return null;
      }
      return parentOfType.getDefaultNSDescriptor(namespace, strict);
    }

    return parentTag.getNSDescriptor(namespace, strict);
  }
  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);
    }
  }
 @Override
 public void visitXmlDocument(final XmlDocument document) {
   if (document.getLanguage() == DTDLanguage.INSTANCE) {
     final PsiMetaData psiMetaData = document.getMetaData();
     if (psiMetaData instanceof Validator) {
       //noinspection unchecked
       ((Validator<XmlDocument>) psiMetaData).validate(document, this);
     }
   }
 }
  public static void handleError(
      SAXParseException ex, PsiFile file, Document document, ValidationMessageConsumer consumer) {
    final String systemId = ex.getSystemId();
    if (LOG.isDebugEnabled()) {
      LOG.debug("RNG Schema error: " + ex.getMessage() + " [" + systemId + "]");
    }

    if (systemId != null) {
      final VirtualFile virtualFile = findVirtualFile(systemId);
      if (!Comparing.equal(virtualFile, file.getVirtualFile())) {
        return;
      }
    }

    final PsiElement at;
    final int line = ex.getLineNumber();
    if (line > 0) {
      final int column = ex.getColumnNumber();
      final int startOffset = document.getLineStartOffset(line - 1);

      if (column > 0) {
        if (file.getFileType() == RncFileType.getInstance()) {
          final PsiElement e = file.findElementAt(startOffset + column);
          if (e == null) {
            at = e;
          } else {
            at = file.findElementAt(startOffset + column - 1);
          }
        } else {
          at = file.findElementAt(startOffset + column - 2);
        }
      } else {
        final PsiElement e = file.findElementAt(startOffset);
        at = e != null ? PsiTreeUtil.nextLeaf(e) : null;
      }
    } else {
      final XmlDocument d = ((XmlFile) file).getDocument();
      assert d != null;
      final XmlTag rootTag = d.getRootTag();
      assert rootTag != null;
      at = rootTag.getFirstChild();
    }

    final PsiElement host;
    if (file instanceof RncFile) {
      host = at;
    } else {
      host = PsiTreeUtil.getParentOfType(at, XmlAttribute.class, XmlTag.class);
    }
    if (at != null && host != null) {
      consumer.onMessage(host, ex.getMessage());
    } else {
      consumer.onMessage(file, ex.getMessage());
    }
  }
Ejemplo n.º 5
0
 @Nullable
 private static XmlNSDescriptor getDtdDescriptor(@NotNull XmlFile containingFile) {
   final XmlDocument document = containingFile.getDocument();
   if (document == null) {
     return null;
   }
   final String url = XmlUtil.getDtdUri(document);
   if (url == null) {
     return null;
   }
   return document.getDefaultNSDescriptor(url, true);
 }
  @Nullable
  @Override
  public MyValidationMessageConsumer collectInformation(@NotNull final PsiFile file) {
    final FileType type = file.getFileType();
    if (type != StdFileTypes.XML && type != RncFileType.getInstance()) {
      return null;
    }
    final XmlFile xmlfile = (XmlFile) file;
    final XmlDocument document = xmlfile.getDocument();
    if (document == null) {
      return null;
    }
    if (type == StdFileTypes.XML) {
      final XmlTag rootTag = document.getRootTag();
      if (rootTag == null) {
        return null;
      }
      if (!ApplicationLoader.RNG_NAMESPACE.equals(rootTag.getNamespace())) {
        return null;
      }
    } else {
      if (!ApplicationManager.getApplication().isUnitTestMode()
          && MyErrorFinder.hasError(xmlfile)) {
        return null;
      }
    }
    final Document doc = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);

    final MyValidationMessageConsumer consumer = new MyValidationMessageConsumer();
    ErrorHandler eh =
        new DefaultHandler() {
          @Override
          public void warning(SAXParseException e) {
            handleError(e, file, doc, consumer.warning());
          }

          @Override
          public void error(SAXParseException e) {
            handleError(e, file, doc, consumer.error());
          }
        };

    RngParser.parsePattern(file, eh, true);
    return consumer;
  }
  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;
  }
  @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());
      }
    };
  }