com.intellij.psi.impl.source.xml.XmlAttributeDeclImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.intellij.psi.impl.source.xml.XmlAttributeDeclImpl.java

Source

/*
 * Copyright 2000-2009 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.psi.impl.source.xml;

import javax.annotation.Nonnull;

import com.intellij.ide.util.EditSourceUtil;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.pom.Navigatable;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.impl.meta.MetaRegistry;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.tree.ChildRoleBase;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.xml.*;
import com.intellij.util.IncorrectOperationException;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NonNls;

/**
 * @author Mike
 */
public class XmlAttributeDeclImpl extends XmlElementImpl implements XmlAttributeDecl, XmlElementType {
    private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlAttributeDeclImpl");
    @NonNls
    private static final String ID_ATT = "ID";
    @NonNls
    private static final String IDREF_ATT = "IDREF";

    public XmlAttributeDeclImpl() {
        super(XML_ATTRIBUTE_DECL);
    }

    public int getChildRole(ASTNode child) {
        LOG.assertTrue(child.getTreeParent() == this);
        IElementType i = child.getElementType();
        if (i == XML_NAME) {
            return XmlChildRole.XML_NAME;
        } else if (i == XML_ATT_REQUIRED) {
            return XmlChildRole.XML_ATT_REQUIRED;
        } else if (i == XML_ATT_FIXED) {
            return XmlChildRole.XML_ATT_FIXED;
        } else if (i == XML_ATT_IMPLIED) {
            return XmlChildRole.XML_ATT_IMPLIED;
        } else if (i == XML_ATTRIBUTE_VALUE) {
            return XmlChildRole.XML_DEFAULT_VALUE;
        } else if (i == XML_ENUMERATED_TYPE) {
            return XmlChildRole.XML_ENUMERATED_TYPE;
        } else {
            return ChildRoleBase.NONE;
        }
    }

    public XmlElement getNameElement() {
        return findElementByTokenType(XML_NAME);
    }

    public boolean isAttributeRequired() {
        return findElementByTokenType(XML_ATT_REQUIRED) != null;
    }

    public boolean isAttributeFixed() {
        return findElementByTokenType(XML_ATT_FIXED) != null;
    }

    public boolean isAttributeImplied() {
        return findElementByTokenType(XML_ATT_IMPLIED) != null;
    }

    public XmlAttributeValue getDefaultValue() {
        return (XmlAttributeValue) findElementByTokenType(XML_ATTRIBUTE_VALUE);
    }

    public String getDefaultValueText() {
        XmlAttributeValue value = getDefaultValue();
        if (value == null)
            return null;
        String text = value.getText();
        if (text.indexOf('%') == -1 && text.indexOf('&') == -1)
            return text;

        final StringBuilder builder = new StringBuilder();
        value.processElements(new PsiElementProcessor() {
            public boolean execute(@Nonnull PsiElement element) {
                builder.append(element.getText());
                return true;
            }
        }, null);
        return builder.toString();
    }

    public boolean isEnumerated() {
        return findElementByTokenType(XML_ENUMERATED_TYPE) != null;
    }

    public XmlElement[] getEnumeratedValues() {
        XmlEnumeratedType enumeratedType = (XmlEnumeratedType) findElementByTokenType(XML_ENUMERATED_TYPE);
        if (enumeratedType != null) {
            return enumeratedType.getEnumeratedValues();
        } else {
            return XmlElement.EMPTY_ARRAY;
        }
    }

    public boolean isIdAttribute() {
        final PsiElement elementType = findElementType();

        return elementType != null && elementType.getText().equals(ID_ATT);
    }

    private PsiElement findElementType() {
        final PsiElement elementName = findElementByTokenType(XML_NAME);
        final PsiElement nextSibling = (elementName != null) ? elementName.getNextSibling() : null;
        final PsiElement elementType = (nextSibling instanceof PsiWhiteSpace) ? nextSibling.getNextSibling()
                : nextSibling;

        return elementType;
    }

    public boolean isIdRefAttribute() {
        final PsiElement elementType = findElementType();

        return elementType != null && elementType.getText().equals(IDREF_ATT);
    }

    public PsiMetaData getMetaData() {
        return MetaRegistry.getMeta(this);
    }

    public PsiElement setName(@Nonnull String name) throws IncorrectOperationException {
        XmlElementChangeUtil.doNameReplacement(this, getNameElement(), name);
        return null;
    }

    public String getName() {
        XmlElement name = getNameElement();
        return (name != null) ? name.getText() : null;
    }

    public boolean canNavigate() {
        if (isPhysical())
            return super.canNavigate();
        final PsiNamedElement psiNamedElement = XmlUtil.findRealNamedElement(this);
        return psiNamedElement != null && psiNamedElement != this && ((Navigatable) psiNamedElement).canNavigate();
    }

    public void navigate(final boolean requestFocus) {
        if (isPhysical()) {
            super.navigate(requestFocus);
            return;
        }
        final PsiNamedElement psiNamedElement = XmlUtil.findRealNamedElement(this);
        Navigatable navigatable = EditSourceUtil.getDescriptor(psiNamedElement);

        if (psiNamedElement instanceof XmlEntityDecl) {
            final OpenFileDescriptor fileDescriptor = (OpenFileDescriptor) navigatable;
            navigatable = new OpenFileDescriptor(fileDescriptor.getProject(), fileDescriptor.getFile(),
                    psiNamedElement.getTextRange().getStartOffset() + psiNamedElement.getText().indexOf(getName()));
        }
        navigatable.navigate(requestFocus);
    }

    @Nonnull
    public PsiElement getNavigationElement() {
        return this;
    }
}