001    package nl.cwi.sen1.tide.tool.support;
002    
003    import java.util.ArrayList;
004    import java.util.HashMap;
005    import java.util.Iterator;
006    import java.util.List;
007    import java.util.Map;
008    
009    import aterm.ATerm;
010    import aterm.ATermAppl;
011    import aterm.ATermFactory;
012    import aterm.ATermInt;
013    
014    public class DebugTool extends DebugToolTool {
015            private Map<ATerm, DebugAdapter> adapters;
016            private List<DebugToolListener> listeners;
017    
018            private Info info;
019    
020            //{{{ public DebugTool(ATermFactory factory)
021    
022            public DebugTool(ATermFactory factory) {
023                    super(factory);
024                    info = new Info("DebugTool");
025                    adapters = new HashMap<ATerm, DebugAdapter>();
026                    listeners = new ArrayList<DebugToolListener>();
027            }
028    
029            //}}}
030    
031            //{{{ public void adapterConnected(ATerm dap)
032    
033            public void adapterConnected(ATerm dap) {
034                    info.info("adapterConnected: " + dap);
035    
036                    DebugAdapter adapter = new DebugAdapter(this, dap);
037                    adapters.put(dap, adapter);
038                    fireAdapterConnected(adapter);
039            }
040    
041            //}}}
042            //{{{ public void adapterDisconnected(ATerm dap)
043    
044            public void adapterDisconnected(ATerm dap) {
045                    info.info("adapterDisconnected: " + dap);
046                    DebugAdapter adapter = findAdapter(dap);
047    
048                    adapter.removeAllProcesses();
049                    fireAdapterDisconnected(adapter);
050                    adapters.remove(dap);
051            }
052    
053            //}}}
054    
055            //{{{ public void processCreated(ATerm proc, String name)
056    
057            public void processCreated(ATerm proc, String name) {
058                    info.info("processCreated: " + proc + " = " + name);
059    
060                    ATerm dap = ((ATermAppl) proc).getArgument(0);
061                    int pid = ((ATermInt) ((ATermAppl) proc).getArgument(1)).getInt();
062                    DebugAdapter adapter = findAdapter(dap);
063                    adapter.processCreated(pid, name);
064            }
065    
066            //}}}
067            //{{{ public void processDestroyed(ATerm proc)
068    
069            public void processDestroyed(ATerm proc) {
070                    info.info("processDestroyed: " + proc);
071                    ATerm dap = ((ATermAppl) proc).getArgument(0);
072                    int pid = ((ATermInt) ((ATermAppl) proc).getArgument(1)).getInt();
073                    DebugAdapter adapter = findAdapter(dap);
074                    adapter.processDestroyed(pid);
075            }
076    
077            //}}}
078    
079            //{{{ public void event(ATerm proc, int rid, ATerm result)
080    
081            public void event(ATerm proc, int rid, ATerm result) {
082                    info.info("event: " + proc + ", rid=" + rid + ", result=" + result);
083                    ATerm dap = ((ATermAppl) proc).getArgument(0);
084                    int pid = ((ATermInt) ((ATermAppl) proc).getArgument(1)).getInt();
085                    DebugAdapter adapter = findAdapter(dap);
086                    adapter.event(pid, rid, result);
087            }
088    
089            //}}}
090    
091            //{{{ public void recAckEvent(ATerm event)
092    
093            public void recAckEvent(ATerm event) {
094                    List<?> result;
095    
096                    info.info("recAckEvent: " + event);
097    
098                    result = event.match("evaluate(proc(<term>,<int>),<term>,<term>,<term>))");
099                    if (result != null) {
100                            handleEvaluationResults(result);
101                            return;
102                    }
103    
104                    result = event.match("create-rule(proc(<term>,<int>),<term>,<term>,<term>,<term>,<term>,<int>)");
105                    if (result != null) {
106                            handleRuleCreation(result);
107                            return;
108                    }
109    
110                    result = event.match("delete-rule(proc(<term>,<int>),<int>)");
111                    if (result != null) {
112                            handleRuleDeletion(result);
113                            return;
114                    }
115    
116                    result = event.match("modify-rule(proc(<term>,<int>),<int>,<term>,<term>,<term>,<term>)");
117                    if (result != null) {
118                            handleRuleModification(result);
119                            return;
120                    }
121            }
122    
123            //}}}
124            //{{{ public void recTerminate(ATerm msg)
125    
126            private void handleEvaluationResults(List<?> result) {
127                    int index = 0;
128    
129                    DebugAdapter adapter = findAdapter((ATerm) result.get(index++));
130                    int pid = ((Integer) result.get(index++)).intValue();
131                    Expr expr = Expr.fromTerm((ATerm) result.get(index++));
132                    String tag = result.get(index++).toString();
133                    Expr value = Expr.fromTerm((ATerm) result.get(index++));
134                    adapter.evaluationResult(pid, expr, value, tag);
135            }
136    
137            private void handleRuleCreation(List<?> result) {
138                    DebugAdapter adapter = findAdapter((ATerm) result.get(0));
139                    int pid = ((Integer) result.get(1)).intValue();
140                    Port port = Port.fromTerm((ATerm) result.get(2));
141                    Expr cond = Expr.fromTerm((ATerm) result.get(3));
142                    Expr act = Expr.fromTerm((ATerm) result.get(4));
143                    String tag = result.get(5).toString();
144                    boolean enabled = result.get(6).equals(factory.parse("true"));
145                    int rid = ((Integer) result.get(7)).intValue();
146                    Rule rule = new Rule(rid, port, cond, act, tag, enabled);
147                    adapter.ruleCreated(pid, rule);
148            }
149    
150            private void handleRuleModification(List<?> result) {
151                    int arg = 0;
152                    DebugAdapter adapter = findAdapter((ATerm) result.get(arg++));
153                    int pid = ((Integer) result.get(arg++)).intValue();
154                    int rid = ((Integer) result.get(arg++)).intValue();
155                    Port port = Port.fromTerm((ATerm) result.get(arg++));
156                    Expr cond = Expr.fromTerm((ATerm) result.get(arg++));
157                    Expr act = Expr.fromTerm((ATerm) result.get(arg++));
158                    boolean enabled = result.get(arg++).equals(factory.parse("true"));
159                    adapter.ruleModified(pid, rid, port, cond, act, enabled);
160    
161                    //}}}
162                    return;
163            }
164    
165            private void handleRuleDeletion(List<?> result) {
166                    DebugAdapter adapter = findAdapter((ATerm) result.get(0));
167                    int pid = ((Integer) result.get(1)).intValue();
168                    int rid = ((Integer) result.get(2)).intValue();
169                    adapter.ruleDeleted(pid, rid);
170            }
171    
172            public void recTerminate(ATerm msg) {}
173    
174            public void addDebugToolListener(DebugToolListener listener) {
175                    listeners.add(listener);
176            }
177    
178            public void removeDebugToolListener(DebugToolListener listener) {
179                    listeners.remove(listener);
180            }
181    
182            private DebugAdapter findAdapter(ATerm dap) {
183                    return adapters.get(dap);
184            }
185    
186            private void fireAdapterConnected(DebugAdapter adapter) {
187                    Iterator<DebugToolListener> iter = listeners.iterator();
188                    while (iter.hasNext()) {
189                            DebugToolListener listener = iter.next();
190                            listener.adapterConnected(this, adapter);
191                    }
192            }
193    
194            private void fireAdapterDisconnected(DebugAdapter adapter) {
195                    Iterator<DebugToolListener> iter = listeners.iterator();
196                    while (iter.hasNext()) {
197                            DebugToolListener listener = iter.next();
198                            listener.adapterDisconnected(this, adapter);
199                    }
200            }
201    
202            public void requestRuleCreation(ATerm dap, int pid, Port port, Expr cond, Expr act, String tag, boolean enabled) {
203                    String pat =
204                            "create-rule(proc(<term>,<int>),<term>,<term>,<term>,<term>,<term>)";
205                    ATerm event =
206                            factory.make(
207                                    pat,
208                                    dap,
209                                    new Integer(pid),
210                                    port.toTerm(),
211                                    cond.toTerm(),
212                                    act.toTerm(),
213                                    factory.parse(tag),
214                                    factory.parse(enabled ? "true" : "false"));
215    
216                    info.info("requesting rule creation: " + event);
217                    postEvent(event);
218            }
219    
220            public void requestRuleDeletion(ATerm dap, int pid, Rule rule) {
221                    ATerm event =
222                            factory.make(
223                                    "delete-rule(proc(<term>,<int>),<int>)",
224                                    dap,
225                                    new Integer(pid),
226                                    new Integer(rule.getRid()));
227                    postEvent(event);
228            }
229    
230            public void requestRuleModification(ATerm dap, int pid, Rule rule, Port port, Expr cond, Expr act, boolean enabled) {
231                    String pat =
232                            "modify-rule(proc(<term>,<int>),<int>,<term>,<term>,<term>,<term>)";
233                    ATerm event =
234                            factory.make(
235                                    pat,
236                                    dap,
237                                    new Integer(pid),
238                                    new Integer(rule.getRid()),
239                                    port.toTerm(),
240                                    cond.toTerm(),
241                                    act.toTerm(),
242                                    factory.parse(enabled ? "true" : "false"));
243    
244                    info.info("requesting rule modification: " + event);
245                    postEvent(event);
246            }
247    
248            public void requestBreak(ATerm dap, int pid) {
249                    ATerm event =
250                            factory.make(
251                                    "evaluate(proc(<term>,<int>),break,tag-break)",
252                                    dap,
253                                    new Integer(pid));
254                    info.info("request break: " + event);
255                    postEvent(event);
256            }
257    
258            public void requestResume(ATerm dap, int pid) {
259                    ATerm event =
260                            factory.make(
261                                    "evaluate(proc(<term>,<int>),resume,tag-resume)",
262                                    dap,
263                                    new Integer(pid));
264                    info.info("request resume: " + event);
265                    postEvent(event);
266            }
267    
268            public void requestEvaluation(ATerm dap, int pid, Expr expr, String tag) {
269                    ATerm event =
270                            factory.make(
271                                    "evaluate(proc(<term>,<int>),<term>,<term>)",
272                                    dap,
273                                    new Integer(pid),
274                                    expr.toTerm(),
275                                    factory.parse(tag));
276                    info.info("request evaluation: " + event);
277                    postEvent(event);
278            }
279    }