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

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

HIGHLIGHTS:

for Joinables running

CHANGELOG:
Add WorkPackageLogic? and classes representing prime experiment state.

Add classes for PrimeExperiment? state.

Extract single netload routine in Simulator.

Working netload with dummy content in PrimeExperiment?.

More development with NetLoadSaveLogic? and PrimeExperiment?.

Improvement around prime.

Improve BufferedDispatcher?.isActive logic.

Add prime-all.xml configuration.

Manual connecting to existing simulators from GUI.

Guard in SimulatorConnector? against expdef mismatch.

Guard against empty target dispatcher in BufferedDispatcher?.

Make BufferedDispatcher? a Dispatcher (and Joinable).

Minor improvements.

Done StackedJoinable?, improve Experiment.

Develop StackedJoinable?.

Add StackedJoinable? utility joinables controller.

Add dependency on apache-commons-lang.

Add ready ListChange? on Simulators.

Improve hints in ListChange?.

Several improvements.

Found bug with dispatching in Experiment.

Minor improvements.

Fix bug with early finishing Server.

Many changes in Dispatching.

Fix bug with connection.

Do not obfuscate log with socket related exceptions.

Add SocketClosedException?.

Add SimulatorConnector?.

Work out conception of experiment composing of logics building blocks.

Rename SinkInterface? to Sink.

Move saving of Accesses into AccessOperations?.

Some improvements to Experiment.

Improve joinables.

Fix issue with joinables closing.

Add direct and managed consoles to popup menu.

