/Users/lyon/j4p/src/classUtils/pack/util/sis/StateInfoSupport.java

1    package classUtils.pack.util.sis; 
2     
3    import classUtils.pack.util.IndentedPrintWriter; 
4    import classUtils.pack.util.ListMapIterator; 
5     
6    import java.io.StringWriter; 
7    import java.util.*; 
8     
9    /** 
10    * Plug-in class for adding state information support to an mbean. 
11    * <p> 
12    * The Mbean owning an instance can record state information entries related 
13    * to a specific key and obtain a String to provide the console user with a log. 
14    *  
15    * @author cris 
16    */ 
17   public class StateInfoSupport { 
18        
19       private Map entries = new HashMap(); 
20       private List keys = new ArrayList(); 
21       private String lastKey; 
22       private int level; 
23        
24       private synchronized void addEntry(String key, InfoEntry entry) {  
25        
26           if (! key.equals(lastKey)) { 
27               keys.add(key); 
28               lastKey=key; 
29           } 
30            
31           List l = (List)entries.get(key); 
32           if (l==null)  {  
33               entries.put(key, l=new ArrayList());  
34           } 
35           l.add(entry);  
36       } 
37    
38       /** 
39        * Add a entry for the given key, containing a textual description. 
40        *  
41        * @param key 
42        * @param description 
43        */  
44       public void addEntry(String key, String description) {   
45           addEntry(key, new InfoEntry(description, level));  
46       } 
47        
48       /** 
49        * Add a entry for the given key, containing a textual description and 
50        * a given exception object. 
51        *  
52        * @param key 
53        * @param description 
54        * @param e 
55        */ 
56       public void addEntry(String key, String description, Throwable e) {  
57           addEntry(key, new InfoEntry(description, level, e));  
58       } 
59        
60       /** 
61        * Add a entry for the same key as the last <tt>addEntry</tt> operation,  
62        * containing a textual description. 
63        * <p> 
64        * This method can be invoked only after one of the <tt>addEntry</tt> overloads 
65        * with <tt>key</tt> parameters have been invoked. 
66        *  
67        * @param description 
68        */ 
69       public void addEntry(String description) {   
70           checkLastKey(); 
71           addEntry(lastKey, new InfoEntry(description, level));  
72       } 
73        
74       /** 
75        * Add a entry for the same key as the last <tt>addEntry</tt> operation,  
76        * containing a textual description anda given exception object. 
77        * <p> 
78        * This method can be invoked only after one of the <tt>addEntry</tt> overloads 
79        * with <tt>key</tt> parameters have been invoked. 
80        *  
81        * @param description 
82        * @param e 
83        */ 
84       public void addEntry(String description, Throwable e) {  
85           checkLastKey(); 
86           addEntry(lastKey, new InfoEntry(description, level, e));  
87       } 
88        
89       private void checkLastKey() { 
90           if (lastKey==null) { 
91               IllegalStateException e = new IllegalStateException("StateInfoSupport: no last key set. Please use the addEntry(String key, ...) overload on the first entry."); 
92               throw e; 
93           } 
94       } 
95        
96       /** 
97        * Return a state log for the given key. If key is <b>null</b> or 
98        * the empty string, all entries are descripted. 
99        * <p> 
100       * If the key does not exist, <b>null</b> is returned. 
101       *  
102       * @param key the key of interest. 
103       * @return a state log for the given key, or <b>null</b>. If key is <b>null</b> or 
104       * the empty string, all entries are descripted. 
105       */ 
106      public synchronized String getStateDescription(String key) { 
107          StringWriter sw = new StringWriter(); 
108          IndentedPrintWriter pw = new IndentedPrintWriter(sw); 
109          Iterator i; 
110           
111          if (key==null || "".equals(key)) 
112              i = new ListMapIterator(entries, keys); 
113          else { 
114              List l = (List)entries.get(key); 
115              if (l==null) return null; 
116              i = l.iterator(); 
117          } 
118           
119          String currentKey=null; 
120           
121          while(i.hasNext()) { 
122              String oldKey=currentKey; 
123              if (i instanceof ListMapIterator) { 
124                  currentKey=(String)((ListMapIterator)i).getCurrentKey(); 
125              } else currentKey=key; 
126               
127              if (! currentKey.equals(oldKey)) { 
128                  pw.println(); 
129                  pw.println("{"+currentKey+"} "); 
130                  pw.println(); 
131              } 
132               
133              InfoEntry entry = (InfoEntry)i.next(); 
134              pw.incIndentation(5+entry.getLevel()); 
135              pw.println(entry); 
136              pw.decIndentation(5); 
137          } 
138           
139          return sw.toString(); 
140      } 
141       
142      // Test method 
143      public static void main(String args[]) throws Exception { 
144          StateInfoSupport sis =new StateInfoSupport(); 
145          sis.addEntry("intialization", "all is right"); 
146          sis.addEntry("something going wrong", new IllegalStateException("illegal state")); 
147          sis.addEntry("doing something", "all ok"); 
148          sis.addEntry("ops!", new RuntimeException("something didnt work")); 
149           
150          System.out.println(sis.getStateDescription("intialization")); 
151           
152      } 
153       
154   
155      /** 
156       * Returns the level. 
157       * @return int 
158       */ 
159      public int getLevel() { 
160          return level; 
161      } 
162   
163      /** 
164       * Sets the level. 
165       * @param level The level to set 
166       */ 
167      public void setLevel(int level) { 
168          this.level = level; 
169      } 
170   
171  } 
172