source: java/main/src/main/java/com/framsticks/params/FramsClass.java @ 85

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

HIGHLIGHTS:

  • upgrade to Java 7
    • use try-multi-catch clauses
    • use try-with-resources were appropriate
  • configure FindBugs? (use mvn site and then navigate in browser to the report)
    • remove most bugs found
  • parametrize Dispatching environment (Dispatcher, RunAt?) to enforce more control on the place of closures actual call

CHANGELOG:
Rework FavouritesXMLFactory.

FindBugs?. Thread start.

FindBugs?. Minor change.

FindBugs?. Iterate over entrySet.

FindBugs?. Various.

FindBug?.

FindBug?. Encoding.

FindBug?. Final fields.

FindBug?.

Remove synchronization bug in ClientConnection?.

Experiments with findbugs.

Finish parametrization.

Make RunAt? an abstract class.

More changes in parametrization.

More changes in parametrizing dispatching.

Several changes to parametrize tasks.

Rename Runnable to RunAt?.

Add specific framsticks Runnable.

Add JSR305 (annotations).

Add findbugs reporting.

More improvements to ParamBuilder? wording.

Make FramsClass? accept also ParamBuilder?.

Change wording of ParamBuilder?.

Change wording of Request creation.

Use Java 7 exception catch syntax.

Add ScopeEnd? class.

Upgrade to Java 7.

