Skip to content

Commit 5ed9bed

Browse files
committed
Introducing GroovyWebApplicationContext along the lines of XmlWebApplicationContext and GenericGroovyApplicationContext
Also includes minor dependency updates such as Groovy 2.3.2. Issue: SPR-11371
1 parent e4aabd5 commit 5ed9bed

File tree

4 files changed

+193
-11
lines changed

4 files changed

+193
-11
lines changed

build.gradle

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,25 @@ configure(allprojects) { project ->
1515

1616
ext.aspectjVersion = "1.8.0"
1717
ext.eclipseLinkVersion = "2.4.2"
18-
ext.groovyVersion = "2.3.1"
18+
ext.groovyVersion = "2.3.2"
1919
ext.hibernate3Version = "3.6.10.Final"
2020
ext.hibernate4Version = "4.3.5.Final"
2121
ext.hibVal4Version = "4.3.1.Final"
2222
ext.hibVal5Version = "5.1.1.Final"
2323
ext.hsqldbVersion = "2.3.2"
2424
ext.jackson2Version = "2.3.3"
2525
ext.gsonVersion = "2.2.4"
26-
ext.jasperReportsVersion = "5.5.2"
27-
ext.jettyVersion = "9.1.5.v20140505"
26+
ext.jasperReportsVersion = "5.6.0"
27+
ext.jettyVersion = "9.2.0.v20140526"
2828
ext.jodaVersion = "2.3"
2929
ext.junitVersion = "4.11"
30-
ext.openJpaVersion = "2.2.2"
30+
ext.openJpaVersion = "2.2.2" // 2.3.0 not Java 8 compatible (based on ASM 4)
3131
ext.slf4jVersion = "1.7.7"
3232
ext.snakeYamlVersion = "1.13"
3333
ext.snifferVersion = "1.11"
3434
ext.tiles2Version = "2.2.2"
3535
ext.tiles3Version = "3.0.4"
36-
ext.tomcatVersion = "8.0.5"
36+
ext.tomcatVersion = "8.0.8"
3737
ext.xstreamVersion = "1.4.7"
3838

3939
ext.gradleScriptDir = "${rootProject.projectDir}/gradle"
@@ -604,6 +604,7 @@ project("spring-context-support") {
604604

605605
project("spring-web") {
606606
description = "Spring Web"
607+
apply plugin: "groovy"
607608

608609
dependencies {
609610
compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean
@@ -617,6 +618,7 @@ project("spring-web") {
617618
optional("javax.el:javax.el-api:2.2.5")
618619
optional("javax.faces:javax.faces-api:2.2")
619620
optional("aopalliance:aopalliance:1.0")
621+
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
620622
optional("com.caucho:hessian:4.0.38")
621623
optional("commons-fileupload:commons-fileupload:1.3.1")
622624
optional("org.apache.httpcomponents:httpclient:4.3.3")

spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -210,7 +210,7 @@ public void load(Class<?> relativeClass, String... resourceNames) {
210210
}
211211

212212

213-
// IMPLEMENTATION OF THE GROOVYOBJECT INTERFACE
213+
// Implementation of the GroovyObject interface
214214

215215
public void setMetaClass(MetaClass metaClass) {
216216
this.metaClass = metaClass;
@@ -244,4 +244,3 @@ else if (this.contextWrapper.isReadableProperty(property)) {
244244
}
245245

246246
}
247-
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright 2002-2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.web.context.support;
18+
19+
import java.io.IOException;
20+
21+
import groovy.lang.GroovyObject;
22+
import groovy.lang.GroovySystem;
23+
import groovy.lang.MetaClass;
24+
25+
import org.springframework.beans.BeanWrapper;
26+
import org.springframework.beans.BeanWrapperImpl;
27+
import org.springframework.beans.BeansException;
28+
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
29+
import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
30+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
31+
32+
/**
33+
* {@link org.springframework.web.context.WebApplicationContext} implementation
34+
* which takes its configuration from Groovy bean definition scripts, understood by
35+
* an {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader}.
36+
* This is essentially the equivalent of
37+
* {@link org.springframework.context.support.GenericGroovyApplicationContext}
38+
* for a web environment.
39+
*
40+
* <p>By default, the configuration will be taken from "/WEB-INF/applicationContext.groovy"
41+
* for the root context, and "/WEB-INF/test-servlet.groovy" for a context with the namespace
42+
* "test-servlet" (like for a DispatcherServlet instance with the servlet-name "test").
43+
*
44+
* <p>The config location defaults can be overridden via the "contextConfigLocation"
45+
* context-param of {@link org.springframework.web.context.ContextLoader} and servlet
46+
* init-param of {@link org.springframework.web.servlet.FrameworkServlet}. Config locations
47+
* can either denote concrete files like "/WEB-INF/context.groovy" or Ant-style patterns
48+
* like "/WEB-INF/*-context.groovy" (see {@link org.springframework.util.PathMatcher}
49+
* javadoc for pattern details).
50+
*
51+
* <p>Note: In case of multiple config locations, later bean definitions will
52+
* override ones defined in earlier loaded files. This can be leveraged to
53+
* deliberately override certain bean definitions via an extra Groovy script.
54+
*
55+
* <p><b>For a WebApplicationContext that reads in a different bean definition format,
56+
* create an analogous subclass of {@link AbstractRefreshableWebApplicationContext}.</b>
57+
* Such a context implementation can be specified as "contextClass" context-param
58+
* for ContextLoader or "contextClass" init-param for FrameworkServlet.
59+
*
60+
* @author Juergen Hoeller
61+
* @since 4.1
62+
* @see #setNamespace
63+
* @see #setConfigLocations
64+
* @see org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader
65+
* @see org.springframework.web.context.ContextLoader#initWebApplicationContext
66+
* @see org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext
67+
*/
68+
public class GroovyWebApplicationContext extends AbstractRefreshableWebApplicationContext implements GroovyObject {
69+
70+
/** Default config location for the root context */
71+
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.groovy";
72+
73+
/** Default prefix for building a config location for a namespace */
74+
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
75+
76+
/** Default suffix for building a config location for a namespace */
77+
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".groovy";
78+
79+
80+
private final BeanWrapper contextWrapper = new BeanWrapperImpl(this);
81+
82+
private MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(getClass());
83+
84+
85+
/**
86+
* Loads the bean definitions via an GroovyBeanDefinitionReader.
87+
* @see org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader
88+
* @see #initBeanDefinitionReader
89+
* @see #loadBeanDefinitions
90+
*/
91+
@Override
92+
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
93+
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
94+
GroovyBeanDefinitionReader beanDefinitionReader = new GroovyBeanDefinitionReader(beanFactory);
95+
96+
// Configure the bean definition reader with this context's
97+
// resource loading environment.
98+
beanDefinitionReader.setEnvironment(getEnvironment());
99+
beanDefinitionReader.setResourceLoader(this);
100+
101+
// Allow a subclass to provide custom initialization of the reader,
102+
// then proceed with actually loading the bean definitions.
103+
initBeanDefinitionReader(beanDefinitionReader);
104+
loadBeanDefinitions(beanDefinitionReader);
105+
}
106+
107+
/**
108+
* Initialize the bean definition reader used for loading the bean
109+
* definitions of this context. Default implementation is empty.
110+
* <p>Can be overridden in subclasses.
111+
* @param beanDefinitionReader the bean definition reader used by this context
112+
*/
113+
protected void initBeanDefinitionReader(GroovyBeanDefinitionReader beanDefinitionReader) {
114+
}
115+
116+
/**
117+
* Load the bean definitions with the given GroovyBeanDefinitionReader.
118+
* <p>The lifecycle of the bean factory is handled by the refreshBeanFactory method;
119+
* therefore this method is just supposed to load and/or register bean definitions.
120+
* <p>Delegates to a ResourcePatternResolver for resolving location patterns
121+
* into Resource instances.
122+
* @throws IOException if the required Groovy script isn't found
123+
* @see #refreshBeanFactory
124+
* @see #getConfigLocations
125+
* @see #getResources
126+
* @see #getResourcePatternResolver
127+
*/
128+
protected void loadBeanDefinitions(GroovyBeanDefinitionReader reader) throws IOException {
129+
String[] configLocations = getConfigLocations();
130+
if (configLocations != null) {
131+
for (String configLocation : configLocations) {
132+
reader.loadBeanDefinitions(configLocation);
133+
}
134+
}
135+
}
136+
137+
/**
138+
* The default location for the root context is "/WEB-INF/applicationContext.groovy",
139+
* and "/WEB-INF/test-servlet.groovy" for a context with the namespace "test-servlet"
140+
* (like for a DispatcherServlet instance with the servlet-name "test").
141+
*/
142+
@Override
143+
protected String[] getDefaultConfigLocations() {
144+
if (getNamespace() != null) {
145+
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
146+
}
147+
else {
148+
return new String[] {DEFAULT_CONFIG_LOCATION};
149+
}
150+
}
151+
152+
153+
// Implementation of the GroovyObject interface
154+
155+
public void setMetaClass(MetaClass metaClass) {
156+
this.metaClass = metaClass;
157+
}
158+
159+
public MetaClass getMetaClass() {
160+
return this.metaClass;
161+
}
162+
163+
public Object invokeMethod(String name, Object args) {
164+
return this.metaClass.invokeMethod(this, name, args);
165+
}
166+
167+
public void setProperty(String property, Object newValue) {
168+
this.metaClass.setProperty(this, property, newValue);
169+
}
170+
171+
public Object getProperty(String property) {
172+
if (containsBean(property)) {
173+
return getBean(property);
174+
}
175+
else if (this.contextWrapper.isReadableProperty(property)) {
176+
return this.contextWrapper.getPropertyValue(property);
177+
}
178+
throw new NoSuchBeanDefinitionException(property);
179+
}
180+
181+
}

spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@
2828
* which takes its configuration from XML documents, understood by an
2929
* {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}.
3030
* This is essentially the equivalent of
31-
* {@link org.springframework.context.support.AbstractXmlApplicationContext}
31+
* {@link org.springframework.context.support.GenericXmlApplicationContext}
3232
* for a web environment.
3333
*
3434
* <p>By default, the configuration will be taken from "/WEB-INF/applicationContext.xml"
@@ -112,7 +112,7 @@ protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionRe
112112
* therefore this method is just supposed to load and/or register bean definitions.
113113
* <p>Delegates to a ResourcePatternResolver for resolving location patterns
114114
* into Resource instances.
115-
* @throws java.io.IOException if the required XML document isn't found
115+
* @throws IOException if the required XML document isn't found
116116
* @see #refreshBeanFactory
117117
* @see #getConfigLocations
118118
* @see #getResources

0 commit comments

Comments
 (0)