package com.seventh7.mybatis.annotation;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Set;
/**
* Simple implementation
* @author yanglin
*/
public class Annotation implements Cloneable{
public static final Annotation PARAM = new Annotation("@Param", "org.apache.ibatis.annotations.Param");
public static final Annotation SELECT = new Annotation("@Select", "org.apache.ibatis.annotations.Select");
public static final Annotation UPDATE = new Annotation("@Update", "org.apache.ibatis.annotations.Update");
public static final Annotation INSERT = new Annotation("@Insert", "org.apache.ibatis.annotations.Insert");
public static final Annotation DELETE = new Annotation("@Delete", "org.apache.ibatis.annotations.Delete");
public static final Annotation ALIAS = new Annotation("@Alias", "org.apache.ibatis.type.Alias");
public static final Annotation AUTOWIRED = new Annotation("@Autowired", "org.springframework.beans.factory.annotation.Autowired");
public static final Annotation RESOURCE = new Annotation("@Resource", "javax.annotation.Resource");
public static final Set<Annotation> STATEMENT_SYMMETRIES = ImmutableSet.of(SELECT, UPDATE, INSERT, DELETE);
private final String label;
private final String qualifiedName;
private Map<String, AnnotationValue> attributePairs;
public interface AnnotationValue {
}
public static class StringValue implements AnnotationValue{
private String value;
public StringValue(@NotNull String value) {
this.value = value;
}
@Override
public String toString() {
return "\"" + value + "\"";
}
}
public Annotation(@NotNull String label, @NotNull String qualifiedName) {
this.label = label;
this.qualifiedName = qualifiedName;
attributePairs = Maps.newHashMap();
}
private Annotation addAttribute(String key, AnnotationValue value) {
this.attributePairs.put(key, value);
return this;
}
public Annotation withAttribute(@NotNull String key, @NotNull AnnotationValue value) {
Annotation copy = this.clone();
copy.attributePairs = Maps.newHashMap(this.attributePairs);
return copy.addAttribute(key, value);
}
public Annotation withValue(@NotNull AnnotationValue value) {
return withAttribute("value", value);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(label);
if (!Iterables.isEmpty(attributePairs.entrySet())) {
builder.append(setupAttributeText());
}
return builder.toString();
}
private String setupAttributeText() {
Optional<String> singleValue = getSingleValue();
return singleValue.isPresent() ? singleValue.get() : getComplexValue();
}
private String getComplexValue() {
StringBuilder builder = new StringBuilder("(");
for (String key : attributePairs.keySet()) {
builder.append(key);
builder.append(" = ");
builder.append(attributePairs.get(key).toString());
builder.append(", ");
}
builder.deleteCharAt(builder.length() - 1);
builder.deleteCharAt(builder.length() - 1);
builder.append(")");
return builder.toString();
}
@NotNull
public Optional<PsiClass> toPsiClass(@NotNull Project project) {
return Optional.fromNullable(JavaPsiFacade.getInstance(project).findClass(getQualifiedName(), GlobalSearchScope.allScope(project)));
}
private Optional<String> getSingleValue() {
try {
String value = Iterables.getOnlyElement(attributePairs.keySet());
StringBuilder builder = new StringBuilder("(");
builder.append(attributePairs.get(value).toString());
builder.append(")");
return Optional.of(builder.toString());
} catch (Exception e) {
return Optional.absent();
}
}
@NotNull
public String getLabel() {
return label;
}
@NotNull
public String getQualifiedName() {
return qualifiedName;
}
@Override
protected Annotation clone() {
try {
return (Annotation)super.clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException();
}
}
}