コード例 #1
0
 public String[] knownNamespaces() {
   final PsiElement parentElement = getParent();
   BidirectionalMap<String, String> map = initNamespaceMaps(parentElement);
   Set<String> known = Collections.emptySet();
   if (map != null) {
     known = new HashSet<String>(map.values());
   }
   if (parentElement instanceof XmlTag) {
     if (known.isEmpty()) return ((XmlTag) parentElement).knownNamespaces();
     ContainerUtil.addAll(known, ((XmlTag) parentElement).knownNamespaces());
   } else {
     XmlExtension xmlExtension = XmlExtension.getExtensionByElement(this);
     if (xmlExtension != null) {
       final XmlFile xmlFile = xmlExtension.getContainingFile(this);
       if (xmlFile != null) {
         final XmlTag rootTag = xmlFile.getRootTag();
         if (rootTag != null && rootTag != this) {
           if (known.isEmpty()) return rootTag.knownNamespaces();
           ContainerUtil.addAll(known, rootTag.knownNamespaces());
         }
       }
     }
   }
   return ArrayUtil.toStringArray(known);
 }
コード例 #2
0
 @Nullable
 @NonNls
 public String getSubTagText(@NonNls String qname) {
   final XmlTag tag = findFirstSubTag(qname);
   if (tag == null) return null;
   return tag.getValue().getText();
 }
コード例 #3
0
  public static String findUrl(PsiFile file, int offset, String uri) {
    final PsiElement currentElement = file.findElementAt(offset);
    final XmlAttribute attribute = PsiTreeUtil.getParentOfType(currentElement, XmlAttribute.class);

    if (attribute != null) {
      final XmlTag tag = PsiTreeUtil.getParentOfType(currentElement, XmlTag.class);

      if (tag != null) {
        final String prefix = tag.getPrefixByNamespace(XmlUtil.XML_SCHEMA_INSTANCE_URI);
        if (prefix != null) {
          final String attrValue =
              tag.getAttributeValue(XmlUtil.SCHEMA_LOCATION_ATT, XmlUtil.XML_SCHEMA_INSTANCE_URI);
          if (attrValue != null) {
            final StringTokenizer tokenizer = new StringTokenizer(attrValue);

            while (tokenizer.hasMoreElements()) {
              if (uri.equals(tokenizer.nextToken())) {
                if (!tokenizer.hasMoreElements()) return uri;
                final String url = tokenizer.nextToken();

                return url.startsWith(HTTP_PROTOCOL) ? url : uri;
              }

              if (!tokenizer.hasMoreElements()) return uri;
              tokenizer.nextToken(); // skip file location
            }
          }
        }
      }
    }
    return uri;
  }
コード例 #4
0
 @NotNull
 public XPathType getExpectedType(XPathExpression expr) {
   final XmlTag tag = PsiTreeUtil.getContextOfType(expr, XmlTag.class, true);
   if (tag != null && XsltSupport.isXsltTag(tag)) {
     final XsltElement element =
         XsltElementFactory.getInstance().wrapElement(tag, XsltElement.class);
     if (element instanceof XsltVariable) {
       return ((XsltVariable) element).getType();
     } else {
       final XmlAttribute attr = PsiTreeUtil.getContextOfType(expr, XmlAttribute.class, true);
       if (attr != null) {
         if (element instanceof XsltWithParam) {
           final XmlAttribute nameAttr = tag.getAttribute("name", null);
           if (nameAttr != null) {
             final XmlAttributeValue valueElement = nameAttr.getValueElement();
             if (valueElement != null) {
               final PsiReference[] references = valueElement.getReferences();
               for (PsiReference reference : references) {
                 final PsiElement psiElement = reference.resolve();
                 if (psiElement instanceof XsltVariable) {
                   return ((XsltVariable) psiElement).getType();
                 }
               }
             }
           }
         } else {
           final String name = attr.getName();
           return getTypeForTag(tag, name);
         }
       }
     }
   }
   return XPathType.UNKNOWN;
 }
コード例 #5
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);
  }
コード例 #6
0
  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);
    }
  }
コード例 #7
0
 private static XmlTag createTag(
     @NotNull XmlTag contextTag, @NotNull XmlElementDescriptor descriptor) {
   String namespace = getNamespace(descriptor);
   XmlTag tag = contextTag.createChildTag(descriptor.getName(), namespace, null, false);
   PsiElement lastChild = tag.getLastChild();
   assert lastChild != null;
   lastChild.delete(); // remove XML_EMPTY_ELEMENT_END
   return tag;
 }
