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    
011    public class DebugProcess {
012            public static final String[] PORT_TYPES = { "step", "stopped", "started" };
013    
014            private static final String TAG_STARTED = "process-started";
015            private static final String TAG_STOPPED = "process-stopped";
016            private static final String TAG_INITIAL_CPE = "initial-cpe";
017    
018            private static int next_id;
019            private int id;
020            private String tag_started;
021            private String tag_stopped;
022            private String tag_initial_cpe;
023    
024            private DebugAdapter adapter;
025            private int pid;
026            private String name;
027            private Rule started;
028            private Rule stopped;
029    
030            private List<Rule> rules;
031            private Map<Integer, Rule> ruleTable;
032    
033            private int running;
034            private Expr lastLocation;
035    
036            private List<ProcessStatusChangeListener> statusChangeListeners;
037            private List<DebugProcessListener> processListeners;
038    
039            private Info info;
040    
041            //{{{ public DebugProcess(DebugAdapter adapter, int pid)
042    
043            public DebugProcess(DebugAdapter adapter, int pid, String name) {
044                    this.id = next_id++;
045                    this.adapter = adapter;
046                    this.pid = pid;
047                    this.name = name;
048    
049                    tag_started = TAG_STARTED + "-" + id;
050                    tag_stopped = TAG_STOPPED + "-" + id;
051                    tag_initial_cpe = TAG_INITIAL_CPE + "-" + id;
052    
053                    info = new Info("DebugProcess");
054    
055                    statusChangeListeners = new ArrayList<ProcessStatusChangeListener>();
056                    processListeners = new ArrayList<DebugProcessListener>();
057    
058                    requestRuleCreation(
059                            Port.makeStarted(),
060                            Expr.makeTrue(),
061                            Expr.makeTrue(),
062                            tag_started);
063                    requestRuleCreation(
064                            Port.makeStopped(),
065                            Expr.makeTrue(),
066                            Expr.makeCpe(),
067                            tag_stopped);
068                    requestEvaluation(Expr.makeCpe(), tag_initial_cpe);
069    
070                    rules = new ArrayList<Rule>();
071                    ruleTable = new HashMap<Integer, Rule>();
072            }
073    
074            //}}}
075    
076            //{{{ public DebugAdapter getAdapter()
077    
078            public DebugAdapter getAdapter() {
079                    return adapter;
080            }
081    
082            //}}}
083    
084            //{{{ public void
085            // addProcessStatusChangeListener(ProcessStatusChangeListener listener)
086    
087            public void addProcessStatusChangeListener(ProcessStatusChangeListener listener) {
088                    statusChangeListeners.add(listener);
089            }
090    
091            //}}}
092            //{{{ public void
093            // removeProcessStatusChangeListener(ProcessStatusChangeListener listener)
094    
095            public void removeProcessStatusChangeListener(ProcessStatusChangeListener listener) {
096                    statusChangeListeners.remove(listener);
097            }
098    
099            //}}}
100            //{{{ public void fireProcessStatusChanged()
101    
102            public void fireProcessStatusChanged() {
103                    Iterator<ProcessStatusChangeListener> iter = statusChangeListeners.iterator();
104    
105                    while (iter.hasNext()) {
106                            ProcessStatusChangeListener listener = iter.next();
107                            listener.processStatusChanged(this);
108                    }
109            }
110    
111            //}}}
112    
113            //{{{ public void addDebugProcessListener(DebugProcessListener listener)
114    
115            public void addDebugProcessListener(DebugProcessListener listener) {
116                    processListeners.add(listener);
117            }
118    
119            //}}}
120            //{{{ public void removeDebugProcessListener(DebugProcessListener
121            // listener)
122    
123            public void removeDebugProcessListener(DebugProcessListener listener) {
124                    processListeners.remove(listener);
125            }
126    
127            //}}}
128            //{{{ public void fireRuleCreated(Rule rule)
129    
130            public void fireRuleCreated(Rule rule) {
131                    Iterator<DebugProcessListener> iter = ((List<DebugProcessListener>) ((ArrayList) processListeners).clone()).iterator();
132                    
133                    while (iter.hasNext()) {
134                            DebugProcessListener listener = iter.next();
135                            listener.ruleCreated(this, rule);
136                    }
137            }
138    
139            //}}}
140            //{{{ public void fireRuleDeleted(Rule rule)
141    
142            public void fireRuleDeleted(Rule rule) {
143                    Iterator<DebugProcessListener> iter = ((List<DebugProcessListener>) ((ArrayList) processListeners).clone()).iterator();
144    
145                    while (iter.hasNext()) {
146                            DebugProcessListener listener = iter.next();
147                            listener.ruleDeleted(this, rule);
148                    }
149            }
150    
151            //}}}
152            //{{{ public void fireRuleModified(Rule rule)
153    
154            public void fireRuleModified(Rule rule) {
155                    Iterator<DebugProcessListener> iter = ((List<DebugProcessListener>) ((ArrayList) processListeners).clone()).iterator();
156    
157                    while (iter.hasNext()) {
158                            DebugProcessListener listener = iter.next();
159                            listener.ruleModified(this, rule);
160                    }
161            }
162    
163            //}}}
164            //{{{ public void fireRuleTriggered(Rule rule, Expr value)
165    
166            public void fireRuleTriggered(Rule rule, Expr value) {
167                    Iterator<DebugProcessListener> iter = ((List<DebugProcessListener>) ((ArrayList) processListeners).clone()).iterator();
168    
169                    while (iter.hasNext()) {
170                            DebugProcessListener listener = iter.next();
171                            listener.ruleTriggered(this, rule, value);
172                    }
173            }
174    
175            //}}}
176            //{{{ public void fireEvaluationResult(Expr expr, Expr value, String tag)
177    
178            public void fireEvaluationResult(Expr expr, Expr value, String tag) {
179                    Iterator<DebugProcessListener> iter = ((List<DebugProcessListener>) ((ArrayList) processListeners).clone()).iterator();
180    
181                    while (iter.hasNext()) {
182                            DebugProcessListener listener = iter.next();
183                            listener.evaluationResult(this, expr, value, tag);
184                    }
185            }
186    
187            //}}}
188    
189            //{{{ public String getName()
190    
191            public String getName() {
192                    return name;
193            }
194    
195            //}}}
196            //{{{ public int getPid()
197    
198            public int getPid() {
199                    return pid;
200            }
201    
202            //}}}
203            //{{{ public boolean isRunning()
204    
205            public boolean isRunning() {
206                    return running > 0;
207            }
208    
209            //}}}
210            //{{{ public boolean isStopped()
211    
212            public boolean isStopped() {
213                    return running <= 0;
214            }
215    
216            //}}}
217            //{{{ public Expr getLastLocation()
218    
219            public Expr getLastLocation() {
220                    return lastLocation;
221            }
222    
223            //}}}
224    
225            //{{{ public void ruleCreated(Rule rule)
226    
227            synchronized public void ruleCreated(Rule rule) {
228                    info.info("ruleCreated: " + rule);
229    
230                    if (rule.getTag().equals(tag_started)) {
231                            started = rule;
232                    }
233    
234                    if (rule.getTag().equals(tag_stopped)) {
235                            stopped = rule;
236                    }
237    
238                    rules.add(rule);
239                    ruleTable.put(new Integer(rule.getRid()), rule);
240    
241                    fireRuleCreated(rule);
242            }
243    
244            //}}}
245            //{{{ public void ruleDeleted(int rid)
246    
247            synchronized public void ruleDeleted(int rid) {
248                    Integer ridKey = new Integer(rid);
249    
250                    Rule rule = ruleTable.get(ridKey);
251                    fireRuleDeleted(rule);
252    
253                    rules.remove(rule);
254                    ruleTable.remove(ridKey);
255    
256                    if (rule == stopped) {
257                            stopped = null;
258                    } else if (rule == started) {
259                            started = null;
260                    }
261            }
262    
263            //}}}
264            //{{{ public void ruleModified(int rid, Expr cond, Expr action, boolean
265            // enabled)
266    
267            public void ruleModified(
268                    int rid,
269                    Port port,
270                    Expr cond,
271                    Expr action,
272                    boolean enabled) {
273                    Integer ridKey = new Integer(rid);
274    
275                    Rule rule = ruleTable.get(ridKey);
276    
277                    rule.modify(port, cond, action, enabled);
278    
279                    fireRuleModified(rule);
280            }
281    
282            //}}}
283    
284            //{{{ public void evaluationResult(Expr expr, Expr value, String tag)
285    
286            public void evaluationResult(Expr expr, Expr value, String tag) {
287                    if (tag.equals(tag_initial_cpe)) {
288                            lastLocation = value;
289                    }
290                    fireEvaluationResult(expr, value, tag);
291            }
292    
293            //}}}
294    
295            //{{{ public Iterator ruleIterator()
296    
297            public Iterator<Rule> ruleIterator() {
298                    return rules.iterator();
299            }
300    
301            //}}}
302            //{{{ public int getNrOfRules()
303    
304            public int getNrOfRules() {
305                    return rules.size();
306            }
307    
308            //}}}
309            //{{{ public Rule getRuleAt(int index)
310    
311            public Rule getRuleAt(int index) {
312                    return rules.get(index);
313            }
314    
315            //}}}
316            //{{{ public int getRuleIndex(Rule rule)
317    
318            public int getRuleIndex(Rule rule) {
319                    return rules.indexOf(rule);
320            }
321    
322            //}}}
323    
324            //{{{ public void event(int rid, ATerm result)
325    
326            public void event(int rid, ATerm result) {
327                    info.info("event: " + result);
328    
329                    Rule rule = ruleTable.get(new Integer(rid));
330                    Expr value = Expr.fromTerm(result);
331    
332                    fireRuleTriggered(rule, value);
333                    if (rule == started) {
334                            running++;
335                            info.info("rule == started, running = " + running);
336                            if (running == 1) {
337                                    fireProcessStatusChanged();
338                            }
339                    } else if (rule == stopped) {
340                            running--;
341                            info.info("rule == stopped, running = " + running);
342                            if (running == 0) {
343                                    info.info("running is now 0, firing processStatusChanged");
344                                    lastLocation = value;
345                                    fireProcessStatusChanged();
346                            }
347                    }
348            }
349    
350            //}}}
351    
352            //{{{ public void requestRuleCreation(port, cond, act, tag)
353    
354            public void requestRuleCreation(
355                    Port port,
356                    Expr cond,
357                    Expr act,
358                    String tag) {
359                    adapter.requestRuleCreation(pid, port, cond, act, tag, true);
360            }
361    
362            //}}}
363            //{{{ public void requestRuleCreation(port, cond, act, tag, enabled)
364    
365            public void requestRuleCreation(
366                    Port port,
367                    Expr cond,
368                    Expr act,
369                    String tag,
370                    boolean enabled) {
371                    adapter.requestRuleCreation(pid, port, cond, act, tag, enabled);
372            }
373    
374            //}}}
375            //{{{ public void requestRuleModification(rule, port, cond, act, enabled)
376    
377            public void requestRuleModification(
378                    Rule rule,
379                    Port port,
380                    Expr cond,
381                    Expr act,
382                    boolean enabled) {
383                    adapter.requestRuleModification(pid, rule, port, cond, act, enabled);
384            }
385    
386            //}}}
387            //{{{ public void requestRuleDeletion(Rule rule)
388    
389            public void requestRuleDeletion(Rule rule) {
390                    adapter.requestRuleDeletion(pid, rule);
391            }
392    
393            //}}}
394            //{{{ public void requestRuleEnabling(Rule rule, boolean enabled)
395    
396            public void requestRuleEnabling(Rule rule, boolean enabled) {
397                    requestRuleModification(
398                            rule,
399                            rule.getPort(),
400                            rule.getCondition(),
401                            rule.getAction(),
402                            enabled);
403            }
404    
405            //}}}
406            //{{{ public void requestBreak()
407    
408            public void requestBreak() {
409                    adapter.requestBreak(pid);
410            }
411    
412            //}}}
413            //{{{ public void requestResume()
414    
415            public void requestResume() {
416                    adapter.requestResume(pid);
417            }
418    
419            //}}}
420            //{{{ public void requestEvaluation(Expr expr, String tag)
421    
422            public void requestEvaluation(Expr expr, String tag) {
423                    adapter.requestEvaluation(pid, expr, tag);
424            }
425    
426            //}}}
427    }