1   package org.mortbay.util.ajax;
2   
3   import java.lang.reflect.Method;
4   import java.lang.reflect.Modifier;
5   import java.util.Arrays;
6   import java.util.HashSet;
7   import java.util.Map;
8   import java.util.Set;
9   
10  import org.mortbay.util.ajax.JSON.Output;
11  
12  /* ------------------------------------------------------------ */
13  /**
14   * Convert an Object to JSON using reflection on getters methods.
15   * 
16   * @author gregw
17   *
18   */
19  public class JSONObjectConvertor implements JSON.Convertor
20  {
21      private boolean _fromJSON;
22      private Set _excluded=null;
23  
24      public JSONObjectConvertor()
25      {
26          _fromJSON=false;
27      }
28      
29      public JSONObjectConvertor(boolean fromJSON)
30      {
31          _fromJSON=fromJSON;
32      }
33      
34      /* ------------------------------------------------------------ */
35      /**
36       * @param fromJSON
37       * @param excluded An array of field names to exclude from the conversion
38       */
39      public JSONObjectConvertor(boolean fromJSON,String[] excluded)
40      {
41          _fromJSON=fromJSON;
42          if (excluded!=null)
43              _excluded=new HashSet(Arrays.asList(excluded));
44      }
45  
46      public Object fromJSON(Map map)
47      {
48          if (_fromJSON)
49              throw new UnsupportedOperationException();
50          return map;
51      }
52  
53      public void toJSON(Object obj, Output out)
54      {
55          try
56          {
57              Class c=obj.getClass();
58  
59              if (_fromJSON)
60                  out.addClass(obj.getClass());
61  
62              Method[] methods = obj.getClass().getMethods();
63  
64              for (int i=0;i<methods.length;i++)
65              {
66                  Method m=methods[i];
67                  if (!Modifier.isStatic(m.getModifiers()) &&  
68                          m.getParameterTypes().length==0 && 
69                          m.getReturnType()!=null &&
70                          m.getDeclaringClass()!=Object.class)
71                  {
72                      String name=m.getName();
73                      if (name.startsWith("is"))
74                          name=name.substring(2,3).toLowerCase()+name.substring(3);
75                      else if (name.startsWith("get"))
76                          name=name.substring(3,4).toLowerCase()+name.substring(4);
77                      else
78                          continue;
79  
80                      if (includeField(name,obj,m))
81                          out.add(name, m.invoke(obj,(Object[])null));
82                  }
83              }
84          } 
85          catch (Throwable e)
86          {
87              // e.printStackTrace();
88              throw new IllegalArgumentException(e);
89          }
90      }
91      
92      protected boolean includeField(String name, Object o, Method m)
93      {
94          return _excluded==null || !_excluded.contains(name);
95      }
96  
97  }