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

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

HIGHLIGHTS:

  • loading f0 schema with XmlLoader?
  • use XmlLoader? to load configuration
  • introduce unified fork-join model of various entities

(Instances, Connections, GUI Frames, etc.),
all those entities clean up gracefully on
shutdown, which may be initialized by user
or by some entity

  • basing on above, simplify several organizing classes

(Observer, main class)

(to host native frams server process from Java level)

CHANGELOG:
Remove redundant Observer class.

Clean up in AbstractJoinable?.

Update ExternalProcess? class to changes in joining model.

Another sweep through code with FindBugs?.

Find bug with not joining RemoteInstance?.

Joining almost works.

Much improved joining model.

More improvement to joining model.

Add logging messages around joinable operations.

Rename methods in AbstractJoinable?.

Improve Joinable.

Rewrite of entity structure.

More simplifications with entities.

Further improve joinables.

Let Frame compose from JFrame instead of inheriting.

Add join classes.

Improvements of closing.

Add Builder interface.

Add FramsServerTest?.xml

FramsServer? may be configured through xml.

Make Framsticks main class an Observer of Entities.

Make Observer a generic type.

Remove variables regarding to removed endpoint.

Simplify observer (remove endpoints).

More changes to Observer and Endpoint.

Minor improvements.

Add OutputListener? to ExternalProcess?.

Improve testing of ExternalProcess?.

Add ExternalProcess? runner.

Rename the Program class to Framsticks.

Migrate Program to use XmlLoader? configuration.

First steps with configuration using XmlLoader?.

Fix several bugs.

Move all f0 classes to apriopriate package.

XmlLoader? is able to load Schema.

XmlLoader? is loading classes and props.

Add GroupBuilder?.

