KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > SOFA > SOFAnode > Util > DFSRChecker > node > ActionRepository


1 /*
2  * $Id: ActionRepository.java,v 1.4 2005/07/08 12:04:11 kofron Exp $
3  *
4  * Copyright 2004
5  * Distributed Systems Research Group
6  * Department of Software Engineering
7  * Faculty of Mathematics and Physics
8  * Charles University, Prague
9  *
10  * Copyright 2005
11  * Formal Methods In Software Engineering Group
12  * Institute of Computer Science
13  * Academy of Sciences of the Czech Republic
14  *
15  * This code was developed by Jan Kofron <kofron@nenya.ms.mff.cuni.cz>
16  */

17
18
19 package SOFA.SOFAnode.Util.DFSRChecker.node;
20
21 import java.util.LinkedList JavaDoc;
22 import java.util.TreeMap JavaDoc;
23 import java.util.NoSuchElementException JavaDoc;
24 import java.util.TreeSet JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 import SOFA.SOFAnode.Util.DFSRChecker.parser.Debug;
28 import SOFA.SOFAnode.Util.SyntaxErrorException;
29
30
31 /**
32  * This class stores the string action identifier and maps integral numbers to
33  * it for faster access. For each action there are stored 10 variants -
34  * a, !a, ?a, !a^, ?a^, !a$, ?a$, #a, #a^, #a$
35  * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
36  */

