package com.javadude.annotation.processors;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sun.mirror.declaration.AnnotationValue;
import com.sun.mirror.declaration.Declaration;
public class Thing extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
private static final Map<String, List<String>> FIELDS = new HashMap<String, List<String>>();
private static final Map<String, List<String>> LISTS = new HashMap<String, List<String>>();
private static void setFields(String type, String...fields) {
FIELDS.put(type, Arrays.asList(fields));
}
private static void setLists(String type, String...lists) {
LISTS.put(type, Arrays.asList(lists));
}
static {
setFields("data",
"packageName", "firstPropertyName", "className", "classModifiers", "superclass",
"genericDecls", "paramStringModifiers", "date", "year", "cloneable", "atLeastOneObject",
"atLeastOneDouble", "atLeastOneDefault", "atLeastOneBound", "definePropertyNameConstants", "propertyNameConstantsInherited", "equalsAndHashCodeCallSuper",
"defineEqualsAndHashCode", "definePropertyChangeSupport", "defineCreatePropertyMap",
"createPropertyMapInherited", "createPropertyMapModifiers",
"getPropertyChangeSupportInherited", "getPropertyChangeSupportModifiers",
"paramStringInherited", "paramStringModifiers");
setLists("data", "properties", "superclassConstructors", "observers", "defaultMethods", "delegates", "nullObjects");
setFields("method", "name", "args", "argDecls", "genericDecls", "returnType", "throwsClause", "modifiers", "nullBody", "abstract", "returns");
setFields("property", "name", "writerAccess", "readerAccess", "type", "notNull", "readable", "writeable", "bound",
"primitive", "pluralName", "keyType", "extraMethodKeywords", "extraFieldKeywords", "omitFromToString", "kind",
"simple", "list", "set", "map", "boolean", "short", "double", "long", "int", "char", "byte", "float");
setFields("type", "name");
setLists("type", "methods");
}
private String type;
public Thing(String type) {
this.type = type;
if (!FIELDS.containsKey(type)) {
throw new RuntimeException("Internal Error: Type " + type + " does not exist");
}
}
@SuppressWarnings("unchecked")
public void add(String name, Object value) {
List<String> lists = LISTS.get(type);
if (lists == null) {
throw new RuntimeException("Internal Error: Type " + type + " not defined");
} else if (!lists.contains(name)) {
throw new RuntimeException("Internal Error: Field " + name + " in type " + type + " is not a collection field");
}
if (value == null) {
value = Symbols.NULL_VALUE;
}
List<Object> list = (List<Object>) get(name);
if (list == null) {
list = new ArrayList<Object>();
super.put(name, list);
}
list.add(value);
}
public void setEmpty(String name) {
List<String> lists = LISTS.get(type);
if (lists == null) {
throw new RuntimeException("Internal Error: Type " + type + " not defined");
} else if (!lists.contains(name)) {
throw new RuntimeException("Internal Error: Field " + name + " in type " + type + " is not a collection field");
}
super.put(name, Collections.emptyList());
}
@Override
public Object put(String key, Object value) {
List<String> fields = FIELDS.get(type);
if (fields == null) {
throw new RuntimeException("Internal Error: Type " + type + " not defined");
} else if (!fields.contains(key)) {
throw new RuntimeException("Internal Error: Field " + key + " does not exist as a single value field in type " + type);
}
if (value == null) {
value = Symbols.NULL_VALUE;
}
return super.put(key, value);
}
@Override
public void putAll(Map<? extends String, ? extends Object> m) {
throw new UnsupportedOperationException();
}
@Override
public Object remove(Object key) {
throw new UnsupportedOperationException();
}
public void checkAllValuesSet(Declaration declaration, BeanAnnotationProcessor beanAnnotationProcessor) {
for (String field : FIELDS.get(type)) {
if (get(field) == null) {
beanAnnotationProcessor.error(declaration, "Internal error: Field " + field + " for type " + type + " not set in processor");
}
}
if (LISTS.get(type) != null) {
for (String field : LISTS.get(type)) {
if (get(field) == null) {
beanAnnotationProcessor.error(declaration, "Internal error: Field " + field + " for type " + type + " not set in processor");
}
}
}
}
public void checkAllValuesSet(AnnotationValue value, BeanAnnotationProcessor beanAnnotationProcessor) {
for (String field : FIELDS.get(type)) {
if (get(field) == null) {
beanAnnotationProcessor.error(value, "Internal error: Field " + field + " for type " + type + " not set in processor");
}
}
if (LISTS.get(type) != null) {
for (String field : LISTS.get(type)) {
if (get(field) == null) {
beanAnnotationProcessor.error(value, "Internal error: Field " + field + " for type " + type + " not set in processor");
}
}
}
}
}