File size: 8.3 KB
Line 
1package com.framsticks.params;
2
3import com.framsticks.params.types.StringParam;
4import com.framsticks.parsers.FileSource;
5import com.framsticks.parsers.Loaders;
6import com.framsticks.util.lang.Casting;
7
8import org.apache.log4j.Logger;
9
10import java.io.InputStream;
11import java.lang.reflect.*;
12import java.util.*;
13
14/**
15 * The class FramsClass represents the class / schema of connected parameters
16 * (such as parameters within the class). It differs from C++ version by storing
17 * information about the class that parameters belong to.
18 *
19 * Based loosely on c++ class Param located in cpp/gdk/param.*
20 *
21 * @author Jarek Szymczak <name.surname@gmail.com>, Mateusz Jarus (please
22 *         replace name and surname with my personal data)
23 *
24 * @author Piotr Sniegowski
25 */
26public final class FramsClass {
27
28        private final static Logger log = Logger.getLogger(FramsClass.class
29                        .getName());
30
31        /**
32         * The Class which represents group.
33         */
34
35        /** The offset of the parameter (applied for newly added parameter). */
36        protected int fieldsNumber;
37
38        /** The groups. */
39        protected List<Group> groups = new ArrayList<Group>();
40
41        /**
42         * The param entry map <parameterId, param> (for fast accessing of parameters
43         * by their name)
44         */
45        protected Map<String, Param> paramEntryMap = new LinkedHashMap<String, Param>();
46
47        /** The param list (for accessing parameters by offset in O(1) time. */
48        protected List<Param> paramList = new ArrayList<Param>();
49
50        /** The param getId map (for fast lookup of offset based on name */
51        protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
52
53        protected String id;
54
55        protected String name;
56
57        protected String description;
58
59        public Collection<Param> getParamEntries() {
60                return paramList;
61        }
62
63        public FramsClass() {
64        }
65
66        public FramsClass(String id, String name, String description) {
67                this.setId(id);
68                this.setName(name);
69                this.setDescription(description);
70        }
71
72        /**
73         * Adds new param entry.
74         *
75         * @param param
76         *            the new param entry
77         */
78        public FramsClass append(Param param) {
79                paramEntryMap.put(param.getId(), param);
80                //paramEntryMap.put(param.getInternalId(), param);
81                paramList.add(param);
82                try {
83                        Group group = groups.get(param.getGroup());
84                        if (group != null) {
85                                group.addProperty(param);
86                        }
87                } catch (IndexOutOfBoundsException ignored) {
88
89                }
90
91                return this;
92        }
93
94        public FramsClass append(ParamBuilder builder) {
95                return append(builder.finish());
96        }
97
98        /**
99         * Adds new group.
100         */
101        public FramsClass appendGroup(Group group) {
102                groups.add(group);
103                return this;
104        }
105
106        public String getDescription() {
107                return description;
108        }
109
110        public int getGroupCount() {
111                return groups.size();
112        }
113
114        /**
115         * Gets the group member.
116         *
117         * @param gi
118         *            the offset of group
119         * @param pi
120         *            the offset of member within a group
121         * @return the pi-th member of group gi
122         */
123        public Param getGroupMember(int gi, int pi) {
124                if (gi < 0 || pi < 0 || gi >= groups.size()) {
125                        return null;
126                }
127                Group group = groups.get(gi);
128                return (group != null ? group.getProperty(pi) : null);
129        }
130
131        /**
132         * Gets the group getName.
133         *
134         * @param gi
135         *            the offset of group
136         * @return the group getName
137         */
138        public String getGroupName(int gi) {
139                if (gi < 0 || gi >= groups.size())
140                        return null;
141                return groups.get(gi).name;
142        }
143
144        public String getId() {
145                return id;
146        }
147
148        public String getName() {
149                return name;
150        }
151
152        public String getNiceName() {
153                return name != null ? name : id;
154        }
155
156        /**
157         * Gets the param entry.
158         *
159         * @param i
160         *            the offset of parameter
161         * @return the param entry
162         */
163        public <T extends Param> T getParamEntry(int i, Class<T> type) {
164                if (i < 0 || i >= paramList.size()) {
165                        return null;
166                }
167                return Casting.tryCast(type, paramList.get(i));
168        }
169
170        /**
171         * Gets the param entry.
172         *
173         * @param id
174         *            the getId of parameter
175         * @return the param entry
176         */
177        public <T extends Param> T getParamEntry(String id, Class<T> type) {
178                return Casting.tryCast(type, paramEntryMap.get(id));
179        }
180
181        public int getParamCount() {
182                return paramList.size();
183        }
184
185        @Override
186        public String toString() {
187                return id;
188        }
189
190        public static FramsClass getFramsClass() {
191                return new FramsClass("class", "class", null)
192                        .append(Param.build().id("name").name("Name").type(StringParam.class))
193                        .append(Param.build().id("id").name("id").type(StringParam.class))
194                        .append(Param.build().id("desc").name("Description").type(StringParam.class));
195        }
196
197        public void setId(String id) {
198                this.id = id;
199        }
200
201        public void setName(String name) {
202                this.name = name;
203        }
204
205        public void setDescription(String description) {
206                this.description = description;
207        }
208
209        public static String getParamTypeForNativeType(Type type) {
210                if (type instanceof ParameterizedType) {
211                        ParameterizedType p = (ParameterizedType) type;
212                        Type rawType = p.getRawType();
213                        if (rawType.equals(Map.class)) {
214                                Type containedType = p.getActualTypeArguments()[1];
215                                //TODO uid should be passed along during construction
216                                if (containedType instanceof Class) {
217                                        return "l " + ((Class<?>) containedType).getCanonicalName()
218                                                        + " name";
219                                }
220                        }
221                        if (rawType.equals(List.class)) {
222                                Type containedType = p.getActualTypeArguments()[0];
223                                if (containedType instanceof Class) {
224                                        return "l " + ((Class<?>) containedType).getCanonicalName();
225                                }
226                        }
227                        return null;
228                }
229
230                if (type.equals(Integer.class)) {
231                        return "d";
232                }
233                if (type.equals(String.class)) {
234                        return "s";
235                }
236                if (type.equals(Double.class)) {
237                        return "f";
238                }
239                if (type instanceof Class) {
240                        return "o " + ((Class<?>) type).getCanonicalName();
241                }
242                return null;
243        }
244
245        public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
246
247        public static FramsClass readFromStream(InputStream stream) {
248                return Loaders.loadFramsClass(new FileSource(stream));
249        }
250
251        public static class Constructor {
252                protected final FramsClass result;
253                protected Class<?> currentClass;
254
255                public Constructor(Class<?> src, String name) {
256                        result = new FramsClass(name, name, GENERATE_HELP_PREFIX
257                                        + src.toString());
258                        currentClass = src;
259                        while (currentClass != null) {
260                                try {
261                                        currentClass.getMethod("constructFramsClass", Constructor.class).invoke(null, this);
262                                } catch (IllegalAccessException | IllegalArgumentException
263                                                | InvocationTargetException | NoSuchMethodException
264                                                | SecurityException e) {
265                                        log.debug("failed to use constructFramsClass static method (skipping): ", e);
266                                }
267                                currentClass = currentClass.getSuperclass();
268                        }
269                        currentClass = src;
270                }
271
272                public final FramsClass getResult() {
273                        return result;
274                }
275
276                public Constructor allFields() {
277                        for (Field f : currentClass.getFields()) {
278                                field(f.getName());
279                        }
280                        return this;
281                }
282
283                public Constructor method(String name, Class<?> ... arguments) {
284                        try {
285                                Method method = currentClass.getMethod(name, arguments);
286                                if (!Modifier.isPublic(method.getModifiers())) {
287                                        return this;
288                                }
289                                String returnParamClass = getParamTypeForNativeType(method.getGenericReturnType());
290                                if (returnParamClass == null) {
291                                        return this;
292                                }
293                                Class<?>[] args = method.getParameterTypes();
294                                if (args.length == 0) {
295                                        if (method.getName().startsWith("get")) {
296                                                String fieldName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
297                                                Param param = Param.build().type(returnParamClass).name(fieldName).id(fieldName).help(GENERATE_HELP_PREFIX + method.toString()).finish();
298                                                assert param != null;
299                                                result.append(param);
300                                                return this;
301                                        }
302                                        return this;
303                                }
304                                return this;
305                        } catch (NoSuchMethodException e) {
306                                log.fatal("method " + name + " was not found in " + currentClass.toString());
307                        }
308                        return this;
309                }
310                public Constructor field(String name) {
311                        try {
312                                Field field = currentClass.getField(name);
313                                if (!Modifier.isPublic(field.getModifiers())) {
314                                        return this;
315                                }
316                                String paramClass = getParamTypeForNativeType(field.getGenericType());
317                                if (paramClass == null) {
318                                        return this;
319                                }
320                                Param param = Param.build().type(paramClass).name(field.getName()).id(field.getName()).help(GENERATE_HELP_PREFIX + field.toString()).finish();
321                                assert param != null;
322                                result.append(param);
323                                return this;
324                        } catch (NoSuchFieldException e) {
325                                log.fatal("field " + name + " was not found in " + currentClass.toString());
326                        }
327                        return this;
328                }
329        }
330}
Note: See TracBrowser for help on using the repository browser.