source: java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java @ 90

Last change on this file since 90 was 90, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

CHANGELOG:
Make ProcedureParam? hold only ValueParams?.

Use id instead of names when naming gui components internally.

Basic procedure calling in GUI.

The actual procedure call is currently only backed
by the ObjectInstance?.

Add UnimplementedException?.

Improve naming of various gui elements.

Allow easy navigating in FEST Swing testing.

Add optional explicit order attribute to FramsClassAnnotation?.

That's because java reflection does return declared members
in any specific order. That ordering is needed only for
classes that have no representation in framsticks and need
a deterministic ordering of params.

Add ControlOwner? interface.

Add test for procedure calling in Browser.

First version of ParamAnnotation? for procedures.

Development of ProcedureParam?.

Add draft version of ProcedureParam? implementation in ReflectionAccess?.

Allow viewing FramsClasses? in gui Browser.

Extract ResourceBuilder? from ModelBuilder?.

Remove internalId from Param.

It was currently completely not utilised. Whether it is still needed
after introduction of ParamAnnotation? is arguable.

Add remaining param attributes to ParamAnnotation?.

Change AutoBuilder? semantics.

AutoBuilder? returns list of objects that are to be appended
with methods @AutoAppendAnnotation?.

This allows to omit explicit addition of ModelPackage? to instance
if the instance uses ModelBuilder? (registration of ModelPackage? comes
from schema).

Fix params ordering problem in auto created FramsClasses?.

Improve ObjectInstance?.

Several fixes to ModelBuilder?.

Improve test for ObjectInstance? in Browser.

Make initialization of robot static.

With robot recreated for second browser test, the test hanged
deep in AWT.

Add base convenience base test for Browser tests.

More tests to ObjectInstance?.

Rename Dispatcher.invokeLater() to dispatch().

Add assertDispatch.

It allows assertions in other threads, than TestNGInvoker.
Assertions are gathered after each method invocation and rethrown.

Use timeOut annotation attribute for tests involving some waiting.

Remove firstTask method (merge with joinableStart).

Clean up leftovers.

Remove unused FavouritesXMLFactory (the reading part is already
completely done with generic XmlLoader?, and writing part will be done
based on the same approach if needed).
Move UserFavourite? to the com.framsticks.gui.configuration package.

Remove GenotypeBrowser? as to specific.

This functionality will be available in ObjectInstance?.

Add interface ParamsPackage?.

Package containing registration of Java classes meant to use with
ReflectionAccess? may be in Instance using configuration.

Minor changes.

Make Group immutable.

Add AutoBuilder? interface extending Builder - only those would
be used to automatically build from XML.

Fix groups in FramsClass?.

Minor naming cleanup in Registry.

Add ModelComponent? interface.

All class creating the Model are implementing that interface.

Extract Model.build into ModelBuilder?.

ModelBuilder? will be compatible with other builders
and allow using it from configuration.

Fix NeuroConnection?.

Add synchronous get operation for dispatchers.

Rename JoinableMonitor? to Monitor.

Add ObjectInstance?.

This class is mainly for demonstration
and testing purposes.

Improve FramsServer? runner.

  • improve ExternalProcess? runner,
  • runner can kill the server but also react properly, when the server exists on it's own,
  • set default path to search for framsticks server installation,
  • add LoggingOutputListener?.
