/
DtoGrailsPlugin.groovy
98 lines (84 loc) · 3.29 KB
/
DtoGrailsPlugin.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import grails.plugins.dto.DTO
import org.codehaus.groovy.grails.plugins.dto.DefaultGrailsDtoGenerator
import org.dozer.spring.DozerBeanMapperFactoryBean
import org.springframework.context.ApplicationContext
class DtoGrailsPlugin {
// the plugin version
def version = "0.1.2"
// the version or versions of Grails the plugin is designed for
def grailsVersion = "1.1 > *"
// the other plugins this plugin depends on
def dependsOn = [:]
def loadAfter = [ "converters" ]
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/views/error.gsp"
]
// TODO Fill in these fields
def author = "Peter Ledbrook"
def authorEmail = ""
def title = "DTO plugin for Grails"
def description = """\\
Manually creating and managing DTO objects for your domain classes is
labour intensive and error-prone. This plugin aims to simplify DTOs
by automatically generating them and providing a mechanism to easily
map domain class instances to DTO instances.
"""
// URL to the plugin's documentation
def documentation = "http://grails.org/plugin/dto"
def doWithSpring = {
dtoGenerator(DefaultGrailsDtoGenerator)
dozerMapper(DozerBeanMapperFactoryBean)
}
def doWithDynamicMethods = { final ctx ->
// Add "as DTO" and toDTO() to domain classes.
for (dc in application.domainClasses) {
addDtoMethods(dc.metaClass, ctx)
}
}
def doWithApplicationContext = { final ctx ->
}
def onChange = { event ->
// TODO Implement code that is executed when any artefact that this plugin is
// watching is modified and reloaded. The event contains: event.source,
// event.application, event.manager, event.ctx, and event.plugin.
}
def onConfigChange = { event ->
// TODO Implement code that is executed when the project configuration changes.
// The event is the same as for 'onChange'.
}
private addDtoMethods(final MetaClass mc, final ApplicationContext ctx) {
// First add the "as DTO".
final originalAsType = mc.getMetaMethod("asType", [ Class ] as Object[])
mc.asType = { Class clazz ->
if (DTO == clazz) {
// Do the DTO conversion.
return mapDomainInstance(ctx, delegate)
}
else {
// Use the original asType implementation.
return originalAsType.invoke(delegate, [ clazz ] as Object[])
}
}
// Then the toDTO() method.
mc.toDTO = {->
return mapDomainInstance(ctx, delegate)
}
}
/**
* Uses the Dozer mapper to map a domain instance to its corresponding
* DTO.
* @param ctx The Spring application context containing the Dozer
* mapper.
* @param obj The domain instance to map.
* @return The DTO corresponding to the given domain instance.
*/
private mapDomainInstance(ctx, obj) {
// Get the appropriate DTO class for this domain instance.
def dtoClassName = obj.getClass().name + "DTO"
def dtoClass = obj.getClass().classLoader.loadClass(dtoClassName)
// Now convert the domain instance to a DTO.
def mapper = ctx.getBean("dozerMapper")
return mapper.map(obj, dtoClass)
}
}