Ignore:
Timestamp:
06/28/13 11:56:03 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

  • FramsClass? and contained Param are now immutable classes (like String),

which allows to refer to them concurrently without synchronization
(which for example in turn simplifies GUI management)

  • also make Path immutable (which was earlier only assumed)
  • add global cache for FramsClasses? created solely and automatically

on base of Java classes.

representations basing on given FramsClass?

  • above changes greatly improved GUI responsivness during browsing
  • furtherly improve Param class hierarchy
  • allow to inject actions on state changes into MultiParamLoader?
  • add more tests

CHANGELOG:

Add StatusListener? to MultiParamLoader?.

Minor refactorization in MultiParamLoader?.

First step with auto append.

Add SchemaTest?.

Improve Registry.

Clean up in Registry.

Work out Registry.

Use annotations for Param.

Fix ListChange?.

Improve fluent interface of the FramsClassBuilder?.

Done caching of ReflectionAccess?.Backend

Fix hashCode of Pair.

A step on a way to cache ReflectionAccess?.Backend

Make SimpleAbstractAccess?.framsClass a final field.

Add static cache for FramsClasses? based on java.

Only classes created strictly and automatically
based on java classes are using this cache.

Make all Params immutable.

Many improvement to make Param immutable.

Make PrimitiveParam? generic type.

Several changes to make Param immutable.

Make FramsClass? immutable.

Another improvement to Path immutability.

Several improvements to Path.

Improve PathTest?.

Configurarable MutabilityDetector?.

Location:
java/main/src/main/java/com/framsticks/params
Files:
1 added
31 edited

Legend:

