Commits

Jason Stonebraker  committed 956d88f

Added support for non domain classes.

Resolved Issue #1

  • Participants
  • Parent commits b0d2e2a

Comments (0)

Files changed (2)

File JsonExclusionMarshallerGrailsPlugin.groovy

 import grails.converters.JSON
-import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
+import groovy.lang.GroovyObject
+import groovy.lang.GroovyClassLoader
+import groovy.util.ConfigSlurper
+import groovy.util.ConfigObject
+
+import java.beans.PropertyDescriptor
+import java.lang.reflect.Field
+import java.lang.reflect.Method
+import java.lang.reflect.Modifier
+
+import org.codehaus.groovy.grails.web.converters.exceptions.ConverterException
+import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller
+import org.codehaus.groovy.grails.web.json.JSONWriter
+import org.springframework.beans.BeanUtils
+
 
 class JsonExclusionMarshallerGrailsPlugin {
     def version = "0.2"
 
                 jsonConverter.createNamedConfig(configName) {
                     it.registerObjectMarshaller(type) {
-                        def obj = it // Object being marshalled
-                        def gdc = new DefaultGrailsDomainClass(type)
+                        def o = it // Object being marshalled
                         def map = [:]
 
-                        map["${gdc.identifier.name}"] = obj."${gdc.identifier.name}"
-                        map['class'] = obj.getClass().name
+                        try {
+                            PropertyDescriptor[] properties = BeanUtils.getPropertyDescriptors(o.getClass())
+                            for (PropertyDescriptor property : properties) {
+                                String propertyName = property.getName()
+                                Method readMethod = property.getReadMethod()
 
-                        gdc.persistentProperties.each { property ->
-                            map["${property.name}"] = obj."${property.name}"
+                                if (readMethod != null
+                                    && !(propertyName.equals("metaClass"))) {
+                                    Object value = readMethod.invoke(o, (Object[]) null)
+                                    map[propertyName] = value
+                                }
+                            }
+
+                            Field[] fields = o.getClass().getDeclaredFields()
+                            for (Field field : fields) {
+                                int modifiers = field.getModifiers()
+                                if (Modifier.isPublic(modifiers)
+                                    && !(Modifier.isStatic(modifiers)
+                                        || Modifier.isTransient(modifiers))) {
+                                    map[field.getName()] = field.get(o)
+                                }
+                            }
+
+                        } catch (ConverterException ce) {
+                            throw ce
+                        } catch (Exception e) {
+                            throw new ConverterException(
+                                "Error converting Bean with class "
+                                + o.getClass().getName(), e)
                         }
 
+                        propertiesToExclude += JSON.globalExclusions()
                         propertiesToExclude.each { property -> map.remove(property) }
-
+                        
                         return map
                     }
                 }
 
             return impl(args)
         }
+
+        JSON.metaClass.static.globalExclusions << { arg ->
+            this.getConfiguredGlobalExclusions(application)
+        }
+    }
+
+    private List getConfiguredGlobalExclusions(application) {
+        GroovyClassLoader classLoader = new GroovyClassLoader(getClass().getClassLoader())
+        ConfigObject config
+        try {
+           config = new ConfigSlurper().parse(classLoader.loadClass('JsonExclusionMarshallerDefaultConfig'))
+        } catch (Exception e) {/*??handle or what? use default here?*/}
+        
+        def configGlobalExclusions = config.merge(application.config).jsonExclusionMarshaller.globalExclusions
+
+        return (configGlobalExclusions) ? configGlobalExclusions.split(/,\s*/).collect { it } : []
     }
 }

File grails-app/conf/JsonExclusionMarshallerDefaultConfig.groovy

+// jsonExclusionMarshaller.globalExclusions = "class, attached, errors, properties, version"