public static void init() { Thing t; t = Lib.extend("base poison", "temporary effect"); t.set("IsActive", 1); t.addHandler("OnAction", new PoisonAction()); t.set("IsPoison", 1); t.set("DamageType", "poison"); t.set("EffectName", "poisoned"); t.set("ResistStat", "TG"); t.set("ResistMessage", null); t.set("ResistDifficulty", 10); t.set("CureDifficulty", 5); Lib.add(t); t = Lib.extend("weakening poison", "base poison"); t.set("LifeTime", 50000); t.set("EffectName", "poisoned"); t.set("Strength", 100); t.set("Damage", 2); t.set("DamageType", "poison"); t.set("DamageMessage", "You feel sick..."); t.set("ResistMessage", "You manage to shake off a feeling of weakness"); t.set("AttributeAddMessage", "You feel weakened!"); t.add("CarriedModifiers", Modifier.linear("ST", 90, 0)); Lib.add(t); t = Lib.extend("poison", "base poison"); t.set("LifeTime", 20000); t.set("Strength", 200); t.set("Damage", 3); t.set("DamageType", "poison"); t.set("ResistMessage", "You feel queasy for a moment"); t.set("DamageMessage", "You feel the effects of poison..."); t.set("AttributeAddMessage", "You feel poisoned!"); Lib.add(t); t = Lib.extend("strong poison", "base poison"); t.set("LifeTime", 30000); t.set("Strength", 300); t.set("Damage", 6); t.set("DamageType", "poison"); t.set("ResistMessage", "You feel very queasy for a moment"); t.set("DamageMessage", "You feel the poison weakening you..."); t.set("AttributeAddMessage", "You feel badly poisoned!"); t.set("CureDifficulty", 15); Lib.add(t); t = Lib.extend("deadly poison", "base poison"); t.set("LifeTime", 40000); t.set("Strength", 2000); t.set("Damage", 10); t.set("DamageType", "poison"); t.set("ResistMessage", "You feel very queasy for a moment"); t.set("DamageMessage", "You feel the poison weakening you..."); t.set("AttributeAddMessage", "You feel badly poisoned!"); t.set("CureDifficulty", 40); Lib.add(t); t = Lib.extend("extreme poison", "base poison"); t.set("LifeTime", 50000); t.set("Strength", 6000); t.set("Damage", 15); t.set("DamageType", "poison"); t.set("ResistMessage", "You feel very queasy for a moment"); t.set("DamageMessage", "You feel the poison weakening you..."); t.set("AttributeAddMessage", "You feel badly poisoned!"); t.set("CureDifficulty", 100); Lib.add(t); t = Lib.extend("ultimate poison", "base poison"); t.set("LifeTime", 100000); t.set("Strength", 12000); t.set("Damage", 30); t.set("DamageType", "poison"); t.set("ResistMessage", "You feel very queasy for a moment"); t.set("DamageMessage", "You feel the poison weakening you..."); t.set("AttributeAddMessage", "You feel badly poisoned!"); t.set("CureDifficulty", 300); Lib.add(t); t = Lib.extend("sickness", "base poison"); t.set("LifeTime", 50000); t.set("Strength", 100); t.set("Damage", 2); t.set("DamageType", "poison"); t.set("DamageMessage", "You feel sick..."); t.set("ResistMessage", "You manage to shake off a feeling of illness"); t.set("AttributeAddMessage", "You feel sick!"); t.add("CarriedModifiers", Modifier.bonus("ST", -2)); t.add("CarriedModifiers", Modifier.bonus("SK", -2)); t.set("CureDifficulty", 15); Lib.add(t); t = Lib.extend("pestilence", "poison"); t.set("LifeTime", 120000); t.set("Strength", 200); t.set("Damage", 4); t.set("EffectName", "pestilent"); t.set("DamageType", "poison"); t.set("DamageMessage", "You feel grotty..."); t.set("AttributeAddMessage", "You feel the touch of pestilence!"); t.set("ResistDifficulty", 20); t.addHandler("OnAction", Scripts.generator("fly swarm", 100)); t.set("CureDifficulty", 25); Lib.add(t); t = Lib.extend("plague", "poison"); t.set("LifeTime", 100000); t.set("Strength", 200); t.set("Damage", 8); t.set("EffectName", "plague"); t.set("DamageType", "poison"); t.set("DamageMessage", "You feel sick..."); t.set("AttributeAddMessage", "You feel the touch of the plague!"); t.set("ResistDifficulty", 20); t.add("CarriedModifiers", Modifier.linear("CH", 100, -10)); t.addHandler("OnAction", Scripts.generator("plague cloud", 30)); t.set("CureDifficulty", 100); Lib.add(t); }
// private AnnotationValue get(Map<String, AnnotationValue> values, String name, AnnotationValue // def) { // AnnotationValue value = values.get(name); // if (value != null) // return value; // return def; // } private void processProperties(Thing data, Map<String, AnnotationValue> beanValues) { boolean atLeastOneBound = false; boolean atLeastOneDouble = false; boolean atLeastOneObject = false; String firstPropertyName = null; AnnotationValue propertiesValue = beanValues.get("properties"); if (propertiesValue == null) { data.setEmpty("properties"); } else { Set<String> propertyNames = new HashSet<String>(); AnnotationValue defaultType = null; AnnotationValue defaultTypeString = null; AnnotationValue defaultKeyType = null; AnnotationValue defaultKeyTypeString = null; AnnotationValue defaultReader = null; AnnotationValue defaultWriter = null; AnnotationValue defaultBound = null; AnnotationValue defaultKind = null; AnnotationValue defaultOmitFromToString = null; AnnotationValue defaultNotNull = null; AnnotationValue defaultIsStatic = null; AnnotationValue defaultIsSynchronized = null; @SuppressWarnings("unchecked") List<AnnotationValue> properties = (List<AnnotationValue>) propertiesValue.getValue(); for (AnnotationValue annotationValue : properties) { AnnotationMirror propertyMirror = (AnnotationMirror) annotationValue.getValue(); Map<String, AnnotationValue> propertyValues = getAnnotationValues(propertyMirror); AnnotationValue name = propertyValues.get("name"); AnnotationValue plural = propertyValues.get("plural"); AnnotationValue type = propertyValues.get("type"); AnnotationValue typeString = propertyValues.get("typeString"); AnnotationValue keyType = propertyValues.get("keyType"); AnnotationValue keyTypeString = propertyValues.get("keyTypeString"); AnnotationValue reader = propertyValues.get("reader"); AnnotationValue writer = propertyValues.get("writer"); AnnotationValue bound = propertyValues.get("bound"); AnnotationValue kind = propertyValues.get("kind"); AnnotationValue omitFromToString = propertyValues.get("omitFromToString"); AnnotationValue notNull = propertyValues.get("notNull"); AnnotationValue isStatic = propertyValues.get("isStatic"); AnnotationValue isSynchronized = propertyValues.get("isSynchronized"); if (Property.DEFAULTS.equals(name.getValue())) { defaultType = type; defaultTypeString = typeString; defaultKeyType = keyType; defaultKeyTypeString = keyTypeString; defaultReader = reader; defaultWriter = writer; defaultBound = bound; defaultKind = kind; defaultOmitFromToString = omitFromToString; defaultNotNull = notNull; defaultIsStatic = isStatic; defaultIsSynchronized = isSynchronized; continue; } // plugin the default values if (type == null && typeString == null) { type = defaultType; typeString = defaultTypeString; } if (keyType == null && keyTypeString == null) { keyType = defaultKeyType; keyTypeString = defaultKeyTypeString; } if (reader == null) { reader = defaultReader; } if (writer == null) { writer = defaultWriter; } if (bound == null) { bound = defaultBound; } if (kind == null) { kind = defaultKind; } if (omitFromToString == null) { omitFromToString = defaultOmitFromToString; } if (notNull == null) { notNull = defaultNotNull; } if (isStatic == null) { isStatic = defaultIsStatic; } if (isSynchronized == null) { isSynchronized = defaultIsSynchronized; } Thing property = new Thing("property"); property.put("name", name.getValue()); if (typeString == null) { if (type == null) { property.put("type", "java.lang.String"); } else { if (type.getValue() instanceof TypeDeclaration) { property.put("type", ((TypeDeclaration) type.getValue()).getQualifiedName()); } else { property.put("type", ((PrimitiveType) type.getValue()).toString()); } } } else { if (type != null) { String message = "@Property cannot have both type and typeString attributes specified"; error(typeString, message); error(type, message); property.put("type", "<ERROR>"); } else { property.put("type", typeString.getValue()); } } PropertyKind propertyKind = PropertyKind.SIMPLE; if (kind != null) { propertyKind = PropertyKind.valueOf(kind.getValue().toString()); } // check for duplicate keytype specifications if (propertyKind.isMap()) { if (keyTypeString == null) { if (keyType == null) { property.put("keyType", "java.lang.String"); } else { property.put("keyType", ((TypeDeclaration) keyType.getValue()).getQualifiedName()); } } else if (keyType != null) { String message = "@Property cannot have both keyType and keyTypeString attributes specified"; error(keyType, message); error(keyTypeString, message); property.put("keyType", "<ERROR>"); } } else { if (keyTypeString != null) { error( keyTypeString, "@Property can only have a keyTypeString attribute if kind is MAP or UNMODIFIABLE_MAP"); } if (keyType != null) { error( keyType, "@Property can only have a keyType attribute if kind is MAP or UNMODIFIABLE_MAP"); } property.put("keyType", "<ERROR>"); } // check for plural names if (propertyKind.isSimple()) { if (plural != null) { error(plural, "@Property cannot have plural specified if kind is SIMPLE"); } property.put("pluralName", null); } else { if (plural == null) { property.put("pluralName", name.getValue() + "s"); } else { property.put("pluralName", plural.getValue()); } } property.put("simple", propertyKind.isSimple()); property.put("list", propertyKind.isList()); property.put("map", propertyKind.isMap()); property.put("set", propertyKind.isSet()); String typeName = (String) property.get("type"); property.put("float", "float".equals(typeName)); property.put("double", "double".equals(typeName)); property.put("boolean", "boolean".equals(typeName)); property.put("char", "char".equals(typeName)); property.put("byte", "byte".equals(typeName)); property.put("long", "long".equals(typeName)); property.put("int", "int".equals(typeName)); property.put("short", "short".equals(typeName)); if (property.containsKey("firstPropertyName")) { property.put("firstPropertyName", name.getValue()); } if (propertyNames.contains(name.getValue())) { error( name, "Duplicate property name '" + name + "' specified for @Bean properties definition"); } else { propertyNames.add((String) name.getValue()); } if (bound != null) { if (isStatic != null) { error(bound, "Static properties cannot be declared bound"); error(isStatic, "Static properties cannot be declared bound"); } else { atLeastOneBound = true; } } if ("double".equals(property.get("type"))) { data.put("atLeastOneDouble", true); } property.put("kind", propertyKind); property.put("omitFromToString", b(omitFromToString)); data.add("properties", property); // evil hack to get the type, which is a Class boolean isPrimitive = BeanAnnotationProcessor.PRIMITIVE_TYPES.contains(property.get("type")); property.put("primitive", isPrimitive); if (!isPrimitive) { data.put("atLeastOneObject", true); } property.put("bound", b(bound)); if (writer == null) { property.put("writerAccess", Access.PUBLIC.getModifier()); property.put("writeable", true); } else { EnumConstantDeclaration writerValue = (EnumConstantDeclaration) writer.getValue(); Access writerAccess = Access.valueOf(writerValue.toString()); property.put("writerAccess", writerAccess.getModifier()); property.put("writeable", writerAccess != Access.NONE); } if (reader == null) { property.put("readerAccess", Access.PUBLIC.getModifier()); property.put("readable", true); } else { EnumConstantDeclaration readerValue = (EnumConstantDeclaration) reader.getValue(); Access readerAccess = Access.valueOf(readerValue.toString()); property.put("readerAccess", readerAccess.getModifier()); property.put("readable", readerAccess != Access.NONE); } boolean bNotNull = b(notNull); boolean bIsStatic = b(isStatic); boolean bIsSynchronized = b(isSynchronized); property.put("notNull", bNotNull); if (bNotNull && isPrimitive) { error( notNull, "Cannot specify notNull for primitive-typed property " + name.getValue() + " in @Property"); } String extraFieldKeywords = ""; String extraMethodKeywords = ""; if (bIsStatic) { extraFieldKeywords = "static "; extraMethodKeywords = "static "; } if (bIsSynchronized) { if (bIsStatic) { extraMethodKeywords += "synchronized "; } else { extraMethodKeywords = "synchronized "; } } property.put("extraFieldKeywords", extraFieldKeywords); property.put("extraMethodKeywords", extraMethodKeywords); property.checkAllValuesSet(propertiesValue, this); } } data.put( "definePropertyChangeSupport", !((Boolean) data.get("getPropertyChangeSupportInherited")) && atLeastOneBound); data.put("atLeastOneDouble", atLeastOneDouble); data.put("atLeastOneObject", atLeastOneObject); data.put("firstPropertyName", firstPropertyName); }
private void processDefaultMethods(Thing data, ClassDeclaration classDeclaration) { // find any methods that have default parameters boolean error = false; for (ConstructorDeclaration constructorDeclaration : classDeclaration.getConstructors()) { Collection<ParameterDeclaration> parameters = constructorDeclaration.getParameters(); for (ParameterDeclaration parameterDeclaration : parameters) { Default annotation = parameterDeclaration.getAnnotation(Default.class); if (annotation != null) { error(parameterDeclaration, "@Default is not legal in constructor parameters"); error = true; } } } if (error) { return; } boolean atLeastOneDefault = false; methods: for (MethodDeclaration methodDeclaration : classDeclaration.getMethods()) { Collection<ParameterDeclaration> parameters = methodDeclaration.getParameters(); boolean seenDefault = false; String[] names = new String[parameters.size()]; String[] types = new String[parameters.size()]; String[] defaults = new String[parameters.size()]; int n = 0; for (ParameterDeclaration parameterDeclaration : parameters) { Default annotation = parameterDeclaration.getAnnotation(Default.class); names[n] = parameterDeclaration.getSimpleName(); types[n] = parameterDeclaration.getType().toString(); if (annotation != null) { seenDefault = true; if ("java.lang.String".equals(types[n])) { defaults[n] = '"' + annotation.value() + '"'; } else { defaults[n] = annotation.value(); } } else if (seenDefault) { error( parameterDeclaration, "All parameters after a parameter annotated with @Default must be annotated with @Default"); continue methods; } n++; } if (seenDefault) { atLeastOneDefault = true; if (methodDeclaration.getModifiers().contains(Modifier.PRIVATE)) { error(methodDeclaration, "Private methods cannot use @Default parameters"); } if (methodDeclaration.getModifiers().contains(Modifier.STATIC)) { error(methodDeclaration, "Static methods cannot use @Default parameters"); } String modifiers3 = ""; if (methodDeclaration.getModifiers().contains(Modifier.PUBLIC)) { modifiers3 = "public "; } else if (methodDeclaration.getModifiers().contains(Modifier.PROTECTED)) { modifiers3 = "protected "; } String throwsClause = getThrowsClause(methodDeclaration); String returnType = methodDeclaration.getReturnType().toString(); String methodName = methodDeclaration.getSimpleName(); String argDecl = ""; String callArgs = ""; for (int i = 0; i < n; i++) { if (defaults[i] != null) { String callArgsWithDefaults = callArgs; for (int j = i; j < n; j++) { if (j > 0) { callArgsWithDefaults += ", "; } callArgsWithDefaults += defaults[j]; } Thing method = new Thing("method"); method.put("name", methodName); method.put("returnType", returnType); method.put("throwsClause", throwsClause); method.put("argDecls", argDecl); method.put("modifiers", modifiers3); method.put("args", callArgsWithDefaults); data.add("defaultMethods", method); } if (i > 0) { argDecl += ", "; callArgs += ", "; } argDecl += types[i] + ' ' + names[i]; callArgs += names[i]; } Thing method = new Thing("method"); method.put("name", methodName); method.put("returnType", returnType); method.put("throwsClause", throwsClause); method.put("modifiers", modifiers3); method.put("abstract", true); method.put("argDecls", argDecl); data.add("defaultMethods", method); } } data.put("atLeastOneDefault", atLeastOneDefault); if (!atLeastOneDefault) { data.setEmpty("defaultMethods"); } }
private void processSuperclass(Thing data, Map<String, AnnotationValue> beanValues) { AnnotationValue value = beanValues.get("superclass"); data.put("superclass", null); data.put("genericDecls", ""); data.put("classModifiers", ""); data.put("propertyNameConstantsInherited", false); data.put("getPropertyChangeSupportInherited", false); data.put("getPropertyChangeSupportModifiers", "protected"); data.put("paramStringInherited", false); data.put("paramStringModifiers", "protected"); data.put("createPropertyMapInherited", false); data.put("createPropertyMapModifiers", "public"); data.put("atLeastOneDouble", false); data.put("atLeastOneBound", false); data.put("atLeastOneObject", false); data.put("atLeastOneDefault", false); if (value == null) { data.setEmpty("superclassConstructors"); } else { if (!(value.getValue() instanceof ClassDeclaration)) { error(value, "superclass must be a class"); return; } ClassDeclaration superclass = (ClassDeclaration) value.getValue(); data.put("superclass", superclass.getQualifiedName()); boolean hasProperties = !l(beanValues, "properties").isEmpty(); // check if getPropertyChangeSupport or some superclass defines bound properties in @Bean checkInheritedMethod( data, "getPropertyChangeSupport", "java.beans.PropertyChangeSupport", superclass, true, new InheritCheck() { @Override public boolean isInherited(Thing d, ClassDeclaration classDeclaration) { Bean beanAnn = classDeclaration.getAnnotation(Bean.class); if (beanAnn != null) { Property[] properties = beanAnn.properties(); for (Property property : properties) { if (property.bound()) { d.put("getPropertyChangeSupportInherited", true); d.put("getPropertyChangeSupportModifiers", "protected"); return true; } } } return false; } }); // check if paramString inherited or some superclass has @Bean checkInheritedMethod( data, "paramString", "java.lang.String", superclass, !hasProperties, new InheritCheck() { @Override public boolean isInherited(Thing d, ClassDeclaration classDeclaration) { if (classDeclaration.getAnnotation(Bean.class) != null) { d.put("paramStringInherited", true); d.put("paramStringModifiers", "protected"); return true; } return false; } }); // check if createPropertyMap inherited or some superclass has @Bean with // defineCreatePropertyMap checkInheritedMethod( data, "createPropertyMap", "java.lang.String", superclass, !hasProperties, new InheritCheck() { @Override public boolean isInherited(Thing d, ClassDeclaration classDeclaration) { Bean beanAnn = classDeclaration.getAnnotation(Bean.class); if (beanAnn != null && beanAnn.defineCreatePropertyMap()) { d.put("createPropertyMapInherited", true); d.put("createPropertyMapModifiers", "public"); return true; } return false; } }); String genericDecls = null; Collection<TypeParameterDeclaration> formalTypeParameters2 = superclass.getFormalTypeParameters(); for (TypeParameterDeclaration typeParameterDeclaration : formalTypeParameters2) { genericDecls = addWithCommasBetween(genericDecls, typeParameterDeclaration); } if (genericDecls == null) { genericDecls = ""; } else { genericDecls = '<' + genericDecls + '>'; } data.put("genericDecls", genericDecls); String classModifiers = ""; for (Modifier modifier : superclass.getModifiers()) { if (!"abstract".equals(modifier.toString())) { classModifiers += modifier.toString() + ' '; } } data.put("classModifiers", classModifiers); Collection<ConstructorDeclaration> constructors = superclass.getConstructors(); if (constructors.isEmpty()) { data.setEmpty("superclassConstructors"); } else { for (ConstructorDeclaration constructorDeclaration : constructors) { data.add("superclassConstructors", setupMethod(constructorDeclaration, false)); } } boolean extendPropertyNameConstants = false; if (b(beanValues, "definePropertyNameConstants")) { // if superclass has a PropertyNameConstants interface or a Bean annotation with // definePropertyNameConstants=true, we need to have our PropertyNameConstants // extend it Collection<TypeDeclaration> nestedTypes = superclass.getNestedTypes(); for (TypeDeclaration typeDeclaration : nestedTypes) { if ("PropertyNames".equals(typeDeclaration.getSimpleName()) && (typeDeclaration instanceof InterfaceDeclaration)) { extendPropertyNameConstants = true; } } if (!extendPropertyNameConstants) { // check if the superclass is annotated with Bean Bean annotation = superclass.getAnnotation(Bean.class); if (annotation != null) { extendPropertyNameConstants = annotation.definePropertyNameConstants(); } } } data.put("propertyNameConstantsInherited", extendPropertyNameConstants); } }