Пример #1
0
    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>());
  }
Пример #5
0
 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;
 }
Пример #6
0
  @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;
  }