blob: 617895ff25760ddd1ca9a0f26ab2889f03dc8650 [file] [log] [blame]
package org.jetbrains.plugins.javaFX.fxml.descriptors;
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
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.AnyXmlAttributeDescriptor;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
import java.util.ArrayList;
import java.util.List;
/**
* User: anna
* Date: 1/10/13
*/
public class JavaFxPropertyElementDescriptor implements XmlElementDescriptor {
private final PsiClass myPsiClass;
private final String myName;
private final boolean myStatic;
public JavaFxPropertyElementDescriptor(PsiClass psiClass, String name, boolean isStatic) {
myPsiClass = psiClass;
myName = name;
myStatic = isStatic;
}
public boolean isStatic() {
return myStatic;
}
@Override
public String getQualifiedName() {
return getName();
}
@Override
public String getDefaultName() {
return getName();
}
@Override
public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) {
final PsiElement declaration = getDeclaration();
if (declaration instanceof PsiField) {
final PsiType psiType = ((PsiField)declaration).getType();
final ArrayList<XmlElementDescriptor> descriptors = new ArrayList<XmlElementDescriptor>();
collectDescriptorsByCollection(psiType, declaration.getResolveScope(), descriptors, declaration.getProject());
for (String name : FxmlConstants.FX_DEFAULT_ELEMENTS) {
descriptors.add(new JavaFxDefaultPropertyElementDescriptor(name, null));
}
if (!descriptors.isEmpty()) return descriptors.toArray(new XmlElementDescriptor[descriptors.size()]);
}
return XmlElementDescriptor.EMPTY_ARRAY;
}
public static void collectDescriptorsByCollection(PsiType psiType,
GlobalSearchScope resolveScope,
final List<XmlElementDescriptor> descriptors,
final Project project) {
final PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(psiType, resolveScope);
if (collectionItemType != null) {
final PsiClass aClass = PsiUtil.resolveClassInType(collectionItemType);
if (aClass != null) {
ClassInheritorsSearch.search(aClass, aClass.getUseScope(), true, true, false).forEach(new Processor<PsiClass>() {
@Override
public boolean process(PsiClass aClass) {
descriptors.add(new JavaFxClassBackedElementDescriptor(aClass.getName(), aClass));
return true;
}
});
descriptors.add(new JavaFxClassBackedElementDescriptor(aClass.getName(), aClass));
}
} else if (InheritanceUtil.isInheritor(psiType, JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY)) {
final PsiType propertyType = JavaFxPsiUtil.getPropertyType(psiType, project);
final PsiClass aClass = PsiUtil.resolveClassInType(propertyType);
if (aClass != null) {
descriptors.add(new JavaFxClassBackedElementDescriptor(aClass.getName(), aClass));
}
}
}
@Nullable
@Override
public XmlElementDescriptor getElementDescriptor(XmlTag childTag, XmlTag contextTag) {
final String name = childTag.getName();
if (FxmlConstants.FX_DEFAULT_ELEMENTS.contains(name)) {
return new JavaFxDefaultPropertyElementDescriptor(name, childTag);
}
return new JavaFxClassBackedElementDescriptor(name, childTag);
}
@Override
public XmlAttributeDescriptor[] getAttributesDescriptors(@Nullable XmlTag context) {
return XmlAttributeDescriptor.EMPTY;
}
@Nullable
@Override
public XmlAttributeDescriptor getAttributeDescriptor(@NonNls String attributeName, @Nullable XmlTag context) {
final PsiElement element = getDeclaration();
if (element instanceof PsiField) {
final PsiType type = ((PsiField)element).getType();
if (InheritanceUtil.isInheritor(type, CommonClassNames.JAVA_UTIL_MAP)) {
return new AnyXmlAttributeDescriptor(attributeName);
}
}
return null;
}
@Nullable
@Override
public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) {
return getAttributeDescriptor(attribute.getName(), attribute.getParent());
}
@Override
public XmlNSDescriptor getNSDescriptor() {
return null;
}
@Nullable
@Override
public XmlElementsGroup getTopGroup() {
return null;
}
@Override
public int getContentType() {
return CONTENT_TYPE_UNKNOWN;
}
@Nullable
@Override
public String getDefaultValue() {
return null;
}
@Override
public PsiElement getDeclaration() {
if (myPsiClass == null) return null;
final PsiField field = myPsiClass.findFieldByName(myName, true);
if (field != null) {
return field;
}
return JavaFxPsiUtil.findPropertySetter(myName, myPsiClass);
}
@Override
public String getName(PsiElement context) {
return getName();
}
@Override
public String getName() {
if (myPsiClass != null && myStatic) {
return StringUtil.getQualifiedName(myPsiClass.getName(), myName);
}
return myName;
}
@Override
public void init(PsiElement element) {}
@Override
public Object[] getDependences() {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
}