View Javadoc

1   /**
2    * 2007, Digitalis Informatica. All rights reserved. Distribuicao e Gestao de Informatica, Lda. Estrada de Paco de Arcos
3    * num.9 - Piso -1 2780-666 Paco de Arcos Telefone: (351) 21 4408990 Fax: (351) 21 4408999 http://www.digitalis.pt
4    */
5   package pt.digitalis.dif.utils;
6   
7   import java.util.ArrayList;
8   import java.util.Iterator;
9   import java.util.List;
10  import java.util.Map;
11  
12  import pt.digitalis.utils.common.StringUtils;
13  
14  /**
15   * Helps to format an object for printing in human readable form
16   * 
17   * @author Pedro Viegas <a href="mailto:pviegas@digitalis.pt">pviegas@digitalis.pt</a>
18   * @created Dec 7, 2007
19   */
20  public class ObjectFormatter {
21  
22      /** The prefix to format the lines with */
23      final static private String PREFIX = "  | ";
24  
25      /** The prefix to format the lines with */
26      final static private String SEPARATOR = ": ";
27  
28      /** The generated buffer to return. Will be built incrementally */
29      private StringBuffer buffer = new StringBuffer();
30  
31      /** the dumpd object list to keep track (avoid circular dump and stack overflow) */
32      private List<Object> dumpedObjects = new ArrayList<Object>();
33  
34      /**
35       * Adds an item to the buffer
36       * 
37       * @param key
38       *            the key that identifies the value
39       * @param value
40       *            the value
41       * @return the updated instance (fluent interface)
42       */
43      public ObjectFormatter addItem(String key, Object value)
44      {
45          if (!dumpedObjects.contains(value)
46                  || (value != null && value.getClass().getPackage().getName().startsWith("java.lang")))
47          {
48              String line = PREFIX + key + SEPARATOR;
49              line += toStringParser(value, line.length());
50  
51              if (!"".equals(buffer))
52                  buffer.append("\n");
53  
54              buffer.append(line);
55          }
56  
57          return this;
58      }
59  
60      /**
61       * Adds an item to the buffer if the value is not null
62       * 
63       * @param key
64       *            the key that identifies the value
65       * @param value
66       *            the value
67       * @return the updated instance (fluent interface)
68       */
69      public ObjectFormatter addItemIfNotNull(String key, Object value)
70      {
71          if (value != null)
72              addItem(key, value);
73  
74          return this;
75      }
76  
77      /**
78       * Formats an iterator in human readable form
79       * 
80       * @param obj
81       *            the list to convert
82       * @return the formatted list
83       */
84      private String formatIterator(Iterable<?> obj)
85      {
86          if (!dumpedObjects.contains(obj))
87          {
88              dumpedObjects.add(obj);
89  
90              Iterator<?> iterator = ((Iterable<?>) obj).iterator();
91  
92              if (!iterator.hasNext())
93                  return "[]";
94              else
95              {
96                  String temp = "[\n";
97                  int pos = 1;
98  
99                  while (iterator.hasNext())
100                 {
101                     Object object = iterator.next();
102                     String ident = " #" + StringUtils.fillStringLeft(Integer.toString(pos++), 2, " ") + " ";
103                     temp += ident + toStringParserWithPrefix(object, ident.length(), " ") + "\n";
104                 }
105 
106                 return temp + "]";
107             }
108         }
109         else
110             return "«see above»";
111     }
112 
113     /**
114      * Formats a map in human readable form
115      * 
116      * @param map
117      *            the map to convert
118      * @return the formatted map
119      */
120     private String formatMap(Map<?, ?> map)
121     {
122         if (!dumpedObjects.contains(map))
123         {
124             dumpedObjects.add(map);
125 
126             if (map.size() == 0)
127                 return "[]";
128             else
129             {
130                 String temp = "[\n";
131                 int pos = 1;
132 
133                 for (Object key: map.keySet())
134                 {
135                     String ident = " " + StringUtils.fillStringLeft("#" + Integer.toString(pos++), 3, " ") + " " + key
136                             + " = ";
137                     Object value = map.get(key);
138                     if (value instanceof String)
139                     {
140                         value = "\"" + value + "\"";
141                     }
142 
143                     temp += ident + toStringParserWithPrefix(value, ident.length(), " ") + "\n";
144                 }
145 
146                 return temp + "]";
147             }
148         }
149         else
150             return "«see above»";
151     }
152 
153     /**
154      * @return the formatted object
155      */
156     public String getFormatedObject()
157     {
158         return buffer.toString();
159     }
160 
161     /**
162      * Parses a string and tries to format it for including has a value in a line.
163      * 
164      * @param obj
165      *            the object to format
166      * @param prefixSize
167      *            the size of the necessary prefix
168      * @return the formatted string
169      */
170     private String toStringParser(Object obj, int prefixSize)
171     {
172         return toStringParserWithPrefix(obj, prefixSize, PREFIX);
173     }
174 
175     /**
176      * Parses a string and tries to format it for including has a value in a line.
177      * 
178      * @param obj
179      *            the object to format
180      * @param prefixSize
181      *            the size of the necessary prefix
182      * @param prefix
183      *            the prefix to use to pad the string
184      * @return the formatted string
185      */
186     private String toStringParserWithPrefix(Object obj, int prefixSize, String prefix)
187     {
188         if (obj == null)
189             return null;
190         else
191         {
192             String temp;
193 
194             if (obj instanceof Map)
195                 temp = formatMap((Map<?, ?>) obj);
196 
197             else if (obj instanceof Iterable)
198                 temp = formatIterator(((Iterable<?>) obj));
199 
200             else
201                 temp = obj.toString();
202 
203             dumpedObjects.add(obj);
204 
205             return temp.replace("\n", "\n" + StringUtils.fillString(prefix, prefixSize, " "));
206         }
207     }
208 }