diff --git a/build.gradle b/build.gradle index b9219d9b403..0fb7ef17c8e 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ configure(allprojects) { project -> ext.aspectjVersion = "1.8.0" ext.eclipseLinkVersion = "2.4.2" - ext.groovyVersion = "2.3.1" + ext.groovyVersion = "2.3.2" ext.hibernate3Version = "3.6.10.Final" ext.hibernate4Version = "4.3.5.Final" ext.hibVal4Version = "4.3.1.Final" @@ -23,17 +23,17 @@ configure(allprojects) { project -> ext.hsqldbVersion = "2.3.2" ext.jackson2Version = "2.3.3" ext.gsonVersion = "2.2.4" - ext.jasperReportsVersion = "5.5.2" - ext.jettyVersion = "9.1.5.v20140505" + ext.jasperReportsVersion = "5.6.0" + ext.jettyVersion = "9.2.0.v20140526" ext.jodaVersion = "2.3" ext.junitVersion = "4.11" - ext.openJpaVersion = "2.2.2" + ext.openJpaVersion = "2.2.2" // 2.3.0 not Java 8 compatible (based on ASM 4) ext.slf4jVersion = "1.7.7" ext.snakeYamlVersion = "1.13" ext.snifferVersion = "1.11" ext.tiles2Version = "2.2.2" ext.tiles3Version = "3.0.4" - ext.tomcatVersion = "8.0.5" + ext.tomcatVersion = "8.0.8" ext.xstreamVersion = "1.4.7" ext.gradleScriptDir = "${rootProject.projectDir}/gradle" @@ -604,6 +604,7 @@ project("spring-context-support") { project("spring-web") { description = "Spring Web" + apply plugin: "groovy" dependencies { compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean @@ -617,6 +618,7 @@ project("spring-web") { optional("javax.el:javax.el-api:2.2.5") optional("javax.faces:javax.faces-api:2.2") optional("aopalliance:aopalliance:1.0") + optional("org.codehaus.groovy:groovy-all:${groovyVersion}") optional("com.caucho:hessian:4.0.38") optional("commons-fileupload:commons-fileupload:1.3.1") optional("org.apache.httpcomponents:httpclient:4.3.3") diff --git a/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java index ba54a71a498..f2b511031f4 100644 --- a/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/GenericGroovyApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -210,7 +210,7 @@ public class GenericGroovyApplicationContext extends GenericApplicationContext i } - // IMPLEMENTATION OF THE GROOVYOBJECT INTERFACE + // Implementation of the GroovyObject interface public void setMetaClass(MetaClass metaClass) { this.metaClass = metaClass; @@ -244,4 +244,3 @@ public class GenericGroovyApplicationContext extends GenericApplicationContext i } } - diff --git a/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java new file mode 100644 index 00000000000..b578ce7647e --- /dev/null +++ b/spring-web/src/main/java/org/springframework/web/context/support/GroovyWebApplicationContext.java @@ -0,0 +1,181 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * 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. + */ + +package org.springframework.web.context.support; + +import java.io.IOException; + +import groovy.lang.GroovyObject; +import groovy.lang.GroovySystem; +import groovy.lang.MetaClass; + +import org.springframework.beans.BeanWrapper; +import org.springframework.beans.BeanWrapperImpl; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; + +/** + * {@link org.springframework.web.context.WebApplicationContext} implementation + * which takes its configuration from Groovy bean definition scripts, understood by + * an {@link org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader}. + * This is essentially the equivalent of + * {@link org.springframework.context.support.GenericGroovyApplicationContext} + * for a web environment. + * + *
By default, the configuration will be taken from "/WEB-INF/applicationContext.groovy" + * for the root context, and "/WEB-INF/test-servlet.groovy" for a context with the namespace + * "test-servlet" (like for a DispatcherServlet instance with the servlet-name "test"). + * + *
The config location defaults can be overridden via the "contextConfigLocation" + * context-param of {@link org.springframework.web.context.ContextLoader} and servlet + * init-param of {@link org.springframework.web.servlet.FrameworkServlet}. Config locations + * can either denote concrete files like "/WEB-INF/context.groovy" or Ant-style patterns + * like "/WEB-INF/*-context.groovy" (see {@link org.springframework.util.PathMatcher} + * javadoc for pattern details). + * + *
Note: In case of multiple config locations, later bean definitions will + * override ones defined in earlier loaded files. This can be leveraged to + * deliberately override certain bean definitions via an extra Groovy script. + * + *
For a WebApplicationContext that reads in a different bean definition format, + * create an analogous subclass of {@link AbstractRefreshableWebApplicationContext}. + * Such a context implementation can be specified as "contextClass" context-param + * for ContextLoader or "contextClass" init-param for FrameworkServlet. + * + * @author Juergen Hoeller + * @since 4.1 + * @see #setNamespace + * @see #setConfigLocations + * @see org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader + * @see org.springframework.web.context.ContextLoader#initWebApplicationContext + * @see org.springframework.web.servlet.FrameworkServlet#initWebApplicationContext + */ +public class GroovyWebApplicationContext extends AbstractRefreshableWebApplicationContext implements GroovyObject { + + /** Default config location for the root context */ + public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.groovy"; + + /** Default prefix for building a config location for a namespace */ + public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; + + /** Default suffix for building a config location for a namespace */ + public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".groovy"; + + + private final BeanWrapper contextWrapper = new BeanWrapperImpl(this); + + private MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(getClass()); + + + /** + * Loads the bean definitions via an GroovyBeanDefinitionReader. + * @see org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader + * @see #initBeanDefinitionReader + * @see #loadBeanDefinitions + */ + @Override + protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { + // Create a new XmlBeanDefinitionReader for the given BeanFactory. + GroovyBeanDefinitionReader beanDefinitionReader = new GroovyBeanDefinitionReader(beanFactory); + + // Configure the bean definition reader with this context's + // resource loading environment. + beanDefinitionReader.setEnvironment(getEnvironment()); + beanDefinitionReader.setResourceLoader(this); + + // Allow a subclass to provide custom initialization of the reader, + // then proceed with actually loading the bean definitions. + initBeanDefinitionReader(beanDefinitionReader); + loadBeanDefinitions(beanDefinitionReader); + } + + /** + * Initialize the bean definition reader used for loading the bean + * definitions of this context. Default implementation is empty. + *
Can be overridden in subclasses. + * @param beanDefinitionReader the bean definition reader used by this context + */ + protected void initBeanDefinitionReader(GroovyBeanDefinitionReader beanDefinitionReader) { + } + + /** + * Load the bean definitions with the given GroovyBeanDefinitionReader. + *
The lifecycle of the bean factory is handled by the refreshBeanFactory method; + * therefore this method is just supposed to load and/or register bean definitions. + *
Delegates to a ResourcePatternResolver for resolving location patterns + * into Resource instances. + * @throws IOException if the required Groovy script isn't found + * @see #refreshBeanFactory + * @see #getConfigLocations + * @see #getResources + * @see #getResourcePatternResolver + */ + protected void loadBeanDefinitions(GroovyBeanDefinitionReader reader) throws IOException { + String[] configLocations = getConfigLocations(); + if (configLocations != null) { + for (String configLocation : configLocations) { + reader.loadBeanDefinitions(configLocation); + } + } + } + + /** + * The default location for the root context is "/WEB-INF/applicationContext.groovy", + * and "/WEB-INF/test-servlet.groovy" for a context with the namespace "test-servlet" + * (like for a DispatcherServlet instance with the servlet-name "test"). + */ + @Override + protected String[] getDefaultConfigLocations() { + if (getNamespace() != null) { + return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; + } + else { + return new String[] {DEFAULT_CONFIG_LOCATION}; + } + } + + + // Implementation of the GroovyObject interface + + public void setMetaClass(MetaClass metaClass) { + this.metaClass = metaClass; + } + + public MetaClass getMetaClass() { + return this.metaClass; + } + + public Object invokeMethod(String name, Object args) { + return this.metaClass.invokeMethod(this, name, args); + } + + public void setProperty(String property, Object newValue) { + this.metaClass.setProperty(this, property, newValue); + } + + public Object getProperty(String property) { + if (containsBean(property)) { + return getBean(property); + } + else if (this.contextWrapper.isReadableProperty(property)) { + return this.contextWrapper.getPropertyValue(property); + } + throw new NoSuchBeanDefinitionException(property); + } + +} diff --git a/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java b/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java index faa9475676e..080f2e92ee5 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/XmlWebApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; * which takes its configuration from XML documents, understood by an * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader}. * This is essentially the equivalent of - * {@link org.springframework.context.support.AbstractXmlApplicationContext} + * {@link org.springframework.context.support.GenericXmlApplicationContext} * for a web environment. * *
By default, the configuration will be taken from "/WEB-INF/applicationContext.xml" @@ -112,7 +112,7 @@ public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationC * therefore this method is just supposed to load and/or register bean definitions. *
Delegates to a ResourcePatternResolver for resolving location patterns * into Resource instances. - * @throws java.io.IOException if the required XML document isn't found + * @throws IOException if the required XML document isn't found * @see #refreshBeanFactory * @see #getConfigLocations * @see #getResources