-
Notifications
You must be signed in to change notification settings - Fork 14
/
MongodbMorphiaGrailsPlugin.groovy
144 lines (124 loc) · 5.87 KB
/
MongodbMorphiaGrailsPlugin.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import grails.plugins.mongodb.MongoPluginSupport
import org.springframework.context.ApplicationContext
import grails.plugins.mongodb.MongoDomainClass
import grails.plugins.mongodb.MongoHolderBean
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.codehaus.groovy.grails.validation.GrailsDomainClassValidator
import org.springframework.beans.factory.config.MethodInvokingFactoryBean
import grails.plugins.mongodb.MongoDomainClassArtefactHandler
import com.google.code.morphia.Morphia
import com.google.code.morphia.Datastore
import com.google.code.morphia.mapping.MappedClass
import grails.plugins.mongodb.audit.MorphiaAuditEntityInterceptor
import com.google.code.morphia.AbstractEntityInterceptor
class MongodbMorphiaGrailsPlugin {
def license = "APACHE"
def developers = [
[ name: "Juri Kuehn", email: "juri.kuehn@gmail.com" ]
]
def issueManagement = [ system: "JIRA", url: "http://jira.grails.org/browse/GPGORMMONGODB" ]
def scm = [ url: "https://github.com/jkuehn/gorm-mongodb" ]
// the plugin version
def version = "0.8.2"
// the version or versions of Grails the plugin is designed for
def grailsVersion = "1.3.4 > *"
// the other plugins this plugin depends on
def dependsOn = [core: '1.3.4 > *']
def loadAfter = ['core', 'controllers', 'domainClass']
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/views/error.gsp",
"grails-app/controllers/**", // they exist only for testing purposes
"grails-app/conf/Config.groovy",
"grails-app/mongo/**",
"grails-app/someotherdir/**",
]
def author = "Juri Kuehn"
def authorEmail = "juri.kuehn at gmail.com"
def title = "Alternative MongoDB GORM based on the Morphia library"
def description = '''GORM implementation for the MongoDB NoSQL database based on the Morphia library'''
// URL to the plugin's documentation
def documentation = "http://wiki.github.com/jkuehn/gorm-mongodb/"
def artefacts = [grails.plugins.mongodb.MongoDomainClassArtefactHandler]
def watchedResources = [
'file:./grails-app/mongo/**',
]
def doWithSpring = { ApplicationContext ctx ->
// register the mongo bean, which will provide access to configured mongo and morphia instances
mongo(MongoHolderBean) { bean ->
bean.autowire = 'constructor'
}
// register all mongo domains as beans
application.MongoDomainClasses.each { GrailsDomainClass dc ->
// Note the use of Groovy's ability to use dynamic strings in method names!
"${dc.fullName}"(dc.clazz) { bean ->
bean.singleton = false
bean.autowire = "byName"
}
"${dc.fullName}DomainClass"(MethodInvokingFactoryBean) { bean ->
targetObject = ref("grailsApplication", true)
targetMethod = "getArtefact"
bean.lazyInit = true
arguments = [MongoDomainClassArtefactHandler.TYPE, dc.fullName]
}
"${dc.fullName}PersistentClass"(MethodInvokingFactoryBean) { bean ->
targetObject = ref("${dc.fullName}DomainClass")
bean.lazyInit = true
targetMethod = "getClazz"
}
"${dc.fullName}Validator"(GrailsDomainClassValidator) { bean ->
messageSource = ref("messageSource")
bean.lazyInit = true
domainClass = ref("${dc.fullName}DomainClass")
grailsApplication = ref("grailsApplication", true)
}
}
morphiaAuditEntityInterceptor(MorphiaAuditEntityInterceptor)
}
def doWithDynamicMethods = { ApplicationContext ctx ->
Morphia morphia = ctx.getBean('mongo').morphia
Datastore datastore = ctx.getBean('mongo').datastore
application.MongoDomainClasses.each { GrailsDomainClass domainClass ->
try {
if (!(domainClass instanceof MongoDomainClass)) return // process mongo domains only
// add dynamic finders, validation, querying methods etc
MongoPluginSupport.enhanceDomainClass(domainClass, application, ctx)
// add domain class to mapper
println "adding domain " + domainClass.getClazz() + " to morphia"
morphia.map(domainClass.getClazz())
} catch (e) {
log.error ("Error processing mongodb domain $domainClass: " + e.message)
}
}
// add fetch method to morphias Key
com.google.code.morphia.Key.metaClass.fetch = {
// @todo waiting until getClassFromKind works
Class clazz = delegate.kindClass
if (!clazz) {
String kind = delegate.kind
for (MappedClass mc in morphia.getMapper().getMappedClasses()) {
if (mc.getCollectionName().equals(kind)) {
clazz = mc.getClazz()
break
}
}
}
datastore.getByKey(clazz, delegate)
}
MongoPluginSupport.enhanceMorphiaQueryClass()
// add auditing feature
def morphiaAuditInterceptor = ctx.getBean('morphiaAuditEntityInterceptor')
if (morphiaAuditInterceptor instanceof AbstractEntityInterceptor) morphia.getMapper().addInterceptor(morphiaAuditInterceptor)
}
/**
* in order to reload the mongoclasses grails app has to be reloaded
*/
def onChange = {event ->
if (event?.source instanceof Class &&
grails.plugins.mongodb.MongoDomainClassArtefactHandler.isMongoDomainClass(event.source)) {
// reload needed, reregistering spring beans, enhancing domainclass, evaluating constraints etc
log.info("MongoDB domain ${event.source} changed, reloading.")
restartContainer()
}
}
}