Unmodified
Added
Removed
  • java/main/src/main/java/com/framsticks/params/AccessInterface.java

    r86 r87  
    7474        FramsClass getFramsClass();
    7575
     76        boolean tryAutoAppend(Object object);
     77
    7678
    7779}
  • java/main/src/main/java/com/framsticks/params/ArrayListAccess.java

    r86 r87  
    3131        @Override
    3232        public Param getParam(int i) {
     33                //TODO listAccessParam
    3334                return Param.build().id(Integer.toString(i)).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
    3435        }
  • java/main/src/main/java/com/framsticks/params/CompositeParam.java

    r84 r87  
    11package com.framsticks.params;
    22
    3 import com.framsticks.util.lang.Strings;
     3import javax.annotation.concurrent.Immutable;
    44
    55/**
    66 * @author Piotr Sniegowski
    77 */
     8@Immutable
    89public abstract class CompositeParam extends ValueParam {
     10
    911        protected final String containedTypeName;
    1012
    11         public CompositeParam(String containedTypeName) {
    12                 this.containedTypeName = Strings.notEmpty(containedTypeName) ? containedTypeName : null;
     13        public CompositeParam(ParamBuilder builder) {
     14                super(builder);
     15                this.containedTypeName = builder.getContainedTypeName();
    1316        }
    1417
  • java/main/src/main/java/com/framsticks/params/FramsClass.java

    r86 r87  
    88
    99import javax.annotation.Nonnull;
     10import javax.annotation.concurrent.Immutable;
     11
     12import org.apache.log4j.Logger;
    1013
    1114/**
     
    2124 * @author Piotr Sniegowski
    2225 */
     26@Immutable
    2327@FramsClassAnnotation(id = "class", name = "class")
    2428public final class FramsClass {
    2529
    26         /** The offset of the parameter (applied for newly added parameter). */
    27         protected int fieldsNumber;
     30        private final static Logger log = Logger.getLogger(FramsClass.class);
    2831
    29         /** The groups. */
    30         protected List<Group> groups = new ArrayList<Group>();
     32        protected final String id;
     33
     34        protected final String name;
     35
     36        protected final String description;
     37
     38        protected final List<Group> groups;
     39
     40        /** The param list (for accessing parameters by offset in O(1) time. */
     41        protected final List<Param> paramList;
    3142
    3243        /**
     
    3647        protected Map<String, Param> paramEntryMap = new LinkedHashMap<String, Param>();
    3748
    38         /** The param list (for accessing parameters by offset in O(1) time. */
    39         protected List<Param> paramList = new ArrayList<Param>();
    40 
    41         /** The param getId map (for fast lookup of offset based on name */
    42         protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
    43 
    44         protected String id;
    45 
    46         protected String name;
    47 
    48         protected String description;
     49        // /** The param getId map (for fast lookup of offset based on name */
     50        // protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
    4951
    5052        public Collection<Param> getParamEntries() {
     
    5254        }
    5355
    54         public FramsClass() {
     56        public FramsClass(String id, String name, String description, List<Param> params, List<Group> groups) {
    5557
    56         }
     58                this.id = id;
     59                this.name = name;
     60                this.description = description;
     61                this.groups = groups;
     62                this.paramList = params;
    5763
    58         public FramsClass(String id, String name, String description) {
    59                 this.setId(id);
    60                 this.setName(name);
    61                 this.setDescription(description);
    62         }
     64                for (Param param : params) {
     65                        paramEntryMap.put(param.getId(), param);
     66                        try {
     67                                Group group = groups.get(param.getGroup());
     68                                if (group != null) {
     69                                        group.addProperty(param);
     70                                }
     71                        } catch (IndexOutOfBoundsException ignored) {
    6372
    64         /**
    65          * Adds new param entry.
    66          *
    67          * @param param
    68          *            the new param entry
    69          */
    70         public FramsClass append(Param param) {
    71                 // if (param.hasFlag(Flags.USERHIDDEN)) {
    72                 //      return this;
    73                 // }
    74                 paramEntryMap.put(param.getId(), param);
    75                 //paramEntryMap.put(param.getInternalId(), param);
    76                 paramList.add(param);
    77                 try {
    78                         Group group = groups.get(param.getGroup());
    79                         if (group != null) {
    80                                 group.addProperty(param);
    8173                        }
    82                 } catch (IndexOutOfBoundsException ignored) {
    83 
    8474                }
    8575
    86                 return this;
    87         }
     76                log.trace("created framsclass " + this);
    8877
    89         public FramsClass append(ParamBuilder builder) {
    90                 return append(builder.finish());
    91         }
    92 
    93         /**
    94          * Adds new group.
    95          */
    96         public FramsClass appendGroup(Group group) {
    97                 groups.add(group);
    98                 return this;
    9978        }
    10079
     
    206185        @Override
    207186        public String toString() {
    208                 return id;
     187                return id + "(" + name + ")";
    209188        }
    210189
    211         @ParamAnnotation
    212         public void setId(String id) {
    213                 this.id = id;
    214         }
    215 
    216         @ParamAnnotation
    217         public void setName(String name) {
    218                 this.name = name;
    219         }
    220 
    221         @ParamAnnotation(id = "desc")
    222         public void setDescription(String description) {
    223                 this.description = description;
     190        public static FramsClassBuilder build() {
     191                return new FramsClassBuilder();
    224192        }
    225193}
  • java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java

    r86 r87  
    77import java.lang.reflect.ParameterizedType;
    88import java.lang.reflect.Type;
     9import java.util.ArrayList;
     10import java.util.Collections;
     11import java.util.HashMap;
     12import java.util.LinkedList;
    913import java.util.List;
    1014import java.util.Map;
     
    1216import org.apache.log4j.Logger;
    1317
     18import com.framsticks.params.annotations.AutoAppendAnnotation;
    1419import com.framsticks.params.annotations.FramsClassAnnotation;
    1520import com.framsticks.params.annotations.ParamAnnotation;
     
    1823import com.framsticks.util.lang.Strings;
    1924
     25@FramsClassAnnotation(id = "class", name = "class")
    2026public class FramsClassBuilder {
    2127        private static final Logger log =
    2228                Logger.getLogger(FramsClassBuilder.class);
    23 
    2429
    2530        public static String getName(FramsClassAnnotation fca, Class<?> javaClass) {
     
    6368                }
    6469
    65                 if (type.equals(Integer.class) || type.equals(int.class)) {
    66                         return "d";
    67                 }
    68                 if (type.equals(String.class)) {
    69                         return "s";
    70                 }
    71                 if (type.equals(Double.class) || type.equals(double.class)) {
    72                         return "f";
    73                 }
    74                 if (type.equals(Boolean.class) || type.equals(boolean.class)) {
    75                         return "d 0 1";
    76                 }
    77                 if (type.equals(Object.class)) {
    78                         return "x";
    79                 }
    8070                if (type instanceof Class) {
     71
     72                        Class<?> cl = (Class<?>) type;
     73
     74                        // TODO: future support for enum
     75                        // if (cl.isEnum()) {
     76                        //      Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) cl;
     77                        //      Enum<?>[] enums = enumType.getEnumConstants();
     78                        //      StringBuilder b = new StringBuilder();
     79
     80                        //      b.append("d 0 ").append(enums.length - 1).append(" 0 ");
     81                        //      for (Enum<?> e : enums) {
     82                        //              b.append("~").append(e.name());
     83                        //      }
     84                        //      return b.toString();
     85                        // }
     86                        if (cl.equals(Integer.class) || cl.equals(int.class)) {
     87                                return "d";
     88                        }
     89                        if (cl.equals(String.class)) {
     90                                return "s";
     91                        }
     92                        if (cl.equals(Double.class) || cl.equals(double.class)) {
     93                                return "f";
     94                        }
     95                        if (cl.equals(Boolean.class) || cl.equals(boolean.class)) {
     96                                return "d 0 1";
     97                        }
     98                        if (cl.equals(Object.class)) {
     99                                return "x";
     100                        }
     101
    81102                        return "o " + ((Class<?>) type).getCanonicalName();
    82103                }
    83                 return null;
     104
     105                throw new ConstructionException().msg("failed to find framsticks for native type").arg("type", type);
    84106        }
    85107
     
    141163        }
    142164
    143         public static FramsClass buildForClass(Class<?> javaClass) throws ConstructionException {
     165        public static Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new HashMap<Class<?>, FramsClass>());
     166
     167        public FramsClass forClass(Class<?> javaClass) throws ConstructionException {
     168                FramsClass result = synchronizedCacheForBasedOnForJavaClass.get(javaClass);
     169                if (result != null) {
     170                        return result;
     171                }
     172
     173                log.info("building for class " + javaClass);
    144174
    145175                FramsClassAnnotation fca = javaClass.getAnnotation(FramsClassAnnotation.class);
    146176                if (fca == null) {
    147                         log.error(javaClass.getName() + " is not annotated with FramsClassAnnotation");
    148                         return null;
    149                 }
    150 
    151                 FramsClass framsClass = new FramsClass(getId(fca, javaClass), getName(fca, javaClass), "");
     177                        throw new ConstructionException().msg("java class is not annotated with FramsClassAnnotation").arg("java", javaClass);
     178                }
     179
     180                id(getId(fca, javaClass));
     181                name(getName(fca, javaClass));
    152182
    153183                Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(javaClass);
    154184
    155185                for (ParamCandidate pc : candidates.values()) {
    156                         framsClass.append(Param.build().id(pc.getId()).name(pc.getName()).type(getParamTypeForNativeType(pc.getType())).flags(pc.getFlags()));
    157                 }
    158 
    159                 return framsClass;
    160         }
     186                        param(Param.build().id(pc.getId()).name(pc.getName()).type(getParamTypeForNativeType(pc.getType())).flags(pc.getFlags()));
     187                }
     188
     189                result = finish();
     190
     191                synchronizedCacheForBasedOnForJavaClass.put(javaClass, result);
     192
     193                return result;
     194        }
     195
     196
     197        protected String id;
     198
     199        protected String name;
     200
     201        protected String description;
     202
     203        protected final List<Param> params = new LinkedList<>();
     204
     205        protected List<Group> groups = new ArrayList<Group>();
     206
     207        @ParamAnnotation
     208        public FramsClassBuilder id(String id) {
     209                this.id = id;
     210                return this;
     211        }
     212
     213        @ParamAnnotation
     214        public FramsClassBuilder name(String name) {
     215                this.name = name;
     216                return this;
     217        }
     218
     219        public FramsClassBuilder idAndName(String v) {
     220                this.id = v;
     221                this.name = v;
     222                return this;
     223        }
     224
     225        @ParamAnnotation(id = "desc")
     226        public FramsClassBuilder description(String description) {
     227                this.description = description;
     228                return this;
     229        }
     230
     231        public FramsClassBuilder() {
     232        }
     233
     234        public FramsClass finish() {
     235                return new FramsClass(id, name, description, params, groups);
     236        }
     237
     238        public FramsClassBuilder append(Param param) {
     239                params.add(param);
     240                return this;
     241        }
     242
     243        @AutoAppendAnnotation
     244        public FramsClassBuilder param(ParamBuilder builder) {
     245                return append(builder.finish());
     246        }
     247
     248        @AutoAppendAnnotation
     249        public FramsClassBuilder group(Group group) {
     250                groups.add(group);
     251                return this;
     252        }
     253
     254        /**
     255         * @return the id
     256         */
     257        @ParamAnnotation
     258        public String getId() {
     259                return id;
     260        }
     261
     262        /**
     263         * @return the name
     264         */
     265        @ParamAnnotation
     266        public String getName() {
     267                return name;
     268        }
     269
     270        /**
     271         * @return the description
     272         */
     273        @ParamAnnotation(id = "desc")
     274        public String getDescription() {
     275                return description;
     276        }
     277
     278        public FramsClassBuilder group(String group) {
     279                return group(new Group(group));
     280        }
     281
     282        public ParamBuilder param(String id) {
     283                return new ParamBuilder(this).id(id);
     284        }
     285
    161286}
  • java/main/src/main/java/com/framsticks/params/Group.java

    r77 r87  
    44import java.util.List;
    55
     6import com.framsticks.params.annotations.FramsClassAnnotation;
     7import com.framsticks.params.annotations.ParamAnnotation;
     8
    69/**
    710 * @author Piotr Sniegowski
    811 */
     12@FramsClassAnnotation
    913public class Group {
    10         String name;
     14
     15        @ParamAnnotation
     16        protected String name;
    1117
    1218        /**
     
    4046        }
    4147
    42         /*
    43                          * (non-Javadoc)
    44                          *
    45                          * @see java.lang.Object#toString()
    46                          */
    4748        @Override
    4849        public String toString() {
     
    5051        }
    5152
     53        /**
     54         * @return the name
     55         */
     56        @ParamAnnotation
     57        public String getName() {
     58                return name;
     59        }
     60
    5261}
  • java/main/src/main/java/com/framsticks/params/ListAccess.java

    r84 r87  
    7575        }
    7676
    77 }
     77        //TODO it could actually be used also
     78        @Override
     79        public boolean tryAutoAppend(Object object) {
     80                return false;
     81        }
     82
     83};
  • java/main/src/main/java/com/framsticks/params/Param.java

    r86 r87  
    22
    33
    4 import com.framsticks.params.types.DecimalParam;
    5 import com.framsticks.params.types.StringParam;
     4import javax.annotation.concurrent.Immutable;
     5
     6import com.framsticks.params.annotations.FramsClassAnnotation;
     7import com.framsticks.params.annotations.ParamAnnotation;
    68
    79/**
     
    1416 * @author Piotr Śniegowski
    1517 */
     18@Immutable
     19@FramsClassAnnotation(id = "prop", name = "prop")
    1620public abstract class Param {
    1721
    1822        /** The parameter id. */
    19         protected String id;
     23        protected final String id;
    2024
     25        //TODO
    2126        /**
    2227         * The parameter internal id. It's set by a user to use user's own getId in
    2328         * code
    2429         */
    25         protected String internalId;
     30        protected final String internalId;
    2631
    2732        /** The parameter name. */
    28         protected String name;
     33        protected final String name;
    2934
    3035        /** The help (description) concerning parameter. */
    31         protected String help;
     36        protected final String help;
    3237
    3338        /** The number of group, that parameter belongs to. */
    34         protected Integer group;
     39        protected final Integer group;
    3540
    3641        /** The getFlags stored as a bit sum. */
    37         protected Integer flags;
     42        protected final Integer flags;
    3843
     44        //TODO
    3945        /** The variable determining whether the parameter is an extra parameter. */
    40         protected Integer extra;
     46        protected final Integer extra;
    4147
    42 
    43         public Param() {
    44 
     48        public Param(ParamBuilder builder) {
     49                id = builder.getId();
     50                internalId = builder.getInternalId();
     51                name = builder.getName();
     52                help = builder.getHelp();
     53                group = builder.getGroup();
     54                flags = builder.getFlags();
     55                extra = 0;
    4556        }
    4657
     58        @ParamAnnotation
    4759        public String getId() {
    4860                return id;
     
    5365        }
    5466
     67        @ParamAnnotation
    5568        public String getName() {
    5669                return name;
    5770        }
    5871
     72        @ParamAnnotation
    5973        public String getHelp() {
    6074                return help;
    6175        }
    6276
     77        @ParamAnnotation
    6378        public Integer getGroup() {
    6479                return group;
    6580        }
    6681
     82        @ParamAnnotation
    6783        public Integer getFlags() {
    6884                return flags;
     
    7995        public Integer getExtra() {
    8096                return extra;
    81         }
    82 
    83         public void setInternalId(String internalId) {
    84                 this.internalId = internalId;
    8597        }
    8698
     
    104116        }
    105117
    106         public static FramsClass getFramsClass() {
    107                 return new FramsClass("prop", "prop", null)
    108                         .append(Param.build().id("name").name("Name").type(StringParam.class).finish())
    109                         .append(Param.build().id("id").name("Id").type(StringParam.class).finish())
    110                         .append(Param.build().id("type").name("Type").type(StringParam.class).finish())
    111                         .append(Param.build().id("help").name("Help").type(StringParam.class).finish())
    112                         .append(Param.build().id("flags").name("Flags").type(DecimalParam.class).finish());
    113         }
    114 
    115118        public static ParamBuilder build() {
    116119                return new ParamBuilder();
    117120        }
    118121
     122        public static ParamBuilder build(FramsClassBuilder builder) {
     123                return new ParamBuilder(builder);
     124        }
     125
    119126}
  • java/main/src/main/java/com/framsticks/params/ParamBuilder.java

    r86 r87  
    44import com.framsticks.params.annotations.ParamAnnotation;
    55import com.framsticks.params.types.*;
    6 import com.framsticks.util.lang.Numbers;
     6import com.framsticks.util.FramsticksException;
     7import com.framsticks.util.lang.Strings;
    78
    89import org.apache.log4j.Logger;
    910
    10 import java.util.ArrayList;
     11import java.lang.reflect.InvocationTargetException;
    1112import java.util.Arrays;
    12 
     13import java.util.List;
    1314
    1415/**
     
    5657        private Class<? extends Param> paramType;
    5758
    58         private Param param;
    59         private PrimitiveParam primitiveParam;
    60         private String typeString;
     59        private Object min;
     60
     61        private Object max;
     62
     63        private Object def;
     64
     65        String containedTypeName;
     66
     67        protected FramsClassBuilder classBuilder;
    6168
    6269        public ParamBuilder() {
     70                this(null);
     71        }
     72
     73
     74        /**
     75         * @param classBuilder
     76         */
     77        public ParamBuilder(FramsClassBuilder classBuilder) {
     78                this.classBuilder = classBuilder;
     79        }
     80
     81
     82        /**
     83         * @return the min
     84         */
     85        public Object getMin() {
     86                return min;
     87        }
     88
     89        /**
     90         * @return the max
     91         */
     92        public Object getMax() {
     93                return max;
     94        }
     95
     96        /**
     97         * @return the def
     98         */
     99        public Object getDef() {
     100                return def;
     101        }
     102
     103        public String getContainedTypeName() {
     104                return Strings.notEmpty(containedTypeName) ? containedTypeName : null;
     105        }
     106
     107        /**
     108         * @return the enumValues
     109         */
     110        public List<String> getEnumValues() {
     111                return enumValues;
     112        }
     113
     114        /**
     115         * @return the procedureSignature
     116         */
     117        public String getProcedureSignature() {
     118                return procedureSignature;
     119        }
     120
     121        /**
     122         * @return the uid
     123         */
     124        public String getUid() {
     125                return uid;
    63126        }
    64127
     
    70133         *             when Param getType is not defined
    71134         */
    72         public Param finish()  {
    73                 assert param != null;
    74                 param.id = id;
    75                 param.name = name;
    76                 param.help = help;
    77                 param.group = group;
    78                 param.flags = flags;
    79                 param.internalId = internalId;
    80                 return param;
     135        public Param finish() {
     136                try {
     137                        return paramType.getConstructor(ParamBuilder.class).newInstance(this);
     138                } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
     139                        throw new FramsticksException().msg("failed to create param").cause(e).arg("name", name);
     140                }
    81141        }
    82142
     
    87147        }
    88148
    89         protected <T extends Param> ParamBuilder internalSetType(Class<? extends Param> type, T param) {
    90                 this.paramType = type;
    91                 this.param = param;
    92                 if (param instanceof PrimitiveParam) {
    93                         primitiveParam = (PrimitiveParam) param;
    94                 }
    95                 typeString = param.getFramsTypeName();
    96                 return this;
    97         }
    98 
    99149        public <T extends Param> ParamBuilder type(Class<T> type) {
    100150                assert type != null;
    101                 try {
    102                         return internalSetType(type, type.newInstance());
    103                 } catch (InstantiationException | IllegalAccessException e) {
    104                         e.printStackTrace();
    105                 }
    106                 return this;
    107         }
    108 
    109         public <T extends Param> ParamBuilder type(T param) {
    110                 return internalSetType(param.getClass(), param);
    111         }
     151                this.paramType = type;
     152                return this;
     153        }
     154
     155        // public <T extends Param> ParamBuilder type(T param) {
     156        //      return internalSetType(param.getClass(), param);
     157        // }
    112158
    113159
     
    120166        }
    121167
     168        /**
     169         * @return the internalId
     170         */
     171        public String getInternalId() {
     172                return internalId;
     173        }
     174
    122175        public ParamBuilder setInternalId(String internalId) {
    123176                this.internalId = internalId;
     
    144197
    145198        protected <T extends Number> void parseMinMaxDefNumber(Class<T> type, String second, String third) {
    146                 if (primitiveParam == null) {
    147                         log.warn("param is not a primitive param");
    148                         return;
    149                 }
    150199                if (second != null) {
    151                         this.primitiveParam.min = Numbers.parse(second, type);
    152                         if (this.primitiveParam.min == null) {
    153                                 log.warn("value of min attribute was invalid");
    154                         }
     200                        min = second;
    155201                }
    156202                if (third != null) {
    157                         this.primitiveParam.max = Numbers.parse(third, type);
    158                         if (this.primitiveParam.max == null) {
    159                                 log.warn("value of min attribute was invalid");
    160                         }
    161                 }
    162         }
     203                        max = third;
     204                }
     205        }
     206
     207        protected List<String> enumValues;
     208
     209        public ParamBuilder enums(List<String> values) {
     210                enumValues = values;
     211                return type(EnumParam.class);
     212        }
     213
     214        protected String procedureSignature;
     215
     216        protected String uid;
    163217
    164218        @ParamAnnotation
    165219        public ParamBuilder type(String type) {
    166                 typeString = type;
     220                // typeString = type;
    167221
    168222                log.trace("parsing type: " + type);
     
    175229                switch (first.charAt(0)) {
    176230                        case 'o': {
    177                                 type(new ObjectParam(second != null ? second : first.substring(1)));
     231                                containedTypeName = second != null ? second : first.substring(1);
     232                                type(ObjectParam.class);
    178233                                break;
    179234                        }
    180235                        case 'p': {
    181                                 ProcedureParam procedureParam = new ProcedureParam();
    182                                 String signature = type.substring(1);
    183                                 try {
    184                                         procedureParam.parseSignature(signature);
    185                                 } catch (Exception e) {
    186                                         log.error("invalid procedure signature '" + signature + "': " + e);
    187                                 }
    188                                 type(procedureParam);
     236                                procedureSignature = type.substring(1);
     237                                type(ProcedureParam.class);
    189238                                break;
    190239                        }
     
    193242                                int tildeIndex = type.indexOf("~");
    194243                                if (tildeIndex != -1) {
    195                                         type(new EnumParam(new ArrayList<String>(Arrays.asList(type.substring(tildeIndex + 1).split("~")))));
     244                                        enums(Arrays.asList(type.substring(tildeIndex + 1).split("~")));
    196245                                } else {
    197246                                        if (first.length() >= 2) {
     
    214263                                                type(BooleanParam.class);
    215264                                        }
    216                                         if (param == null) {
     265                                        if (paramType == null) {
    217266                                                type(DecimalParam.class);
    218267                                        }
    219268                                }
    220                                 if (this.param instanceof DecimalParam) {
     269                                if (DecimalParam.class.isAssignableFrom(this.paramType)) {
    221270                                        parseMinMaxDefNumber(Integer.class, second, third);
    222271                                }
     
    243292                        }
    244293                        case 'l': {
    245                                 type(third != null ? new UniqueListParam(second, third) : new ArrayListParam(second));
     294                                containedTypeName = second;
     295                                if (third != null) {
     296                                        type(UniqueListParam.class);
     297                                        uid = third;
     298                                } else {
     299                                        type(ArrayListParam.class);
     300                                }
    246301                                break;
    247302                        }
     
    294349        @ParamAnnotation
    295350        public String getType() {
    296                 return typeString;
     351                return "?";
    297352        }
    298353
     
    304359        }
    305360
    306         public <T> ParamBuilder min(T min) {
    307                 if (primitiveParam != null) {
    308                         this.primitiveParam.min = min;
    309                 }
    310                 return this;
    311         }
    312 
    313         public <T> ParamBuilder max(T max) {
    314                 if (primitiveParam != null) {
    315                         this.primitiveParam.max = max;
    316                 }
    317                 return this;
    318         }
    319 
    320         public <T> ParamBuilder def(T def) {
    321                 if (def != null && primitiveParam != null) {
    322                         this.primitiveParam.def = def;
    323                 }
    324                 return this;
    325         }
    326 
    327         public Class<?> getStorageType() {
    328                 assert param != null;
    329                 return param.getStorageType();
    330         }
     361        public ParamBuilder min(Object min) {
     362                this.min = min;
     363                return this;
     364        }
     365
     366        public ParamBuilder max(Object max) {
     367                this.max = max;
     368                return this;
     369        }
     370
     371        public ParamBuilder def(Object def) {
     372                this.def = def;
     373                return this;
     374        }
     375
     376        // public Class<?> getStorageType() {
     377        //      assert param != null;
     378        //      return param.getStorageType();
     379        // }
    331380
    332381        public Param build(String line) throws Exception {
     
    386435        }
    387436
    388 
     437        public ParamBuilder defaultDef(Object def) {
     438                if (this.def == null) {
     439                        return def(def);
     440                }
     441                return this;
     442        }
    389443
    390444}
  • java/main/src/main/java/com/framsticks/params/PrimitiveParam.java

    r84 r87  
    11package com.framsticks.params;
    22
     3import com.framsticks.util.FramsticksException;
     4import com.framsticks.util.lang.Numbers;
     5
     6import javax.annotation.concurrent.Immutable;
    37
    48/**
    59 * @author Piotr Sniegowski
    610 */
    7 public abstract class PrimitiveParam extends ValueParam {
     11@Immutable
     12public abstract class PrimitiveParam<S> extends ValueParam {
    813
    914        /** The minimum allowed value of parameter. */
    10         protected Object min;
     15        protected final Object min;
    1116
    1217        /** The maximum allowed value of parameter. */
    13         protected Object max;
     18        protected final Object max;
    1419
    1520        /** The default value of parameter. */
    16         protected Object def;
     21        protected final Object def;
     22
     23        /**
     24         * @param builder
     25         */
     26        public PrimitiveParam(ParamBuilder builder) {
     27                super(builder);
     28                min = builder.getMin();
     29                max = builder.getMax();
     30                def = builder.getDef();
     31        }
    1732
    1833        public void save(SinkInterface sink, Object value) {
     
    2136
    2237        protected <T> T tryCastAndReturn(Object value, Class<T> type) {
    23                 if (value == null)
     38                if (value == null) {
    2439                        return null;
     40                }
    2541                try {
    26                         return type.cast(value);
     42                        if (type.equals(Object.class)) {
     43                                return type.cast(value);
     44                        }
     45                        if (value instanceof String) {
     46                                if (type.equals(String.class)) {
     47                                        return type.cast(value);
     48                                }
     49                                // if (Number.class.isAssignableFrom(type)) {
     50                                return Numbers.parse((String) value, type);
     51                                // }
     52                                // return null;
     53                        } else {
     54                                return type.cast(value);
     55                        }
    2756                } catch (ClassCastException e) {
    28                         throw new ClassCastException("property \"" + name
    29                                         + "\" type is \"" + value.getClass().getName()
    30                                         + "\", not \"" + type.getName() + "\"");
     57                        throw new FramsticksException().msg("failed to cast").cause(e).arg("param", this).arg("actual", value.getClass()).arg("requested", type);
    3158                }
    3259        }
     
    6491         * @throws ClassCastException the class cast exception, thrown when given getType is incorrect
    6592         */
    66         public <T> T getDef(Class<T> type) throws ClassCastException {
     93        public <T> T getDef(Class<T> type) {
    6794                return tryCastAndReturn(def, type);
    6895        }
  • java/main/src/main/java/com/framsticks/params/PropertiesAccess.java

    r85 r87  
    2727
    2828        public PropertiesAccess(FramsClass framsClass) {
    29                 setFramsClass(framsClass);
     29                super(framsClass);
    3030        }
    3131
     
    8888        }
    8989
     90        @Override
     91        public boolean tryAutoAppend(Object object) {
     92                return false;
     93        }
    9094
    9195}
  • java/main/src/main/java/com/framsticks/params/ReflectionAccess.java

    r86 r87  
    44import java.lang.reflect.InvocationTargetException;
    55import java.lang.reflect.Method;
     6import java.util.Collections;
    67import java.util.HashMap;
    78import java.util.Map;
    89
     10import javax.annotation.concurrent.Immutable;
     11
    912import org.apache.log4j.Logger;
    1013
     14import com.framsticks.params.annotations.AutoAppendAnnotation;
    1115import com.framsticks.util.FramsticksException;
     16import com.framsticks.util.lang.Pair;
    1217
    1318import static com.framsticks.util.lang.Containers.*;
     
    2227 */
    2328public class ReflectionAccess extends SimpleAbstractAccess {
    24         private final static Logger log = Logger.getLogger(ReflectionAccess.class
    25                         .getName());
     29        private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
    2630
    2731        protected final Class<?> reflectedClass;
     32        protected final Backend backend;
     33
    2834        private Object object;
    2935
    30 
    31         protected interface ReflectedSetter {
    32                 public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
    33         }
    34 
    35         protected interface ReflectedGetter {
    36                 public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
    37         }
    38 
    39         protected static class ReflectedValueParam {
    40                 public ReflectedSetter setter;
    41                 public ReflectedGetter getter;
    42         }
    43 
    44         protected final Map<ValueParam, ReflectedValueParam> reflectedValueParams = new HashMap<>();
     36        @Immutable
     37        public static class Backend {
     38
     39                protected static Map<Pair<Class<?>, FramsClass>, Backend> synchronizedCache = Collections.synchronizedMap(new HashMap<Pair<Class<?>, FramsClass>, Backend>());
     40
     41                public static class ReflectedValueParam {
     42                        public ReflectedSetter setter;
     43                        public ReflectedGetter getter;
     44                }
     45
     46                public interface ReflectedSetter {
     47                        public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
     48                }
     49
     50                public interface ReflectedGetter {
     51                        public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
     52                }
     53
     54                protected final Map<ValueParam, ReflectedValueParam> params;
     55                protected final Map<Class<?>, Method> autoAppendMethods;
     56
     57                /**
     58                 * @param params
     59                 */
     60                public Backend(Map<ValueParam, ReflectedValueParam> params, Map<Class<?>, Method> autoAppendMethods) {
     61                        // this.params = Collections.unmodifiableMap(params);
     62                        this.params = params;
     63                        this.autoAppendMethods = autoAppendMethods;
     64                }
     65
     66                public static Backend getOrCreateFor(Class<?> reflectedClass, FramsClass framsClass) {
     67
     68                        Pair<Class<?>, FramsClass> id = new Pair<Class<?>, FramsClass>(reflectedClass, framsClass);
     69                        Backend backend = synchronizedCache.get(id);
     70                        if (backend != null) {
     71                                return backend;
     72                        }
     73
     74                        log.debug("constructing backend for " + id);
     75                        final Map<ValueParam, ReflectedValueParam> params = new HashMap<>();
     76
     77                        Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
     78
     79                        try {
     80                                for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
     81                                        if (!candidates.containsKey(vp.getId())) {
     82                                                throw new ConstructionException().msg("missing candidate for param").arg("param", vp);
     83                                        }
     84                                        ParamCandidate pc = candidates.get(vp.getId());
     85                                        if (pc.isReadOnly() && !vp.hasFlag(Flags.READONLY)) {
     86                                                throw new ConstructionException().msg("readonly state conflict").arg("param", vp);
     87                                        }
     88                                        if (!typeMatch(pc.getRawType(), vp.getStorageType())) {
     89                                                throw new ConstructionException().msg("types mismatch for param").arg("param", vp).arg("candidate", pc.getType()).arg("storage", vp.getStorageType());
     90                                        }
     91
     92                                        ReflectedValueParam rvp = new ReflectedValueParam();
     93                                        params.put(vp, rvp);
     94                                        final boolean primitive = pc.isPrimitive();
     95                                        if (pc.getField() != null) {
     96                                                final Field f = pc.getField();
     97                                                rvp.getter = new ReflectedGetter() {
     98                                                        @Override
     99                                                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
     100                                                                return type.cast(f.get(object));
     101                                                        }
     102                                                };
     103                                                if (!pc.isFinal()) {
     104                                                        rvp.setter = new ReflectedSetter() {
     105                                                                @Override
     106                                                                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
     107                                                                        if (value == null && primitive) {
     108                                                                                throw new FramsticksException().msg("setting null to primitive value");
     109                                                                        }
     110                                                                        f.set(object, value);
     111                                                                }
     112                                                        };
     113                                                }
     114                                        } else {
     115                                                final Method g = pc.getGetter();
     116
     117                                                rvp.getter = new ReflectedGetter() {
     118                                                        @Override
     119                                                        public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     120                                                                return type.cast(g.invoke(object));
     121                                                        }
     122                                                };
     123
     124                                                if (!pc.isFinal()) {
     125                                                        final Method s = pc.getSetter();
     126                                                        rvp.setter = new ReflectedSetter() {
     127                                                                @Override
     128                                                                public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
     129                                                                        if (value == null && primitive) {
     130                                                                                throw new FramsticksException().msg("setting null to primitive value");
     131                                                                        }
     132                                                                        s.invoke(object, value);
     133                                                                }
     134                                                        };
     135                                                }
     136                                        }
     137                                }
     138                        } catch (ConstructionException e) {
     139                                throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
     140                        }
     141
     142                        Map<Class<?>, Method> autoAppendMethods = new HashMap<>();
     143
     144                        Class<?> javaClass = reflectedClass;
     145                        while (javaClass != null) {
     146
     147                                for (Method m : javaClass.getDeclaredMethods()) {
     148                                        AutoAppendAnnotation a = m.getAnnotation(AutoAppendAnnotation.class);
     149                                        if (a == null) {
     150                                                continue;
     151                                        }
     152                                        Class<?>[] args = m.getParameterTypes();
     153                                        if (args.length != 1) {
     154                                                throw new ConstructionException().msg("invalid number of arguments in AutoAppend marked method").arg("method", m).arg("arguments", args.length);
     155                                        }
     156                                        autoAppendMethods.put(args[0], m);
     157                                }
     158
     159                                javaClass = javaClass.getSuperclass();
     160                        }
     161
     162                        backend = new Backend(params, autoAppendMethods);
     163                        synchronizedCache.put(id, backend);
     164                        return backend;
     165                }
     166
     167        }
    45168
    46169        public ReflectionAccess(Class<?> reflectedClass) throws ConstructionException {
    47                 this(reflectedClass, FramsClassBuilder.buildForClass(reflectedClass));
     170                this(reflectedClass, FramsClass.build().forClass(reflectedClass));
    48171        }
    49172
     
    68191
    69192        public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException {
     193                super(framsClass);
    70194                this.reflectedClass = reflectedClass;
    71                 setFramsClass(framsClass);
    72 
    73                 Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
    74 
    75                 try {
    76                         for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
    77                                 if (!candidates.containsKey(vp.getId())) {
    78                                         throw new ConstructionException().msg("missing candidate for param").arg("param", vp);
    79                                 }
    80                                 ParamCandidate pc = candidates.get(vp.getId());
    81                                 if (pc.isReadOnly() && !vp.hasFlag(Flags.READONLY)) {
    82                                         throw new ConstructionException().msg("readonly state conflict").arg("param", vp);
    83                                 }
    84                                 if (!typeMatch(pc.getRawType(), vp.getStorageType())) {
    85                                         throw new ConstructionException().msg("types mismatch for param").arg("param", vp).arg("candidate", pc.getType()).arg("storage", vp.getStorageType());
    86                                 }
    87 
    88                                 ReflectedValueParam rvp = new ReflectedValueParam();
    89                                 reflectedValueParams.put(vp, rvp);
    90                                 final boolean primitive = pc.isPrimitive();
    91                                 if (pc.getField() != null) {
    92                                         final Field f = pc.getField();
    93                                         rvp.getter = new ReflectedGetter() {
    94                                                 @Override
    95                                                 public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
    96                                                         return type.cast(f.get(object));
    97                                                 }
    98                                         };
    99                                         if (!pc.isFinal()) {
    100                                                 rvp.setter = new ReflectedSetter() {
    101                                                         @Override
    102                                                         public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
    103                                                                 if (value == null && primitive) {
    104                                                                         throw new FramsticksException().msg("setting null to primitive value");
    105                                                                 }
    106                                                                 f.set(object, value);
    107                                                         }
    108                                                 };
    109                                         }
    110                                 } else {
    111                                         final Method g = pc.getGetter();
    112 
    113                                         rvp.getter = new ReflectedGetter() {
    114                                                 @Override
    115                                                 public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    116                                                         return type.cast(g.invoke(object));
    117                                                 }
    118                                         };
    119 
    120                                         if (!pc.isFinal()) {
    121                                                 final Method s = pc.getSetter();
    122                                                 rvp.setter = new ReflectedSetter() {
    123                                                         @Override
    124                                                         public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
    125                                                                 if (value == null && primitive) {
    126                                                                         throw new FramsticksException().msg("setting null to primitive value");
    127                                                                 }
    128                                                                 s.invoke(object, value);
    129                                                         }
    130                                                 };
    131                                         }
    132                                 }
    133                         }
    134                 } catch (ConstructionException e) {
    135                         throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
    136                 }
     195                this.backend = Backend.getOrCreateFor(reflectedClass, framsClass);
     196                // log.info("created ReflectionAccess " + this);
    137197        }
    138198
     
    149209                                }
    150210
    151                                 return reflectedValueParams.get(param).getter.get(object, type);
     211                                return backend.params.get(param).getter.get(object, type);
    152212                        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
    153213                                throw new FramsticksException().msg("failed to get").cause(e);
     
    169229                                        throw new FramsticksException().msg("no object set");
    170230                                }
    171                                 ReflectedSetter s = reflectedValueParams.get(param).setter;
     231                                Backend.ReflectedSetter s = backend.params.get(param).setter;
    172232                                if (s == null) {
    173233                                        throw new FramsticksException().msg("trying to set final");
     
    238298        }
    239299
    240 
    241300        @Override
    242301        public ReflectionAccess cloneAccess() throws ConstructionException {
     
    265324        }
    266325
     326        @Override
     327        public boolean tryAutoAppend(Object value) {
     328                assert object != null;
     329                for (Map.Entry<Class<?>, Method> a : backend.autoAppendMethods.entrySet()) {
     330                        if (a.getKey().isAssignableFrom(value.getClass())) {
     331                                try {
     332                                        a.getValue().invoke(object, value);
     333                                        return true;
     334                                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
     335                                        throw new FramsticksException().msg("failed to auto append").cause(e).arg("value", value).arg("into object", object).arg("with method", a.getValue());
     336                                }
     337                        }
     338                }
     339                return false;
     340        }
    267341}
    268342
  • java/main/src/main/java/com/framsticks/params/Registry.java

    r86 r87  
    55import com.framsticks.params.annotations.FramsClassAnnotation;
    66
     7import java.util.Collections;
    78import java.util.HashMap;
     9import java.util.HashSet;
    810import java.util.Map;
     11import java.util.Set;
    912
    1013/**
     
    1417        private static final Logger log = Logger.getLogger(Registry.class.getName());
    1518
    16         protected final Map<String, Class<?>> reflectedClasses = new HashMap<String, Class<?>>();
    17         protected final Map<String, String> invertedReflectedClasses = new HashMap<String, String>();
    18         protected final Map<String, FramsClass> infoCache = new HashMap<String, FramsClass>();
     19        public static class DoubleSet<K1, K2, V> {
     20                protected final Map<K1, V> byId = new HashMap<>();
     21                protected final Map<K2, V> byName = new HashMap<>();
     22                protected final Set<V> values = new HashSet<>();
    1923
    20         public final void registerReflectedClass(String name, String id, String className) {
    21                 try {
    22                         registerReflectedClass(name, id, Class.forName(className));
    23                 } catch (ClassNotFoundException e) {
    24                         log.fatal("class not found during registration: " + e);
     24                public int size() {
     25                        return values.size();
     26                }
     27
     28                public void put(K1 id, K2 name, V value) {
     29                        values.add(value);
     30                        if (id != null) {
     31                                byId.put(id, value);
     32                        }
     33                        if (name != null) {
     34                                byName.put(name, value);
     35                        }
     36                }
     37
     38                public boolean containsValue(V value) {
     39                        return values.contains(value);
     40
     41                }
     42
     43                public boolean containsKey(String identifier) {
     44                        return byId.containsKey(identifier) || byName.containsKey(identifier);
     45                }
     46
     47                public V get(String identifier) {
     48                        if (byId.containsKey(identifier)) {
     49                                return byId.get(identifier);
     50                        }
     51                        if (byName.containsKey(identifier)) {
     52                                return byName.get(identifier);
     53                        }
     54                        return null;
     55                }
     56
     57                public Set<V> getValues() {
     58                        return Collections.unmodifiableSet(values);
    2559                }
    2660        }
    2761
    28         public void registerReflectedClass(String name, String id,
    29                         Class<?> reflectedClass) {
    30                 if (name != null) {
    31                         reflectedClasses.put(name, reflectedClass);
    32                         invertedReflectedClasses.put(reflectedClass.getCanonicalName(), name);
    33                 }
    34                 if (id != null) {
    35                         reflectedClasses.put(id, reflectedClass);
    36                 }
     62        // protected void internalRegisterClass(FramsClass framsClass, @Nullable Class<?> javaClass) {
     63        //      assert framsClass.getName() != null;
     64        //      assert framsClass.getId() != null;
     65        //      infoCacheByName.put(framsClass.getName(), framsClass);
     66        //      infoCacheById.put(framsClass.getId(), framsClass);
     67
     68        //      if (javaClass != null) {
     69        //              reflectedClasses.put(framsClass, javaClass);
     70        //              infoCacheByJavaName.put(javaClass.getCanonicalName(), framsClass);
     71        //      }
     72        // }
     73        protected final DoubleSet<String, String, Class<?>> javaClasses = new DoubleSet<>();
     74        protected final DoubleSet<String, String, FramsClass> framsClasses = new DoubleSet<>();
     75
     76        public void registerReflectedClass(String name, String id, Class<?> reflectedClass) {
     77                javaClasses.put(id, name, reflectedClass);
    3778        }
    3879
     
    5091
    5192        public AccessInterface createAccess(String name, FramsClass framsClass) throws ConstructionException {
    52                 if (reflectedClasses.containsKey(name)) {
    53                         return new ReflectionAccess(reflectedClasses.get(name), framsClass);
     93                assert framsClasses.containsValue(framsClass);
     94                if (javaClasses.containsKey(name)) {
     95                        return new ReflectionAccess(javaClasses.get(name), framsClass);
    5496                }
    5597                return new PropertiesAccess(framsClass);
     
    5799
    58100        public void putInfoIntoCache(FramsClass framsClass) {
    59                 if (infoCache.containsKey(framsClass.getId())) {
    60                         log.info("already cached " + framsClass);
    61                         return;
    62                 }
    63101                log.debug("caching info for " + framsClass);
    64                 infoCache.put(framsClass.getId(), framsClass);
    65                 infoCache.put(framsClass.getName(), framsClass);
     102                framsClasses.put(framsClass.getId(), framsClass.getName(), framsClass);
    66103        }
    67104
    68         public FramsClass getInfoFromCache(String id) {
    69                 if (id == null) {
     105        public FramsClass getInfoFromCache(String identifier) {
     106                if (identifier == null) {
    70107                        return null;
    71108                }
    72                 if (infoCache.containsKey(id)) {
    73                         return infoCache.get(id);
    74                 }
    75                 if (invertedReflectedClasses.containsKey(id)) {
    76                         return getInfoFromCache(invertedReflectedClasses.get(id));
    77                 }
    78                 return null;
     109                return framsClasses.get(identifier);
    79110        }
    80111
     
    102133        }
    103134
     135        public Set<Class<?>> getReflectedClasses() {
     136                return javaClasses.getValues();
     137        }
     138
     139        public Set<FramsClass> getInfoCache() {
     140                return framsClasses.getValues();
     141        }
     142
    104143}
  • java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java

    r86 r87  
    2424        private final static Logger log = Logger.getLogger(SimpleAbstractAccess.class.getName());
    2525
     26        protected final FramsClass framsClass;
     27
     28        /**
     29         * @param framsClass
     30         */
     31        public SimpleAbstractAccess(FramsClass framsClass) {
     32                this.framsClass = framsClass;
     33        }
     34
    2635        @Override
    2736        public final FramsClass getFramsClass() {
     
    2938        }
    3039
    31         public void setFramsClass(FramsClass framsClass) {
    32                 this.framsClass = framsClass;
    33         }
    3440        /**
    3541         * Simple String key, value class.
     
    5157        }
    5258
    53         protected FramsClass framsClass;
    5459
    5560        @Override
     
    141146        @Override
    142147        public void setMin(int i) {
    143                 PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class);
     148                PrimitiveParam<?> entry = framsClass.getParamEntry(i, PrimitiveParam.class);
    144149                if (entry == null) {
    145150                        return;
     
    160165        @Override
    161166        public void setMax(int i) {
    162                 PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class);
     167                PrimitiveParam<?> entry = framsClass.getParamEntry(i, PrimitiveParam.class);
    163168                if (entry == null) {
    164169                        return;
     
    188193                assert framsClass != null;
    189194                sink.print(framsClass.getId()).print(":").breakLine();
    190                 for (PrimitiveParam p : filterInstanceof(framsClass.getParamEntries(), PrimitiveParam.class)) {
     195                for (PrimitiveParam<?> p : filterInstanceof(framsClass.getParamEntries(), PrimitiveParam.class)) {
    191196                        Object value = get(p, Object.class);
    192197                        if (value == null) {
  • java/main/src/main/java/com/framsticks/params/UniqueListAccess.java

    r85 r87  
    4444                        return getParam(i);
    4545                }
     46                //TODO list access here
    4647                return Param.build().id(id).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
    4748        }
  • java/main/src/main/java/com/framsticks/params/ValueParam.java

    r84 r87  
    11package com.framsticks.params;
    22
     3
     4import javax.annotation.concurrent.Immutable;
    35
    46/**
    57 * @author Piotr Sniegowski
    68 */
     9@Immutable
    710public abstract class ValueParam extends Param {
     11
     12        /**
     13         * @param builder
     14         */
     15        public ValueParam(ParamBuilder builder) {
     16                super(builder);
     17        }
    818
    919        public ReassignResult<?> reassign(Object newValue, Object oldValue) throws CastFailure {
     
    1121        }
    1222
    13         public abstract <T> T getDef(Class<T> type) throws ClassCastException;
     23        public abstract <T> T getDef(Class<T> type);
    1424
    1525}
  • java/main/src/main/java/com/framsticks/params/types/ArrayListParam.java

    r84 r87  
    44import com.framsticks.params.ArrayListAccess;
    55import com.framsticks.params.CastFailure;
     6import com.framsticks.params.ParamBuilder;
    67import com.framsticks.params.ReassignResult;
    78import com.framsticks.util.lang.Casting;
     
    1213import java.util.List;
    1314
     15import javax.annotation.concurrent.Immutable;
     16
    1417/**
    1518 * @author Piotr Sniegowski
    1619 */
     20@Immutable
    1721public class ArrayListParam extends ListParam {
    1822
    19         public ArrayListParam(String containedTypeName) {
    20                 super(containedTypeName);
     23        public ArrayListParam(ParamBuilder builder) {
     24                super(builder);
    2125        }
    2226
  • java/main/src/main/java/com/framsticks/params/types/BinaryParam.java

    r84 r87  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.ParamBuilder;
    45import com.framsticks.params.PrimitiveParam;
    56import com.framsticks.params.ReassignResult;
    67import com.framsticks.util.lang.Numbers;
    78
     9import javax.annotation.concurrent.Immutable;
     10
    811/**
    912 * @author Piotr Sniegowski
    1013 */
    11 public class BinaryParam extends PrimitiveParam {
     14@Immutable
     15public class BinaryParam extends PrimitiveParam<Integer> {
     16
     17        /**
     18         * @param builder
     19         */
     20        public BinaryParam(ParamBuilder builder) {
     21                super(builder);
     22        }
    1223
    1324        @Override
  • java/main/src/main/java/com/framsticks/params/types/BooleanParam.java

    r84 r87  
    11package com.framsticks.params.types;
    22
     3import javax.annotation.concurrent.Immutable;
     4
    35import com.framsticks.params.CastFailure;
     6import com.framsticks.params.ParamBuilder;
    47import com.framsticks.params.PrimitiveParam;
    58import com.framsticks.params.ReassignResult;
     
    1013 * @author Piotr Sniegowski
    1114 */
    12 public class BooleanParam extends PrimitiveParam {
     15@Immutable
     16public class BooleanParam extends PrimitiveParam<Boolean> {
    1317
    14         public BooleanParam() {
    15                 def = false;
     18        /**
     19         * @param builder
     20         */
     21        public BooleanParam(ParamBuilder builder) {
     22                super(builder.defaultDef(false));
    1623        }
    1724
  • java/main/src/main/java/com/framsticks/params/types/ColorParam.java

    r84 r87  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.ParamBuilder;
    45import com.framsticks.params.PrimitiveParam;
    56import com.framsticks.params.ReassignResult;
     7
     8import javax.annotation.concurrent.Immutable;
    69
    710/**
    811 * @author Piotr Sniegowski
    912 */
    10 public class ColorParam extends PrimitiveParam {
     13@Immutable
     14public class ColorParam extends PrimitiveParam<Object> {
     15
     16
     17
     18        /**
     19         * @param builder
     20         */
     21        public ColorParam(ParamBuilder builder) {
     22                super(builder);
     23        }
    1124
    1225        @Override
  • java/main/src/main/java/com/framsticks/params/types/DecimalParam.java

    r84 r87  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.ParamBuilder;
    45import com.framsticks.params.ReassignResult;
     6
     7import javax.annotation.concurrent.Immutable;
    58
    69/**
    710 * @author Piotr Sniegowski
    811 */
     12@Immutable
    913public class DecimalParam extends NumberParam<Integer> {
    1014
    11         public DecimalParam() {
    12                 def = 0;
     15        /**
     16         * @param builder
     17         */
     18        public DecimalParam(ParamBuilder builder) {
     19                super(builder.defaultDef(0));
    1320        }
    1421
  • java/main/src/main/java/com/framsticks/params/types/EnumParam.java

    r84 r87  
    33import java.util.List;
    44
     5import com.framsticks.params.ParamBuilder;
     6
     7import javax.annotation.concurrent.Immutable;
     8
    59/**
    610 * @author Piotr Sniegowski
    711 */
     12@Immutable
    813public class EnumParam extends DecimalParam {
    914
    10         List<String> enums;
     15
     16        protected final List<String> enums;
    1117
    1218        /**
     
    1521         * @param enums
    1622         */
    17         public EnumParam(List<String> enums) {
    18                 assert(enums != null);
    19                 this.enums = enums;
     23        public EnumParam(ParamBuilder builder) {
     24                super(builder);
     25                this.enums = builder.getEnumValues();
     26                assert(this.enums != null);
    2027        }
    2128
  • java/main/src/main/java/com/framsticks/params/types/EventParam.java

    r84 r87  
    22
    33import com.framsticks.params.Param;
     4import com.framsticks.params.ParamBuilder;
     5
     6import javax.annotation.concurrent.Immutable;
    47
    58/**
    69 * @author Piotr Sniegowski
    710 */
     11@Immutable
    812public class EventParam extends Param {
     13
     14
     15
     16        /**
     17         * @param builder
     18         */
     19        public EventParam(ParamBuilder builder) {
     20                super(builder);
     21        }
    922
    1023        @Override
  • java/main/src/main/java/com/framsticks/params/types/FloatParam.java

    r84 r87  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.ParamBuilder;
    45import com.framsticks.params.ReassignResult;
     6
     7import javax.annotation.concurrent.Immutable;
    58
    69/**
    710 * @author Piotr Sniegowski
    811 */
     12@Immutable
    913public class FloatParam extends NumberParam<Double> {
    1014
    11         public FloatParam() {
    12                 def = 0.0;
     15        /**
     16         * @param builder
     17         */
     18        public FloatParam(ParamBuilder builder) {
     19                super(builder.defaultDef(0.0));
    1320        }
    1421
  • java/main/src/main/java/com/framsticks/params/types/ListParam.java

    r84 r87  
    22
    33import com.framsticks.params.CompositeParam;
     4import com.framsticks.params.ParamBuilder;
     5
     6import javax.annotation.concurrent.Immutable;
    47
    58/**
    69 * @author Piotr Sniegowski
    710 */
     11@Immutable
    812public abstract class ListParam extends CompositeParam {
    913
    10         public ListParam(String containedTypeName) {
    11                 super(containedTypeName);
     14        public ListParam(ParamBuilder builder) {
     15                super(builder);
    1216        }
    1317
  • java/main/src/main/java/com/framsticks/params/types/NumberParam.java

    r84 r87  
    33import com.framsticks.params.CastFailure;
    44import com.framsticks.params.Flags;
     5import com.framsticks.params.ParamBuilder;
    56import com.framsticks.params.PrimitiveParam;
    67import com.framsticks.params.ReassignResult;
     
    89import com.framsticks.util.lang.Numbers;
    910
     11import javax.annotation.concurrent.Immutable;
     12
    1013/**
    1114 * @author Piotr Sniegowski
    1215 */
    13 public abstract class NumberParam<T extends Number & Comparable<T>> extends PrimitiveParam {
     16@Immutable
     17public abstract class NumberParam<T extends Number & Comparable<T>> extends PrimitiveParam<T> {
     18
     19        /**
     20         * @param builder
     21         */
     22        public NumberParam(ParamBuilder builder) {
     23                super(builder);
     24        }
    1425
    1526        @Override
     
    2132                T v = null;
    2233                if (newValue instanceof String) {
    23                         v = Numbers.parse((String)newValue, type);
     34                        v = Numbers.parse((String) newValue, type);
    2435                } else {
    2536                        v = Casting.tryCast(type, newValue);
  • java/main/src/main/java/com/framsticks/params/types/ObjectParam.java

    r84 r87  
    44import com.framsticks.params.CastFailure;
    55import com.framsticks.params.CompositeParam;
     6import com.framsticks.params.ParamBuilder;
    67import com.framsticks.params.ReassignResult;
     8
     9import javax.annotation.concurrent.Immutable;
    710
    811/**
    912 * @author Piotr Sniegowski
    1013 */
     14@Immutable
    1115public class ObjectParam extends CompositeParam {
    1216
    13         public ObjectParam(String containedTypeName) {
    14                 super(containedTypeName);
     17        public ObjectParam(ParamBuilder builder) {
     18                super(builder);
    1519        }
    1620
  • java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java

    r85 r87  
    22
    33import com.framsticks.params.Param;
     4import com.framsticks.params.ParamBuilder;
     5import com.framsticks.util.FramsticksException;
    46import com.framsticks.util.lang.Strings;
    57
     
    911import java.util.regex.Pattern;
    1012
     13import javax.annotation.concurrent.Immutable;
     14
    1115/**
    1216 * @author Piotr Sniegowski
    1317 */
     18@Immutable
    1419public class ProcedureParam extends Param {
    15         private Param resultType;
    16         private List<Param> argumentsType = new ArrayList<Param>();
     20        private final Param resultType;
     21        private final List<Param> argumentsType = new ArrayList<Param>();
    1722
    1823        private static Pattern addressPattern = Pattern.compile("^([^\\(]+)?\\(([^\\)]*)\\)$");
     24
     25        /**
     26         * @param builder
     27         */
     28        public ProcedureParam(ParamBuilder builder) {
     29                super(builder);
     30                String signature = builder.getProcedureSignature();
     31                if (Strings.notEmpty(signature)) {
     32                        Matcher matcher = addressPattern.matcher(signature);
     33                        if (!matcher.matches()) {
     34                                throw new FramsticksException().msg("invalid signature");
     35                        }
     36                        String result = Strings.collapse(matcher.group(1));
     37                        resultType = (result != null) ? parseType(result, null) : null;
     38                        String arguments = matcher.group(2);
     39                        if (!Strings.notEmpty(arguments)) {
     40                                return;
     41                        }
     42                        for (String a : arguments.split(",")) {
     43                                int space = a.indexOf(' ');
     44                                String type;
     45                                String name;
     46                                if (space == -1) {
     47                                        type = a;
     48                                        name = null;
     49                                } else {
     50                                        type = a.substring(0, space);
     51                                        name = a.substring(space + 1);
     52                                }
     53                                argumentsType.add(parseType(type, name));
     54                        }
     55                } else {
     56                        resultType = null;
     57                }
     58        }
    1959
    2060        protected static Param parseType(String type, String name) {
    2161                return Param.build().type(type).name(name).finish();
    2262        }
    23 
    24         public void parseSignature(String signature) throws Exception {
    25                 if (!Strings.notEmpty(signature)) {
    26                         return;
    27                 }
    28                 Matcher matcher = addressPattern.matcher(signature);
    29                 if (!matcher.matches()) {
    30                         throw new Exception("invalid signature");
    31                 }
    32                 String result = Strings.collapse(matcher.group(1));
    33                 if (result != null) {
    34                         resultType = parseType(result, null);
    35                 }
    36                 String arguments = matcher.group(2);
    37                 if (!Strings.notEmpty(arguments)) {
    38                         return;
    39                 }
    40                 for (String a : arguments.split(",")) {
    41                         int space = a.indexOf(' ');
    42                         String type;
    43                         String name;
    44                         if (space == -1) {
    45                                 type = a;
    46                                 name = null;
    47                         } else {
    48                                 type = a.substring(0, space);
    49                                 name = a.substring(space + 1);
    50                         }
    51                         argumentsType.add(parseType(type, name));
    52                 }
    53         }
    54 
    5563
    5664        @Override
  • java/main/src/main/java/com/framsticks/params/types/StringParam.java

    r84 r87  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.ParamBuilder;
    45import com.framsticks.params.PrimitiveParam;
    56import com.framsticks.params.ReassignResult;
    67import com.framsticks.params.SinkInterface;
    78
     9import javax.annotation.concurrent.Immutable;
     10
    811/**
    912 * @author Piotr Sniegowski
    1013 */
    11 public class StringParam extends PrimitiveParam {
     14@Immutable
     15public class StringParam extends PrimitiveParam<String> {
     16
     17
     18
     19        /**
     20         * @param builder
     21         */
     22        public StringParam(ParamBuilder builder) {
     23                super(builder);
     24        }
     25
    1226        @Override
    1327        public Class<?> getStorageType() {
  • java/main/src/main/java/com/framsticks/params/types/UniqueListParam.java

    r84 r87  
    33import com.framsticks.params.AccessInterface;
    44import com.framsticks.params.CastFailure;
     5import com.framsticks.params.ParamBuilder;
    56import com.framsticks.params.ReassignResult;
    67import com.framsticks.params.UniqueListAccess;
     
    1011import java.util.Map;
    1112
     13import javax.annotation.concurrent.Immutable;
     14
    1215/**
    1316 * @author Piotr Sniegowski
    1417 */
     18@Immutable
    1519public class UniqueListParam extends ListParam {
    1620
    1721        final String uidName;
    1822
    19         public UniqueListParam(String containedTypeName, String uidName) {
    20                 super(containedTypeName);
    21                 this.uidName = uidName;
     23        public UniqueListParam(ParamBuilder builder) {
     24                super(builder);
     25                this.uidName = builder.getUid();
    2226        }
    2327
  • java/main/src/main/java/com/framsticks/params/types/UniversalParam.java

    r84 r87  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.ParamBuilder;
    45import com.framsticks.params.PrimitiveParam;
    56import com.framsticks.params.ReassignResult;
     7
     8import javax.annotation.concurrent.Immutable;
    69
    710/**
    811 * @author Piotr Sniegowski
    912 */
    10 public class UniversalParam extends PrimitiveParam {
     13@Immutable
     14public class UniversalParam extends PrimitiveParam<Object> {
     15
     16
     17        /**
     18         * @param builder
     19         */
     20        public UniversalParam(ParamBuilder builder) {
     21                super(builder);
     22        }
     23
    1124        @Override
    1225        public Class<?> getStorageType() {
Note: See TracChangeset for help on using the changeset viewer.