source: java/main/src/main/java/com/framsticks/core/Instance.java @ 78

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

Add f0 parsing and f0->Model transformation.

File size: 10.5 KB
Line 
1package com.framsticks.core;
2
3import com.framsticks.communication.*;
4import com.framsticks.params.*;
5import com.framsticks.params.types.CompositeParam;
6import com.framsticks.params.types.ObjectParam;
7import com.framsticks.parsers.Loaders;
8import com.framsticks.parsers.MultiParamLoader;
9import com.framsticks.util.*;
10import com.framsticks.util.UnsupportedOperationException;
11import org.apache.log4j.Logger;
12
13import java.util.*;
14
15/**
16 * @author Piotr Sniegowski
17 */
18public abstract class Instance extends Entity {
19
20        private static final Logger LOGGER = Logger.getLogger(Instance.class.getName());
21
22
23    protected Node root;
24
25    public Set<InstanceListener> listeners = new HashSet<InstanceListener>();
26
27    public Instance(Parameters parameters) {
28        super(parameters);
29        root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o").build(), null);
30        }
31
32    @Override
33    protected void run() {
34        super.run();
35                com.framsticks.model.Package.register(registry);
36    }
37
38    @Override
39    protected void configure() throws Exception {
40        super.configure();
41    }
42
43    protected void fetchInfo(Path path, Future<FramsClass> future) {
44                future.result(null, new UnsupportedOperationException());
45        }
46
47        public void resolve(Path path, Future<Path> future) {
48                assert isActive();
49                assert path.isOwner(this);
50                if (path.getTop().getObject() != null) {
51                        future.result(path, null);
52                        return;
53                }
54                AccessInterface access = bindAccess(path.getUnder());
55                Object object = access.get(path.getTop().getParam(), Object.class);
56                if (object == null) {
57                        future.result(path, null);
58                        return;
59                }
60                future.result(path.appendResolution(object), null);
61        }
62
63    public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
64                stateFunctor.call(null);
65        }
66
67    public void fetchValues(Path path, StateFunctor stateFunctor) {
68                stateFunctor.call(null);
69        }
70
71    protected void tryRegisterOnChangeEvents(Path path) {
72
73        }
74
75        public void storeValue(Path path, Param param, Object value, final StateFunctor stateFunctor) {
76                assert isActive();
77                invokeLater(new Runnable() {
78                        @Override
79                        public void run() {
80                                stateFunctor.call(new UnsupportedOperationException());
81                        }
82                });
83        }
84
85    protected void fireRun(Exception e) {
86        for (InstanceListener l : this.listeners) {
87            l.onRun(e);
88        }
89    }
90
91    protected void fireStop(Exception e) {
92        for (InstanceListener l : this.listeners) {
93            l.onStop(e);
94        }
95    }
96
97    public void addListener(final InstanceListener listener) {
98        assert Dispatching.isThreadSafe();
99        Dispatching.invokeLaterOrNow(this, new Runnable() {
100            @Override
101            public void run() {
102                listeners.add(listener);
103            }
104        });
105    }
106
107    public void removeListener(final InstanceListener listener) {
108        assert Dispatching.isThreadSafe();
109        Dispatching.invokeLaterOrNow(this, new Runnable() {
110            @Override
111            public void run() {
112                listeners.remove(listener);
113            }
114        });
115    }
116
117
118    protected void fireListChange(Path path, ListChange change) {
119        assert isActive();
120        for (InstanceListener l : this.listeners) {
121                        l.onListChange(path, change);
122                }
123        }
124
125
126    public final FramsClass getInfoFromCache(Path path) {
127        return getInfoFromCache(path.getTop().getParam().getContainedTypeName());
128    }
129
130
131    public FramsClass getInfoFromCache(String id) {
132        assert isActive();
133                return registry.getInfoFromCache(id);
134        }
135
136        protected Registry registry = new Registry();
137
138        public AccessInterface createAccess(String name) {
139        assert isActive();
140        if (name == null) {
141                        return null;
142                }
143                FramsClass framsClass = getInfoFromCache(name);
144                if (framsClass == null) {
145                        return null;
146                }
147
148                return registry.createAccess(name, framsClass);
149        }
150
151        public static AccessInterface wrapAccessWithListIfNeeded(CompositeParam param, AccessInterface access) {
152        if (access == null) {
153                        return null;
154                }
155        return param.prepareAccessInterface(access);
156        }
157
158    public AccessInterface prepareAccess(CompositeParam param) {
159        return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
160    }
161
162    public <T> T get(Node node, Param childParam, Class<T> type) {
163        return bindAccess(node).get(childParam, type);
164    }
165
166    public void findInfo(final Path path, final Future<FramsClass> future) {
167        assert isActive();
168        final String name = path.getTop().getParam().getContainedTypeName();
169        final FramsClass framsClass = getInfoFromCache(name);
170        if (framsClass != null) {
171            LOGGER.trace("info for " + name + " found in cache");
172            future.result(framsClass, null);
173            return;
174        }
175        fetchInfo(path, future);
176    }
177
178    public final AccessInterface bindAccess(Node node) {
179        assert node.getObject() != null;
180        AccessInterface access = prepareAccess(node.getParam());
181        if (access == null) {
182                        LOGGER.error("missing access for: " + node.getParam());
183            return null;
184        }
185        access.select(node.getObject());
186        return access;
187    }
188
189    public final <T> T getParam(Path path, String id, Class<T> type) {
190        return Casting.tryCast(type, prepareAccess(path.getTop().getParam()).getParam(id));
191    }
192
193    public final AccessInterface bindAccess(Path path) {
194        assert path.isResolved();
195        return bindAccess(path.getTop());
196    }
197
198    public void resolve(final String targetPath, final Future<Path> future) {
199        assert isActive();
200        final Path path = new Path(this, targetPath);
201        resolve(path, new Future<Path>() {
202            @Override
203            public void result(Path result, Exception e) {
204                assert isActive();
205                if (e != null) {
206                    future.result(path, e);
207                    return;
208                }
209                if (path.isResolved(targetPath)) {
210                    future.result(path, null);
211                    return;
212                }
213                if (path.isResolved()) {
214                    future.result(path, new Exception("testing"));
215                    return;
216                }
217                resolve(targetPath, future);
218            }
219        });
220    }
221
222    public void resolveAndFetch(final String targetPath, final Future<Path> future) {
223        assert isActive();
224        resolve(targetPath, new Future<Path>() {
225            @Override
226            public void result(final Path path, Exception e) {
227                if (e != null) {
228                    future.result(path, e);
229                    return;
230                }
231                assert path.isResolved(targetPath);
232                fetchValues(path, new StateFunctor() {
233                    @Override
234                    public void call(Exception e) {
235                        future.result(path, e);
236                    }
237                });
238            }
239        });
240    }
241
242    public Path createIfNeeded(String path) {
243        Path p;
244        while (!(p = new Path(this, path)).isResolved(path)) {
245            create(p);
246        }
247        return p;
248    }
249
250    public Path create(Path path) {
251        assert isActive();
252        assert !path.isResolved();
253        Path resolved = path.findResolution();
254        if (!resolved.isResolved()) {
255            LOGGER.debug("creating: " + path);
256            AccessInterface access = prepareAccess(path.getTop().getParam());
257            assert access != null;
258            Object child = access.createAccessee();
259            assert child != null;
260            if (path.size() == 1) {
261                root = new Node(root.getParam(), child);
262            } else {
263                bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
264            }
265            resolved = path.appendResolution(child);
266        }
267        tryRegisterOnChangeEvents(resolved);
268        return resolved;
269    }
270
271
272
273
274    public FramsClass processFetchedInfo(File file) {
275        assert isActive();
276        FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
277        if ("/".equals(file.getPath())) {
278            if (root.getParam().getContainedTypeName() == null) {
279                root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o " + framsClass.getId()).build(), root.getObject());
280            }
281        }
282        registry.putInfoIntoCache(framsClass);
283        return framsClass;
284    }
285
286    public void processFetchedValues(Path path, List<File> files) {
287        assert isActive();
288        assert files.size() == 1;
289        assert path.isTheSame(files.get(0).getPath());
290        Node node = path.getTop();
291        MultiParamLoader loader = new MultiParamLoader();
292        loader.setNewSource(files.get(0).getContent());
293        loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
294
295        try {
296            if (node.getParam() instanceof ObjectParam) {
297                loader.addAccessInterface(bindAccess(node));
298                loader.go();
299    //            for (NodeListener l : listeners) {
300    //                l.onChange(this);
301    //            }
302                return;
303            }
304
305            ListAccess listAccess = ((ListAccess)bindAccess(node));
306            assert listAccess != null;
307            listAccess.clearValues();
308
309            AccessInterface elementAccess = listAccess.getElementAccess();
310            loader.addAccessInterface(elementAccess);
311            MultiParamLoader.Status status;
312            while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
313                if (status == MultiParamLoader.Status.AfterObject) {
314                    AccessInterface accessInterface = loader.getLastAccessInterface();
315
316                    String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
317                    Param param = new ParamBuilder().setType("o " + accessInterface.getId()).setId(id).build();
318                    Object child = accessInterface.getSelected();
319                    accessInterface.select(null);
320                    assert child != null;
321                    bindAccess(node).set(param, child);
322                }
323            }
324    //        for (NodeListener l : listeners) {
325    //            l.onChange(this);
326    //        }
327        } catch (Exception e) {
328            LOGGER.error("exception occurred while loading: " + e);
329        }
330
331    }
332
333    public static Iterator<String> splitPath(String path) {
334        List<String> list = new LinkedList<String>();
335        for (String s : path.split("/")) {
336            if (!s.isEmpty()) {
337                list.add(s);
338            }
339        }
340        return list.iterator();
341    }
342
343        public Registry getRegistry() {
344                return registry;
345        }
346}
347
Note: See TracBrowser for help on using the repository browser.