| /* |
| * Copyright 2000-2014 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.util.xml.impl; |
| |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.util.ArrayUtil; |
| import com.intellij.util.Function; |
| import com.intellij.util.IncorrectOperationException; |
| import com.intellij.util.NotNullFunction; |
| import com.intellij.util.containers.ContainerUtil; |
| import com.intellij.util.xml.*; |
| import com.intellij.util.xml.reflect.DomCollectionChildDescription; |
| import com.intellij.psi.xml.XmlTag; |
| import com.intellij.psi.xml.XmlFile; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.AnnotatedElement; |
| import java.lang.reflect.Type; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| /** |
| * @author peter |
| */ |
| public class CollectionChildDescriptionImpl extends DomChildDescriptionImpl implements DomCollectionChildDescription, AbstractCollectionChildDescription { |
| private final Collection<JavaMethod> myGetterMethods; |
| private final NotNullFunction<DomInvocationHandler, List<XmlTag>> myTagsGetter = new NotNullFunction<DomInvocationHandler, List<XmlTag>>() { |
| @Override |
| @NotNull |
| public List<XmlTag> fun(final DomInvocationHandler handler) { |
| XmlTag tag = handler.getXmlTag(); |
| if (tag == null) { |
| return Collections.emptyList(); |
| } |
| return DomImplUtil.findSubTags(tag, handler.createEvaluatedXmlName(getXmlName()), handler.getFile()); |
| } |
| }; |
| |
| public CollectionChildDescriptionImpl(final XmlName tagName, final Type type, final Collection<JavaMethod> getterMethods) { |
| super(tagName, type); |
| myGetterMethods = getterMethods; |
| } |
| |
| @Override |
| public String toString() { |
| return "CollectionChildDescription:" + getXmlName(); |
| } |
| |
| public NotNullFunction<DomInvocationHandler, List<XmlTag>> getTagsGetter() { |
| return myTagsGetter; |
| } |
| |
| @Override |
| public DomElement addValue(@NotNull DomElement element) { |
| assert element.getGenericInfo().getCollectionChildrenDescriptions().contains(this); |
| return addChild(element, getType(), Integer.MAX_VALUE); |
| } |
| |
| private DomElement addChild(final DomElement element, final Type type, final int index) { |
| try { |
| final DomInvocationHandler handler = DomManagerImpl.getDomInvocationHandler(element); |
| assert handler != null; |
| return handler.addCollectionChild(this, type, index); |
| } |
| catch (IncorrectOperationException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| @Override |
| public DomElement addValue(@NotNull DomElement element, int index) { |
| return addChild(element, getType(), index); |
| } |
| |
| @Override |
| public DomElement addValue(@NotNull DomElement parent, Type type) { |
| return addValue(parent, type, Integer.MAX_VALUE); |
| } |
| |
| @Override |
| public final DomElement addValue(@NotNull DomElement parent, Type type, int index) { |
| return addChild(parent, type, index); |
| } |
| |
| @Override |
| @Nullable |
| public final JavaMethod getGetterMethod() { |
| final Collection<JavaMethod> methods = myGetterMethods; |
| return methods.isEmpty() ? null : methods.iterator().next(); |
| } |
| |
| @Override |
| @NotNull |
| public List<? extends DomElement> getValues(@NotNull final DomElement element) { |
| final DomInvocationHandler handler = DomManagerImpl.getDomInvocationHandler(element); |
| if (handler != null) { |
| return handler.getCollectionChildren(this, myTagsGetter); |
| } |
| final JavaMethod getterMethod = getGetterMethod(); |
| if (getterMethod == null) { |
| final Collection<DomElement> collection = ModelMergerUtil.getFilteredImplementations(element); |
| return ContainerUtil.concat(collection, new Function<DomElement, Collection<? extends DomElement>>() { |
| @Override |
| public Collection<? extends DomElement> fun(final DomElement domElement) { |
| final DomInvocationHandler handler = DomManagerImpl.getDomInvocationHandler(domElement); |
| assert handler != null : domElement; |
| return handler.getCollectionChildren(CollectionChildDescriptionImpl.this, myTagsGetter); |
| } |
| }); |
| } |
| return (List<? extends DomElement>)getterMethod.invoke(element, ArrayUtil.EMPTY_OBJECT_ARRAY); |
| } |
| |
| @Override |
| @NotNull |
| public String getCommonPresentableName(@NotNull DomNameStrategy strategy) { |
| String words = strategy.splitIntoWords(getXmlElementName()); |
| return StringUtil.capitalizeWords(words.endsWith("es") ? words: StringUtil.pluralize(words), true); |
| } |
| |
| @Override |
| @Nullable |
| public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { |
| final JavaMethod method = getGetterMethod(); |
| if (method != null) { |
| final T annotation = method.getAnnotation(annotationClass); |
| if (annotation != null) return annotation; |
| } |
| |
| final Type elemType = getType(); |
| return elemType instanceof AnnotatedElement ? ((AnnotatedElement)elemType).getAnnotation(annotationClass) : super.getAnnotation(annotationClass); |
| } |
| |
| @Override |
| public List<XmlTag> getSubTags(final DomInvocationHandler handler, final XmlTag[] subTags, final XmlFile file) { |
| return DomImplUtil.findSubTags(subTags, handler.createEvaluatedXmlName(getXmlName()), file); |
| } |
| |
| @Override |
| public EvaluatedXmlName createEvaluatedXmlName(final DomInvocationHandler parent, final XmlTag childTag) { |
| return parent.createEvaluatedXmlName(getXmlName()); |
| } |
| } |