37 public class ActionRepository {
38
39     /** Creates a new instance of ActionRepository */
40     public ActionRepository() {
41         repository = new TreeMap JavaDoc();
42         inverseRepository = new TreeMap JavaDoc();
43         atomicRepository = new TreeMap JavaDoc();
44         atomicInverseRepository = new TreeMap JavaDoc();
45         usedItems = new TreeSet JavaDoc();
46     }
47
48     /**
49      * Adds the item to the database.
50      *
51      * @return the index of this new item
52      */

53     public int addItem(String JavaDoc item) throws SyntaxErrorException {
54         Integer JavaDoc i;
55
56         Debug.println(3, "Adding item to repository: " + item);
57
58         try {
59             i = (Integer JavaDoc) inverseRepository.get(item);
60         } catch (ClassCastException JavaDoc e) {
61             i = null;
62         } catch (NullPointerException JavaDoc e) {
63             i = null;
64         }
65
66         if (i != null) { // the item is already present within the database
67
touchItem(i.intValue());
68             return i.intValue();
69         }
70
71         else { // the item is NOT present within the database
72
int index;
73             try {
74                 index = ((Integer JavaDoc) repository.lastKey()).intValue() + 1;
75             } catch (NoSuchElementException JavaDoc e) {
76                 index = 0;
77             }
78
79             String JavaDoc next;
80
81             String JavaDoc purename = getPureName(item);
82             //Debug.println("ActionRepository: purename: " + purename);
83
repository.put(new Integer JavaDoc(index), purename);
84
85             inverseRepository.put(purename, new Integer JavaDoc(index));
86
87             next = "!" + purename;
88             ++index;
89             repository.put(new Integer JavaDoc(index), next);
90             inverseRepository.put(next, new Integer JavaDoc(index));
91
92             next = "?" + purename;
93             ++index;
94             repository.put(new Integer JavaDoc(index), next);
95             inverseRepository.put(next, new Integer JavaDoc(index));
96
97             next = "!" + purename + "^";
98             ++index;
99             repository.put(new Integer JavaDoc(index), next);
100             inverseRepository.put(next, new Integer JavaDoc(index));
101
102             next = "?" + purename + "^";
103             ++index;
104             repository.put(new Integer JavaDoc(index), next);
105             inverseRepository.put(next, new Integer JavaDoc(index));
106
107             next = "!" + purename + "$";
108             ++index;
109             repository.put(new Integer JavaDoc(index), next);
110             inverseRepository.put(next, new Integer JavaDoc(index));
111
112             next = "?" + purename + "$";
113             ++index;
114             repository.put(new Integer JavaDoc(index), next);
115             inverseRepository.put(next, new Integer JavaDoc(index));
116
117             next = "#" + purename;
118             ++index;
119             repository.put(new Integer JavaDoc(index), next);
120             inverseRepository.put(next, new Integer JavaDoc(index));
121
122             next = "#" + purename + "^";
123             ++index;
124             repository.put(new Integer JavaDoc(index), next);
125             inverseRepository.put(next, new Integer JavaDoc(index));
126
127             next = "#" + purename + "$";
128             ++index;
129             repository.put(new Integer JavaDoc(index), next);
130             inverseRepository.put(next, new Integer JavaDoc(index));
131
132             Debug.println(3, "Action added");
133
134             Integer JavaDoc returnindex = (Integer JavaDoc) inverseRepository.get(item);
135             if (returnindex == null) {
136                 throw new SyntaxErrorException("This is not an event: " + item);
137             }
138             touchItem(returnindex.intValue());
139             return (returnindex).intValue();
140
141         }
142     }
143     
144     /**
145      * Adds the atomic action (and all variants) to the repository.
146      *
147      * @param events the events forming this atomic action
148      * @return the id of the atomic action
149      */

150     public int addAtomicItem(TreeSet JavaDoc events) {
151         Integer JavaDoc i;
152         
153         try {
154             i = (Integer JavaDoc) atomicInverseRepository.get(events);
155         } catch (ClassCastException JavaDoc e) {
156             i = null;
157         } catch (NullPointerException JavaDoc e) {
158             i = null;
159         }
160
161         if (i != null) { // the item is already present within the database
162
touchItem(i.intValue());
163             return i.intValue();
164         }
165         else {
166            
167             LinkedList JavaDoc copy = new LinkedList JavaDoc();
168             copy.addAll(events);
169             LinkedList JavaDoc variants = this.createAtomicVariants(copy);
170             
171             Iterator JavaDoc it = variants.iterator();
172             while (it.hasNext()) {
173                 int index = -1 - atomicRepository.size();
174                 
175                 AtomicAction item = new AtomicAction((LinkedList JavaDoc)it.next());
176                 atomicRepository.put(new Integer JavaDoc(index),item);
177                 atomicInverseRepository.put(item, new Integer JavaDoc(index));
178             }
179             
180             return ((Integer JavaDoc)atomicInverseRepository.get(new AtomicAction(events))).intValue();
181         }
182     }
183
184     /**
185      * @return all used indices of actions.
186      */

187     public TreeSet JavaDoc getAllUsedEventIndices() {
188         return new TreeSet JavaDoc(usedItems);
189
190         /*
191          * TreeSet items = new TreeSet();
192          *
193          * for (int i = 0; i < repository.size(); ++i) items.add(new
194          * Integer(i));
195          *
196          * return items; /
197          */

198     }
199
200     /**
201      * Tests the presence of a key in the database.
202      *
203      * @return whether the action identifier with specified index is present in
204      * the repository
205      */

206     public boolean getItemPresence(int index) {
207         return repository.containsKey(new Integer JavaDoc(index));
208     }
209
210     /**
211      * @return the textual form of the item If the key is not present, null is
212      * returned (note that this is the default behavior, not the
213      * consequence of an exception occurence).
214      */

215     public String JavaDoc getItemString(int index) {
216         try {
217             if (index >= 0)
218                 return (String JavaDoc) repository.get(new Integer JavaDoc(index));
219             else {
220                 String JavaDoc result = new String JavaDoc("[");
221                 TreeSet JavaDoc actions = (TreeSet JavaDoc)atomicRepository.get(new Integer JavaDoc(index));
222                 Iterator JavaDoc it = actions.iterator();
223                 while (it.hasNext()) {
224                     result = result + getItemString(((Integer JavaDoc)it.next()).intValue());
225                     if (it.hasNext())
226                         result += ", ";
227                 }
228                 result += "]";
229                 
230                 return result;
231             }
232         } catch (NullPointerException JavaDoc e) {
233             return null;
234         }
235     }
236
237     /**
238      * @return the index of the given action
239      */

240     public int getItemIndex(String JavaDoc item) {
241         try {
242             Integer JavaDoc result = (Integer JavaDoc) inverseRepository.get(item);
243             touchItem(result.intValue());
244             return result.intValue();
245         } catch (NullPointerException JavaDoc e) {
246             if (!item.equals(""))
247                 Debug.println(1, "Action repository: try to access action '" + item + "' - not present in repository.\n");
248             return -1;
249         }
250     }
251     
252     /**
253      * Gets the index of an atomic action.
254      *
255      * @param action atomic action
256      * @return the index of the action
257      */

258     public int getItemIndex(AtomicAction action) {
259         try {
260             Integer JavaDoc result = (Integer JavaDoc)atomicInverseRepository.get(action);
261             return result.intValue();
262         } catch (NullPointerException JavaDoc e) {
263             if (!action.equals(null))
264                 Debug.println(1, "Action repository: try to access atomic action '" + action + "' - not present in repository.\n");
265             return -1;
266         }
267            
268     }
269
270     /**
271      * The method returns the index of the basic variant of the operation
272      * specified. It doesn't check whether the event index is valid.
273      *
274      * @return the pure index of the name of the action
275      */

276     static public int getPure(int event) {
277         return (event / VARIANTCNT) * VARIANTCNT;
278     }
279
280     /**
281      * It doesn't check whether the event index is valid. If there's no inverse
282      * action, it returns back the original index.
283      *
284      * @return the inverse action
285      */

286     public int getInverseAction(int event) {
287         if (((event % VARIANTCNT) < 7) && (event % VARIANTCNT > 0)) {
288             if ((event % 2) == 1) {
289                 touchItem(event + 1);
290                 return event + 1;
291             } else {
292                 touchItem(event - 1);
293                 return event - 1;
294             }
295         }
296
297         else
298             return event;
299     }
300
301     /**
302      * @return the index of corresponing tau action
303      */

304     public int getTauAction(int event) {
305         int root = (event / VARIANTCNT) * VARIANTCNT;
306         int index = event % VARIANTCNT;
307
308         if ((index == 3) || (index == 4)) {
309             touchItem(root + 8);
310             return root + 8;
311         } else if ((index == 5) || (index == 6)) {
312             touchItem(root + 9);
313             return root + 9;
314         } else {
315             touchItem(root + 7);
316             return root + 7;
317         }
318     }
319
320     /**
321      * @param event
322      * the event index
323      * @return true iff this is a response action
324      */

325     public boolean isResponse(int event) {
326         int subtype = event % VARIANTCNT;
327         return (subtype == 2) || (subtype == 4) || (subtype == 6);
328     }
329
330     /**
331      * @param event
332      * the event index
333      * @return true iff this is a tau action
334      */

335     public boolean isTau(int event) {
336         int subtype = event % VARIANTCNT;
337         return subtype >= 7;
338     }
339
340     /**
341      *
342      * @param event
343      * event index
344      * @return the event index of the action corresponding to the event (the
345      * code corresponding to the name without the last character
346      * (request/response mark))
347      */

348     public int getEventAction(int event) {
349         if ((event % VARIANTCNT == 3) || (event % VARIANTCNT == 5))
350             return event / 10 * 10 + 1;
351         else if ((event % VARIANTCNT == 4) || (event % VARIANTCNT == 6))
352             return event / 10 * 10 + 2;
353         else if ((event % VARIANTCNT == 8) || (event % VARIANTCNT == 9))
354             return event / 10 * 10 + 7;
355         else
356             return event;
357     }
358
359     /**
360      * Parses the name and return the pure name of the action.
361      *
362      * @return pure name of the action
363      */

364     static private String JavaDoc getPureName(String JavaDoc action) {
365         String JavaDoc result = new String JavaDoc(action);
366
367         char first = action.charAt(0);
368         char last = action.charAt(action.length() - 1);
369
370         if ((first == '?') || (first == '!') || (first == '#'))
371             result = result.substring(1);
372
373         if ((last == '^') || (last == '$'))
374             result = result.substring(0, result.length() - 1);
375
376         return result;
377     }
378
379     /**
380      * Touches the item in the repository. Doesn't touch those items that don't
381      * represent real actions.
382      */

383     private void touchItem(int index) {
384         if ((index % VARIANTCNT != 0) && (index % VARIANTCNT != 1) && (index % VARIANTCNT != 2) && (index % VARIANTCNT != 7))
385             usedItems.add(new Integer JavaDoc(index));
386     }
387     
388     /**
389      * @param atomicactionindex
390      * @return the AtomicAction at the given index
391      */

392     public AtomicAction getAtomicEvents(int atomicactionindex) {
393         return (AtomicAction)atomicRepository.get(new Integer JavaDoc(atomicactionindex));
394     }
395
396     
397     
398     /**
399      * Generates all variants of an atomic events.
400      */

401     private LinkedList JavaDoc createAtomicVariants(LinkedList JavaDoc events) {
402         LinkedList JavaDoc result = new LinkedList JavaDoc();
403         LinkedList JavaDoc subresult1;
404         LinkedList JavaDoc subresult2 = new LinkedList JavaDoc();
405         
406         if (events.size() == 0)
407             return result;
408         
409         if (events.size() == 1) {
410             subresult2.add(events.getFirst());
411             result.add(subresult2);
412             subresult2 = new LinkedList JavaDoc();
413             subresult2.add(new Integer JavaDoc(getTauAction(((Integer JavaDoc)events.getFirst()).intValue())));
414             result.add(subresult2);
415             return result;
416         }
417         
418         Integer JavaDoc first = (Integer JavaDoc)events.removeFirst();
419         
420         subresult1 = createAtomicVariants(events);
421         subresult2 = duplicateList(subresult1);
422
423         
424         Iterator JavaDoc it = subresult1.iterator();
425         while (it.hasNext()) {
426             LinkedList JavaDoc item = (LinkedList JavaDoc)it.next();
427             item.add(first);
428             result.add(item);
429         }
430         
431         Integer JavaDoc tau = new Integer JavaDoc(getTauAction(first.intValue()));
432         it = subresult2.iterator();
433         while (it.hasNext()) {
434             LinkedList JavaDoc item = (LinkedList JavaDoc)it.next();
435             item.add(tau);
436             result.add(item);
437         }
438         
439         return result;
440     }
441     
442     /**
443      * Duplicates the list of lists.
444      * @return the duplicated list
445      */

446     private LinkedList JavaDoc duplicateList(LinkedList JavaDoc source) {
447         LinkedList JavaDoc newlist = new LinkedList JavaDoc();
448         
449         Iterator JavaDoc it = source.iterator();
450         
451         while(it.hasNext()) {
452             LinkedList JavaDoc item = (LinkedList JavaDoc)it.next();
453             LinkedList JavaDoc newitem = new LinkedList JavaDoc();
454             
455             Iterator JavaDoc internal = item.iterator();
456                         
457             while (internal.hasNext()) {
458                 newitem.add(new Integer JavaDoc(((Integer JavaDoc)internal.next()).intValue()));
459             }
460             
461             newlist.add(newitem);
462         }
463         
464         return newlist;
465     }
466
467     /**
468      * Prints out the content of the cache.
469      */

470     public void flushCache() {
471         Iterator JavaDoc it = repository.keySet().iterator();
472
473         while (it.hasNext()) {
474             System.out.println(repository.get((Integer JavaDoc) it.next()));
475         }
476     }
477
478     //--------------------------------------------------------------------------
479

480     /**
481      * The map where the identifiers of action are stored
482      */

483     private TreeMap JavaDoc repository;
484
485     /**
486      * Inverse database for presence checking. It maps the string indentifiers
487      * to their indices
488      */

489     private TreeMap JavaDoc inverseRepository;
490
491     /**
492      * The map where the identifiers of action are stored
493      */

494     private TreeMap JavaDoc atomicRepository;
495
496     /**
497      * Inverse database for presence checking. It maps the string indentifiers
498      * to their indices
499      */

500     private TreeMap JavaDoc atomicInverseRepository;
501
502     /**
503      * The number of variants per event
504      */

505     static final int VARIANTCNT = 10;
506
507     /**
508      * Action used within the input protocols
509      */

510     private TreeSet JavaDoc usedItems;
511
512 }
Popular Tags