source: java/main/src/main/java/com/framsticks/core/AbstractTree.java @ 103

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

HIGHLIGHTS:

  • add auto loading and saving algorithms between

frams files format and Java classes

  • respect ValueChange? events in GUI (do not reload object)
  • support results of procedures in Java server
  • make Experiment automatically convert between frams file and NetFile? object
  • add MessageLogger? (compatible with original frams server messages)
  • WorkPackageLogic? now validates results, is able to discard them, reschedule

whole package, or only uncomputed remainder

CHANGELOG:
Show just a short description in PrimeExperiment?.

Add primes_changed event to the PrimeExperiment?.

Make WorkPackageLogic? robust to frams server returning invalid results.

Add MessageLogger? to logics.

Add NetFile? interface. Support Messages from server.

Minor changes to connections.

Merge results in the PrimeExperiment?.

More netload class->file conversion to Simulator.

Move netsave parsing to Simulator.

Fix bug with inverted ordering of events firing in Experiment.

Minor changes.

Minor logging changes.

Use AccessOperations?.convert in NetLoadSaveLogic?

NetLoadSaveLogic? now encloses the conversion.

Use more generic AccessOperations? saveAll and loadAll in PrimePackage?.

Add Result class for enclosing of call invocations' results.

Improve feature request handling in Connections.

Use AccessOperations?.convert in RemoteTree? events parsing.

Minor change.

Add some information params to Java server root and CLI objects.

A draft implementation of loadAll algorithm.

That algorithm tries to load objects into a tree structure.

Add AccessOperationsTest? test.

Develop WorkPackageLogic?.

  • add state tracking fields
  • add work package generation

Add utility class SimplePrimitive?.

Meant for Java backend classes, enclose a single primitive value
and set of listeners.

Improve primitive value refresh in GUI.

When ValueChange? found in called event, do not reload whole
object, but only update GUI (no communication is performed).

Use ValueChange? in the TestClass? test.

Minor changes.

Sending all packages in PrimeExperiment? to the frams servers.

Develop AccessOperations?.loadComposites().

Remove addAccess from MultiParamLoader? interface.

There is now no default AccessProvider? in MultiParamLoader?.
User must explicitely set AccessStash? or Registry.

Improve saving algorithms in AccessOperations?.