File size: 8.5 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
106        protected void tryRegisterOnChangeEvents(Path path) {
107
108        }
109
110        @Override
111        public final FramsClass getInfoFromCache(String id) {
112                assert isActive();
113                return registry.getFramsClass(id);
114        }
115
116        protected Registry registry = new Registry();
117
118
119        @Override
120        public @Nonnull Access prepareAccess(CompositeParam param) {
121                return registry.prepareAccess(param);
122        }
123
124        @Override
125        public void takeAllFrom(Registry source) {
126                registry.takeAllFrom(source);
127        }
128
129        @AutoAppendAnnotation
130        public void usePackage(ParamsPackage paramsPackage) {
131                log.debug("using package {} in tree {}", paramsPackage, this);
132                paramsPackage.register(registry);
133        }
134
135        @AutoAppendAnnotation
136        public void takeFromRegistry(Registry registry) {
137                log.debug("taking from registry {} in tree {}", registry, this);
138                this.registry.takeAllFrom(registry);
139        }
140
141
142        @Override
143        public void putInfoIntoCache(FramsClass framclass) {
144                registry.putFramsClass(framclass);
145        }
146
147
148        /**
149         * @return the handler
150         */
151        @Override
152        public ExceptionResultHandler getExceptionHandler() {
153                return handler;
154        }
155
156        /**
157         * @param handler the handler to set
158         */
159        @Override
160        public void setExceptionHandler(ExceptionResultHandler handler) {
161                this.handler = handler;
162        }
163
164        @Override
165        public void handle(FramsticksException exception) {
166                handler.handle(exception);
167        }
168
169        /**
170         * @return the dispatcher
171         */
172        @Override
173        public Dispatcher<Tree> getDispatcher() {
174                return bufferedDispatcher;
175        }
176
177        /**
178         * @param dispatcher the dispatcher to set
179         */
180        @Override
181        public void setDispatcher(Dispatcher<Tree> dispatcher) {
182                bufferedDispatcher.setTargetDispatcher(dispatcher);
183        }
184
185        /**
186         * @return the name
187         */
188        @ParamAnnotation(flags = ParamFlags.USERREADONLY)
189        public String getName() {
190                return name;
191        }
192
193        /**
194         * @param name the name to set
195         */
196        @ParamAnnotation
197        public void setName(String name) {
198                this.name = name;
199        }
200
201        /**
202         * @return the registry
203         */
204        @Override
205        public Registry getRegistry() {
206                return registry;
207        }
208
209        @Override
210        protected void joinableStart() {
211                bufferedDispatcher.createThreadIfNeeded();
212                Dispatching.use(bufferedDispatcher, this);
213        }
214
215        @Override
216        protected void joinableInterrupt() {
217                Dispatching.drop(bufferedDispatcher, this);
218        }
219
220        @Override
221        protected void joinableFinish() {
222
223        }
224
225        @Override
226        protected void joinableJoin() throws InterruptedException {
227                Dispatching.join(bufferedDispatcher);
228        }
229
230        @Override
231        public void childChangedState(Joinable joinable, JoinableState state) {
232                if (joinable == bufferedDispatcher) {
233                        proceedToState(state);
234                }
235        }
236
237        @Override
238        public boolean isActive() {
239                return bufferedDispatcher.isActive();
240        }
241
242        @Override
243        public void dispatch(RunAt<? extends Tree> runnable) {
244                bufferedDispatcher.dispatch(runnable);
245        }
246
247
248        @SuppressWarnings("unchecked")
249        protected final Map<Object, Object> sideNotes = (Map<Object, Object>) new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
250
251        @Override
252        public <T> void putSideNote(Object object, SideNoteKey<T> key, T value) {
253                assert isActive();
254                Misc.throwIfNull(object);
255                Misc.throwIfNull(key);
256                Misc.throwIfNull(value);
257                Object sideNote = sideNotes.get(object);
258                if (sideNote == null) {
259                        sideNote = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
260                        sideNotes.put(object, sideNote);
261                }
262                @SuppressWarnings("unchecked")
263                Map<SideNoteKey<?>, Object> sideNotesMap = (Map<SideNoteKey<?>, Object>) sideNote;
264                sideNotesMap.put(key, value);
265        }
266
267        @SuppressWarnings("unchecked")
268        @Override
269        public <T> T getSideNote(Object object, SideNoteKey<T> key) {
270                assert isActive();
271                Misc.throwIfNull(object);
272                Misc.throwIfNull(key);
273                Object sideNote = sideNotes.get(object);
274                if (sideNote == null) {
275                        return null;
276                }
277                Object value = ((Map<SideNoteKey<?>, Object>) sideNote).get(key);
278                if (value == null) {
279                        return null;
280                }
281                return (T) value;
282        }
283
284        @Override
285        public boolean removeSideNote(Object object, SideNoteKey<?> key) {
286                assert isActive();
287                Object sideNote = sideNotes.get(object);
288                if (sideNote == null) {
289                        return false;
290                }
291                @SuppressWarnings("unchecked")
292                Map<SideNoteKey<?>, Object> sideNotesMap = (Map<SideNoteKey<?>, Object>) sideNote;
293                boolean result = (sideNotesMap.remove(key) != null);
294                if (sideNotesMap.isEmpty()) {
295                        sideNotes.remove(object);
296                }
297                return result;
298        }
299
300        @Override
301        public void addNeedFileAcceptor(int priority, NeedFileAcceptor acceptor) {
302                assert isActive();
303                needFileAcceptors.add(Pair.make(priority, acceptor));
304        }
305
306        @Override
307        public void removeNeedFileAcceptor(NeedFileAcceptor acceptor) {
308                assert isActive();
309                Iterator<Pair<Integer, NeedFileAcceptor>> i = needFileAcceptors.iterator();
310                while (i.hasNext()) {
311                        if (i.next().second == acceptor) {
312                                i.remove();
313                                break;
314                        }
315                }
316        }
317
318        @Override
319        public boolean acceptNeed(final NeedFile needFile) {
320                Dispatching.dispatchIfNotActive(this, new RunAt<AbstractTree>(needFile.getFuture()) {
321
322                        @Override
323                        protected void runAt() {
324                                for (Pair<Integer, NeedFileAcceptor> acceptor : needFileAcceptors) {
325                                        if (acceptor.second.acceptNeed(needFile)) {
326                                                return;
327                                        }
328                                }
329                                throw new FramsticksException().msg("failed to find need file acceptor in tree").arg("tree", AbstractTree.this).arg("needfile", needFile);
330                        }
331                });
332                return true;
333        }
334
335}
336
Note: See TracBrowser for help on using the repository browser.