Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Predrag Knezevic committed Dec 5, 2011
0 parents commit dc8d3d6
Show file tree
Hide file tree
Showing 19 changed files with 445 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
@@ -0,0 +1,4 @@
.classpath
.project
.settings
target
14 changes: 14 additions & 0 deletions LICENSE
@@ -0,0 +1,14 @@
Copyright 2009 Peter Ledbrook

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

45 changes: 45 additions & 0 deletions MarshallersGrailsPlugin.groovy
@@ -0,0 +1,45 @@
import org.grails.plugins.marshallers.ExtendedConvertersConfigurationInitializer
import org.grails.plugins.marshallers.XmlMarshallerArtefactHandler
import org.grails.plugins.marshallers.JsonMarshallerArtefactHandler

class MarshallersGrailsPlugin {
// the plugin version
def version = "0.1"
// the version or versions of Grails the plugin is designed for
def grailsVersion = "1.1 > *"

def loadAfter = ['converters']


// the other plugins this plugin depends on
def dependsOn = [:]
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/views/error.gsp"
]

def artefacts = [ XmlMarshallerArtefactHandler, JsonMarshallerArtefactHandler ]

def author = "Predrag Knezevic"
def authorEmail = "pedjak@gmail.com"
def title = "Easy Custom XML and JSON Marshalling for Grails Converters"
def description = '''\\
Brief description of the plugin.
'''

// URL to the plugin's documentation
def documentation = "http://grails.org/plugin/marshallers"

def doWithSpring = {
// replace default convertersConfigurationInitializer from Converters plugin with ours
convertersConfigurationInitializer(ExtendedConvertersConfigurationInitializer)
["xml", "json"].each { type ->
application."${type}MarshallerClasses".each { marshallerClass ->
"${marshallerClass.fullName}"(marshallerClass.clazz) { bean ->
bean.autowire = "byName"
}
}
}
}

}
6 changes: 6 additions & 0 deletions application.properties
@@ -0,0 +1,6 @@
#Grails Metadata file
#Fri Dec 02 15:35:52 CET 2011
app.grails.version=1.3.7
app.name=marshallers
plugins.hibernate=1.3.7
plugins.tomcat=1.3.7
31 changes: 31 additions & 0 deletions grails-app/conf/BuildConfig.groovy
@@ -0,0 +1,31 @@
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
//grails.project.war.file = "target/${appName}-${appVersion}.war"
grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
// uncomment to disable ehcache
// excludes 'ehcache'
}
log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
repositories {
grailsPlugins()
grailsHome()
grailsCentral()

// uncomment the below to enable remote dependency resolution
// from public Maven repositories
//mavenLocal()
//mavenCentral()
//mavenRepo "http://snapshots.repository.codehaus.org"
//mavenRepo "http://repository.codehaus.org"
//mavenRepo "http://download.java.net/maven/2/"
//mavenRepo "http://repository.jboss.com/maven2/"
}
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes eg.

// runtime 'mysql:mysql-connector-java:5.1.13'
}
}
24 changes: 24 additions & 0 deletions grails-app/conf/Config.groovy
@@ -0,0 +1,24 @@
// configuration for plugin testing - will not be included in the plugin zip

log4j = {
// Example of changing the log pattern for the default console
// appender:
//
//appenders {
// console name:'stdout', layout:pattern(conversionPattern: '%c{2} %m%n')
//}

error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate'

warn 'org.mortbay.log'
}
32 changes: 32 additions & 0 deletions grails-app/conf/DataSource.groovy
@@ -0,0 +1,32 @@
dataSource {
pooled = true
driverClassName = "org.hsqldb.jdbcDriver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:hsqldb:mem:devDB"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:mem:testDb"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:hsqldb:file:prodDb;shutdown=true"
}
}
}
13 changes: 13 additions & 0 deletions grails-app/conf/UrlMappings.groovy
@@ -0,0 +1,13 @@
class UrlMappings {

static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}

"/"(view:"/index")
"500"(view:'/error')
}
}
10 changes: 10 additions & 0 deletions scripts/_Install.groovy
@@ -0,0 +1,10 @@
//
// This script is executed by Grails after plugin was installed to project.
// This script is a Gant script so you can use all special variables provided
// by Gant (such as 'baseDir' which points on project base dir). You can
// use 'ant' to access a global instance of AntBuilder
//
// For example you can create directory under project tree:
//
// ant.mkdir(dir:"${basedir}/grails-app/jobs")
//
5 changes: 5 additions & 0 deletions scripts/_Uninstall.groovy
@@ -0,0 +1,5 @@
//
// This script is executed by Grails when the plugin is uninstalled from project.
// Use this script if you intend to do any additional clean-up on uninstall, but
// beware of messing up SVN directories!
//
10 changes: 10 additions & 0 deletions scripts/_Upgrade.groovy
@@ -0,0 +1,10 @@
//
// This script is executed by Grails during application upgrade ('grails upgrade'
// command). This script is a Gant script so you can use all special variables
// provided by Gant (such as 'baseDir' which points on project base dir). You can
// use 'ant' to access a global instance of AntBuilder
//
// For example you can create directory under project tree:
//
// ant.mkdir(dir:"${basedir}/grails-app/jobs")
//
120 changes: 120 additions & 0 deletions src/groovy/org/grails/plugins/marshallers/ConfigurationBuilder.groovy
@@ -0,0 +1,120 @@


package org.grails.plugins.marshallers


import org.codehaus.groovy.grails.web.converters.configuration.ConvertersConfigurationHolder;
import org.codehaus.groovy.grails.web.converters.configuration.DefaultConverterConfiguration;
import org.codehaus.groovy.grails.web.converters.marshaller.NameAwareMarshaller;
import org.codehaus.groovy.grails.web.converters.marshaller.ObjectMarshaller;