File size: 7.7 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.FramsticksException;
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 String getParamTypeForNativeType(Type type) {
41                if (type instanceof ParameterizedType) {
42                        ParameterizedType p = (ParameterizedType) type;
43                        Type rawType = p.getRawType();
44                        Type containedType = null;
45                        //TODO make implementation here
46                        boolean map = false;
47                        if (rawType.equals(Map.class)) {
48                                containedType = p.getActualTypeArguments()[1];
49                                map = true;
50                        } else if (rawType.equals(List.class)) {
51                                containedType = p.getActualTypeArguments()[0];
52                        }
53                        if (!(containedType instanceof Class)) {
54                                return null;
55                        }
56                        Class<?> containedClass = (Class<?>) containedType;
57                        StringBuilder b = new StringBuilder();
58                        b.append("l ");
59                        FramsClassAnnotation fca = containedClass.getAnnotation(FramsClassAnnotation.class);
60                        if (fca == null) {
61                                log.error("the class is not annotated: " + containedClass);
62                                return null;
63                        }
64                        b.append(getName(fca, containedClass));
65                        if (map) {
66                                b.append(" name");
67                        }
68
69                        return b.toString();
70                }
71
72                if (type instanceof Class) {
73
74                        Class<?> cl = (Class<?>) type;
75
76                        // TODO: future support for enum
77                        // if (cl.isEnum()) {
78                        //      Class<? extends Enum<?>> enumType = (Class<? extends Enum<?>>) cl;
79                        //      Enum<?>[] enums = enumType.getEnumConstants();
80                        //      StringBuilder b = new StringBuilder();
81
82                        //      b.append("d 0 ").append(enums.length - 1).append(" 0 ");
83                        //      for (Enum<?> e : enums) {
84                        //              b.append("~").append(e.name());
85                        //      }
86                        //      return b.toString();
87                        // }
88                        if (cl.equals(Integer.class) || cl.equals(int.class)) {
89                                return "d";
90                        }
91                        if (cl.equals(String.class)) {
92                                return "s";
93                        }
94                        if (cl.equals(Double.class) || cl.equals(double.class)) {
95                                return "f";
96                        }
97                        if (cl.equals(Boolean.class) || cl.equals(boolean.class)) {
98                                return "d 0 1";
99                        }
100                        if (cl.equals(Object.class)) {
101                                return "x";
102                        }
103
104                        return "o " + ((Class<?>) type).getCanonicalName();
105                }
106
107                throw new ConstructionException().msg("failed to find framsticks for native type").arg("type", type);
108        }
109
110        public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
111
112        public static FramsClass readFromStream(InputStream stream) {
113                return Loaders.loadFramsClass(new FileSource(stream));
114        }
115
116        // public static Class<? extends Param> getParamType(@Nonnull Class<?> c) {
117        //      if (c.equals(Integer.class)) {
118        //              return DecimalParam.class;
119        //      }
120        //      if (c.equals(Double.class)) {
121        //              return FloatParam.class;
122        //      }
123        //      if (c.equals(String.class)) {
124        //              return StringParam.class;
125        //      }
126        //      if (c.equals(Object.class)) {
127        //              return UniversalParam.class;
128        //      }
129        //      return null;
130        // }
131
132        public static String extractIdOf(Member member) {
133                if (member instanceof Field) {
134                        return member.getName();
135                }
136                if (member instanceof Method) {
137                        Method m = (Method) member;
138                        String n = m.getName();
139                        int argsNum = m.getParameterTypes().length;
140                        if (argsNum == 0) {
141                                return n.startsWith("get") ? Strings.uncapitalize(n.substring(3)) : n;
142                        }
143                        if (argsNum == 1) {
144                                return n.startsWith("set") ? Strings.uncapitalize(n.substring(3)) : n;
145                        }
146                        log.error("invalid number of arguments");
147                        return null;
148                }
149                log.error("invalid kind of member");
150                return null;
151        }
152        public static String getName(ParamAnnotation annotation, Member member) {
153                return annotation.name().equals("") ? Strings.capitalize(extractIdOf(member)) : annotation.name();
154        }
155
156        public static String getId(ParamAnnotation annotation, Member member) {
157                return annotation.id().equals("") ? extractIdOf(member) : annotation.id();
158        }
159
160        public static ParamBuilder fill(ParamBuilder builder, Member member, ParamAnnotation annotation) {
161                return builder
162                        .id(getId(annotation, member))
163                        .name(getName(annotation, member));
164
165        }
166
167        public static final Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new HashMap<Class<?>, FramsClass>());
168
169        public FramsClass forClass(Class<?> javaClass) throws ConstructionException {
170                FramsClass result = synchronizedCacheForBasedOnForJavaClass.get(javaClass);
171                if (result != null) {
172                        return result;
173                }
174
175                log.debug("building for class " + javaClass);
176
177                FramsClassAnnotation fca = javaClass.getAnnotation(FramsClassAnnotation.class);
178                if (fca == null) {
179                        throw new ConstructionException().msg("java class is not annotated with FramsClassAnnotation").arg("java", javaClass);
180                }
181
182                id(getId(fca, javaClass));
183                name(getName(fca, javaClass));
184
185                Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(javaClass);
186
187                for (ParamCandidate pc : candidates.values()) {
188                        String type = getParamTypeForNativeType(pc.getType());
189                        if (type == null) {
190                                throw new FramsticksException().msg("failed to find type for param candidate").arg("candidate", pc);
191                        }
192                        param(Param.build().id(pc.getId()).name(pc.getName()).type(type).flags(pc.getFlags()));
193                }
194
195                result = finish();
196
197                synchronizedCacheForBasedOnForJavaClass.put(javaClass, result);
198
199                return result;
200        }
201
202
203        protected String id;
204
205        protected String name;
206
207        protected String description;
208
209        protected final List<Param> params = new LinkedList<>();
210
211        protected List<Group> groups = new ArrayList<Group>();
212
213        @ParamAnnotation
214        public FramsClassBuilder id(String id) {
215                this.id = id;
216                return this;
217        }
218
219        @ParamAnnotation
220        public FramsClassBuilder name(String name) {
221                this.name = name;
222                return this;
223        }
224
225        public FramsClassBuilder idAndName(String v) {
226                this.id = v;
227                this.name = v;
228                return this;
229        }
230
231        @ParamAnnotation(id = "desc")
232        public FramsClassBuilder description(String description) {
233                this.description = description;
234                return this;
235        }
236
237        public FramsClassBuilder() {
238        }
239
240        public FramsClass finish() {
241                return new FramsClass(this);
242        }
243
244        public FramsClassBuilder append(Param param) {
245                params.add(param);
246                return this;
247        }
248
249        @AutoAppendAnnotation
250        public FramsClassBuilder param(ParamBuilder builder) {
251                return append(builder.finish());
252        }
253
254        @AutoAppendAnnotation
255        public FramsClassBuilder group(GroupBuilder builder) {
256                return group(builder.finish());
257        }
258
259        @AutoAppendAnnotation
260        public FramsClassBuilder group(Group group) {
261                groups.add(group);
262                return this;
263        }
264
265        /**
266         * @return the id
267         */
268        @ParamAnnotation
269        public String getId() {
270                return id;
271        }
272
273        /**
274         * @return the name
275         */
276        @ParamAnnotation
277        public String getName() {
278                return name;
279        }
280
281        /**
282         * @return the description
283         */
284        @ParamAnnotation(id = "desc")
285        public String getDescription() {
286                return description;
287        }
288
289        public FramsClassBuilder group(String group) {
290                return group(new Group(group));
291        }
292
293        public ParamBuilder param(String id) {
294                return new ParamBuilder(this).id(id);
295        }
296
297}
Note: See TracBrowser for help on using the repository browser.