forked from krasserm/grails-jaxrs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
JaxrsGrailsPlugin.groovy
247 lines (212 loc) · 8.53 KB
/
JaxrsGrailsPlugin.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
import static org.grails.jaxrs.web.JaxrsUtils.JAXRS_CONTEXT_NAME;
import org.codehaus.groovy.grails.commons.ConfigurationHolder
import org.grails.jaxrs.DefaultGrailsResourceClass
import org.grails.jaxrs.ProviderArtefactHandler
import org.grails.jaxrs.ResourceArtefactHandler
import org.grails.jaxrs.generator.CodeGenerator
import org.grails.jaxrs.provider.DomainObjectReader
import org.grails.jaxrs.provider.DomainObjectWriter
import org.grails.jaxrs.provider.JSONReader
import org.grails.jaxrs.provider.JSONWriter
import org.grails.jaxrs.provider.XMLReader
import org.grails.jaxrs.provider.XMLWriter
import org.grails.jaxrs.web.JaxrsContext
import org.grails.jaxrs.web.JaxrsFilter
import org.grails.jaxrs.web.JaxrsListener
class JaxrsGrailsPlugin {
// the plugin version
def version = "0.6"
// the version or versions of Grails the plugin is designed for
def grailsVersion = "2.0 > *"
// the other plugins this plugin depends on
def dependsOn = [:]
// resources that are excluded from plugin packaging
def pluginExcludes = [
"grails-app/domain/*",
"grails-app/providers/*",
"grails-app/resources/*",
"grails-app/views/error.gsp",
"lib/*-sources.jar"
]
def loadAfter = ['controllers','services','spring-security-core']
def artefacts = [
new ResourceArtefactHandler(),
new ProviderArtefactHandler()
]
def watchedResources = [
"file:./grails-app/resources/**/*Resource.groovy",
"file:./grails-app/providers/**/*Reader.groovy",
"file:./grails-app/providers/**/*Writer.groovy",
"file:./plugins/*/grails-app/resources/**/*Resource.groovy",
"file:./plugins/*/grails-app/providers/**/*Reader.groovy",
"file:./plugins/*/grails-app/providers/**/*Writer.groovy"
]
def author = "Martin Krasser"
def authorEmail = "[email protected]"
def title = "JSR 311 plugin"
def description = """
A plugin that supports the development of RESTful web services based on the
Java API for RESTful Web Services (JSR 311: JAX-RS). It is targeted at
developers who want to structure the web service layer of an application in
a JSR 311 compatible way but still want to continue to use Grails' powerful
features such as GORM, automated XML and JSON marshalling, Grails services,
Grails filters and so on. This plugin is an alternative to Grails' built-in
mechanism for implementing RESTful web services.
At the moment, plugin users may choose between Jersey and Restlet as JAX-RS
implementation. Both implementations are packaged with the plugin. Support for
Restlet was added in version 0.2 of the plugin in order to support deployments
on the Google App Engine. Other JAX-RS implementations such as RestEasy or
Apache Wink are likely to be added in upcoming versions of the plugin.
"""
// URL to the plugin's documentation
def documentation = 'http://code.google.com/p/grails-jaxrs/'
/**
* Adds the JaxrsFilter and JaxrsListener to the web application
* descriptor.
*/
def doWithWebDescriptor = { xml ->
def lastListener = xml.'listener'.iterator().toList().last()
lastListener + {
'listener' {
'listener-class'(JaxrsListener.class.name)
}
}
def firstFilter = xml.'filter'[0]
firstFilter + {
'filter' {
'filter-name'('jaxrsFilter')
'filter-class'(JaxrsFilter.class.name)
}
}
def firstFilterMapping = xml.'filter-mapping'[0]
firstFilterMapping + {
'filter-mapping' {
'filter-name'('jaxrsFilter')
'url-pattern'('/*')
'dispatcher'('FORWARD')
'dispatcher'('REQUEST')
}
}
}
/**
* Adds the JaxrsContext and plugin- and application-specific JAX-RS
* resource and provider classes to the application context.
*/
def doWithSpring = {
// Configure the JAX-RS context
'jaxrsContext'(JaxrsContext)
// Configure default providers
"${XMLWriter.class.name}"(XMLWriter)
"${XMLReader.class.name}"(XMLReader)
"${JSONWriter.class.name}"(JSONWriter)
"${JSONReader.class.name}"(JSONReader)
"${DomainObjectReader.class.name}"(DomainObjectReader)
"${DomainObjectWriter.class.name}"(DomainObjectWriter)
// Configure application-provided resources
application.resourceClasses.each { rc ->
"${rc.propertyName}"(rc.clazz) { bean ->
bean.scope = this.resourceScope
bean.autowire = true
}
}
// Configure application-provided providers
application.providerClasses.each { pc ->
"${pc.propertyName}"(pc.clazz) { bean ->
bean.scope = 'singleton'
bean.autowire = true
}
}
// Configure the resource code generator
"${CodeGenerator.class.name}"(CodeGenerator)
}
/**
* Updates application-specific JAX-RS resource and provider classes in
* the application context.
*/
def onChange = { event ->
if (!event.ctx) {
return
}
if (application.isArtefactOfType(ResourceArtefactHandler.TYPE, event.source)) {
def resourceClass = application.addArtefact(ResourceArtefactHandler.TYPE, event.source)
beans {
"${resourceClass.propertyName}"(resourceClass.clazz) { bean ->
bean.scope = this.resourceScope
bean.autowire = true
}
}.registerBeans(event.ctx)
} else if (application.isArtefactOfType(ProviderArtefactHandler.TYPE, event.source)) {
def providerClass = application.addArtefact(ProviderArtefactHandler.TYPE, event.source)
beans {
"${providerClass.propertyName}"(providerClass.clazz) { bean ->
bean.scope = 'singleton'
bean.autowire = true
}
}.registerBeans(event.ctx)
} else {
return
}
// Setup the JaxrsConfig
doWithApplicationContext(event.ctx)
// Resfresh the JaxrsContext
event.ctx.getBean(JAXRS_CONTEXT_NAME).refresh()
}
/**
* Reconfigures the JaxrsConfig with plugin- and application-specific
* JAX-RS resource and provider classes. Configures the JaxrsContext
* with the JAX-RS implementation to use. The name of the JAX-RS
* implementation is obtained from the configuration property
* <code>org.grails.jaxrs.provider.name</code>. Default value is
* <code>jersey</code>.
*/
def doWithApplicationContext = { applicationContext ->
def context = applicationContext.getBean(JAXRS_CONTEXT_NAME)
def config = context.jaxrsConfig
context.jaxrsProviderName = this.providerName
context.jaxrsProviderExtraPaths = this.providerExtraPaths
context.jaxrsProviderInitParameters = this.providerInitParameters
config.reset()
config.classes << XMLWriter.class
config.classes << XMLReader.class
config.classes << JSONWriter.class
config.classes << JSONReader.class
config.classes << DomainObjectReader.class
config.classes << DomainObjectWriter.class
application.getArtefactInfo('Resource').classesByName.values().each { clazz ->
config.classes << clazz
}
application.getArtefactInfo('Provider').classesByName.values().each { clazz ->
config.classes << clazz
}
}
/**
*
*/
def doWithDynamicMethods = { ctx ->
}
/**
*
*/
def onConfigChange = { event ->
}
private String getResourceScope() {
def scope = ConfigurationHolder.config.org.grails.jaxrs.resource.scope
if (!scope) {
scope = 'prototype'
}
scope
}
private String getProviderName() {
def name = ConfigurationHolder.config.org.grails.jaxrs.provider.name
if (!name) {
name = JaxrsContext.JAXRS_PROVIDER_NAME_JERSEY
}
name
}
private String getProviderExtraPaths() {
ConfigurationHolder.config.org.grails.jaxrs.provider.extra.paths
}
private Map<String, String> getProviderInitParameters() {
ConfigurationHolder.config.org.grails.jaxrs.provider.init.parameters
}
}