source: java/main/src/main/java/com/framsticks/structure/AbstractTree.java @ 107

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

HIGHLIGHTS:

  • add SimultorProviders? hierarchy
  • start Framsticks server over SSH
  • FJF compatible with Framsticks 4.0rc3
  • reading and writing of standard.expt
  • a proof-of-concept implementation of StandardExperiment?

CHANGELOG:
Optionally return FreeAccess? from registry.

Add SimulatorRange?.

StandardExperiment? with genotypes circulation.

Automate registration around StandardState?.

More improvements to StandardExperiment?.

Skeleton version of StandardExperiment?.

Test saving of StandardState?.

Standard experiment state is being loaded.

More development towards StandardState? reading.

Work on reading standard experiment state.

Add classes for standard experiment.

Update example standard.expt

Add FreeAccess? and FreeObject?.

Made compatible with version 4.0rc3

Change deserialization policy.

Improve SSH support.

Working running simulator over SSH.

Fix joining bug in Experiment.

Working version of SimulatorRunner?.

Add more SimulatorProviders?.

Working PrimeExperimentTest? with 4.0rc3

Add references to deserialization.

Add OpaqueObject? and it's serialization.

Add deserialization of dictionaries.

Partial implementation of deserialization.

Add more tests for deserialization.

Prepare tests for deserialization.

Add proper result to prime experiment test.

Minor fixes to simulators providers.

Draft version of SimulatorProvider?.

Add SimulatorProvider? interface.

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