source: java/main/src/main/java/com/framsticks/params/ParamCandidate.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: 6.1 KB
Line 
1package com.framsticks.params;
2
3import java.lang.reflect.AnnotatedElement;
4import java.lang.reflect.Array;
5import java.lang.reflect.Field;
6import java.lang.reflect.GenericArrayType;
7import java.lang.reflect.Member;
8import java.lang.reflect.Method;
9import java.lang.reflect.Modifier;
10import java.lang.reflect.ParameterizedType;
11import java.lang.reflect.Type;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.Map;
15
16import com.framsticks.params.annotations.ParamAnnotation;
17
18public class ParamCandidate {
19
20        public class OneTime<T> {
21                protected final String name;
22                T value;
23
24                /**
25                 * @param name
26                 */
27                public OneTime(String name) {
28                        this.name = name;
29                }
30
31                final void set(T value) {
32                        if (this.value == null) {
33                                this.value = value;
34                                return;
35                        }
36                        if (!this.value.equals(value)) {
37                                throw new ConstructionException().msg("already set")
38                                        .arg("name", name)
39                                        .arg("in", ParamCandidate.this)
40                                        .arg("already", this.value)
41                                        .arg("now", value);
42                        }
43                }
44
45                public final T get() {
46                        return value;
47                }
48
49                public final boolean has() {
50                        return value != null;
51                }
52
53                @Override
54                public String toString() {
55                        return value == null ? "<null>" : value.toString();
56                }
57
58
59        }
60
61        protected final String id;
62        protected final OneTime<String> name = new OneTime<>("name");
63        protected final OneTime<Type> type = new OneTime<>("type");
64        protected final OneTime<Field> field = new OneTime<>("field");
65        protected final OneTime<Method> setter = new OneTime<>("setter");
66        protected final OneTime<Method> getter = new OneTime<>("getter");
67
68        /**
69         * @param id
70         */
71        public ParamCandidate(String id) {
72                this.id = id;
73        }
74
75        /**
76         * @return the id
77         */
78        public String getId() {
79                return id;
80        }
81
82        /**
83         * @return the name
84         */
85        public String getName() {
86                return name.get();
87        }
88
89        /**
90         * @return the type
91         */
92        public Type getType() {
93                return type.get();
94        }
95
96        public Class<?> getRawType() {
97                return getRawClass(type.get());
98        }
99
100        void setType(Type type) {
101                this.type.set(type);
102        }
103
104
105        /**
106         * @return the field
107         */
108        public Field getField() {
109                return field.get();
110        }
111
112        /**
113         * @return the setter
114         */
115        public Method getSetter() {
116                return setter.get();
117        }
118
119        /**
120         * @return the getter
121         */
122        public Method getGetter() {
123                return getter.get();
124        }
125
126        void validate() throws ConstructionException {
127                try {
128                        if (isPublic(field)) {
129                                if (getter.has()) {
130                                        throw new ConstructionException().msg("getter and public field coexist");
131                                }
132                                return;
133                        }
134                        if (isPublic(field)) {
135                                if (setter.has()) {
136                                        throw new ConstructionException().msg("setter and field coexist");
137                                }
138                        }
139
140                        if (!getter.has() && !field.has()) {
141                                throw new ConstructionException().msg("missing getter or field");
142                        }
143                } catch (ConstructionException e) {
144                        throw e.arg("in", this);
145                }
146        }
147
148        boolean isFinal() {
149                if (Collection.class.isAssignableFrom(getRawType())) {
150                        return false;
151                }
152                if (setter.has()) {
153                        return false;
154                }
155                if (field.has()) {
156                        return Modifier.isFinal(field.get().getModifiers());
157                }
158                return true;
159        }
160
161        boolean isReadOnly() {
162                if (Collection.class.isAssignableFrom(getRawType())) {
163                        return false;
164                }
165                if (isPublic(setter)) {
166                        return false;
167                }
168                if (isPublic(field)) {
169                        return Modifier.isFinal(field.get().getModifiers());
170                }
171                return true;
172        }
173
174        void add(Member member, String name) {
175                this.name.set(name);
176                if (member instanceof Field) {
177                        this.field.set((Field) member);
178                        setType(field.get().getGenericType());
179                        return;
180                }
181                if (member instanceof Method) {
182                        Method m = (Method) member;
183                        Type[] ps = m.getGenericParameterTypes();
184                        if (ps.length == 0) {
185                                getter.set(m);
186                                setType(m.getGenericReturnType());
187                                return;
188                        }
189                        if (ps.length == 1) {
190                                setter.set(m);
191                                setType(ps[0]);
192                                return;
193                        }
194                        throw new ConstructionException().msg("invalid number of arguments").arg("method", m).arg("in", this);
195                }
196                throw new ConstructionException().msg("invalid kind of member").arg("member", member).arg("in", this);
197        }
198
199        public boolean isPrimitive() {
200                return getRawType().isPrimitive();
201        }
202
203        public int getFlags() {
204                int f = 0;
205                if (isReadOnly()) {
206                        f |= Flags.READONLY;
207                }
208                return f;
209        }
210
211        @Override
212        public String toString() {
213                return id + "(" + type.toString() + ")";
214        }
215
216        public static boolean isPublic(Member member) {
217                return Modifier.isPublic(member.getModifiers());
218        }
219
220        public static boolean isPublic(OneTime<? extends Member> v) {
221                return v.has() ? isPublic(v.get()) : false;
222        }
223
224        public static <M extends Member & AnnotatedElement> void filterParamsCandidates(Map<String, ParamCandidate> params, M[] members) {
225                for (M m : members) {
226                        ParamAnnotation pa = m.getAnnotation(ParamAnnotation.class);
227                        if (pa == null) {
228                                continue;
229                        }
230                        // if (!isPublic(m)) {
231                        //      throw new ConstructionException().msg("field is not public").arg("field", m);
232                        // }
233                        String id = FramsClassBuilder.getId(pa, m);
234                        ParamCandidate pc = null;
235                        if (params.containsKey(id)) {
236                                pc = params.get(id);
237                        } else {
238                                pc = new ParamCandidate(id);
239                                params.put(id, pc);
240                        }
241                        pc.add(m, FramsClassBuilder.getName(pa, m));
242
243                }
244        }
245
246        public static Map<String, ParamCandidate> getAllCandidates(Class<?> javaClass) throws ConstructionException {
247                Map<String, ParamCandidate> candidates = new HashMap<>();
248
249                while (javaClass != null) {
250                        filterParamsCandidates(candidates, javaClass.getDeclaredFields());
251                        filterParamsCandidates(candidates, javaClass.getDeclaredMethods());
252
253                        javaClass = javaClass.getSuperclass();
254                }
255
256                for (ParamCandidate pc : candidates.values()) {
257                        pc.validate();
258                }
259
260                return candidates;
261        }
262
263        public static Class<?> getRawClass(final Type type) {
264                if (Class.class.isInstance(type)) {
265                        return Class.class.cast(type);
266                }
267                if (ParameterizedType.class.isInstance(type)) {
268                        final ParameterizedType parameterizedType = ParameterizedType.class.cast(type);
269                        return getRawClass(parameterizedType.getRawType());
270                } else if (GenericArrayType.class.isInstance(type)) {
271                        GenericArrayType genericArrayType = GenericArrayType.class.cast(type);
272                        Class<?> c = getRawClass(genericArrayType.getGenericComponentType());
273                        return Array.newInstance(c, 0).getClass();
274                } else {
275                        return null;
276                }
277        }
278
279};
Note: See TracBrowser for help on using the repository browser.