コード例 #8
0
  public static Pair<TextRange, PsiElement> getProblemRange(final XmlTag tag) {
    final PsiElement startToken = XmlTagUtil.getStartTagNameElement(tag);
    if (startToken == null) {
      return Pair.create(tag.getTextRange(), (PsiElement) tag);
    }

    return Pair.create(
        startToken.getTextRange().shiftRight(-tag.getTextRange().getStartOffset()),
        (PsiElement) tag);
  }
コード例 #9
0
  @Override
  protected boolean isValidForFile(
      @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
    if (!(file instanceof XmlFile)) return false;

    XmlTag contextTag = getContextTag(editor, file);
    return contextTag != null
        && isInsideTagBody(contextTag, editor)
        && contextTag.getDescriptor() != null;
  }
コード例 #10
0
 public static void acceptAvailableChildren(
     final DomElement element, final DomElementVisitor visitor) {
   final XmlTag tag = element.getXmlTag();
   if (tag != null) {
     for (XmlTag xmlTag : tag.getSubTags()) {
       final DomElement childElement = element.getManager().getDomElement(xmlTag);
       if (childElement != null) {
         childElement.accept(visitor);
       }
     }
   }
 }
コード例 #11
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()]);
 }
コード例 #12
0
  private static void processElementDescriptors(
      XmlElementDescriptor descriptor,
      XmlTag tag,
      ElementNames names,
      Set<XmlElementDescriptor> history) {
    if (!history.add(descriptor)) {
      return;
    }
    final String namespace =
        descriptor instanceof XmlElementDescriptorImpl
            ? ((XmlElementDescriptorImpl) descriptor).getNamespace()
            : tag.getNamespace();
    names.elementNames.add(new QName(namespace, descriptor.getName()));

    final XmlAttributeDescriptor[] attributesDescriptors =
        descriptor.getAttributesDescriptors(null);
    for (XmlAttributeDescriptor attributesDescriptor : attributesDescriptors) {
      final String localPart = attributesDescriptor.getName();
      if (!"xmlns".equals(localPart)) names.attributeNames.add(new QName(localPart));
    }

    final XmlElementDescriptor[] descriptors = descriptor.getElementsDescriptors(tag);
    for (XmlElementDescriptor elem : descriptors) {
      processElementDescriptors(elem, tag, names, history);
    }
  }
コード例 #13
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;
  }
コード例 #14
0
  @Nullable
  public static <T extends DomElement> T findDomElement(
      @Nullable final PsiElement element, final Class<T> beanClass, boolean strict) {
    if (element == null) return null;

    XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class, strict);
    DomElement domElement;

    while (tag != null) {
      domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag);

      if (domElement != null) {
        return domElement.getParentOfType(beanClass, false);
      }
      tag = tag.getParentTag();
    }
    return null;
  }
コード例 #15
0
 public static void generateTag(@NotNull XmlTag newTag, Editor editor) {
   generateRaw(newTag);
   final XmlTag restored = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(newTag);
   if (restored == null) {
     LOG.error("Could not restore tag: " + newTag.getText());
   }
   TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(restored);
   replaceElements(restored, builder);
   builder.run(editor, false);
 }
コード例 #16
0
  public static List<DomElement> getDefinedChildren(
      @NotNull final DomElement parent, final boolean tags, final boolean attributes) {
    if (parent instanceof MergedObject) {
      final SmartList<DomElement> result = new SmartList<>();
      parent.acceptChildren(
          new DomElementVisitor() {
            @Override
            public void visitDomElement(final DomElement element) {
              if (hasXml(element)) {
                result.add(element);
              }
            }
          });
      return result;
    }

    ProgressManager.checkCanceled();

    if (parent instanceof GenericAttributeValue) return Collections.emptyList();

    if (parent instanceof DomFileElement) {
      final DomFileElement element = (DomFileElement) parent;
      return tags ? Arrays.asList(element.getRootElement()) : Collections.<DomElement>emptyList();
    }

    final XmlElement xmlElement = parent.getXmlElement();
    if (xmlElement instanceof XmlTag) {
      XmlTag tag = (XmlTag) xmlElement;
      final DomManager domManager = parent.getManager();
      final SmartList<DomElement> result = new SmartList<>();
      if (attributes) {
        for (final XmlAttribute attribute : tag.getAttributes()) {
          if (!attribute.isValid()) {
            LOG.error("Invalid attr: parent.valid=" + tag.isValid());
            continue;
          }
          GenericAttributeValue element = domManager.getDomElement(attribute);
          if (checkHasXml(attribute, element)) {
            ContainerUtil.addIfNotNull(result, element);
          }
        }
      }
      if (tags) {
        for (final XmlTag subTag : tag.getSubTags()) {
          if (!subTag.isValid()) {
            LOG.error("Invalid subtag: parent.valid=" + tag.isValid());
            continue;
          }
          DomElement element = domManager.getDomElement(subTag);
          if (checkHasXml(subTag, element)) {
            ContainerUtil.addIfNotNull(result, element);
          }
        }
      }
      return result;
    }
    return Collections.emptyList();
  }