File size: 8.9 KB
Line 
1package com.framsticks.params;
2
3import java.io.InputStream;
4import java.lang.reflect.Field;
5import java.lang.reflect.Member;
6import java.lang.reflect.Method;
7import java.lang.reflect.ParameterizedType;
8import java.lang.reflect.Type;
9import java.util.ArrayList;
10import java.util.Collections;
11import java.util.HashMap;
12import java.util.LinkedList;
13import java.util.List;
14import java.util.Map;
15
16import org.apache.log4j.Logger;
17
18import com.framsticks.params.annotations.AutoAppendAnnotation;
19import com.framsticks.params.annotations.FramsClassAnnotation;
20import com.framsticks.params.annotations.ParamAnnotation;
21import com.framsticks.parsers.FileSource;
22import com.framsticks.parsers.Loaders;
23import com.framsticks.util.Builder;
24import com.framsticks.util.lang.Containers;
25import com.framsticks.util.lang.Strings;
26
27@FramsClassAnnotation(id = "class", name = "class")
28public class FramsClassBuilder implements Builder<FramsClass> {
29        private static final Logger log =
30                Logger.getLogger(FramsClassBuilder.class);
31
32        public static String getName(FramsClassAnnotation fca, Class<?> javaClass) {
33                return fca.name().equals("") ? javaClass.getSimpleName() : fca.name();
34        }
35
36        public static String getId(FramsClassAnnotation fca, Class<?> javaClass) {
37                return fca.id().equals("") ? javaClass.getSimpleName() : fca.id();
38        }
39
40        public static ParamBuilder induceParamType(ParamBuilder builder, Type type) {
41
42                if (type instanceof ParameterizedType) {
43                        ParameterizedType p = (ParameterizedType) type;
44                        Type rawType = p.getRawType();
45                        Type containedType = null;
46                        //TODO make implementation here
47                        boolean map = false;
48                        if (rawType.equals(Map.class)) {
49                                containedType = p.getActualTypeArguments()[1];
50                                map = true;
51                        } else if (rawType.equals(List.class)) {
52                                containedType = p.getActualTypeArguments()[0];
53                        }
54                        if (!(containedType instanceof Class)) {
55                                return builder;
56                        }
57                        Class<?> containedClass = (Class<?>) containedType;
58                        StringBuilder b = new StringBuilder();
59                        b.append("l ");
60                        FramsClassAnnotation fca = containedClass.getAnnotation(FramsClassAnnotation.class);
61                        if (fca == null) {
62                                log.error("the class is not annotated: " + containedClass);
63                                return builder;
64                        }
65                        b.append(getName(fca, containedClass));
66                        if (map) {
67                                b.append(" name");
68                        }
69
70                        builder.type(b.toString());
71                        return builder;
72                }
73
74                if (type instanceof Class) {
75
76                        Class<?> cl = (Class<?>) type;
77
78                        // TODO: future support for enum
79                        // if (cl.isEnum()) {
80                        //      Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) cl;
81                        //      Enum<?>[] enums = enumType.getEnumConstants();
82                        //      StringBuilder b = new StringBuilder();
83
84                        //      b.append("d 0 ").append(enums.length - 1).append(" 0 ");
85                        //      for (Enum<?> e : enums) {
86                        //              b.append("~").append(e.name());
87                        //      }
88                        //      return b.toString();
89                        // }
90                        if (cl.equals(Integer.class) || cl.equals(int.class)) {
91                                builder.type("d");
92                                return builder;
93                        }
94                        if (cl.equals(String.class)) {
95                                builder.type("s");
96                                return builder;
97                        }
98                        if (cl.equals(Double.class) || cl.equals(double.class)) {
99                                builder.type("f");
100                                return builder;
101                        }
102                        if (cl.equals(Boolean.class) || cl.equals(boolean.class)) {
103                                builder.type( "d 0 1");
104                                return builder;
105                        }
106                        if (cl.equals(Object.class)) {
107                                builder.type("x");
108                                return builder;
109                        }
110
111                        // builder.type("o " + (cl).getCanonicalName());
112                        builder.type("o " + cl.getSimpleName());
113                        builder.fillStorageType(cl);
114                        return builder;
115                }
116
117                throw new ConstructionException().msg("failed to find framsticks for native type").arg("type", type);
118        }
119
120
121        public static ParamBuilder induceParamType(ParamBuilder builder, ParamCandidate candidate) {
122                Method method = candidate.getCaller();
123                if (method == null) {
124                        return induceParamType(builder, candidate.getType());
125                }
126
127                builder.resultType(induceParamType(Param.build(), method.getGenericReturnType()).finish(ValueParam.class));
128
129                List<ValueParam> arguments = new ArrayList<>();
130                int number = 0;
131                for (Type arg : method.getGenericParameterTypes()) {
132                        arguments.add(induceParamType(Param.build(), arg).idAndName("arg" + (number++)).finish(ValueParam.class));
133                }
134                builder.argumentsType(arguments);
135
136                return builder;
137        }
138
139        public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
140
141        public static FramsClass readFromStream(InputStream stream) {
142                return Loaders.loadFramsClass(new FileSource(stream));
143        }
144
145        // public static Class<? extends Param> getParamType(@Nonnull Class<?> c) {
146        //      if (c.equals(Integer.class)) {
147        //              return DecimalParam.class;
148        //      }
149        //      if (c.equals(Double.class)) {
150        //              return FloatParam.class;
151        //      }
152        //      if (c.equals(String.class)) {
153        //              return StringParam.class;
154        //      }
155        //      if (c.equals(Object.class)) {
156        //              return UniversalParam.class;
157        //      }
158        //      return null;
159        // }
160
161        public static String extractIdOf(Member member) {
162                if (member instanceof Field) {
163                        return member.getName();
164                }
165                if (member instanceof Method) {
166                        Method m = (Method) member;
167                        String n = m.getName();
168                        int argsNum = m.getParameterTypes().length;
169                        if (argsNum == 0) {
170                                return n.startsWith("get") ? Strings.uncapitalize(n.substring(3)) : n;
171                        }
172                        if (argsNum == 1) {
173                                return n.startsWith("set") ? Strings.uncapitalize(n.substring(3)) : n;
174                        }
175                        log.error("invalid number of arguments");
176                        return null;
177                }
178                log.error("invalid kind of member");
179                return null;
180        }
181        public static String getName(ParamAnnotation annotation, Member member) {
182                return annotation.name().equals("") ? Strings.capitalize(extractIdOf(member)) : annotation.name();
183        }
184
185        public static String getId(ParamAnnotation annotation, Member member) {
186                return annotation.id().equals("") ? extractIdOf(member) : annotation.id();
187        }
188
189        public static ParamBuilder fill(ParamBuilder builder, Member member, ParamAnnotation annotation) {
190                return builder
191                        .id(getId(annotation, member))
192                        .name(getName(annotation, member));
193
194        }
195
196        public static final Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new HashMap<Class<?>, FramsClass>());
197
198        public FramsClass forClass(Class<?> javaClass) throws ConstructionException {
199                FramsClass result = synchronizedCacheForBasedOnForJavaClass.get(javaClass);
200                if (result != null) {
201                        return result;
202                }
203
204                log.debug("building for class " + javaClass);
205
206                FramsClassAnnotation fca = javaClass.getAnnotation(FramsClassAnnotation.class);
207                if (fca == null) {
208                        throw new ConstructionException().msg("java class is not annotated with FramsClassAnnotation").arg("java", javaClass);
209                }
210
211                id(getId(fca, javaClass));
212                name(getName(fca, javaClass));
213
214                for (ParamCandidate pc : ParamCandidate.getAllCandidates(javaClass).getOrder()) {
215                        ParamBuilder builder = Param.build().id(pc.getId()).name(pc.getName()).flags(pc.getFlags());
216
217                        induceParamType(builder, pc);
218
219                        for (ParamAnnotation pa : pc.getAnnotations()) {
220                                if (!"".equals(pa.def())) {
221                                        builder.def(pa.def());
222                                }
223                                if (!"".equals(pa.help())) {
224                                        builder.help(pa.help());
225                                }
226                                if (!"".equals(pa.min())) {
227                                        builder.min(pa.min());
228                                }
229                                if (!"".equals(pa.max())) {
230                                        builder.max(pa.max());
231                                }
232                                builder.extra(pa.extra());
233                                if (!"".equals(pa.stringType())) {
234                                        builder.type(pa.stringType());
235                                }
236                                if (!pa.paramType().equals(Param.class)) {
237                                        builder.type(pa.paramType());
238                                }
239                        }
240                        param(builder);
241                }
242
243                result = finish();
244
245                synchronizedCacheForBasedOnForJavaClass.put(javaClass, result);
246
247                return result;
248        }
249
250
251        protected String id;
252
253        protected String name;
254
255        protected String description;
256
257        protected final List<Param> params = new LinkedList<>();
258
259        protected List<GroupBuilder> groupBuilders = new ArrayList<GroupBuilder>();
260
261        @ParamAnnotation
262        public FramsClassBuilder id(String id) {
263                this.id = id;
264                return this;
265        }
266
267        @ParamAnnotation
268        public FramsClassBuilder name(String name) {
269                this.name = name;
270                return this;
271        }
272
273        public FramsClassBuilder idAndName(String v) {
274                this.id = v;
275                this.name = v;
276                return this;
277        }
278
279        @ParamAnnotation(id = "desc")
280        public FramsClassBuilder description(String description) {
281                this.description = description;
282                return this;
283        }
284
285        public FramsClassBuilder() {
286        }
287
288        public FramsClass finish() {
289                return new FramsClass(this);
290        }
291
292        @AutoAppendAnnotation
293        public FramsClassBuilder param(ParamBuilder builder) {
294                Param param = builder.finish();
295
296                Integer group = param.getGroup();
297                if (group != null) {
298                        Containers.getFromList(groupBuilders, group, "group", this).addParam(param);
299                }
300
301                params.add(param);
302                return this;
303        }
304
305        @AutoAppendAnnotation
306        public FramsClassBuilder group(GroupBuilder builder) {
307                groupBuilders.add(builder);
308                return this;
309        }
310
311        /**
312         * @return the id
313         */
314        @ParamAnnotation
315        public String getId() {
316                return id;
317        }
318
319        /**
320         * @return the name
321         */
322        @ParamAnnotation
323        public String getName() {
324                return name;
325        }
326
327        /**
328         * @return the description
329         */
330        @ParamAnnotation(id = "desc")
331        public String getDescription() {
332                return description;
333        }
334
335        public FramsClassBuilder group(String group) {
336                return group(new GroupBuilder().name(group));
337        }
338
339
340}
Note: See TracBrowser for help on using the repository browser.