blob: a436b22e17a78021ffbd35c2d51a1abd682d873f [file] [log] [blame]
/*
* 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.schema;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PairProcessor;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.xml.impl.XmlEnumerationDescriptor;
import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author Dmitry Avdeev
* Date: 22.08.13
*/
public abstract class XsdEnumerationDescriptor<T extends XmlElement> extends XmlEnumerationDescriptor<T> {
private boolean myExhaustiveEnum;
public abstract XmlTag getDeclaration();
@Override
public String getDefaultValue() {
if (isFixed()) {
return getDeclaration().getAttributeValue("fixed");
}
return getDeclaration().getAttributeValue("default");
}
@Override
public boolean isFixed() {
return getDeclaration().getAttributeValue("fixed") != null;
}
@Override
public String[] getEnumeratedValues() {
return getEnumeratedValues(null);
}
public String[] getEnumeratedValues(XmlElement context) {
final List<String> list = new SmartList<String>();
processEnumeration(context, new PairProcessor<PsiElement, String>() {
@Override
public boolean process(PsiElement element, String s) {
list.add(s);
return true;
}
});
String defaultValue = getDefaultValue();
if (defaultValue != null) {
list.add(defaultValue);
}
return ArrayUtil.toStringArray(list);
}
private boolean processEnumeration(XmlElement context, PairProcessor<PsiElement, String> processor) {
XmlTag contextTag = context != null ? PsiTreeUtil.getContextOfType(context, XmlTag.class, false) : null;
final XmlElementDescriptorImpl elementDescriptor = (XmlElementDescriptorImpl)XmlUtil.findXmlDescriptorByType(getDeclaration(), contextTag);
if (elementDescriptor!=null && elementDescriptor.getType() instanceof ComplexTypeDescriptor) {
return processEnumerationImpl(((ComplexTypeDescriptor)elementDescriptor.getType()).getDeclaration(), processor);
}
final String namespacePrefix = getDeclaration().getNamespacePrefix();
XmlTag type = getDeclaration().findFirstSubTag(
((namespacePrefix.length() > 0) ? namespacePrefix + ":" : "") + "simpleType"
);
if (type != null) {
return processEnumerationImpl(type, processor);
}
return false;
}
private boolean processEnumerationImpl(final XmlTag declaration, final PairProcessor<PsiElement, String> pairProcessor) {
if ("boolean".equals(declaration.getAttributeValue("name"))) {
XmlAttributeValue valueElement = declaration.getAttribute("name").getValueElement();
pairProcessor.process(valueElement, "true");
pairProcessor.process(valueElement, "false");
myExhaustiveEnum = true;
return true;
}
else {
final Ref<Boolean> found = new Ref<Boolean>(Boolean.FALSE);
myExhaustiveEnum = XmlUtil.processEnumerationValues(declaration, new Processor<XmlTag>() {
@Override
public boolean process(XmlTag tag) {
found.set(Boolean.TRUE);
XmlAttribute name = tag.getAttribute("value");
return name == null || pairProcessor.process(tag, name.getValue());
}
});
return found.get();
}
}
@Override
public PsiElement getValueDeclaration(XmlElement attributeValue, String value) {
PsiElement declaration = super.getValueDeclaration(attributeValue, value);
if (declaration == null && !myExhaustiveEnum) {
return getDeclaration();
}
return declaration;
}
@Override
public boolean isEnumerated(@Nullable XmlElement context) {
return processEnumeration(context, PairProcessor.TRUE);
}
@Override
public PsiElement getEnumeratedValueDeclaration(XmlElement xmlElement, final String value) {
final Ref<PsiElement> result = new Ref<PsiElement>();
processEnumeration(getDeclaration(), new PairProcessor<PsiElement, String>() {
@Override
public boolean process(PsiElement element, String s) {
if (value.equals(s)) {
result.set(element);
return false;
}
return true;
}
});
return result.get();
}
@Override
protected PsiElement getDefaultValueDeclaration() {
return getDeclaration();
}
}