コード例 #17
0
 private static void replaceElements(XmlTag tag, TemplateBuilder builder) {
   for (XmlAttribute attribute : tag.getAttributes()) {
     XmlAttributeValue value = attribute.getValueElement();
     if (value != null) {
       builder.replaceElement(value, TextRange.from(1, 0), new MacroCallNode(new CompleteMacro()));
     }
   }
   if ("<".equals(tag.getText())) {
     builder.replaceElement(
         tag, TextRange.from(1, 0), new MacroCallNode(new CompleteSmartMacro()));
   } else if (tag.getSubTags().length == 0) {
     int i = tag.getText().indexOf("></");
     if (i > 0) {
       builder.replaceElement(
           tag, TextRange.from(i + 1, 0), new MacroCallNode(new CompleteMacro()));
     }
   }
   for (XmlTag subTag : tag.getSubTags()) {
     replaceElements(subTag, builder);
   }
 }
コード例 #18
0
  @Nullable
  public static DomElement getDomElement(@Nullable final PsiElement element) {
    if (element == null) return null;

    final Project project = element.getProject();
    final DomManager domManager = DomManager.getDomManager(project);
    final XmlAttribute attr = PsiTreeUtil.getParentOfType(element, XmlAttribute.class, false);
    if (attr != null) {
      final GenericAttributeValue value = domManager.getDomElement(attr);
      if (value != null) return value;
    }

    XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class, false);
    while (tag != null) {
      final DomElement domElement = domManager.getDomElement(tag);
      if (domElement != null) return domElement;

      tag = tag.getParentTag();
    }
    return null;
  }
コード例 #19
0
 @Override
 public void visitXmlTag(XmlTag tag) {
   super.visitXmlTag(tag);
   final XmlElementDescriptor descriptor = tag.getDescriptor();
   if (descriptor instanceof JavaFxClassTagDescriptorBase) {
     appendClassName(descriptor.getDeclaration());
   } else if (descriptor instanceof JavaFxPropertyTagDescriptor
       && ((JavaFxPropertyTagDescriptor) descriptor).isStatic()) {
     final PsiElement declaration = descriptor.getDeclaration();
     if (declaration instanceof PsiMember) {
       appendClassName(((PsiMember) declaration).getContainingClass());
     }
   }
 }
コード例 #20
0
 private static void generateRaw(final @NotNull XmlTag newTag) {
   XmlElementDescriptor selected = newTag.getDescriptor();
   if (selected == null) return;
   switch (selected.getContentType()) {
     case XmlElementDescriptor.CONTENT_TYPE_EMPTY:
       newTag.collapseIfEmpty();
       ASTNode node = newTag.getNode();
       assert node != null;
       ASTNode elementEnd = node.findChildByType(XmlTokenType.XML_EMPTY_ELEMENT_END);
       if (elementEnd == null) {
         LeafElement emptyTagEnd =
             Factory.createSingleLeafElement(
                 XmlTokenType.XML_EMPTY_ELEMENT_END, "/>", 0, 2, null, newTag.getManager());
         node.addChild(emptyTagEnd);
       }
       break;
     case XmlElementDescriptor.CONTENT_TYPE_MIXED:
       newTag.getValue().setText("");
   }
   for (XmlAttributeDescriptor descriptor : selected.getAttributesDescriptors(newTag)) {
     if (descriptor.isRequired()) {
       newTag.setAttribute(descriptor.getName(), "");
     }
   }
   List<XmlElementDescriptor> tags = getRequiredSubTags(selected);
   for (XmlElementDescriptor descriptor : tags) {
     if (descriptor == null) {
       XmlTag tag =
           XmlElementFactory.getInstance(newTag.getProject())
               .createTagFromText("<", newTag.getLanguage());
       newTag.addSubTag(tag, false);
     } else {
       XmlTag subTag = newTag.addSubTag(createTag(newTag, descriptor), false);
       generateRaw(subTag);
     }
   }
 }
