예제 #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 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;
  }