File size: 8.7 KB
Line 
1package com.framsticks.core;
2
3import java.util.Comparator;
4import java.util.Iterator;
5import java.util.Map;
6import java.util.PriorityQueue;
7
8import javax.annotation.Nonnull;
9
10import org.apache.commons.collections.map.ReferenceIdentityMap;
11import org.apache.logging.log4j.Logger;
12import org.apache.logging.log4j.LogManager;
13
14import com.framsticks.communication.queries.NeedFile;
15import com.framsticks.communication.queries.NeedFileAcceptor;
16import com.framsticks.params.Access;
17import com.framsticks.params.CompositeParam;
18import com.framsticks.params.FramsClass;
19import com.framsticks.params.ParamFlags;
20import com.framsticks.params.ParamsPackage;
21import com.framsticks.params.Registry;
22import com.framsticks.params.annotations.AutoAppendAnnotation;
23import com.framsticks.params.annotations.FramsClassAnnotation;
24import com.framsticks.params.annotations.ParamAnnotation;
25import com.framsticks.util.FramsticksException;
26import com.framsticks.util.Misc;
27import com.framsticks.util.dispatching.AbstractJoinable;
28import com.framsticks.util.dispatching.BufferedDispatcher;
29import com.framsticks.util.dispatching.Dispatcher;
30import com.framsticks.util.dispatching.Dispatching;
31import com.framsticks.util.dispatching.ExceptionResultHandler;
32import com.framsticks.util.dispatching.Joinable;
33import com.framsticks.util.dispatching.JoinableParent;
34import com.framsticks.util.dispatching.JoinableState;
35import com.framsticks.util.dispatching.RunAt;
36import com.framsticks.util.dispatching.ThrowExceptionHandler;
37import com.framsticks.util.lang.Pair;
38
39/**
40 * @author Piotr Sniegowski
41 */
42@FramsClassAnnotation
43public abstract class AbstractTree extends AbstractJoinable implements Tree, JoinableParent, NeedFileAcceptor {
44
45        private static final Logger log = LogManager.getLogger(AbstractTree.class);
46
47        private Node root = null;
48        private ExceptionResultHandler handler = ThrowExceptionHandler.getInstance();
49
50        protected final BufferedDispatcher<Tree> bufferedDispatcher = new BufferedDispatcher<>(this);
51
52        protected final PriorityQueue<Pair<Integer, NeedFileAcceptor>> needFileAcceptors = new PriorityQueue<>(32, new Comparator<Pair<Integer, NeedFileAcceptor>>() {
53
54                @Override
55                public int compare(Pair<Integer, NeedFileAcceptor> arg0, Pair<Integer, NeedFileAcceptor> arg1) {
56                        if (arg0.first < arg1.first) {
57                                return -1;
58                        }
59                        if (arg0.first > arg1.first) {
60                                return 1;
61                        }
62                        return 0;
63                }
64        });
65
66        @Override
67        public void assignRootParam(CompositeParam param) {
68                if (root != null) {
69                        throw new FramsticksException().msg("root has already specified type");
70                }
71                root = new Node(this, param, null);
72                log.debug("assigned root type: {}", root);
73        }
74
75        @Override
76        public void assignRootObject(Object object) {
77                if (root == null) {
78                        throw new FramsticksException().msg("root has no type specified");
79                }
80                if (root.getObject() != null) {
81                        throw new FramsticksException().msg("root has already object assigned").arg("current", root.getObject()).arg("candidate", object);
82                }
83                root = new Node(this, root.getParam(), object);
84                log.debug("assigned root object: {}", root);
85        }
86
87        @Override
88        public @Nonnull Node getAssignedRoot() {
89                if (root == null) {
90                        throw new FramsticksException().msg("root has no type specified yet").arg("in", this);
91                }
92                return root;
93        }
94
95        public boolean isRootAssigned() {
96                // assert isActive();
97                return root != null;
98        }
99
100        protected String name;
101
102        public AbstractTree() {
103                setName("tree");
104
105                registry.registerAndBuild(Result.class);
106                registry.registerAndBuild(ValueChange.class);
107                registry.registerAndBuild(ListChange.class);
108                registry.registerAndBuild(Message.class);
109        }
110
111        protected void tryRegisterOnChangeEvents(Path path) {
112
113        }
114
115        @Override
116        public final FramsClass getInfoFromCache(String id) {
117                assert isActive();
118                return registry.getFramsClass(id);
119        }
120
121        protected Registry registry = new Registry();
122
123
124        @Override
125        public @Nonnull Access prepareAccess(CompositeParam param) {
126                return registry.prepareAccess(param);
127        }
128
129        @Override
130        public void takeAllFrom(Registry source) {
131                registry.takeAllFrom(source);
132        }
133
134        @AutoAppendAnnotation
135        public void usePackage(ParamsPackage paramsPackage) {
136                log.debug("using package {} in tree {}", paramsPackage, this);
137                paramsPackage.register(registry);
138        }
139
140        @AutoAppendAnnotation
141        public void takeFromRegistry(Registry registry) {
142                log.debug("taking from registry {} in tree {}", registry, this);
143                this.registry.takeAllFrom(registry);
144        }
145
146
147        @Override
148        public void putInfoIntoCache(FramsClass framclass) {
149                registry.putFramsClass(framclass);
150        }
151
152
153        /**
154         * @return the handler
155         */
156        @Override
157        public ExceptionResultHandler getExceptionHandler() {
158                return handler;
159        }
160
161        /**
162         * @param handler the handler to set
163         */
164        @Override
165        public void setExceptionHandler(ExceptionResultHandler handler) {
166                this.handler = handler;
167        }
168
169        @Override
170        public void handle(FramsticksException exception) {
171                handler.handle(exception);
172        }
173
174        /**
175         * @return the dispatcher
176         */
177        @Override
178        public Dispatcher<Tree> getDispatcher() {
179                return bufferedDispatcher;
180        }
181
182        /**
183         * @param dispatcher the dispatcher to set
184         */
185        @Override
186        public void setDispatcher(Dispatcher<Tree> dispatcher) {
187                bufferedDispatcher.setTargetDispatcher(dispatcher);
188        }
189
190        /**
191         * @return the name
192         */
193        @ParamAnnotation(flags = ParamFlags.USERREADONLY)
194        public String getName() {
195                return name;
196        }
197
198        /**
199         * @param name the name to set
200         */
201        @ParamAnnotation
202        public void setName(String name) {
203                this.name = name;
204        }
205
206        /**
207         * @return the registry
208         */
209        @Override
210        public Registry getRegistry() {
211                return registry;
212        }
213
214        @Override
215        protected void joinableStart() {
216                bufferedDispatcher.createThreadIfNeeded();
217                Dispatching.use(bufferedDispatcher, this);
218        }
219
220        @Override
221        protected void joinableInterrupt() {
222                Dispatching.drop(bufferedDispatcher, this);
223        }
224
225        @Override
226        protected void joinableFinish() {
227
228        }
229
230        @Override
231        protected void joinableJoin() throws InterruptedException {
232                Dispatching.join(bufferedDispatcher);
233        }
234
235        @Override
236        public void childChangedState(Joinable joinable, JoinableState state) {
237                if (joinable == bufferedDispatcher) {
238                        proceedToState(state);
239                }
240        }
241
242        @Override
243        public boolean isActive() {
244                return bufferedDispatcher.isActive();
245        }
246
247        @Override
248        public void dispatch(RunAt<? extends Tree> runnable) {
249                bufferedDispatcher.dispatch(runnable);
250        }
251
252
253        @SuppressWarnings("unchecked")
254        protected final Map<Object, Object> sideNotes = (Map<Object, Object>) new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
255
256        @Override
257        public <T> void putSideNote(Object object, SideNoteKey<T> key, T value) {
258                assert isActive();
259                Misc.throwIfNull(object);
260                Misc.throwIfNull(key);
261                Misc.throwIfNull(value);
262                Object sideNote = sideNotes.get(object);
263                if (sideNote == null) {
264                        sideNote = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
265                        sideNotes.put(object, sideNote);
266                }
267                @SuppressWarnings("unchecked")
268                Map<SideNoteKey<?>, Object> sideNotesMap = (Map<SideNoteKey<?>, Object>) sideNote;
269                sideNotesMap.put(key, value);
270        }
271
272        @SuppressWarnings("unchecked")
273        @Override
274        public <T> T getSideNote(Object object, SideNoteKey<T> key) {
275                assert isActive();
276                Misc.throwIfNull(object);
277                Misc.throwIfNull(key);
278                Object sideNote = sideNotes.get(object);
279                if (sideNote == null) {
280                        return null;
281                }
282                Object value = ((Map<SideNoteKey<?>, Object>) sideNote).get(key);
283                if (value == null) {
284                        return null;
285                }
286                return (T) value;
287        }
288
289        @Override
290        public boolean removeSideNote(Object object, SideNoteKey<?> key) {
291                assert isActive();
292                Object sideNote = sideNotes.get(object);
293                if (sideNote == null) {
294                        return false;
295                }
296                @SuppressWarnings("unchecked")
297                Map<SideNoteKey<?>, Object> sideNotesMap = (Map<SideNoteKey<?>, Object>) sideNote;
298                boolean result = (sideNotesMap.remove(key) != null);
299                if (sideNotesMap.isEmpty()) {
300                        sideNotes.remove(object);
301                }
302                return result;
303        }
304
305        @Override
306        public void addNeedFileAcceptor(int priority, NeedFileAcceptor acceptor) {
307                assert isActive();
308                needFileAcceptors.add(Pair.make(priority, acceptor));
309        }
310
311        @Override
312        public void removeNeedFileAcceptor(NeedFileAcceptor acceptor) {
313                assert isActive();
314                Iterator<Pair<Integer, NeedFileAcceptor>> i = needFileAcceptors.iterator();
315                while (i.hasNext()) {
316                        if (i.next().second == acceptor) {
317                                i.remove();
318                                break;
319                        }
320                }
321        }
322
323        @Override
324        public boolean acceptNeed(final NeedFile needFile) {
325                Dispatching.dispatchIfNotActive(this, new RunAt<AbstractTree>(needFile.getFuture()) {
326
327                        @Override
328                        protected void runAt() {
329                                for (Pair<Integer, NeedFileAcceptor> acceptor : needFileAcceptors) {
330                                        if (acceptor.second.acceptNeed(needFile)) {
331                                                return;
332                                        }
333                                }
334                                throw new FramsticksException().msg("failed to find need file acceptor in tree").arg("tree", AbstractTree.this).arg("needfile", needFile);
335                        }
336                });
337                return true;
338        }
339
340}
341
Note: See TracBrowser for help on using the repository browser.