コード例 #21
0
 @Nullable
 private static XmlTag getAnchor(
     @NotNull XmlTag contextTag, Editor editor, XmlElementDescriptor selected) {
   XmlContentDFA contentDFA = XmlContentDFA.getContentDFA(contextTag);
   int offset = editor.getCaretModel().getOffset();
   if (contentDFA == null) {
     return null;
   }
   XmlTag anchor = null;
   boolean previousPositionIsPossible = true;
   for (XmlTag subTag : contextTag.getSubTags()) {
     if (contentDFA.getPossibleElements().contains(selected)) {
       if (subTag.getTextOffset() > offset) {
         break;
       }
       anchor = subTag;
       previousPositionIsPossible = true;
     } else {
       previousPositionIsPossible = false;
     }
     contentDFA.transition(subTag);
   }
   return previousPositionIsPossible ? null : anchor;
 }
コード例 #22
0
 protected XPathType getTypeForTag(XmlTag tag, String attribute) {
   String tagName = tag.getLocalName();
   if ("select".equals(attribute)) {
     if ("copy-of".equals(tagName)
         || "for-each".equals(tagName)
         || "apply-templates".equals(tagName)) {
       return XPathType.NODESET;
     } else if ("value-of".equals(tagName) || "sort".equals(tagName)) {
       return XPathType.STRING;
     }
     return XPathType.ANY;
   } else if ("test".equals(attribute)) {
     if ("if".equals(tagName) || "when".equals(tagName)) {
       return XPathType.BOOLEAN;
     }
   } else if ("number".equals(attribute)) {
     if ("value".equals(tagName)) {
       return XPathType.NUMBER;
     }
   }
   return XPathType.UNKNOWN;
 }
コード例 #23
0
  @Override
  public void invoke(
      @NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
    if (!CodeInsightUtilBase.prepareEditorForWrite(editor)) return;
    try {
      final XmlTag contextTag = getContextTag(editor, file);
      if (contextTag == null) {
        throw new CommonRefactoringUtil.RefactoringErrorHintException(
            "Caret should be positioned inside a tag");
      }
      XmlElementDescriptor currentTagDescriptor = contextTag.getDescriptor();
      assert currentTagDescriptor != null;
      final XmlElementDescriptor[] descriptors =
          currentTagDescriptor.getElementsDescriptors(contextTag);
      Arrays.sort(
          descriptors,
          new Comparator<XmlElementDescriptor>() {
            @Override
            public int compare(XmlElementDescriptor o1, XmlElementDescriptor o2) {
              return o1.getName().compareTo(o2.getName());
            }
          });
      final JBList list = new JBList(descriptors);
      list.setCellRenderer(new MyListCellRenderer());
      Runnable runnable =
          new Runnable() {
            @Override
            public void run() {
              final XmlElementDescriptor selected = (XmlElementDescriptor) list.getSelectedValue();
              new WriteCommandAction.Simple(project, "Generate XML Tag", file) {
                @Override
                protected void run() {
                  if (selected == null) return;
                  XmlTag newTag = createTag(contextTag, selected);

                  PsiElement anchor = getAnchor(contextTag, editor, selected);
                  if (anchor == null) { // insert it in the cursor position
                    int offset = editor.getCaretModel().getOffset();
                    Document document = editor.getDocument();
                    document.insertString(offset, newTag.getText());
                    PsiDocumentManager.getInstance(project).commitDocument(document);
                    newTag =
                        PsiTreeUtil.getParentOfType(
                            file.findElementAt(offset + 1), XmlTag.class, false);
                  } else {
                    newTag = (XmlTag) contextTag.addAfter(newTag, anchor);
                  }
                  if (newTag != null) {
                    generateTag(newTag, editor);
                  }
                }
              }.execute();
            }
          };
      if (ApplicationManager.getApplication().isUnitTestMode()) {
        XmlElementDescriptor descriptor =
            ContainerUtil.find(
                descriptors,
                new Condition<XmlElementDescriptor>() {
                  @Override
                  public boolean value(XmlElementDescriptor xmlElementDescriptor) {
                    return xmlElementDescriptor.getName().equals(TEST_THREAD_LOCAL.get());
                  }
                });
        list.setSelectedValue(descriptor, false);
        runnable.run();
      } else {
        JBPopupFactory.getInstance()
            .createListPopupBuilder(list)
            .setTitle("Choose Tag Name")
            .setItemChoosenCallback(runnable)
            .setFilteringEnabled(
                new Function<Object, String>() {
                  @Override
                  public String fun(Object o) {
                    return ((XmlElementDescriptor) o).getName();
                  }
                })
            .createPopup()
            .showInBestPositionFor(editor);
      }
    } catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
      HintManager.getInstance().showErrorHint(editor, e.getMessage());
    }
  }
コード例 #24
0
 private static boolean isInsideTagBody(XmlTag contextTag, @NotNull Editor editor) {
   return contextTag.getValue().getTextRange().contains(editor.getCaretModel().getOffset());
 }