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(); }
@NotNull public static List<XmlTag> getElementTags(@NotNull Collection<? extends DomElement> list) { ArrayList<XmlTag> result = new ArrayList<>(list.size()); for (DomElement element : list) { XmlTag tag = element.getXmlTag(); if (tag != null) { result.add(tag); } } return result; }
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); } } } }
@NotNull public static XmlTag[] getElementTags(@NotNull DomElement[] list) { XmlTag[] result = new XmlTag[list.length]; int i = 0; for (DomElement element : list) { XmlTag tag = element.getXmlTag(); if (tag != null) { result[i++] = tag; } } return result; }
@Nullable public static <T> T getParentOfType( final DomElement element, final Class<T> requiredClass, final boolean strict) { for (DomElement curElement = strict && element != null ? element.getParent() : element; curElement != null; curElement = curElement.getParent()) { if (requiredClass.isInstance(curElement)) { return (T) curElement; } } return null; }
@NotNull public static String[] getElementNames(@NotNull Collection<? extends DomElement> list) { ArrayList<String> result = new ArrayList<>(list.size()); if (list.size() > 0) { for (DomElement element : list) { String name = element.getGenericInfo().getElementName(element); if (name != null) { result.add(name); } } } return ArrayUtil.toStringArray(result); }
public static <T extends DomElement> DomFileElement<T> getFileElement( @NotNull DomElement element) { if (element instanceof DomFileElement) { return (DomFileElement) element; } DomFileElement fileElement = element.getUserData(FILE_ELEMENT_KEY); if (fileElement == null) { DomElement parent = element.getParent(); if (parent != null) { fileElement = getFileElement(parent); } element.putUserData(FILE_ELEMENT_KEY, fileElement); } return fileElement; }
@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; }
@Nullable public static List<JavaMethod> getFixedPath(DomElement element) { assert element.isValid(); final LinkedList<JavaMethod> methods = new LinkedList<>(); while (true) { final DomElement parent = element.getParent(); if (parent instanceof DomFileElement) { break; } final JavaMethod method = getGetterMethod(element, parent); if (method == null) { return null; } methods.addFirst(method); element = element.getParent(); } return methods; }
/** * @param domElement DomElement to search root of * @return the topmost valid DomElement being a parent of the given one. May be and may be not * DomFileElement. If root tag has changed, file may lose its domness, so there will be no * DomFileElement, but the inner DomElement's will be still alive because the underlying XML * tags are valid */ @NotNull public static DomElement getRoot(@NotNull DomElement domElement) { while (true) { final DomElement parent = domElement.getParent(); if (parent == null) { return domElement; } domElement = parent; } }
@Nullable private static JavaMethod getGetterMethod(final DomElement element, final DomElement parent) { final String xmlElementName = element.getXmlElementName(); final String namespace = element.getXmlElementNamespaceKey(); final DomGenericInfo genericInfo = parent.getGenericInfo(); if (element instanceof GenericAttributeValue) { final DomAttributeChildDescription description = genericInfo.getAttributeChildDescription(xmlElementName, namespace); assert description != null; return description.getGetterMethod(); } final DomFixedChildDescription description = genericInfo.getFixedChildDescription(xmlElementName, namespace); return description != null ? description.getGetterMethod(description.getValues(parent).indexOf(element)) : null; }
public static <T> List<T> getChildrenOfType( @NotNull final DomElement parent, final Class<T> type) { final List<T> result = new SmartList<>(); parent.acceptChildren( new DomElementVisitor() { @Override public void visitDomElement(final DomElement element) { if (type.isInstance(element)) { result.add((T) element); } } }); return result; }
@NotNull public static <T extends DomElement> T getOriginalElement(@NotNull final T domElement) { final XmlElement psiElement = domElement.getXmlElement(); if (psiElement == null) return domElement; final PsiFile psiFile = psiElement.getContainingFile().getOriginalFile(); final TextRange range = psiElement.getTextRange(); final PsiElement element = psiFile.findElementAt(range.getStartOffset()); final int maxLength = range.getLength(); final boolean isAttribute = psiElement instanceof XmlAttribute; final Class<? extends XmlElement> clazz = isAttribute ? XmlAttribute.class : XmlTag.class; final DomManager domManager = domElement.getManager(); DomElement current = null; for (XmlElement next = PsiTreeUtil.getParentOfType(element, clazz, false); next != null && next.getTextLength() <= maxLength; next = PsiTreeUtil.getParentOfType(next, clazz, true)) { current = isAttribute ? domManager.getDomElement((XmlAttribute) next) : domManager.getDomElement((XmlTag) next); if (current != null && domElement.getClass() != current.getClass()) current = null; } return (T) current; }
@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; }
public static List<? extends DomElement> getIdentitySiblings(DomElement element) { final GenericDomValue nameDomElement = element.getGenericInfo().getNameDomElement(element); if (nameDomElement == null) return Collections.emptyList(); final NameValue nameValue = nameDomElement.getAnnotation(NameValue.class); if (nameValue == null || !nameValue.unique()) return Collections.emptyList(); final String stringValue = ElementPresentationManager.getElementName(element); if (stringValue == null) return Collections.emptyList(); final DomElement scope = element.getManager().getIdentityScope(element); if (scope == null) return Collections.emptyList(); final DomGenericInfo domGenericInfo = scope.getGenericInfo(); final String tagName = element.getXmlElementName(); final DomCollectionChildDescription childDescription = domGenericInfo.getCollectionChildDescription(tagName, element.getXmlElementNamespaceKey()); if (childDescription != null) { final ArrayList<DomElement> list = new ArrayList<>(childDescription.getValues(scope)); list.remove(element); return list; } return Collections.emptyList(); }
public static boolean hasXml(@NotNull DomElement element) { return element.exists(); }
public static boolean isAncestor( @NotNull DomElement ancestor, @NotNull DomElement descendant, boolean strict) { if (!strict && ancestor.equals(descendant)) return true; final DomElement parent = descendant.getParent(); return parent != null && isAncestor(ancestor, parent, false); }