import groovy.lang.Closure;

import org.codehaus.groovy.grails.web.converters.Converter;

import org.codehaus.groovy.grails.web.converters.marshaller.ClosureOjectMarshaller;

import groovy.lang.Closure;
import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU

/**
* @author Predrag Knezevic
* @version $Date: $
*/
class ConfigurationBuilder {
private static String CONFIGURATION_FIELD = "configuration"

def log
def applicationContext
def cfg
def converterClass
def cfgName
def type

def ensureCfg() {
if (! (cfg instanceof DefaultConverterConfiguration)) {
cfg = new DefaultConverterConfiguration(cfg)
ConvertersConfigurationHolder.setDefaultConfiguration(converterClass, cfg)
}
}
def registerSpringMarshallers() {
// find all marshallers with the given configuration
applicationContext.grailsApplication."${type}MarshallerClasses"*.clazz.findAll { clazz ->
def cfg = GCU.getStaticPropertyValue(clazz, CONFIGURATION_FIELD)
def found = cfg == null && cfgName == "default"
if (!found) {
found = cfg instanceof Collection ? cfg.contains(cfgName) : (cfg == cfgName)
}
found
}.each { register(it) }
}

def register(Object marshaller) {
ensureCfg()
if (!cfg.orderedObjectMarshallers.contains(marshaller)) {
cfg.registerObjectMarshaller(marshaller)
log.debug "Registered marshaller ${marshaller.class.name}"
}
}
def register(Class clazz) {
def marshaller = applicationContext.containsBean(clazz.name) ? applicationContext.getBean(clazz.name) : clazz.newInstance()
register(marshaller)
}

def register(String marshallerName) {
def marshaller = applicationContext.containsBean(marshallerName) ? applicationContext.getBean(marshallerName) : null
if (marshaller == null) {
log.warn("Cannot find and register marshaller with the name ${marshallerName}")
} else {
register(marshaller)
}
}

def register(Class clazz, Closure cl) {
ensureCfg()
cfg.registerObjectMarshaller(clazz, cl)
log.debug "Registered closure marshaller for ${clazz.name}"
}

def register(Class clazz, String elementName, Closure cl) {
ensureCfg()
cfg.registerObjectMarshaller(new NameAwareClosureObjectMarshaller(clazz, elementName, cl))
log.debug "Registered closure marshaller for ${clazz.name}"
}

def invokeMethod(String name, args) {
if (args.size() != 1) {
log.error "the number of params can be only one for ${name}"
} else if (! args[0] instanceof Closure) {
log.error "${name} accepts only closure as param"
} else {
log.info "create config with name ${name} under ${cfgName}"
def newCfg = ConvertersConfigurationHolder.getNamedConverterConfiguration(name, converterClass)
if (newCfg == null) {
newCfg = new DefaultConverterConfiguration(cfg)
ConvertersConfigurationHolder.setNamedConverterConfiguration(converterClass, name, newCfg)
}
def builder = new ConfigurationBuilder(type: type, applicationContext: applicationContext, cfg: newCfg, converterClass: converterClass, log: log, cfgName: name)
builder.registerSpringMarshallers()
def closure = args[0]
closure.delegate = builder
closure.resolveStrategy = Closure.DELEGATE_FIRST;
closure.call()
}
}
}

class NameAwareClosureObjectMarshaller<T extends Converter> extends ClosureOjectMarshaller<T> implements NameAwareMarshaller {

def elementName

def NameAwareClosureObjectMarshaller(Class clazz, String elementName, Closure closure) {
super(clazz, closure)
this.elementName = elementName
}

String getElementName(Object o) {
elementName
}

}
@@ -0,0 +1,42 @@

package org.grails.plugins.marshallers

import grails.converters.JSON;
import grails.converters.XML;
import grails.util.GrailsConfig;

import org.codehaus.groovy.grails.web.converters.configuration.ConvertersConfigurationHolder;
import org.codehaus.groovy.grails.web.converters.configuration.ConvertersConfigurationInitializer;
import org.codehaus.groovy.grails.web.converters.configuration.DefaultConverterConfiguration;

/**
* @author Predrag Knezevic
* @version $Date: $
*/
class ExtendedConvertersConfigurationInitializer extends ConvertersConfigurationInitializer {

@Override
public void initialize() {
super.initialize()
processGrailsConfigurations()
}

protected def processGrailsConfigurations() {
[xml: XML, json: JSON].each { type, converterClass ->
def marshallerCfg = GrailsConfig.get("grails.plugins.marshallers.${type}")
if (marshallerCfg != null) {
processConfig(marshallerCfg, converterClass, type)
}
}
}

public void processConfig(Closure cfg, Class converterClass, type) {
def converterCfg = ConvertersConfigurationHolder.getConverterConfiguration(converterClass)
def builder = new ConfigurationBuilder(type: type, applicationContext: applicationContext, cfg: converterCfg, log: LOG, converterClass: converterClass, cfgName: "default")
builder.registerSpringMarshallers()
cfg.delegate = builder
cfg.resolveStrategy = Closure.DELEGATE_FIRST;
cfg.call()
}
}

@@ -0,0 +1,16 @@
package org.grails.plugins.marshallers;

import org.codehaus.groovy.grails.commons.AbstractInjectableGrailsClass;

/**
* @author Predrag Knezevic
* @version $Date: $
*/
public class DefaultJsonMarshallerGrailsClass extends AbstractInjectableGrailsClass
implements JsonMarshallerGrailsClass {

public DefaultJsonMarshallerGrailsClass(Class<?> clazz) {
super(clazz, JsonMarshallerArtefactHandler.TYPE);
}

}

0 comments on commit dc8d3d6

Please sign in to comment.