package com.seventh7.mybatis.reference; import com.google.common.base.Optional; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.PsiReferenceBase; import com.intellij.psi.xml.XmlAttributeValue; import com.seventh7.mybatis.dom.MapperBacktrackingUtils; import com.seventh7.mybatis.service.JavaService; import com.seventh7.mybatis.util.JavaUtils; import com.seventh7.mybatis.util.MybatisConstants; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author yanglin */ public class ContextPsiFieldReference extends PsiReferenceBase<XmlAttributeValue>{ protected ContextReferenceSetResolver resolver; protected int index; public ContextPsiFieldReference(XmlAttributeValue element, TextRange range, int index) { super(element, range, false); this.index = index; resolver = ReferenceSetResolverFactory.createPsiFieldResolver(element); } @SuppressWarnings("unchecked") @Nullable @Override public PsiElement resolve() { Optional<PsiElement> resolved = resolver.resolve(index); return resolved.orNull(); } @NotNull @Override public Object[] getVariants() { Optional<PsiClass> clazz = getTargetClazz(); return clazz.isPresent() ? JavaUtils.findSettablePsiFields(clazz.get()) : PsiReference.EMPTY_ARRAY; } @SuppressWarnings("unchecked") private Optional<PsiClass> getTargetClazz() { if (getElement().getValue().contains(MybatisConstants.DOT_SEPARATOR)) { int ind = 0 == index ? 0 : index - 1; Optional<PsiElement> resolved = resolver.resolve(ind); if (resolved.isPresent()) { return JavaService.getInstance(myElement.getProject()).getReferenceClazzOfPsiField(resolved.get()); } } else { return MapperBacktrackingUtils.getPropertyClazz(myElement); } return Optional.absent(); } public ContextReferenceSetResolver getResolver() { return resolver; } public void setResolver(ContextReferenceSetResolver resolver) { this.resolver = resolver; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } }