source: java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java @ 100

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

HIGHLIGHTS:

  • add <include/> to configuration
  • add side notes to tree
    • used to store arbitrary information alongside the tree structure
  • migrate to log4j2
    • supports lazy string evaluation of passed arguments
  • improve GUI tree
    • it stays in synchronization with actual state (even in high load test scenario)
  • improve panel management in GUI
  • make loading objects in GUI more lazy
  • offload parsing to connection receiver thread
    • info parsing
    • first step of objects parsing
  • fix connection parsing bug (eof in long values)
  • support zero-arguments procedure in table view

CHANGELOG:
Implement procedure calls from table view.

Refactorization around procedures in tables.

Add table editor for buttons.

Render buttons in the the list view.

Further improve Columns.

Add Column class for TableModel?.

Accept also non-arguments ProcedureParams? in tableView.

Increase maximal TextAreaControl? size.

Add tooltip to ProcedureControl?.

Fix bug of interpreting eofs in long values by connection reader.

Further rework connection parsing.

Simplify client connection processing.

Test ListChange? modification.

Test ListChange? events with java server.

Add TestChild?.

Fix bug with fast deregistering when connecting to running server.

Another minor refactorization in TreeOperations?.

Fix bug in SimpleAbstractAccess? loading routine.

Another minor improvement.

Minor change.

Make reading of List objects two-phase.

Another minor change.

Dispatch parsing into receiver thread.

Another step.

Enclose passing value in ObjectParam? case in closure.

Minor step.

Minor change on way to offload parsing.

Temporarily comment out single ValueParam? get.

It will be generalized to multi ValueParam?.

Process info in receiver thread.

Add DispatchingExceptionHandler?.

Make waits in browser test longer.

Use FETCHED_MARK.

It is honored in GUI, where it used to decide whether to get values

after user action.

It is set in standard algorithm for processing fetched values.

Add remove operation to side notes.

Make loading more lazy.

Improve loading policy.

On node choose load itself, on node expansion, load children.

Minor improvement.

Fix bug with panel interleaving.

Minor improvements.

Improve panel management.

More cleaning around panels.

Reorganize panels.

Further improve tree.

Fix bug in TreeModel?.

Remove children from TreeNode?.

Implement TreeNode? hashCode and equals.

Make TreeNode? delegate equals and hashcode to internal reference.

Move listeners from TreeNode? to side notes.

Store path.textual as a side note.

Side note params instead of accesses for objects.

More refactorizations.

In TreeNode? bindAccess based on side notes.

Minor step.

Hide createAccess.

Rename AccessInterface? to Access.

Minor changes.

Several improvements in high load scenarios.

Change semantics of ArrayListAccess?.set(index, null);

It now removes the element, making list shorter
(it was set to null before).

Add path remove handler.

Handle exceptions in Connection.

Update .gitignore

Configure logging to file.

Move registration to TreeModel?.

Further refactorization.

Minor refactorization.

Minor improvements.

Use specialized event also for Modify action of ListChange?.

Use remove events.

Use the insertion events for tree.

Further improve tree refreshing.

Further improve reacting on events in GUI.

Fix problem with not adding objects on addition list change.

Migrate to log4j lazy String construction interface.

Migrate imports to log4j2.

Drop dependency on adapter to version 1.2.

Switch log4j implementation to log4j2.

Add dirty mark to the NodeAtFrame?.

Make selecting in AccessInterfaces? type safe.

Ignore containers size settings in Model and Genotype.

Use tree side notes to remember local changes and panels.

Add sideNotes to tree.

They will be used to store various accompanying information
right in the tree.

Use ReferenceIdentityMap? from apache in TreeNode?.

It suits the need perfectly (weak semantics on both key and value).

Make ArrayListParam? do not react size changes.

Guard in TableModel? before not yet loaded objects.

Add <include/> clause and AutoInjector?.

Extract common columns configuration to separate xml,
that can be included by other configurations.

File size: 7.2 KB
Line 
1package com.framsticks.params;
2
3
4import static com.framsticks.util.lang.Containers.filterInstanceof;
5
6import org.apache.logging.log4j.Logger;
7import org.apache.logging.log4j.LogManager;
8
9import com.framsticks.params.types.ObjectParam;
10import com.framsticks.util.FramsticksException;
11import static com.framsticks.params.SetStateFlags.*;
12
13/**
14 * The Class SimpleAbstractAccess implements all the methods of Access
15 * which actions can be implemented with usage of {@link Access} methods
16 * or concern schema, which is stored in {@link #framsClass}
17 *
18 * Based on c++ class SimpleAbstractParam located in: cpp/gdk/param.*
19 *
20 * @author Jarek Szymczak <name.surname@gmail.com>, Mateusz Jarus (please
21 *         replace name and surname with my personal data)
22 *
23 * @author Piotr Sniegowski
24 */
25public abstract class SimpleAbstractAccess implements Access {
26
27        private final static Logger log = LogManager.getLogger(SimpleAbstractAccess.class.getName());
28
29        protected final FramsClass framsClass;
30
31        /**
32         * @param framsClass
33         */
34        public SimpleAbstractAccess(FramsClass framsClass) {
35                this.framsClass = framsClass;
36        }
37
38        @Override
39        public final FramsClass getFramsClass() {
40                return framsClass;
41        }
42
43        /**
44         * Simple String key, value class.
45         */
46        public static class Entry {
47
48                public final String key;
49                public final String value;
50
51                public Entry(String key, String value) {
52                        this.key = key;
53                        this.value = value;
54                }
55
56                @Override
57                public String toString() {
58                        return key + " = " + value;
59                }
60        }
61
62
63        @Override
64        public String getId() {
65                return framsClass.getId();
66        }
67
68        @Override
69        public int getParamCount() {
70                return framsClass.getParamCount();
71        }
72
73        @Override
74        public Param getParam(int i) {
75                return framsClass.getParam(i);
76        }
77
78        @Override
79        public Param getParam(String id) {
80                return framsClass.getParam(id);
81        }
82
83        // @Override
84        // public Param getGroupMember(int gi, int n) {
85        //      return framsClass.getGroupMember(gi, n);
86        // }
87
88        @Override
89        public <T> T get(int i, Class<T> type) {
90                return get(framsClass.getParamEntry(i, ValueParam.class), type);
91        }
92
93        @Override
94        public <T> T get(String id, Class<T> type) {
95                return get(framsClass.getParamEntry(id, ValueParam.class), type);
96        }
97
98        @Override
99        public <T> int set(int i, T value) {
100                return set(framsClass.getParamEntry(i, ValueParam.class), value);
101        }
102
103        @Override
104        public <T> int set(String id, T value) {
105                return set(framsClass.getParamEntry(id, ValueParam.class), value);
106        }
107
108        @Override
109        public <T> int set(ValueParam param, T value) {
110
111                //String id = param.getEffectiveId();
112                try {
113                        Object oldValue = get(param, param.getStorageType());
114                        ReassignResult<?> result = param.reassign(value, oldValue);
115                        Object casted = result.getValue();
116                        if (casted != null && !casted.equals(oldValue)) {
117                                internalSet(param, casted);
118                        }
119                        return result.getFlags();
120                } catch (CastFailure e) {
121                        throw new FramsticksException()
122                                .msg("casting failure while set")
123                                .arg("param", param)
124                                .arg("value", value)
125                                .arg("value's type", (value == null ? "<null>" : value.getClass().getCanonicalName()))
126                                .arg("in", this).cause(e);
127                }
128        }
129
130        @Override
131        public void setDefault(boolean numericOnly) {
132                for (int i = 0; i < framsClass.getParamCount(); i++) {
133                        setDefault(i, numericOnly);
134                }
135        }
136
137        @Override
138        public void setDefault(int i, boolean numericOnly) {
139                ValueParam entry = framsClass.getParamEntry(i, ValueParam.class);
140                if ((entry != null)     && (!numericOnly || entry.isNumeric())) {
141                        set(i, entry.getDef(entry.getStorageType()));
142                }
143        }
144
145        @Override
146        public void setMin() {
147                for (int i = 0; i < framsClass.getParamCount(); i++) {
148                        setMin(i);
149                }
150        }
151
152        @Override
153        public void setMin(int i) {
154                PrimitiveParam<?> entry = framsClass.getParamEntry(i, PrimitiveParam.class);
155                Object min = entry.getMin(entry.getStorageType());
156                if (min != null) {
157                        set(i, min);
158                }
159        }
160
161        @Override
162        public void setMax() {
163                for (int i = 0; i < framsClass.getParamCount(); i++) {
164                        setMax(i);
165                }
166        }
167
168        @Override
169        public void setMax(int i) {
170                PrimitiveParam<?> entry = framsClass.getParamEntry(i, PrimitiveParam.class);
171                Object max = entry.getMax(entry.getStorageType());
172                if (max != null) {
173                        set(i, max);
174                }
175        }
176
177        @Override
178        public void save(SinkInterface sink) {
179                assert framsClass != null;
180                sink.print(framsClass.getId()).print(":").breakLine();
181                for (PrimitiveParam<?> p : filterInstanceof(framsClass.getParamEntries(), PrimitiveParam.class)) {
182                        Object value = get(p, Object.class);
183                        if ((value == null) || value.equals(p.getDef(Object.class))) {
184                                continue;
185                        }
186                        sink.print(p.getId()).print(":");
187                        p.save(sink, value);
188                        sink.breakLine();
189                }
190                sink.breakLine();
191        }
192
193        private static Entry readEntry(SourceInterface source) {
194
195                String line;
196                String key = null;
197                StringBuilder value = null;
198                while ((line = source.readLine()) != null) {
199                        if (key == null) {
200                                int colonIndex = line.indexOf(':');
201                                if (colonIndex == -1) {
202                                        return null;
203                                }
204                                key = line.substring(0, colonIndex);
205                                String inlineValue = line.substring(colonIndex + 1);
206
207
208                                if (!inlineValue.startsWith("~")) {
209                                        return new Entry(key, inlineValue);
210                                }
211                                value = new StringBuilder();
212                                value.append(inlineValue.substring(1));
213                                continue;
214                        }
215                        if (value.length() != 0) {
216                                value.append(System.getProperty("line.separator"));
217                        }
218                        if (line.endsWith("~") && !line.endsWith("\\~")) {
219                                value.append(line.substring(0, line.length() - 1));
220                                return new Entry(key, value.toString().replaceAll("\\\\~", "~"));
221                        }
222                        value.append(line);
223                }
224                return null;
225        }
226
227        @Override
228        public void load(SourceInterface source) {
229                //TODO not clearing values, because get from manager gives only fields, not children
230                //this.clearValues();
231
232                Entry entry;
233                while ((entry = readEntry(source)) != null) {
234                        Param param = getParam(entry.key);
235                        if (param == null) {
236                                throw new FramsticksException().msg("param not found in access").arg("name", entry.key).arg("access", this);
237                        }
238                        if (!(param instanceof ValueParam)) {
239                                throw new FramsticksException().msg("param is not a value param").arg("param", param).arg("access", this);
240                        }
241                        if ((param.getFlags() & ParamFlags.DONTLOAD) == 0) {
242                                int retFlags = this.set((ValueParam) param, entry.value);
243                                if ((retFlags & (PSET_HITMIN | PSET_HITMAX)) != 0) {
244                                        String which = ((retFlags & PSET_HITMIN) != 0) ? "small" : "big";
245                                        log.warn("value of key '{}' was too {}, adjusted", entry.key, which);
246                                }
247                        }
248                }
249        }
250
251        protected abstract <T> void internalSet(ValueParam param, T value);
252
253        @Override
254        public Iterable<Param> getParams() {
255                return framsClass.getParamEntries();
256        }
257
258        @Override
259        public int getCompositeParamCount() {
260                return framsClass.getCompositeParamCount();
261        }
262
263        @Override
264        public CompositeParam getCompositeParam(int number) {
265                return framsClass.getCompositeParam(number);
266        }
267
268        /*
269        protected <T extends Comparable<T>> int setAndCut(Param param, Object value, Class<T> type) {
270                int flags = 0;
271                T val = type.cast(value);
272                T min = param.getMin(type);
273                T max = param.getMax(type);
274                if (min != null && val.compareTo(min) < 0) {
275                        val = min;
276                        flags |= Flags.PSET_HITMIN;
277                }
278                if (max != null && val.compareTo(max) > 0) {
279                        val = max;
280                        flags |= Flags.PSET_HITMAX;
281                }
282                internalSet(param, val);
283                return flags;
284        }*/
285
286
287        @Override
288        public ParamBuilder buildParam(ParamBuilder builder) {
289                return builder.name(getId()).type(ObjectParam.class).containedTypeName(getId());
290        }
291
292}
Note: See TracBrowser for help on using the repository browser.