| /* |
| * 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.xml.impl.dom; |
| |
| import com.intellij.pom.PomTarget; |
| import com.intellij.pom.references.PomService; |
| import com.intellij.psi.PsiElement; |
| import com.intellij.psi.xml.XmlAttribute; |
| import com.intellij.psi.xml.XmlDocument; |
| import com.intellij.psi.xml.XmlFile; |
| import com.intellij.psi.xml.XmlTag; |
| import com.intellij.util.xml.DomElement; |
| import com.intellij.util.xml.DomManager; |
| import com.intellij.util.xml.EvaluatedXmlName; |
| import com.intellij.util.xml.impl.AttributeChildDescriptionImpl; |
| import com.intellij.util.xml.reflect.*; |
| import com.intellij.xml.XmlAttributeDescriptor; |
| import com.intellij.xml.XmlElementDescriptor; |
| import com.intellij.xml.XmlElementsGroup; |
| import com.intellij.xml.XmlNSDescriptor; |
| import com.intellij.xml.impl.schema.AnyXmlElementDescriptor; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * @author peter |
| */ |
| public abstract class AbstractDomChildrenDescriptor implements XmlElementDescriptor { |
| protected final DomManager myManager; |
| |
| protected AbstractDomChildrenDescriptor(DomManager manager) { |
| myManager = manager; |
| } |
| |
| @Override |
| public XmlElementDescriptor[] getElementsDescriptors(final XmlTag context) { |
| final DomElement domElement = myManager.getDomElement(context); |
| if (domElement == null) return EMPTY_ARRAY; |
| |
| List<XmlElementDescriptor> xmlElementDescriptors = new ArrayList<XmlElementDescriptor>(); |
| |
| for (DomCollectionChildDescription childrenDescription : domElement.getGenericInfo().getCollectionChildrenDescriptions()) { |
| xmlElementDescriptors.add(new DomElementXmlDescriptor(childrenDescription, myManager)); |
| } |
| |
| for (DomFixedChildDescription childrenDescription : domElement.getGenericInfo().getFixedChildrenDescriptions()) { |
| xmlElementDescriptors.add(new DomElementXmlDescriptor(childrenDescription, myManager)); |
| } |
| |
| final List<? extends CustomDomChildrenDescription> customs = domElement.getGenericInfo().getCustomNameChildrenDescription(); |
| |
| for (final CustomDomChildrenDescription custom : customs) { |
| final CustomDomChildrenDescription.TagNameDescriptor tagNameDescriptor = custom.getTagNameDescriptor(); |
| if (tagNameDescriptor == null) continue; |
| final XmlTag xmlTag = domElement.getXmlTag(); |
| for (final EvaluatedXmlName name : tagNameDescriptor.getCompletionVariants(domElement)) { |
| AbstractDomChildrenDescriptor descriptor = new AbstractDomChildrenDescriptor(myManager) { |
| @Override |
| public String getDefaultName() { |
| final String ns = xmlTag != null ? name.getNamespace(xmlTag, (XmlFile)xmlTag.getContainingFile()) : null; |
| if (ns != null) { |
| final String prefix = xmlTag.getPrefixByNamespace(ns); |
| if (prefix != null) { |
| return prefix + ":" + name.getXmlName().getLocalName(); |
| } |
| } |
| return name.getXmlName().getLocalName(); |
| } |
| |
| @Override |
| @Nullable |
| public PsiElement getDeclaration() { |
| final PomTarget target = tagNameDescriptor.findDeclaration(domElement, name); |
| return target == null ? null : PomService.convertToPsi(context.getProject(), target); |
| } |
| }; |
| xmlElementDescriptors.add(descriptor); |
| } |
| |
| xmlElementDescriptors.add(new AnyXmlElementDescriptor(this, getNSDescriptor())); |
| } |
| |
| return xmlElementDescriptors.toArray(new XmlElementDescriptor[xmlElementDescriptors.size()]); |
| } |
| |
| @Override |
| public XmlElementsGroup getTopGroup() { |
| return null; |
| } |
| |
| @Override |
| @Nullable |
| public XmlElementDescriptor getElementDescriptor(@NotNull final XmlTag childTag, @Nullable XmlTag contextTag) { |
| DomElement domElement = myManager.getDomElement(childTag); |
| if (domElement == null) { |
| domElement = myManager.getDomElement(contextTag); |
| if (domElement != null) { |
| AbstractDomChildrenDescription description = myManager.findChildrenDescription(childTag, domElement); |
| if (description instanceof DomChildrenDescription) { |
| return new DomElementXmlDescriptor((DomChildrenDescription)description, myManager); |
| } |
| } |
| return null; |
| } |
| |
| final DomElement parent = domElement.getParent(); |
| if (parent == null) return new DomElementXmlDescriptor(domElement); |
| |
| final AbstractDomChildrenDescription description = domElement.getChildDescription(); |
| if (description instanceof CustomDomChildrenDescription) { |
| final DomElement finalDomElement = domElement; |
| return new AbstractDomChildrenDescriptor(myManager) { |
| @Override |
| public String getDefaultName() { |
| return finalDomElement.getXmlElementName(); |
| } |
| |
| @Override |
| @Nullable |
| public PsiElement getDeclaration() { |
| final PomTarget target = ((CustomDomChildrenDescription)description).getTagNameDescriptor().findDeclaration(finalDomElement); |
| if (target == description) { |
| return childTag; |
| } |
| return target == null ? null : PomService.convertToPsi(childTag.getProject(), target); |
| } |
| |
| }; |
| } |
| if (!(description instanceof DomChildrenDescription)) return null; |
| |
| return new DomElementXmlDescriptor((DomChildrenDescription)description, myManager); |
| } |
| |
| @Override |
| public XmlAttributeDescriptor[] getAttributesDescriptors(final @Nullable XmlTag context) { |
| if (context == null) return XmlAttributeDescriptor.EMPTY; |
| |
| DomElement domElement = myManager.getDomElement(context); |
| if (domElement == null) return XmlAttributeDescriptor.EMPTY; |
| |
| final List<? extends DomAttributeChildDescription> descriptions = domElement.getGenericInfo().getAttributeChildrenDescriptions(); |
| List<XmlAttributeDescriptor> descriptors = new ArrayList<XmlAttributeDescriptor>(); |
| |
| for (DomAttributeChildDescription description : descriptions) { |
| descriptors.add(new DomAttributeXmlDescriptor(description, myManager.getProject())); |
| } |
| List<? extends CustomDomChildrenDescription> customs = domElement.getGenericInfo().getCustomNameChildrenDescription(); |
| for (CustomDomChildrenDescription custom : customs) { |
| CustomDomChildrenDescription.AttributeDescriptor descriptor = custom.getCustomAttributeDescriptor(); |
| if (descriptor != null) { |
| for (EvaluatedXmlName variant : descriptor.getCompletionVariants(domElement)) { |
| AttributeChildDescriptionImpl childDescription = new AttributeChildDescriptionImpl(variant.getXmlName(), String.class); |
| descriptors.add(new DomAttributeXmlDescriptor(childDescription, myManager.getProject())); |
| } |
| } |
| } |
| return descriptors.toArray(new XmlAttributeDescriptor[descriptors.size()]); |
| } |
| |
| @Override |
| @Nullable |
| public XmlAttributeDescriptor getAttributeDescriptor(final String attributeName, final @Nullable XmlTag context) { |
| DomElement domElement = myManager.getDomElement(context); |
| if (domElement == null) return null; |
| |
| for (DomAttributeChildDescription description : domElement.getGenericInfo().getAttributeChildrenDescriptions()) { |
| if (attributeName.equals(DomAttributeXmlDescriptor.getQualifiedAttributeName(context, description.getXmlName()))) { |
| return new DomAttributeXmlDescriptor(description, myManager.getProject()); |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| @Nullable |
| public XmlAttributeDescriptor getAttributeDescriptor(final XmlAttribute attribute) { |
| return getAttributeDescriptor(attribute.getName(), attribute.getParent()); |
| } |
| |
| @Override |
| public XmlNSDescriptor getNSDescriptor() { |
| return new XmlNSDescriptor() { |
| @Override |
| @Nullable |
| public XmlElementDescriptor getElementDescriptor(@NotNull final XmlTag tag) { |
| throw new UnsupportedOperationException("Method getElementDescriptor not implemented in " + getClass()); |
| } |
| |
| @Override |
| @NotNull |
| public XmlElementDescriptor[] getRootElementsDescriptors(@Nullable final XmlDocument document) { |
| throw new UnsupportedOperationException("Method getRootElementsDescriptors not implemented in " + getClass()); |
| } |
| |
| @Override |
| @Nullable |
| public XmlFile getDescriptorFile() { |
| return null; |
| } |
| |
| @Override |
| public boolean isHierarhyEnabled() { |
| throw new UnsupportedOperationException("Method isHierarhyEnabled not implemented in " + getClass()); |
| } |
| |
| @Override |
| @Nullable |
| public PsiElement getDeclaration() { |
| throw new UnsupportedOperationException("Method getDeclaration not implemented in " + getClass()); |
| } |
| |
| @Override |
| @NonNls |
| public String getName(final PsiElement context) { |
| throw new UnsupportedOperationException("Method getName not implemented in " + getClass()); |
| } |
| |
| @Override |
| @NonNls |
| public String getName() { |
| throw new UnsupportedOperationException("Method getName not implemented in " + getClass()); |
| } |
| |
| @Override |
| public void init(final PsiElement element) { |
| throw new UnsupportedOperationException("Method init not implemented in " + getClass()); |
| } |
| |
| @Override |
| public Object[] getDependences() { |
| throw new UnsupportedOperationException("Method getDependences not implemented in " + getClass()); |
| } |
| }; |
| } |
| |
| @Override |
| public int getContentType() { |
| return CONTENT_TYPE_UNKNOWN; |
| } |
| |
| @Override |
| public String getDefaultValue() { |
| return null; |
| } |
| |
| @Override |
| public void init(final PsiElement element) { |
| throw new UnsupportedOperationException("Method init not implemented in " + getClass()); |
| } |
| |
| @Override |
| public Object[] getDependences() { |
| throw new UnsupportedOperationException("Method getDependences not implemented in " + getClass()); |
| } |
| |
| @Override |
| @NonNls |
| public String getName() { |
| return getDefaultName(); |
| } |
| |
| @Override |
| public String getQualifiedName() { |
| return getDefaultName(); |
| } |
| |
| @Override |
| public String getName(PsiElement context) { |
| return getDefaultName(); |
| } |
| } |