Drop deprecated dependencies on Log4j, JRuby, JExcel, Burlap, Commons Pool/DBCP
This commit also removes outdated support classes for Oracle, GlassFish, JBoss. Issue: SPR-14429
This commit is contained in:
parent
fb5a096ca2
commit
0fc0ce78ae
17
build.gradle
17
build.gradle
|
|
@ -54,12 +54,10 @@ configure(allprojects) { project ->
|
|||
ext.javamailVersion = "1.5.5"
|
||||
ext.jettyVersion = "9.3.10.v20160621"
|
||||
ext.jodaVersion = "2.9.4"
|
||||
ext.jrubyVersion = "1.7.25" // JRuby 9000 only supported through JSR-223 (StandardScriptFactory)
|
||||
ext.jtaVersion = "1.2"
|
||||
ext.junitVersion = "4.12"
|
||||
ext.junitJupiterVersion = '5.0.0-SNAPSHOT'
|
||||
ext.junitPlatformVersion = '1.0.0-SNAPSHOT'
|
||||
ext.log4jVersion = "1.2.17"
|
||||
ext.nettyVersion = "4.1.1.Final"
|
||||
ext.okhttpVersion = "2.7.5"
|
||||
ext.okhttp3Version = "3.3.1"
|
||||
|
|
@ -189,8 +187,6 @@ configure(allprojects) { project ->
|
|||
"http://glassfish.java.net/nonav/docs/v3/api/",
|
||||
"http://docs.jboss.org/jbossas/javadoc/4.0.5/connector/",
|
||||
"http://docs.jboss.org/jbossas/javadoc/7.1.2.Final/",
|
||||
"http://commons.apache.org/proper/commons-lang/javadocs/api-2.5/",
|
||||
"http://commons.apache.org/proper/commons-dbcp/apidocs/",
|
||||
"http://tiles.apache.org/tiles-request/apidocs/",
|
||||
"http://tiles.apache.org/framework/apidocs/",
|
||||
"http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/",
|
||||
|
|
@ -348,7 +344,6 @@ project("spring-core") {
|
|||
compile("commons-logging:commons-logging:1.2")
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("net.sf.jopt-simple:jopt-simple:5.0.2")
|
||||
optional("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
testCompile("com.fasterxml.woodstox:woodstox-core:5.0.2") {
|
||||
|
|
@ -379,7 +374,6 @@ project("spring-beans") {
|
|||
optional("javax.inject:javax.inject:1")
|
||||
optional("javax.el:javax.el-api:2.2.5")
|
||||
optional("org.yaml:snakeyaml:${snakeyamlVersion}")
|
||||
testCompile("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
}
|
||||
}
|
||||
|
|
@ -419,7 +413,6 @@ project("spring-aop") {
|
|||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
compile(files(project(":spring-core").objenesisRepackJar))
|
||||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("commons-pool:commons-pool:1.6")
|
||||
optional("org.apache.commons:commons-pool2:2.4.2")
|
||||
optional("com.jamonapi:jamon:2.81")
|
||||
}
|
||||
|
|
@ -469,12 +462,10 @@ project("spring-context") {
|
|||
optional("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
optional("org.beanshell:bsh:2.0b4")
|
||||
optional("org.jruby:jruby:${jrubyVersion}")
|
||||
testCompile("javax.inject:javax.inject-tck:1")
|
||||
testCompile("javax.el:javax.el-api:2.2.5")
|
||||
testCompile("org.glassfish.web:javax.el:2.2.6")
|
||||
testCompile("org.javamoney:moneta:1.1")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("org.apache.commons:commons-pool2:2.4.2")
|
||||
testCompile("org.slf4j:slf4j-api:${slf4jVersion}")
|
||||
}
|
||||
|
|
@ -513,8 +504,6 @@ project("spring-messaging") {
|
|||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("xmlunit:xmlunit:${xmlunitVersion}")
|
||||
}
|
||||
|
|
@ -692,7 +681,6 @@ project("spring-web") {
|
|||
optional("org.eclipse.jetty:jetty-server:${jettyVersion}") {
|
||||
exclude group: "javax.servlet", module: "javax.servlet-api"
|
||||
}
|
||||
optional("log4j:log4j:${log4jVersion}")
|
||||
optional("com.google.protobuf:protobuf-java:2.6.1")
|
||||
optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.4")
|
||||
optional("javax.mail:javax.mail-api:${javamailVersion}")
|
||||
|
|
@ -727,7 +715,6 @@ project("spring-orm") {
|
|||
}
|
||||
optional("org.hibernate:hibernate-core:${hibernate5Version}")
|
||||
optional("javax.servlet:javax.servlet-api:3.0.1")
|
||||
testCompile("commons-dbcp:commons-dbcp:1.4")
|
||||
testCompile("org.aspectj:aspectjweaver:${aspectjVersion}")
|
||||
testCompile("org.hsqldb:hsqldb:${hsqldbVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
|
|
@ -750,7 +737,6 @@ project("spring-webmvc") {
|
|||
optional(project(":spring-oxm")) // for MarshallingView
|
||||
optional("javax.servlet.jsp:javax.servlet.jsp-api:2.2.1")
|
||||
optional("javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1")
|
||||
optional("net.sourceforge.jexcelapi:jxl:2.6.12")
|
||||
optional("org.apache.poi:poi:${poiVersion}")
|
||||
optional("org.apache.poi:poi-ooxml:${poiVersion}")
|
||||
optional("org.freemarker:freemarker:${freemarkerVersion}")
|
||||
|
|
@ -808,7 +794,6 @@ project("spring-webmvc") {
|
|||
testCompile("commons-io:commons-io:1.3")
|
||||
testCompile("joda-time:joda-time:${jodaVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
testCompile("org.jruby:jruby:${jrubyVersion}")
|
||||
testCompile("org.python:jython-standalone:2.5.3")
|
||||
testCompile("org.mozilla:rhino:1.7.7.1")
|
||||
testCompile("org.webjars:underscorejs:1.8.3")
|
||||
|
|
@ -855,7 +840,6 @@ project("spring-websocket") {
|
|||
testCompile("org.apache.tomcat.embed:tomcat-embed-websocket:${tomcatVersion}")
|
||||
testCompile("io.projectreactor:reactor-net:${reactorVersion}")
|
||||
testCompile("io.netty:netty-all:${nettyVersion}")
|
||||
testCompile("log4j:log4j:${log4jVersion}")
|
||||
testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}")
|
||||
}
|
||||
}
|
||||
|
|
@ -917,7 +901,6 @@ project("spring-test") {
|
|||
testCompile("org.apache.httpcomponents:httpclient:${httpclientVersion}")
|
||||
testCompile("javax.cache:cache-api:1.0.0")
|
||||
testRuntime("org.junit.jupiter:junit-jupiter-engine:${junitJupiterVersion}")
|
||||
testRuntime("log4j:log4j:${log4jVersion}")
|
||||
|
||||
testRuntime("org.ehcache:ehcache:${ehcache3Version}")
|
||||
testRuntime("org.terracotta:management-model:2.0.0")
|
||||
|
|
|
|||
|
|
@ -1,307 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.aop.target;
|
||||
|
||||
import org.apache.commons.pool.ObjectPool;
|
||||
import org.apache.commons.pool.PoolableObjectFactory;
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.core.Constants;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.aop.TargetSource} implementation that holds
|
||||
* objects in a configurable Apache Commons Pool.
|
||||
*
|
||||
* <p>By default, an instance of {@code GenericObjectPool} is created.
|
||||
* Subclasses may change the type of {@code ObjectPool} used by
|
||||
* overriding the {@code createObjectPool()} method.
|
||||
*
|
||||
* <p>Provides many configuration properties mirroring those of the Commons Pool
|
||||
* {@code GenericObjectPool} class; these properties are passed to the
|
||||
* {@code GenericObjectPool} during construction. If creating a subclass of this
|
||||
* class to change the {@code ObjectPool} implementation type, pass in the values
|
||||
* of configuration properties that are relevant to your chosen implementation.
|
||||
*
|
||||
* <p>The {@code testOnBorrow}, {@code testOnReturn} and {@code testWhileIdle}
|
||||
* properties are explicitly not mirrored because the implementation of
|
||||
* {@code PoolableObjectFactory} used by this class does not implement
|
||||
* meaningful validation. All exposed Commons Pool properties use the
|
||||
* corresponding Commons Pool defaults.
|
||||
*
|
||||
* <p>Compatible with Apache Commons Pool 1.5.x and 1.6.
|
||||
* Note that this class doesn't declare Commons Pool 1.6's generic type
|
||||
* in order to remain compatible with Commons Pool 1.5.x at runtime.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @see GenericObjectPool
|
||||
* @see #createObjectPool()
|
||||
* @see #setMaxSize
|
||||
* @see #setMaxIdle
|
||||
* @see #setMinIdle
|
||||
* @see #setMaxWait
|
||||
* @see #setTimeBetweenEvictionRunsMillis
|
||||
* @see #setMinEvictableIdleTimeMillis
|
||||
* @deprecated as of Spring 4.2, in favor of {@link CommonsPool2TargetSource}
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked", "serial"})
|
||||
@Deprecated
|
||||
public class CommonsPoolTargetSource extends AbstractPoolingTargetSource implements PoolableObjectFactory {
|
||||
|
||||
private static final Constants constants = new Constants(GenericObjectPool.class);
|
||||
|
||||
|
||||
private int maxIdle = GenericObjectPool.DEFAULT_MAX_IDLE;
|
||||
|
||||
private int minIdle = GenericObjectPool.DEFAULT_MIN_IDLE;
|
||||
|
||||
private long maxWait = GenericObjectPool.DEFAULT_MAX_WAIT;
|
||||
|
||||
private long timeBetweenEvictionRunsMillis = GenericObjectPool.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
|
||||
|
||||
private long minEvictableIdleTimeMillis = GenericObjectPool.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
|
||||
|
||||
private byte whenExhaustedAction = GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION;
|
||||
|
||||
/**
|
||||
* The Apache Commons {@code ObjectPool} used to pool target objects
|
||||
*/
|
||||
private ObjectPool pool;
|
||||
|
||||
|
||||
/**
|
||||
* Create a CommonsPoolTargetSource with default settings.
|
||||
* Default maximum size of the pool is 8.
|
||||
* @see #setMaxSize
|
||||
* @see GenericObjectPool#setMaxActive
|
||||
*/
|
||||
public CommonsPoolTargetSource() {
|
||||
setMaxSize(GenericObjectPool.DEFAULT_MAX_ACTIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of idle objects in the pool.
|
||||
* Default is 8.
|
||||
* @see GenericObjectPool#setMaxIdle
|
||||
*/
|
||||
public void setMaxIdle(int maxIdle) {
|
||||
this.maxIdle = maxIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of idle objects in the pool.
|
||||
*/
|
||||
public int getMaxIdle() {
|
||||
return this.maxIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum number of idle objects in the pool.
|
||||
* Default is 0.
|
||||
* @see GenericObjectPool#setMinIdle
|
||||
*/
|
||||
public void setMinIdle(int minIdle) {
|
||||
this.minIdle = minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum number of idle objects in the pool.
|
||||
*/
|
||||
public int getMinIdle() {
|
||||
return this.minIdle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum waiting time for fetching an object from the pool.
|
||||
* Default is -1, waiting forever.
|
||||
* @see GenericObjectPool#setMaxWait
|
||||
*/
|
||||
public void setMaxWait(long maxWait) {
|
||||
this.maxWait = maxWait;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum waiting time for fetching an object from the pool.
|
||||
*/
|
||||
public long getMaxWait() {
|
||||
return this.maxWait;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time between eviction runs that check idle objects whether
|
||||
* they have been idle for too long or have become invalid.
|
||||
* Default is -1, not performing any eviction.
|
||||
* @see GenericObjectPool#setTimeBetweenEvictionRunsMillis
|
||||
*/
|
||||
public void setTimeBetweenEvictionRunsMillis(long timeBetweenEvictionRunsMillis) {
|
||||
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time between eviction runs that check idle objects.
|
||||
*/
|
||||
public long getTimeBetweenEvictionRunsMillis() {
|
||||
return this.timeBetweenEvictionRunsMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum time that an idle object can sit in the pool before
|
||||
* it becomes subject to eviction. Default is 1800000 (30 minutes).
|
||||
* <p>Note that eviction runs need to be performed to take this
|
||||
* setting into effect.
|
||||
* @see #setTimeBetweenEvictionRunsMillis
|
||||
* @see GenericObjectPool#setMinEvictableIdleTimeMillis
|
||||
*/
|
||||
public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
|
||||
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum time that an idle object can sit in the pool.
|
||||
*/
|
||||
public long getMinEvictableIdleTimeMillis() {
|
||||
return this.minEvictableIdleTimeMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action to take when the pool is exhausted. Uses the
|
||||
* constant names defined in Commons Pool's GenericObjectPool class:
|
||||
* "WHEN_EXHAUSTED_BLOCK", "WHEN_EXHAUSTED_FAIL", "WHEN_EXHAUSTED_GROW".
|
||||
* @see #setWhenExhaustedAction(byte)
|
||||
*/
|
||||
public void setWhenExhaustedActionName(String whenExhaustedActionName) {
|
||||
setWhenExhaustedAction(constants.asNumber(whenExhaustedActionName).byteValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action to take when the pool is exhausted. Uses the
|
||||
* constant values defined in Commons Pool's GenericObjectPool class.
|
||||
* @see GenericObjectPool#setWhenExhaustedAction(byte)
|
||||
* @see GenericObjectPool#WHEN_EXHAUSTED_BLOCK
|
||||
* @see GenericObjectPool#WHEN_EXHAUSTED_FAIL
|
||||
* @see GenericObjectPool#WHEN_EXHAUSTED_GROW
|
||||
*/
|
||||
public void setWhenExhaustedAction(byte whenExhaustedAction) {
|
||||
this.whenExhaustedAction = whenExhaustedAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the action to take when the pool is exhausted.
|
||||
*/
|
||||
public byte getWhenExhaustedAction() {
|
||||
return whenExhaustedAction;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates and holds an ObjectPool instance.
|
||||
* @see #createObjectPool()
|
||||
*/
|
||||
@Override
|
||||
protected final void createPool() {
|
||||
logger.debug("Creating Commons object pool");
|
||||
this.pool = createObjectPool();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses can override this if they want to return a specific Commons pool.
|
||||
* They should apply any configuration properties to the pool here.
|
||||
* <p>Default is a GenericObjectPool instance with the given pool size.
|
||||
* @return an empty Commons {@code ObjectPool}.
|
||||
* @see org.apache.commons.pool.impl.GenericObjectPool
|
||||
* @see #setMaxSize
|
||||
*/
|
||||
protected ObjectPool createObjectPool() {
|
||||
GenericObjectPool gop = new GenericObjectPool(this);
|
||||
gop.setMaxActive(getMaxSize());
|
||||
gop.setMaxIdle(getMaxIdle());
|
||||
gop.setMinIdle(getMinIdle());
|
||||
gop.setMaxWait(getMaxWait());
|
||||
gop.setTimeBetweenEvictionRunsMillis(getTimeBetweenEvictionRunsMillis());
|
||||
gop.setMinEvictableIdleTimeMillis(getMinEvictableIdleTimeMillis());
|
||||
gop.setWhenExhaustedAction(getWhenExhaustedAction());
|
||||
return gop;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Borrow an object from the {@code ObjectPool}.
|
||||
*/
|
||||
@Override
|
||||
public Object getTarget() throws Exception {
|
||||
return this.pool.borrowObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified object to the underlying {@code ObjectPool}.
|
||||
*/
|
||||
@Override
|
||||
public void releaseTarget(Object target) throws Exception {
|
||||
this.pool.returnObject(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getActiveCount() throws UnsupportedOperationException {
|
||||
return this.pool.getNumActive();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIdleCount() throws UnsupportedOperationException {
|
||||
return this.pool.getNumIdle();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closes the underlying {@code ObjectPool} when destroying this object.
|
||||
*/
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
logger.debug("Closing Commons ObjectPool");
|
||||
this.pool.close();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Implementation of org.apache.commons.pool.PoolableObjectFactory interface
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public Object makeObject() throws BeansException {
|
||||
return newPrototypeInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(Object obj) throws Exception {
|
||||
destroyPrototypeInstance(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(Object obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(Object obj) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(Object obj) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.aop.target;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.tests.sample.beans.ITestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.tests.TestResourceUtils.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class CommonsPoolTargetSourceProxyTests {
|
||||
|
||||
private static final Resource CONTEXT =
|
||||
qualifiedResource(CommonsPoolTargetSourceProxyTests.class, "context.xml");
|
||||
|
||||
@Test
|
||||
public void testProxy() throws Exception {
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
|
||||
reader.loadBeanDefinitions(CONTEXT);
|
||||
beanFactory.preInstantiateSingletons();
|
||||
ITestBean bean = (ITestBean)beanFactory.getBean("testBean");
|
||||
assertTrue(AopUtils.isAopProxy(bean));
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,6 @@ public class LangNamespaceHandler extends NamespaceHandlerSupport {
|
|||
@Override
|
||||
public void init() {
|
||||
registerScriptBeanDefinitionParser("groovy", "org.springframework.scripting.groovy.GroovyScriptFactory");
|
||||
registerScriptBeanDefinitionParser("jruby", "org.springframework.scripting.jruby.JRubyScriptFactory");
|
||||
registerScriptBeanDefinitionParser("bsh", "org.springframework.scripting.bsh.BshScriptFactory");
|
||||
registerScriptBeanDefinitionParser("std", "org.springframework.scripting.support.StandardScriptFactory");
|
||||
registerBeanDefinitionParser("defaults", new ScriptingDefaultsParser());
|
||||
|
|
|
|||
|
|
@ -1,141 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.scripting.jruby;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jruby.RubyException;
|
||||
import org.jruby.exceptions.JumpException;
|
||||
import org.jruby.exceptions.RaiseException;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.scripting.ScriptCompilationException;
|
||||
import org.springframework.scripting.ScriptFactory;
|
||||
import org.springframework.scripting.ScriptSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.scripting.ScriptFactory} implementation
|
||||
* for a JRuby script.
|
||||
*
|
||||
* <p>Typically used in combination with a
|
||||
* {@link org.springframework.scripting.support.ScriptFactoryPostProcessor};
|
||||
* see the latter's javadoc for a configuration example.
|
||||
*
|
||||
* <p>Note: Spring 4.0 supports JRuby 1.5 and higher.
|
||||
* As of Spring 4.2, JRuby 9.0.0.0 is supported but only through
|
||||
* {@link org.springframework.scripting.support.StandardScriptFactory}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @since 2.0
|
||||
* @see JRubyScriptUtils
|
||||
* @see org.springframework.scripting.support.ScriptFactoryPostProcessor
|
||||
* @deprecated in favor of JRuby support via the JSR-223 abstraction
|
||||
* ({@link org.springframework.scripting.support.StandardScriptFactory})
|
||||
*/
|
||||
@Deprecated
|
||||
public class JRubyScriptFactory implements ScriptFactory, BeanClassLoaderAware {
|
||||
|
||||
private final String scriptSourceLocator;
|
||||
|
||||
private final Class<?>[] scriptInterfaces;
|
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
|
||||
/**
|
||||
* Create a new JRubyScriptFactory for the given script source.
|
||||
* @param scriptSourceLocator a locator that points to the source of the script.
|
||||
* Interpreted by the post-processor that actually creates the script.
|
||||
* @param scriptInterfaces the Java interfaces that the scripted object
|
||||
* is supposed to implement
|
||||
*/
|
||||
public JRubyScriptFactory(String scriptSourceLocator, Class<?>... scriptInterfaces) {
|
||||
Assert.hasText(scriptSourceLocator, "'scriptSourceLocator' must not be empty");
|
||||
Assert.notEmpty(scriptInterfaces, "'scriptInterfaces' must not be empty");
|
||||
this.scriptSourceLocator = scriptSourceLocator;
|
||||
this.scriptInterfaces = scriptInterfaces;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getScriptSourceLocator() {
|
||||
return this.scriptSourceLocator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?>[] getScriptInterfaces() {
|
||||
return this.scriptInterfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* JRuby scripts do require a config interface.
|
||||
*/
|
||||
@Override
|
||||
public boolean requiresConfigInterface() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and parse the JRuby script via JRubyScriptUtils.
|
||||
* @see JRubyScriptUtils#createJRubyObject(String, Class[], ClassLoader)
|
||||
*/
|
||||
@Override
|
||||
public Object getScriptedObject(ScriptSource scriptSource, Class<?>... actualInterfaces)
|
||||
throws IOException, ScriptCompilationException {
|
||||
try {
|
||||
return JRubyScriptUtils.createJRubyObject(
|
||||
scriptSource.getScriptAsString(), actualInterfaces, this.beanClassLoader);
|
||||
}
|
||||
catch (RaiseException ex) {
|
||||
RubyException rubyEx = ex.getException();
|
||||
String msg = (rubyEx != null && rubyEx.message != null) ?
|
||||
rubyEx.message.toString() : "Unexpected JRuby error";
|
||||
throw new ScriptCompilationException(scriptSource, msg, ex);
|
||||
}
|
||||
catch (JumpException ex) {
|
||||
throw new ScriptCompilationException(scriptSource, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getScriptedObjectType(ScriptSource scriptSource)
|
||||
throws IOException, ScriptCompilationException {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresScriptedObjectRefresh(ScriptSource scriptSource) {
|
||||
return scriptSource.isModified();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JRubyScriptFactory: script source locator [" + this.scriptSourceLocator + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.scripting.jruby;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jruby.Ruby;
|
||||
import org.jruby.RubyArray;
|
||||
import org.jruby.RubyNil;
|
||||
import org.jruby.ast.ClassNode;
|
||||
import org.jruby.ast.Colon2Node;
|
||||
import org.jruby.ast.NewlineNode;
|
||||
import org.jruby.ast.Node;
|
||||
import org.jruby.exceptions.JumpException;
|
||||
import org.jruby.exceptions.RaiseException;
|
||||
import org.jruby.javasupport.JavaEmbedUtils;
|
||||
import org.jruby.runtime.builtin.IRubyObject;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility methods for handling JRuby-scripted objects.
|
||||
*
|
||||
* <p>Note: Spring 4.0 supports JRuby 1.5 and higher.
|
||||
* As of Spring 4.2, JRuby 9.0.0.0 is supported but only through
|
||||
* {@link org.springframework.scripting.support.StandardScriptFactory}.
|
||||
*
|
||||
* @author Rob Harrop
|
||||
* @author Juergen Hoeller
|
||||
* @author Rick Evans
|
||||
* @since 2.0
|
||||
* @deprecated in favor of JRuby support via the JSR-223 abstraction
|
||||
* ({@link org.springframework.scripting.support.StandardScriptFactory})
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class JRubyScriptUtils {
|
||||
|
||||
/**
|
||||
* Create a new JRuby-scripted object from the given script source,
|
||||
* using the default {@link ClassLoader}.
|
||||
* @param scriptSource the script source text
|
||||
* @param interfaces the interfaces that the scripted Java object is to implement
|
||||
* @return the scripted Java object
|
||||
* @throws JumpException in case of JRuby parsing failure
|
||||
* @see ClassUtils#getDefaultClassLoader()
|
||||
*/
|
||||
public static Object createJRubyObject(String scriptSource, Class<?>... interfaces) throws JumpException {
|
||||
return createJRubyObject(scriptSource, interfaces, ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new JRuby-scripted object from the given script source.
|
||||
* @param scriptSource the script source text
|
||||
* @param interfaces the interfaces that the scripted Java object is to implement
|
||||
* @param classLoader the {@link ClassLoader} to create the script proxy with
|
||||
* @return the scripted Java object
|
||||
* @throws JumpException in case of JRuby parsing failure
|
||||
*/
|
||||
public static Object createJRubyObject(String scriptSource, Class<?>[] interfaces, ClassLoader classLoader) {
|
||||
Ruby ruby = initializeRuntime();
|
||||
|
||||
Node scriptRootNode = ruby.parseEval(scriptSource, "", null, 0);
|
||||
IRubyObject rubyObject = ruby.runNormally(scriptRootNode);
|
||||
|
||||
if (rubyObject instanceof RubyNil) {
|
||||
String className = findClassName(scriptRootNode);
|
||||
rubyObject = ruby.evalScriptlet("\n" + className + ".new");
|
||||
}
|
||||
// still null?
|
||||
if (rubyObject instanceof RubyNil) {
|
||||
throw new IllegalStateException("Compilation of JRuby script returned RubyNil: " + rubyObject);
|
||||
}
|
||||
|
||||
return Proxy.newProxyInstance(classLoader, interfaces, new RubyObjectInvocationHandler(rubyObject, ruby));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an instance of the {@link org.jruby.Ruby} runtime.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Ruby initializeRuntime() {
|
||||
return JavaEmbedUtils.initialize(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given the root {@link Node} in a JRuby AST will locate the name of the
|
||||
* class defined by that AST.
|
||||
* @throws IllegalArgumentException if no class is defined by the supplied AST
|
||||
*/
|
||||
private static String findClassName(Node rootNode) {
|
||||
ClassNode classNode = findClassNode(rootNode);
|
||||
if (classNode == null) {
|
||||
throw new IllegalArgumentException("Unable to determine class name for root node '" + rootNode + "'");
|
||||
}
|
||||
Colon2Node node = (Colon2Node) classNode.getCPath();
|
||||
return node.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first {@link ClassNode} under the supplied {@link Node}.
|
||||
* @return the corresponding {@code ClassNode}, or {@code null} if none found
|
||||
*/
|
||||
private static ClassNode findClassNode(Node node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
if (node instanceof ClassNode) {
|
||||
return (ClassNode) node;
|
||||
}
|
||||
List<Node> children = node.childNodes();
|
||||
for (Node child : children) {
|
||||
if (child instanceof ClassNode) {
|
||||
return (ClassNode) child;
|
||||
}
|
||||
else if (child instanceof NewlineNode) {
|
||||
NewlineNode nn = (NewlineNode) child;
|
||||
ClassNode found = findClassNode(nn.getNextNode());
|
||||
if (found != null) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Node child : children) {
|
||||
ClassNode found = findClassNode(child);
|
||||
if (found != null) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* InvocationHandler that invokes a JRuby script method.
|
||||
*/
|
||||
private static class RubyObjectInvocationHandler implements InvocationHandler {
|
||||
|
||||
private final IRubyObject rubyObject;
|
||||
|
||||
private final Ruby ruby;
|
||||
|
||||
public RubyObjectInvocationHandler(IRubyObject rubyObject, Ruby ruby) {
|
||||
this.rubyObject = rubyObject;
|
||||
this.ruby = ruby;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if (ReflectionUtils.isEqualsMethod(method)) {
|
||||
return (isProxyForSameRubyObject(args[0]));
|
||||
}
|
||||
else if (ReflectionUtils.isHashCodeMethod(method)) {
|
||||
return this.rubyObject.hashCode();
|
||||
}
|
||||
else if (ReflectionUtils.isToStringMethod(method)) {
|
||||
String toStringResult = this.rubyObject.toString();
|
||||
if (!StringUtils.hasText(toStringResult)) {
|
||||
toStringResult = ObjectUtils.identityToString(this.rubyObject);
|
||||
}
|
||||
return "JRuby object [" + toStringResult + "]";
|
||||
}
|
||||
try {
|
||||
IRubyObject[] rubyArgs = convertToRuby(args);
|
||||
IRubyObject rubyResult =
|
||||
this.rubyObject.callMethod(this.ruby.getCurrentContext(), method.getName(), rubyArgs);
|
||||
return convertFromRuby(rubyResult, method.getReturnType());
|
||||
}
|
||||
catch (RaiseException ex) {
|
||||
throw new JRubyExecutionException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isProxyForSameRubyObject(Object other) {
|
||||
if (!Proxy.isProxyClass(other.getClass())) {
|
||||
return false;
|
||||
}
|
||||
InvocationHandler ih = Proxy.getInvocationHandler(other);
|
||||
return (ih instanceof RubyObjectInvocationHandler &&
|
||||
this.rubyObject.equals(((RubyObjectInvocationHandler) ih).rubyObject));
|
||||
}
|
||||
|
||||
private IRubyObject[] convertToRuby(Object[] javaArgs) {
|
||||
if (javaArgs == null || javaArgs.length == 0) {
|
||||
return new IRubyObject[0];
|
||||
}
|
||||
IRubyObject[] rubyArgs = new IRubyObject[javaArgs.length];
|
||||
for (int i = 0; i < javaArgs.length; ++i) {
|
||||
rubyArgs[i] = JavaEmbedUtils.javaToRuby(this.ruby, javaArgs[i]);
|
||||
}
|
||||
return rubyArgs;
|
||||
}
|
||||
|
||||
private Object convertFromRuby(IRubyObject rubyResult, Class<?> returnType) {
|
||||
Object result = JavaEmbedUtils.rubyToJava(this.ruby, rubyResult, returnType);
|
||||
if (result instanceof RubyArray && returnType.isArray()) {
|
||||
result = convertFromRubyArray(((RubyArray) result).toJavaArray(), returnType);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object convertFromRubyArray(IRubyObject[] rubyArray, Class<?> returnType) {
|
||||
Class<?> targetType = returnType.getComponentType();
|
||||
Object javaArray = Array.newInstance(targetType, rubyArray.length);
|
||||
for (int i = 0; i < rubyArray.length; i++) {
|
||||
IRubyObject rubyObject = rubyArray[i];
|
||||
Array.set(javaArray, i, convertFromRuby(rubyObject, targetType));
|
||||
}
|
||||
return javaArray;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exception thrown in response to a JRuby {@link RaiseException}
|
||||
* being thrown from a JRuby method invocation.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public static class JRubyExecutionException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Create a new {@code JRubyException},
|
||||
* wrapping the given JRuby {@code RaiseException}.
|
||||
* @param ex the cause (must not be {@code null})
|
||||
*/
|
||||
public JRubyExecutionException(RaiseException ex) {
|
||||
super(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
/**
|
||||
* Package providing integration of
|
||||
* <a href="http://jruby.sourceforge.net">JRuby</a>
|
||||
* into Spring's scripting infrastructure.
|
||||
*/
|
||||
package org.springframework.scripting.jruby;
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.aop.target;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.apache.commons.pool.impl.GenericObjectPool;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.tests.sample.beans.Person;
|
||||
import org.springframework.tests.sample.beans.SerializablePerson;
|
||||
import org.springframework.tests.sample.beans.SideEffectBean;
|
||||
import org.springframework.util.SerializationTestUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests for pooling invoker interceptor.
|
||||
* TODO: need to make these tests stronger: it's hard to
|
||||
* make too many assumptions about a pool.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class CommonsPoolTargetSourceTests {
|
||||
|
||||
/**
|
||||
* Initial count value set in bean factory XML
|
||||
*/
|
||||
private static final int INITIAL_COUNT = 10;
|
||||
|
||||
private DefaultListableBeanFactory beanFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.beanFactory = new DefaultListableBeanFactory();
|
||||
new XmlBeanDefinitionReader(this.beanFactory).loadBeanDefinitions(
|
||||
new ClassPathResource(getClass().getSimpleName() + "-context.xml", getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
* We must simulate container shutdown, which should clear threads.
|
||||
*/
|
||||
@After
|
||||
public void tearDown() {
|
||||
// Will call pool.close()
|
||||
this.beanFactory.destroySingletons();
|
||||
}
|
||||
|
||||
private void testFunctionality(String name) {
|
||||
SideEffectBean pooled = (SideEffectBean) beanFactory.getBean(name);
|
||||
assertEquals(INITIAL_COUNT, pooled.getCount());
|
||||
pooled.doWork();
|
||||
assertEquals(INITIAL_COUNT + 1, pooled.getCount());
|
||||
|
||||
pooled = (SideEffectBean) beanFactory.getBean(name);
|
||||
// Just check that it works--we can't make assumptions
|
||||
// about the count
|
||||
pooled.doWork();
|
||||
//assertEquals(INITIAL_COUNT + 1, apartment.getCount() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionality() {
|
||||
testFunctionality("pooled");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFunctionalityWithNoInterceptors() {
|
||||
testFunctionality("pooledNoInterceptors");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigMixin() {
|
||||
SideEffectBean pooled = (SideEffectBean) beanFactory.getBean("pooledWithMixin");
|
||||
assertEquals(INITIAL_COUNT, pooled.getCount());
|
||||
PoolingConfig conf = (PoolingConfig) beanFactory.getBean("pooledWithMixin");
|
||||
// TODO one invocation from setup
|
||||
//assertEquals(1, conf.getInvocations());
|
||||
pooled.doWork();
|
||||
// assertEquals("No objects active", 0, conf.getActive());
|
||||
assertEquals("Correct target source", 25, conf.getMaxSize());
|
||||
// assertTrue("Some free", conf.getFree() > 0);
|
||||
//assertEquals(2, conf.getInvocations());
|
||||
assertEquals(25, conf.getMaxSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetSourceSerializableWithoutConfigMixin() throws Exception {
|
||||
CommonsPoolTargetSource cpts = (CommonsPoolTargetSource) beanFactory.getBean("personPoolTargetSource");
|
||||
|
||||
SingletonTargetSource serialized = (SingletonTargetSource) SerializationTestUtils.serializeAndDeserialize(cpts);
|
||||
assertTrue(serialized.getTarget() instanceof Person);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testProxySerializableWithoutConfigMixin() throws Exception {
|
||||
Person pooled = (Person) beanFactory.getBean("pooledPerson");
|
||||
|
||||
//System.out.println(((Advised) pooled).toProxyConfigString());
|
||||
assertTrue(((Advised) pooled).getTargetSource() instanceof CommonsPoolTargetSource);
|
||||
|
||||
//((Advised) pooled).setTargetSource(new SingletonTargetSource(new SerializablePerson()));
|
||||
Person serialized = (Person) SerializationTestUtils.serializeAndDeserialize(pooled);
|
||||
assertTrue(((Advised) serialized).getTargetSource() instanceof SingletonTargetSource);
|
||||
serialized.setAge(25);
|
||||
assertEquals(25, serialized.getAge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHitMaxSize() throws Exception {
|
||||
int maxSize = 10;
|
||||
|
||||
CommonsPoolTargetSource targetSource = new CommonsPoolTargetSource();
|
||||
targetSource.setMaxSize(maxSize);
|
||||
targetSource.setMaxWait(1);
|
||||
prepareTargetSource(targetSource);
|
||||
|
||||
Object[] pooledInstances = new Object[maxSize];
|
||||
|
||||
for (int x = 0; x < maxSize; x++) {
|
||||
Object instance = targetSource.getTarget();
|
||||
assertNotNull(instance);
|
||||
pooledInstances[x] = instance;
|
||||
}
|
||||
|
||||
// should be at maximum now
|
||||
try {
|
||||
targetSource.getTarget();
|
||||
fail("Should throw NoSuchElementException");
|
||||
}
|
||||
catch (NoSuchElementException ex) {
|
||||
// desired
|
||||
}
|
||||
|
||||
// lets now release an object and try to accquire a new one
|
||||
targetSource.releaseTarget(pooledInstances[9]);
|
||||
pooledInstances[9] = targetSource.getTarget();
|
||||
|
||||
// release all objects
|
||||
for (int i = 0; i < pooledInstances.length; i++) {
|
||||
targetSource.releaseTarget(pooledInstances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHitMaxSizeLoadedFromContext() throws Exception {
|
||||
Advised person = (Advised) beanFactory.getBean("maxSizePooledPerson");
|
||||
CommonsPoolTargetSource targetSource = (CommonsPoolTargetSource) person.getTargetSource();
|
||||
|
||||
int maxSize = targetSource.getMaxSize();
|
||||
Object[] pooledInstances = new Object[maxSize];
|
||||
|
||||
for (int x = 0; x < maxSize; x++) {
|
||||
Object instance = targetSource.getTarget();
|
||||
assertNotNull(instance);
|
||||
pooledInstances[x] = instance;
|
||||
}
|
||||
|
||||
// should be at maximum now
|
||||
try {
|
||||
targetSource.getTarget();
|
||||
fail("Should throw NoSuchElementException");
|
||||
}
|
||||
catch (NoSuchElementException ex) {
|
||||
// desired
|
||||
}
|
||||
|
||||
// lets now release an object and try to accquire a new one
|
||||
targetSource.releaseTarget(pooledInstances[9]);
|
||||
pooledInstances[9] = targetSource.getTarget();
|
||||
|
||||
// release all objects
|
||||
for (int i = 0; i < pooledInstances.length; i++) {
|
||||
targetSource.releaseTarget(pooledInstances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetWhenExhaustedAction() {
|
||||
CommonsPoolTargetSource targetSource = new CommonsPoolTargetSource();
|
||||
targetSource.setWhenExhaustedActionName("WHEN_EXHAUSTED_BLOCK");
|
||||
assertEquals(GenericObjectPool.WHEN_EXHAUSTED_BLOCK, targetSource.getWhenExhaustedAction());
|
||||
}
|
||||
|
||||
private void prepareTargetSource(CommonsPoolTargetSource targetSource) {
|
||||
String beanName = "target";
|
||||
|
||||
StaticApplicationContext applicationContext = new StaticApplicationContext();
|
||||
applicationContext.registerPrototype(beanName, SerializablePerson.class);
|
||||
|
||||
targetSource.setTargetBeanName(beanName);
|
||||
targetSource.setBeanFactory(applicationContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -229,7 +229,6 @@ class DerivedConstructorDependenciesBean extends ConstructorDependenciesBean {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
interface DummyBo {
|
||||
|
|
@ -239,7 +238,6 @@ interface DummyBo {
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rod Johnson
|
||||
*/
|
||||
class DummyBoImpl implements DummyBo {
|
||||
|
|
@ -260,12 +258,6 @@ class DummyBoImpl implements DummyBo {
|
|||
* @author Rod Johnson
|
||||
*/
|
||||
class DummyDao {
|
||||
|
||||
DataSource ds;
|
||||
|
||||
public DummyDao(DataSource ds) {
|
||||
this.ds = ds;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ public class GroovyScriptFactoryTests {
|
|||
@Test // SPR-6268
|
||||
public void testProxyTargetClassNotAllowedIfNotGroovy() throws Exception {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("jruby-with-xsd-proxy-target-class.xml", getClass());
|
||||
new ClassPathXmlApplicationContext("groovy-with-xsd-proxy-target-class.xml", getClass());
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
assertTrue(ex.getMessage().contains("Cannot use proxyTargetClass=true"));
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.scripting.jruby;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.scripting.Messenger;
|
||||
import org.springframework.tests.aop.advice.CountingBeforeAdvice;
|
||||
import org.springframework.util.MBeanTestUtils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public final class AdvisedJRubyScriptFactoryTests {
|
||||
|
||||
private static final Class<?> CLASS = AdvisedJRubyScriptFactoryTests.class;
|
||||
private static final String CLASSNAME = CLASS.getSimpleName();
|
||||
|
||||
private static final String FACTORYBEAN_CONTEXT = CLASSNAME + "-factoryBean.xml";
|
||||
private static final String APC_CONTEXT = CLASSNAME + "-beanNameAutoProxyCreator.xml";
|
||||
|
||||
@After
|
||||
public void resetMBeanServers() throws Exception {
|
||||
MBeanTestUtils.resetMBeanServers();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdviseWithProxyFactoryBean() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(FACTORYBEAN_CONTEXT, CLASS);
|
||||
try {
|
||||
Messenger bean = (Messenger) ctx.getBean("messenger");
|
||||
assertTrue("Bean is not a proxy", AopUtils.isAopProxy(bean));
|
||||
assertTrue("Bean is not an Advised object", bean instanceof Advised);
|
||||
|
||||
CountingBeforeAdvice advice = (CountingBeforeAdvice) ctx.getBean("advice");
|
||||
assertEquals(0, advice.getCalls());
|
||||
bean.getMessage();
|
||||
assertEquals(1, advice.getCalls());
|
||||
}
|
||||
finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdviseWithBeanNameAutoProxyCreator() {
|
||||
ClassPathXmlApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext(APC_CONTEXT, CLASS);
|
||||
try {
|
||||
Messenger bean = (Messenger) ctx.getBean("messenger");
|
||||
assertTrue("Bean is not a proxy", AopUtils.isAopProxy(bean));
|
||||
assertTrue("Bean is not an Advised object", bean instanceof Advised);
|
||||
|
||||
CountingBeforeAdvice advice = (CountingBeforeAdvice) ctx.getBean("advice");
|
||||
assertEquals(0, advice.getCalls());
|
||||
bean.getMessage();
|
||||
assertEquals(1, advice.getCalls());
|
||||
}
|
||||
finally {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.scripting.jruby;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.aop.target.dynamic.Refreshable;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.scripting.Calculator;
|
||||
import org.springframework.scripting.ConfigurableMessenger;
|
||||
import org.springframework.scripting.Messenger;
|
||||
import org.springframework.scripting.ScriptCompilationException;
|
||||
import org.springframework.scripting.TestBeanAwareMessenger;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class JRubyScriptFactoryTests {
|
||||
|
||||
private static final String RUBY_SCRIPT_SOURCE_LOCATOR =
|
||||
"inline:require 'java'\n" +
|
||||
"class RubyBar\n" +
|
||||
"end\n" +
|
||||
"RubyBar.new";
|
||||
|
||||
|
||||
@Test
|
||||
public void testStaticScript() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyContext.xml", getClass());
|
||||
Calculator calc = (Calculator) ctx.getBean("calculator");
|
||||
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
||||
|
||||
assertFalse("Scripted object should not be instance of Refreshable", calc instanceof Refreshable);
|
||||
assertFalse("Scripted object should not be instance of Refreshable", messenger instanceof Refreshable);
|
||||
|
||||
assertEquals(calc, calc);
|
||||
assertEquals(messenger, messenger);
|
||||
assertTrue(!messenger.equals(calc));
|
||||
assertNotSame(messenger.hashCode(), calc.hashCode());
|
||||
assertTrue(!messenger.toString().equals(calc.toString()));
|
||||
|
||||
assertEquals(3, calc.add(1, 2));
|
||||
String desiredMessage = "Hello World!";
|
||||
assertEquals("Message is incorrect", desiredMessage, messenger.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStaticScriptUsingJsr223() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyContextWithJsr223.xml", getClass());
|
||||
Calculator calc = (Calculator) ctx.getBean("calculator");
|
||||
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
||||
|
||||
assertFalse("Scripted object should not be instance of Refreshable", calc instanceof Refreshable);
|
||||
assertFalse("Scripted object should not be instance of Refreshable", messenger instanceof Refreshable);
|
||||
|
||||
assertEquals(calc, calc);
|
||||
assertEquals(messenger, messenger);
|
||||
assertTrue(!messenger.equals(calc));
|
||||
assertNotSame(messenger.hashCode(), calc.hashCode());
|
||||
assertTrue(!messenger.toString().equals(calc.toString()));
|
||||
|
||||
assertEquals(3, calc.add(1, 2));
|
||||
String desiredMessage = "Hello World!";
|
||||
assertEquals("Message is incorrect", desiredMessage, messenger.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonStaticScript() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyRefreshableContext.xml", getClass());
|
||||
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
||||
|
||||
assertTrue("Should be a proxy for refreshable scripts", AopUtils.isAopProxy(messenger));
|
||||
assertTrue("Should be an instance of Refreshable", messenger instanceof Refreshable);
|
||||
|
||||
String desiredMessage = "Hello World!";
|
||||
assertEquals("Message is incorrect.", desiredMessage, messenger.getMessage());
|
||||
|
||||
Refreshable refreshable = (Refreshable) messenger;
|
||||
refreshable.refresh();
|
||||
|
||||
assertEquals("Message is incorrect after refresh.", desiredMessage, messenger.getMessage());
|
||||
assertEquals("Incorrect refresh count", 2, refreshable.getRefreshCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScriptCompilationException() throws Exception {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("jrubyBrokenContext.xml", getClass());
|
||||
fail("Should throw exception for broken script file");
|
||||
}
|
||||
catch (BeanCreationException ex) {
|
||||
assertTrue(ex.contains(ScriptCompilationException.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithNullScriptSourceLocator() throws Exception {
|
||||
try {
|
||||
new JRubyScriptFactory(null, Messenger.class);
|
||||
fail("Must have thrown exception by this point.");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithEmptyScriptSourceLocator() throws Exception {
|
||||
try {
|
||||
new JRubyScriptFactory("", Messenger.class);
|
||||
fail("Must have thrown exception by this point.");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithWhitespacedScriptSourceLocator() throws Exception {
|
||||
try {
|
||||
new JRubyScriptFactory("\n ", Messenger.class);
|
||||
fail("Must have thrown exception by this point.");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithNullScriptInterfacesArray() throws Exception {
|
||||
try {
|
||||
new JRubyScriptFactory(RUBY_SCRIPT_SOURCE_LOCATOR);
|
||||
fail("Must have thrown exception by this point.");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCtorWithEmptyScriptInterfacesArray() throws Exception {
|
||||
try {
|
||||
new JRubyScriptFactory(RUBY_SCRIPT_SOURCE_LOCATOR, new Class<?>[]{});
|
||||
fail("Must have thrown exception by this point.");
|
||||
}
|
||||
catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceScriptFromTag() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd.xml", getClass());
|
||||
TestBean testBean = (TestBean) ctx.getBean("testBean");
|
||||
|
||||
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
||||
assertEquals("Hello World!", messenger.getMessage());
|
||||
assertFalse(messenger instanceof Refreshable);
|
||||
|
||||
TestBeanAwareMessenger messengerByType = (TestBeanAwareMessenger) ctx.getBean("messengerByType");
|
||||
assertEquals(testBean, messengerByType.getTestBean());
|
||||
|
||||
TestBeanAwareMessenger messengerByName = (TestBeanAwareMessenger) ctx.getBean("messengerByName");
|
||||
assertEquals(testBean, messengerByName.getTestBean());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceScriptFromTagUsingJsr223() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd-jsr223.xml", getClass());
|
||||
|
||||
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
||||
assertEquals("Hello World!", messenger.getMessage());
|
||||
assertFalse(messenger instanceof Refreshable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrototypeScriptFromTag() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd.xml", getClass());
|
||||
ConfigurableMessenger messenger = (ConfigurableMessenger) ctx.getBean("messengerPrototype");
|
||||
ConfigurableMessenger messenger2 = (ConfigurableMessenger) ctx.getBean("messengerPrototype");
|
||||
|
||||
assertNotSame(messenger, messenger2);
|
||||
assertSame(messenger.getClass(), messenger2.getClass());
|
||||
assertEquals("Hello World!", messenger.getMessage());
|
||||
assertEquals("Hello World!", messenger2.getMessage());
|
||||
messenger.setMessage("Bye World!");
|
||||
messenger2.setMessage("Byebye World!");
|
||||
assertEquals("Bye World!", messenger.getMessage());
|
||||
assertEquals("Byebye World!", messenger2.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInlineScriptFromTag() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd.xml", getClass());
|
||||
Calculator calculator = (Calculator) ctx.getBean("calculator");
|
||||
assertNotNull(calculator);
|
||||
assertFalse(calculator instanceof Refreshable);
|
||||
assertEquals(3, calculator.add(1, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInlineScriptFromTagUsingJsr223() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd-jsr223.xml", getClass());
|
||||
Calculator calculator = (Calculator) ctx.getBean("calculator");
|
||||
assertNotNull(calculator);
|
||||
assertFalse(calculator instanceof Refreshable);
|
||||
assertEquals(3, calculator.add(1, 2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshableFromTag() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd.xml", getClass());
|
||||
Messenger messenger = (Messenger) ctx.getBean("refreshableMessenger");
|
||||
assertEquals("Hello World!", messenger.getMessage());
|
||||
assertTrue("Messenger should be Refreshable", messenger instanceof Refreshable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefreshableFromTagUsingJsr223() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd-jsr223.xml", getClass());
|
||||
Messenger messenger = (Messenger) ctx.getBean("refreshableMessenger");
|
||||
assertEquals("Hello World!", messenger.getMessage());
|
||||
assertTrue("Messenger should be Refreshable", messenger instanceof Refreshable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThatMultipleScriptInterfacesAreSupported() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-with-xsd.xml", getClass());
|
||||
Messenger messenger = (Messenger) ctx.getBean("calculatingMessenger");
|
||||
assertEquals("Hello World!", messenger.getMessage());
|
||||
|
||||
// cool, now check that the Calculator interface is also exposed
|
||||
Calculator calc = (Calculator) messenger;
|
||||
assertEquals(0, calc.add(2, -2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithComplexArg() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyContext.xml", getClass());
|
||||
Printer printer = (Printer) ctx.getBean("printer");
|
||||
CountingPrintable printable = new CountingPrintable();
|
||||
printer.print(printable);
|
||||
assertEquals(1, printable.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithComplexArgUsingJsr223() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyContextWithJsr223.xml", getClass());
|
||||
Printer printer = (Printer) ctx.getBean("printer");
|
||||
CountingPrintable printable = new CountingPrintable();
|
||||
printer.print(printable);
|
||||
assertEquals(1, printable.count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithPrimitiveArgsInReturnTypeAndParameters() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyContextForPrimitives.xml", getClass());
|
||||
PrimitiveAdder adder = (PrimitiveAdder) ctx.getBean("adder");
|
||||
assertEquals(2, adder.addInts(1, 1));
|
||||
assertEquals(4, adder.addShorts((short) 1, (short) 3));
|
||||
assertEquals(5, adder.addLongs(2L, 3L));
|
||||
assertEquals(5, new Float(adder.addFloats(2.0F, 3.1F)).intValue());
|
||||
assertEquals(5, new Double(adder.addDoubles(2.0, 3.1)).intValue());
|
||||
assertFalse(adder.resultIsPositive(-200, 1));
|
||||
assertEquals("ri", adder.concatenate('r', 'i'));
|
||||
assertEquals('c', adder.echo('c'));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithWrapperArgsInReturnTypeAndParameters() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jrubyContextForWrappers.xml", getClass());
|
||||
WrapperAdder adder = (WrapperAdder) ctx.getBean("adder");
|
||||
|
||||
assertEquals(new Integer(2), adder.addInts(new Integer(1), new Integer(1)));
|
||||
assertEquals(Integer.class, adder.addInts(new Integer(1), new Integer(1)).getClass());
|
||||
assertEquals(new Short((short) 4), adder.addShorts(new Short((short) 1), new Short((short) 3)));
|
||||
assertEquals(Short.class, adder.addShorts(new Short((short) 1), new Short((short) 3)).getClass());
|
||||
assertEquals(new Long(5L), adder.addLongs(new Long(2L), new Long(3L)));
|
||||
assertEquals(Long.class, adder.addLongs(new Long(2L), new Long(3L)).getClass());
|
||||
assertEquals(5, adder.addFloats(new Float(2.0F), new Float(3.1F)).intValue());
|
||||
assertEquals(Float.class, adder.addFloats(new Float(2.0F), new Float(3.1F)).getClass());
|
||||
assertEquals(5, new Double(adder.addDoubles(new Double(2.0), new Double(3.1)).intValue()).intValue());
|
||||
assertEquals(Double.class, adder.addDoubles(new Double(2.0), new Double(3.1)).getClass());
|
||||
assertFalse(adder.resultIsPositive(new Integer(-200), new Integer(1)).booleanValue());
|
||||
assertEquals(Boolean.class, adder.resultIsPositive(new Integer(-200), new Integer(1)).getClass());
|
||||
assertEquals("ri", adder.concatenate(new Character('r'), new Character('i')));
|
||||
assertEquals(String.class, adder.concatenate(new Character('r'), new Character('i')).getClass());
|
||||
assertEquals(new Character('c'), adder.echo(new Character('c')));
|
||||
assertEquals(Character.class, adder.echo(new Character('c')).getClass());
|
||||
Integer[] numbers = new Integer[]{new Integer(1), new Integer(2), new Integer(3), new Integer(4), new Integer(5)};
|
||||
assertEquals("12345", adder.concatArrayOfIntegerWrappers(numbers));
|
||||
assertEquals(String.class, adder.concatArrayOfIntegerWrappers(numbers).getClass());
|
||||
|
||||
Short[] shorts = adder.populate(new Short((short) 1), new Short((short) 2));
|
||||
assertEquals(2, shorts.length);
|
||||
assertNotNull(shorts[0]);
|
||||
assertEquals(new Short((short) 1), shorts[0]);
|
||||
assertNotNull(shorts[1]);
|
||||
assertEquals(new Short((short) 2), shorts[1]);
|
||||
|
||||
String[][] lol = adder.createListOfLists("1", "2", "3");
|
||||
assertNotNull(lol);
|
||||
assertEquals(3, lol.length);
|
||||
assertEquals("1", lol[0][0]);
|
||||
assertEquals("2", lol[1][0]);
|
||||
assertEquals("3", lol[2][0]);
|
||||
|
||||
Map<?, ?> singleValueMap = adder.toMap("key", "value");
|
||||
assertNotNull(singleValueMap);
|
||||
assertEquals(1, singleValueMap.size());
|
||||
assertEquals("key", singleValueMap.keySet().iterator().next());
|
||||
assertEquals("value", singleValueMap.values().iterator().next());
|
||||
|
||||
String[] expectedStrings = new String[]{"1", "2", "3"};
|
||||
Map<?, ?> map = adder.toMap("key", expectedStrings);
|
||||
assertNotNull(map);
|
||||
assertEquals(1, map.size());
|
||||
assertEquals("key", map.keySet().iterator().next());
|
||||
String[] strings = (String[]) map.values().iterator().next();
|
||||
for (int i = 0; i < expectedStrings.length; ++i) {
|
||||
assertEquals(expectedStrings[i], strings[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAop() throws Exception {
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("jruby-aop.xml", getClass());
|
||||
Messenger messenger = (Messenger) ctx.getBean("messenger");
|
||||
assertEquals(new StringBuffer("Hello World!").reverse().toString(), messenger.getMessage());
|
||||
}
|
||||
|
||||
|
||||
private static final class CountingPrintable implements Printable {
|
||||
|
||||
public int count;
|
||||
|
||||
@Override
|
||||
public String getContent() {
|
||||
this.count++;
|
||||
return "Hello World!";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package org.springframework.scripting.jruby;
|
||||
|
||||
/**
|
||||
* http://opensource.atlassian.com/projects/spring/browse/SPR-3026
|
||||
*
|
||||
* @author Rick Evans
|
||||
*/
|
||||
public interface PrimitiveAdder {
|
||||
|
||||
int addInts(int x, int y);
|
||||
|
||||
short addShorts(short x, short y);
|
||||
|
||||
long addLongs(long x, long y);
|
||||
|
||||
float addFloats(float x, float y);
|
||||
|
||||
double addDoubles(double x, double y);
|
||||
|
||||
boolean resultIsPositive(int x, int y);
|
||||
|
||||
String concatenate(char c, char d);
|
||||
|
||||
char echo(char c);
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2006 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.scripting.jruby;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public interface Printable {
|
||||
|
||||
String getContent();
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2006 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.scripting.jruby;
|
||||
|
||||
/**
|
||||
* @author Rob Harrop
|
||||
* @since 2.0.2
|
||||
*/
|
||||
public interface Printer {
|
||||
|
||||
void print(Printable arg);
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 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.scripting.jruby;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* http://opensource.atlassian.com/projects/spring/browse/SPR-3038
|
||||
*
|
||||
* @author Rick Evans
|
||||
*/
|
||||
public interface WrapperAdder {
|
||||
|
||||
Integer addInts(Integer x, Integer y);
|
||||
|
||||
Short addShorts(Short x, Short y);
|
||||
|
||||
Long addLongs(Long x, Long y);
|
||||
|
||||
Float addFloats(Float x, Float y);
|
||||
|
||||
Double addDoubles(Double x, Double y);
|
||||
|
||||
Boolean resultIsPositive(Integer x, Integer y);
|
||||
|
||||
String concatenate(Character c, Character d);
|
||||
|
||||
Character echo(Character c);
|
||||
|
||||
String concatArrayOfIntegerWrappers(Integer[] numbers);
|
||||
|
||||
Short[] populate(Short one, Short two);
|
||||
|
||||
String[][] createListOfLists(String one, String second, String third);
|
||||
|
||||
Map<?, ?> toMap(String key, Object value);
|
||||
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
<beans>
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"/>
|
||||
|
||||
<bean id="dao" class="org.springframework.beans.factory.xml.DummyDao" autowire="constructor"/>
|
||||
|
||||
<bean id="boPrototype" autowire="constructor" class="org.springframework.beans.factory.xml.DummyBoImpl"
|
||||
|
|
|
|||
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
import org.apache.log4j.xml.DOMConfigurator;
|
||||
|
||||
/**
|
||||
* Convenience class that features simple methods for custom log4j configuration.
|
||||
*
|
||||
* <p>Only needed for non-default log4j initialization, for example with a custom
|
||||
* config location or a refresh interval. By default, log4j will simply read its
|
||||
* configuration from a "log4j.properties" or "log4j.xml" file in the root of
|
||||
* the classpath.
|
||||
*
|
||||
* <p>For web environments, the analogous Log4jWebConfigurer class can be found
|
||||
* in the web package, reading in its configuration from context-params in
|
||||
* {@code web.xml}. In a J2EE web application, log4j is usually set up
|
||||
* via Log4jConfigListener, delegating to Log4jWebConfigurer underneath.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 13.03.2003
|
||||
* @see org.springframework.web.util.Log4jWebConfigurer
|
||||
* @see org.springframework.web.util.Log4jConfigListener
|
||||
* @deprecated as of Spring 4.2.1, in favor of Apache Log4j 2
|
||||
* (following Apache's EOL declaration for log4j 1.x)
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class Log4jConfigurer {
|
||||
|
||||
/** Pseudo URL prefix for loading from the class path: "classpath:" */
|
||||
public static final String CLASSPATH_URL_PREFIX = "classpath:";
|
||||
|
||||
/** Extension that indicates a log4j XML config file: ".xml" */
|
||||
public static final String XML_FILE_EXTENSION = ".xml";
|
||||
|
||||
|
||||
/**
|
||||
* Initialize log4j from the given file location, with no config file refreshing.
|
||||
* Assumes an XML file in case of a ".xml" file extension, and a properties file
|
||||
* otherwise.
|
||||
* @param location the location of the config file: either a "classpath:" location
|
||||
* (e.g. "classpath:myLog4j.properties"), an absolute file URL
|
||||
* (e.g. "file:C:/log4j.properties), or a plain absolute path in the file system
|
||||
* (e.g. "C:/log4j.properties")
|
||||
* @throws FileNotFoundException if the location specifies an invalid file path
|
||||
*/
|
||||
public static void initLogging(String location) throws FileNotFoundException {
|
||||
String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
|
||||
URL url = ResourceUtils.getURL(resolvedLocation);
|
||||
if (ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol()) && !ResourceUtils.getFile(url).exists()) {
|
||||
throw new FileNotFoundException("Log4j config file [" + resolvedLocation + "] not found");
|
||||
}
|
||||
|
||||
if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
|
||||
DOMConfigurator.configure(url);
|
||||
}
|
||||
else {
|
||||
PropertyConfigurator.configure(url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize log4j from the given location, with the given refresh interval
|
||||
* for the config file. Assumes an XML file in case of a ".xml" file extension,
|
||||
* and a properties file otherwise.
|
||||
* <p>Log4j's watchdog thread will asynchronously check whether the timestamp
|
||||
* of the config file has changed, using the given interval between checks.
|
||||
* A refresh interval of 1000 milliseconds (one second), which allows to
|
||||
* do on-demand log level changes with immediate effect, is not unfeasible.
|
||||
* <p><b>WARNING:</b> Log4j's watchdog thread does not terminate until VM shutdown;
|
||||
* in particular, it does not terminate on LogManager shutdown. Therefore, it is
|
||||
* recommended to <i>not</i> use config file refreshing in a production J2EE
|
||||
* environment; the watchdog thread would not stop on application shutdown there.
|
||||
* @param location the location of the config file: either a "classpath:" location
|
||||
* (e.g. "classpath:myLog4j.properties"), an absolute file URL
|
||||
* (e.g. "file:C:/log4j.properties), or a plain absolute path in the file system
|
||||
* (e.g. "C:/log4j.properties")
|
||||
* @param refreshInterval interval between config file refresh checks, in milliseconds
|
||||
* @throws FileNotFoundException if the location specifies an invalid file path
|
||||
*/
|
||||
public static void initLogging(String location, long refreshInterval) throws FileNotFoundException {
|
||||
String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
|
||||
File file = ResourceUtils.getFile(resolvedLocation);
|
||||
if (!file.exists()) {
|
||||
throw new FileNotFoundException("Log4j config file [" + resolvedLocation + "] not found");
|
||||
}
|
||||
|
||||
if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
|
||||
DOMConfigurator.configureAndWatch(file.getAbsolutePath(), refreshInterval);
|
||||
}
|
||||
else {
|
||||
PropertyConfigurator.configureAndWatch(file.getAbsolutePath(), refreshInterval);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down log4j, properly releasing all file locks.
|
||||
* <p>This isn't strictly necessary, but recommended for shutting down
|
||||
* log4j in a scenario where the host VM stays alive (for example, when
|
||||
* shutting down an application in a J2EE environment).
|
||||
*/
|
||||
public static void shutdownLogging() {
|
||||
LogManager.shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specified system property to the current working directory.
|
||||
* <p>This can be used e.g. for test environments, for applications that leverage
|
||||
* Log4jWebConfigurer's "webAppRootKey" support in a web environment.
|
||||
* @param key system property key to use, as expected in Log4j configuration
|
||||
* (for example: "demo.root", used as "${demo.root}/WEB-INF/demo.log")
|
||||
* @see org.springframework.web.util.Log4jWebConfigurer
|
||||
*/
|
||||
public static void setWorkingDirSystemProperty(String key) {
|
||||
System.setProperty(key, new File("").getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.util;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Log4jConfigurerTests {
|
||||
|
||||
@Test
|
||||
public void initLoggingWithClasspath() throws FileNotFoundException {
|
||||
doTestInitLogging("classpath:org/springframework/util/testlog4j.properties", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithRelativeFilePath() throws FileNotFoundException {
|
||||
doTestInitLogging("src/test/resources/org/springframework/util/testlog4j.properties", false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithAbsoluteFilePath() throws FileNotFoundException {
|
||||
URL url = getClass().getResource("testlog4j.properties");
|
||||
doTestInitLogging(url.toString(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithClasspathAndRefreshInterval() throws FileNotFoundException {
|
||||
doTestInitLogging("classpath:org/springframework/util/testlog4j.properties", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithRelativeFilePathAndRefreshInterval() throws FileNotFoundException {
|
||||
doTestInitLogging("src/test/resources/org/springframework/util/testlog4j.properties", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithAbsoluteFilePathAndRefreshInterval() throws FileNotFoundException {
|
||||
URL url = getClass().getResource("testlog4j.properties");
|
||||
doTestInitLogging(url.getFile(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithFileUrlAndRefreshInterval() throws FileNotFoundException {
|
||||
URL url = getClass().getResource("testlog4j.properties");
|
||||
doTestInitLogging(url.toString(), true);
|
||||
}
|
||||
|
||||
@Test(expected = FileNotFoundException.class)
|
||||
public void initLoggingWithRefreshIntervalAndFileNotFound() throws FileNotFoundException {
|
||||
Log4jConfigurer.initLogging("test/org/springframework/util/bla.properties", 10);
|
||||
}
|
||||
|
||||
private void doTestInitLogging(String location, boolean refreshInterval) throws FileNotFoundException {
|
||||
if (refreshInterval) {
|
||||
Log4jConfigurer.initLogging(location, 10);
|
||||
}
|
||||
else {
|
||||
Log4jConfigurer.initLogging(location);
|
||||
}
|
||||
|
||||
Log log = LogFactory.getLog(this.getClass());
|
||||
log.debug("debug");
|
||||
log.info("info");
|
||||
log.warn("warn");
|
||||
log.error("error");
|
||||
log.fatal("fatal");
|
||||
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("debug"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("info"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("warn"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("error"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("fatal"));
|
||||
|
||||
Log4jConfigurer.shutdownLogging();
|
||||
assertTrue(MockLog4jAppender.closeCalled);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.AppenderSkeleton;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
|
||||
/**
|
||||
* @author Alef Arendsen
|
||||
*/
|
||||
public class MockLog4jAppender extends AppenderSkeleton {
|
||||
|
||||
public static final List<String> loggingStrings = new ArrayList<String>();
|
||||
|
||||
public static boolean closeCalled = false;
|
||||
|
||||
|
||||
@Override
|
||||
protected void append(LoggingEvent evt) {
|
||||
loggingStrings.add(evt.getMessage().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
closeCalled = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresLayout() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,625 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2016 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.jdbc.support.lob;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* {@link LobHandler} implementation for Oracle databases. Uses proprietary API
|
||||
* to create {@code oracle.sql.BLOB} and {@code oracle.sql.CLOB}
|
||||
* instances, as necessary when working with Oracle's JDBC driver.
|
||||
* Note that this LobHandler requires Oracle JDBC driver 9i or higher!
|
||||
*
|
||||
* <p>While most databases are able to work with {@link DefaultLobHandler},
|
||||
* Oracle 9i (or more specifically, the Oracle 9i JDBC driver) just accepts
|
||||
* Blob/Clob instances created via its own proprietary BLOB/CLOB API,
|
||||
* and additionally doesn't accept large streams for PreparedStatement's
|
||||
* corresponding setter methods. Therefore, you need to use a strategy like
|
||||
* this LobHandler implementation, or upgrade to the Oracle 10g/11g driver
|
||||
* (which still supports access to Oracle 9i databases).
|
||||
*
|
||||
* <p><b>NOTE: As of Oracle 10.2, {@link DefaultLobHandler} should work equally
|
||||
* well out of the box. On Oracle 11g, JDBC 4.0 based options such as
|
||||
* {@link DefaultLobHandler#setStreamAsLob} and {@link DefaultLobHandler#setCreateTemporaryLob}
|
||||
* are available as well, rendering this proprietary OracleLobHandler obsolete.</b>
|
||||
* Also, consider upgrading to a new driver even when accessing an older database.
|
||||
* See the {@link LobHandler} interface javadoc for a summary of recommendations.
|
||||
*
|
||||
* <p>Needs to work on a native JDBC Connection, to be able to cast it to
|
||||
* {@code oracle.jdbc.OracleConnection}. If you pass in Connections from a
|
||||
* connection pool (the usual case in a Java EE environment), you need to set an
|
||||
* appropriate {@link org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor}
|
||||
* to allow for automatic retrieval of the underlying native JDBC Connection.
|
||||
* LobHandler and NativeJdbcExtractor are separate concerns, therefore they
|
||||
* are represented by separate strategy interfaces.
|
||||
*
|
||||
* <p>Coded via reflection to avoid dependencies on Oracle classes.
|
||||
* Even reads in Oracle constants via reflection because of different Oracle
|
||||
* drivers (classes12, ojdbc14, ojdbc5, ojdbc6) having different constant values!
|
||||
* As this LobHandler initializes Oracle classes on instantiation, do not define
|
||||
* this as eager-initializing singleton if you do not want to depend on the Oracle
|
||||
* JAR being in the class path: use "lazy-init=true" to avoid this issue.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Thomas Risberg
|
||||
* @since 04.12.2003
|
||||
* @see DefaultLobHandler
|
||||
* @see #setNativeJdbcExtractor
|
||||
* @deprecated in favor of {@link DefaultLobHandler} for the Oracle 10g driver and
|
||||
* higher. Consider using the 10g/11g driver even against an Oracle 9i database!
|
||||
* {@link DefaultLobHandler#setCreateTemporaryLob} is the direct equivalent of this
|
||||
* OracleLobHandler's implementation strategy, just using standard JDBC 4.0 API.
|
||||
* That said, in most cases, regular DefaultLobHandler setup will work fine as well.
|
||||
*/
|
||||
@Deprecated
|
||||
public class OracleLobHandler extends AbstractLobHandler {
|
||||
|
||||
private static final String BLOB_CLASS_NAME = "oracle.sql.BLOB";
|
||||
|
||||
private static final String CLOB_CLASS_NAME = "oracle.sql.CLOB";
|
||||
|
||||
private static final String DURATION_SESSION_FIELD_NAME = "DURATION_SESSION";
|
||||
|
||||
private static final String MODE_READWRITE_FIELD_NAME = "MODE_READWRITE";
|
||||
|
||||
private static final String MODE_READONLY_FIELD_NAME = "MODE_READONLY";
|
||||
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private NativeJdbcExtractor nativeJdbcExtractor;
|
||||
|
||||
private Boolean cache = Boolean.TRUE;
|
||||
|
||||
private Boolean releaseResourcesAfterRead = Boolean.FALSE;
|
||||
|
||||
private Class<?> blobClass;
|
||||
|
||||
private Class<?> clobClass;
|
||||
|
||||
private final Map<Class<?>, Integer> durationSessionConstants = new HashMap<Class<?>, Integer>(2);
|
||||
|
||||
private final Map<Class<?>, Integer> modeReadWriteConstants = new HashMap<Class<?>, Integer>(2);
|
||||
|
||||
private final Map<Class<?>, Integer> modeReadOnlyConstants = new HashMap<Class<?>, Integer>(2);
|
||||
|
||||
|
||||
/**
|
||||
* Set an appropriate NativeJdbcExtractor to be able to retrieve the underlying
|
||||
* native {@code oracle.jdbc.OracleConnection}. This is necessary for
|
||||
* DataSource-based connection pools, as those need to return wrapped JDBC
|
||||
* Connection handles that cannot be cast to a native Connection implementation.
|
||||
* <p>Effectively, this LobHandler just invokes a single NativeJdbcExtractor
|
||||
* method, namely {@code getNativeConnectionFromStatement} with a
|
||||
* PreparedStatement argument (falling back to a
|
||||
* {@code PreparedStatement.getConnection()} call if no extractor is set).
|
||||
* <p>A common choice is {@code SimpleNativeJdbcExtractor}, whose Connection unwrapping
|
||||
* (which is what OracleLobHandler needs) will work with many connection pools.
|
||||
* See {@code SimpleNativeJdbcExtractor} and
|
||||
* <a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/jdbc/OracleConnection.html">
|
||||
* oracle.jdbc.OracleConnection</a> javadoc for details.
|
||||
* @see org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor#getNativeConnectionFromStatement
|
||||
* @see org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor
|
||||
* @see org.springframework.jdbc.support.nativejdbc.OracleJdbc4NativeJdbcExtractor
|
||||
*/
|
||||
public void setNativeJdbcExtractor(NativeJdbcExtractor nativeJdbcExtractor) {
|
||||
this.nativeJdbcExtractor = nativeJdbcExtractor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to cache the temporary LOB in the buffer cache.
|
||||
* This value will be passed into BLOB/CLOB.createTemporary.
|
||||
* <p>Default is {@code true}.
|
||||
* <p><strong>See Also:</strong>
|
||||
* <ul>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#createTemporary()">oracle.sql.BLOB.createTemporary</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#createTemporary()">oracle.sql.CLOB.createTemporary</a></li>
|
||||
* </ul>
|
||||
*/
|
||||
public void setCache(boolean cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to aggressively release any resources used by the LOB. If set to {@code true}
|
||||
* then you can only read the LOB values once. Any subsequent reads will fail since the resources
|
||||
* have been closed.
|
||||
* <p>Setting this property to {@code true} can be useful when your queries generates large
|
||||
* temporary LOBs that occupy space in the TEMPORARY tablespace or when you want to free up any
|
||||
* memory allocated by the driver for the LOB reading.
|
||||
* <p>Default is {@code false}.
|
||||
* <p><strong>See Also:</strong>
|
||||
* <ul>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#freeTemporary()">oracle.sql.BLOB.freeTemporary</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#freeTemporary()">oracle.sql.CLOB.freeTemporary</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#open()">oracle.sql.BLOB.open</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#open()">oracle.sql.CLOB.open</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#open()">oracle.sql.BLOB.close</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#open()">oracle.sql.CLOB.close</a></li>
|
||||
* </ul>
|
||||
*/
|
||||
public void setReleaseResourcesAfterRead(boolean releaseResources) {
|
||||
this.releaseResourcesAfterRead = releaseResources;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the {@code oracle.sql.BLOB} and {@code oracle.sql.CLOB}
|
||||
* classes via reflection, and initialize the values for the
|
||||
* DURATION_SESSION, MODE_READWRITE and MODE_READONLY constants defined there.
|
||||
* <p><strong>See Also:</strong>
|
||||
* <ul>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#DURATION_SESSION">oracle.sql.BLOB.DURATION_SESSION</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#MODE_READWRITE">oracle.sql.BLOB.MODE_READWRITE</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/BLOB.html#MODE_READONLY">oracle.sql.BLOB.MODE_READONLY</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#DURATION_SESSION">oracle.sql.CLOB.DURATION_SESSION</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#MODE_READWRITE">oracle.sql.CLOB.MODE_READWRITE</a></li>
|
||||
* <li><a href="http://download.oracle.com/otn_hosted_doc/jdeveloper/905/jdbc-javadoc/oracle/sql/CLOB.html#MODE_READONLY">oracle.sql.CLOB.MODE_READONLY</a></li>
|
||||
* </ul>
|
||||
* @param con the Oracle Connection, for using the exact same class loader
|
||||
* that the Oracle driver was loaded with
|
||||
*/
|
||||
protected synchronized void initOracleDriverClasses(Connection con) {
|
||||
if (this.blobClass == null) {
|
||||
try {
|
||||
// Initialize oracle.sql.BLOB class
|
||||
this.blobClass = con.getClass().getClassLoader().loadClass(BLOB_CLASS_NAME);
|
||||
this.durationSessionConstants.put(
|
||||
this.blobClass, this.blobClass.getField(DURATION_SESSION_FIELD_NAME).getInt(null));
|
||||
this.modeReadWriteConstants.put(
|
||||
this.blobClass, this.blobClass.getField(MODE_READWRITE_FIELD_NAME).getInt(null));
|
||||
this.modeReadOnlyConstants.put(
|
||||
this.blobClass, this.blobClass.getField(MODE_READONLY_FIELD_NAME).getInt(null));
|
||||
|
||||
// Initialize oracle.sql.CLOB class
|
||||
this.clobClass = con.getClass().getClassLoader().loadClass(CLOB_CLASS_NAME);
|
||||
this.durationSessionConstants.put(
|
||||
this.clobClass, this.clobClass.getField(DURATION_SESSION_FIELD_NAME).getInt(null));
|
||||
this.modeReadWriteConstants.put(
|
||||
this.clobClass, this.clobClass.getField(MODE_READWRITE_FIELD_NAME).getInt(null));
|
||||
this.modeReadOnlyConstants.put(
|
||||
this.clobClass, this.clobClass.getField(MODE_READONLY_FIELD_NAME).getInt(null));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"Couldn't initialize OracleLobHandler because Oracle driver classes are not available. " +
|
||||
"Note that OracleLobHandler requires Oracle JDBC driver 9i or higher!", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] getBlobAsBytes(ResultSet rs, int columnIndex) throws SQLException {
|
||||
logger.debug("Returning Oracle BLOB as bytes");
|
||||
Blob blob = rs.getBlob(columnIndex);
|
||||
initializeResourcesBeforeRead(rs.getStatement().getConnection(), blob);
|
||||
byte[] retVal = (blob != null ? blob.getBytes(1, (int) blob.length()) : null);
|
||||
releaseResourcesAfterRead(rs.getStatement().getConnection(), blob);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBlobAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException {
|
||||
logger.debug("Returning Oracle BLOB as binary stream");
|
||||
Blob blob = rs.getBlob(columnIndex);
|
||||
initializeResourcesBeforeRead(rs.getStatement().getConnection(), blob);
|
||||
InputStream retVal = (blob != null ? blob.getBinaryStream() : null);
|
||||
releaseResourcesAfterRead(rs.getStatement().getConnection(), blob);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClobAsString(ResultSet rs, int columnIndex) throws SQLException {
|
||||
logger.debug("Returning Oracle CLOB as string");
|
||||
Clob clob = rs.getClob(columnIndex);
|
||||
initializeResourcesBeforeRead(rs.getStatement().getConnection(), clob);
|
||||
String retVal = (clob != null ? clob.getSubString(1, (int) clob.length()) : null);
|
||||
releaseResourcesAfterRead(rs.getStatement().getConnection(), clob);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getClobAsAsciiStream(ResultSet rs, int columnIndex) throws SQLException {
|
||||
logger.debug("Returning Oracle CLOB as ASCII stream");
|
||||
Clob clob = rs.getClob(columnIndex);
|
||||
initializeResourcesBeforeRead(rs.getStatement().getConnection(), clob);
|
||||
InputStream retVal = (clob != null ? clob.getAsciiStream() : null);
|
||||
releaseResourcesAfterRead(rs.getStatement().getConnection(), clob);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getClobAsCharacterStream(ResultSet rs, int columnIndex) throws SQLException {
|
||||
logger.debug("Returning Oracle CLOB as character stream");
|
||||
Clob clob = rs.getClob(columnIndex);
|
||||
initializeResourcesBeforeRead(rs.getStatement().getConnection(), clob);
|
||||
Reader retVal = (clob != null ? clob.getCharacterStream() : null);
|
||||
releaseResourcesAfterRead(rs.getStatement().getConnection(), clob);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobCreator getLobCreator() {
|
||||
return new OracleLobCreator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize any LOB resources before a read is done.
|
||||
* <p>This implementation calls {@code BLOB.open(BLOB.MODE_READONLY)} or
|
||||
* {@code CLOB.open(CLOB.MODE_READONLY)} on any non-temporary LOBs if
|
||||
* {@code releaseResourcesAfterRead} property is set to {@code true}.
|
||||
* <p>This method can be overridden by sublcasses if different behavior is desired.
|
||||
* @param con the connection to be usde for initilization
|
||||
* @param lob the LOB to initialize
|
||||
*/
|
||||
protected void initializeResourcesBeforeRead(Connection con, Object lob) {
|
||||
if (this.releaseResourcesAfterRead) {
|
||||
initOracleDriverClasses(con);
|
||||
try {
|
||||
/*
|
||||
if (!((BLOB) lob.isTemporary() {
|
||||
*/
|
||||
Method isTemporary = lob.getClass().getMethod("isTemporary");
|
||||
Boolean temporary = (Boolean) isTemporary.invoke(lob);
|
||||
if (!temporary) {
|
||||
/*
|
||||
((BLOB) lob).open(BLOB.MODE_READONLY);
|
||||
*/
|
||||
Method open = lob.getClass().getMethod("open", int.class);
|
||||
open.invoke(lob, this.modeReadOnlyConstants.get(lob.getClass()));
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
logger.error("Could not open Oracle LOB", ex.getTargetException());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DataAccessResourceFailureException("Could not open Oracle LOB", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release any LOB resources after read is complete.
|
||||
* <p>If {@code releaseResourcesAfterRead} property is set to {@code true}
|
||||
* then this implementation calls
|
||||
* {@code BLOB.close()} or {@code CLOB.close()}
|
||||
* on any non-temporary LOBs that are open or
|
||||
* {@code BLOB.freeTemporary()} or {@code CLOB.freeTemporary()}
|
||||
* on any temporary LOBs.
|
||||
* <p>This method can be overridden by sublcasses if different behavior is desired.
|
||||
* @param con the connection to be usde for initilization
|
||||
* @param lob the LOB to initialize
|
||||
*/
|
||||
protected void releaseResourcesAfterRead(Connection con, Object lob) {
|
||||
if (this.releaseResourcesAfterRead) {
|
||||
initOracleDriverClasses(con);
|
||||
Boolean temporary = Boolean.FALSE;
|
||||
try {
|
||||
/*
|
||||
if (((BLOB) lob.isTemporary() {
|
||||
*/
|
||||
Method isTemporary = lob.getClass().getMethod("isTemporary");
|
||||
temporary = (Boolean) isTemporary.invoke(lob);
|
||||
if (temporary) {
|
||||
/*
|
||||
((BLOB) lob).freeTemporary();
|
||||
*/
|
||||
Method freeTemporary = lob.getClass().getMethod("freeTemporary");
|
||||
freeTemporary.invoke(lob);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
if (((BLOB) lob.isOpen() {
|
||||
*/
|
||||
Method isOpen = lob.getClass().getMethod("isOpen");
|
||||
Boolean open = (Boolean) isOpen.invoke(lob);
|
||||
if (open) {
|
||||
/*
|
||||
((BLOB) lob).close();
|
||||
*/
|
||||
Method close = lob.getClass().getMethod("close");
|
||||
close.invoke(lob);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
if (temporary) {
|
||||
logger.error("Could not free Oracle LOB", ex.getTargetException());
|
||||
}
|
||||
else {
|
||||
logger.error("Could not close Oracle LOB", ex.getTargetException());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (temporary) {
|
||||
throw new DataAccessResourceFailureException("Could not free Oracle LOB", ex);
|
||||
}
|
||||
else {
|
||||
throw new DataAccessResourceFailureException("Could not close Oracle LOB", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* LobCreator implementation for Oracle databases.
|
||||
* Creates Oracle-style temporary BLOBs and CLOBs that it frees on close.
|
||||
* @see #close
|
||||
*/
|
||||
protected class OracleLobCreator implements LobCreator {
|
||||
|
||||
private final List<Object> temporaryLobs = new LinkedList<Object>();
|
||||
|
||||
@Override
|
||||
public void setBlobAsBytes(PreparedStatement ps, int paramIndex, final byte[] content)
|
||||
throws SQLException {
|
||||
|
||||
if (content != null) {
|
||||
Blob blob = (Blob) createLob(ps, false, new LobCallback() {
|
||||
@Override
|
||||
public void populateLob(Object lob) throws Exception {
|
||||
Method methodToInvoke = lob.getClass().getMethod("getBinaryOutputStream");
|
||||
OutputStream out = (OutputStream) methodToInvoke.invoke(lob);
|
||||
FileCopyUtils.copy(content, out);
|
||||
}
|
||||
});
|
||||
ps.setBlob(paramIndex, blob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Set bytes for Oracle BLOB with length " + blob.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
ps.setBlob(paramIndex, (Blob) null);
|
||||
logger.debug("Set Oracle BLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlobAsBinaryStream(
|
||||
PreparedStatement ps, int paramIndex, final InputStream binaryStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
if (binaryStream != null) {
|
||||
Blob blob = (Blob) createLob(ps, false, new LobCallback() {
|
||||
@Override
|
||||
public void populateLob(Object lob) throws Exception {
|
||||
Method methodToInvoke = lob.getClass().getMethod("getBinaryOutputStream", (Class[]) null);
|
||||
OutputStream out = (OutputStream) methodToInvoke.invoke(lob, (Object[]) null);
|
||||
FileCopyUtils.copy(binaryStream, out);
|
||||
}
|
||||
});
|
||||
ps.setBlob(paramIndex, blob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Set binary stream for Oracle BLOB with length " + blob.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
ps.setBlob(paramIndex, (Blob) null);
|
||||
logger.debug("Set Oracle BLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClobAsString(PreparedStatement ps, int paramIndex, final String content)
|
||||
throws SQLException {
|
||||
|
||||
if (content != null) {
|
||||
Clob clob = (Clob) createLob(ps, true, new LobCallback() {
|
||||
@Override
|
||||
public void populateLob(Object lob) throws Exception {
|
||||
Method methodToInvoke = lob.getClass().getMethod("getCharacterOutputStream", (Class[]) null);
|
||||
Writer writer = (Writer) methodToInvoke.invoke(lob, (Object[]) null);
|
||||
FileCopyUtils.copy(content, writer);
|
||||
}
|
||||
});
|
||||
ps.setClob(paramIndex, clob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Set string for Oracle CLOB with length " + clob.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
logger.debug("Set Oracle CLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClobAsAsciiStream(
|
||||
PreparedStatement ps, int paramIndex, final InputStream asciiStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
if (asciiStream != null) {
|
||||
Clob clob = (Clob) createLob(ps, true, new LobCallback() {
|
||||
@Override
|
||||
public void populateLob(Object lob) throws Exception {
|
||||
Method methodToInvoke = lob.getClass().getMethod("getAsciiOutputStream", (Class[]) null);
|
||||
OutputStream out = (OutputStream) methodToInvoke.invoke(lob, (Object[]) null);
|
||||
FileCopyUtils.copy(asciiStream, out);
|
||||
}
|
||||
});
|
||||
ps.setClob(paramIndex, clob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Set ASCII stream for Oracle CLOB with length " + clob.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
logger.debug("Set Oracle CLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClobAsCharacterStream(
|
||||
PreparedStatement ps, int paramIndex, final Reader characterStream, int contentLength)
|
||||
throws SQLException {
|
||||
|
||||
if (characterStream != null) {
|
||||
Clob clob = (Clob) createLob(ps, true, new LobCallback() {
|
||||
@Override
|
||||
public void populateLob(Object lob) throws Exception {
|
||||
Method methodToInvoke = lob.getClass().getMethod("getCharacterOutputStream", (Class[]) null);
|
||||
Writer writer = (Writer) methodToInvoke.invoke(lob, (Object[]) null);
|
||||
FileCopyUtils.copy(characterStream, writer);
|
||||
}
|
||||
});
|
||||
ps.setClob(paramIndex, clob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Set character stream for Oracle CLOB with length " + clob.length());
|
||||
}
|
||||
}
|
||||
else {
|
||||
ps.setClob(paramIndex, (Clob) null);
|
||||
logger.debug("Set Oracle CLOB to null");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a LOB instance for the given PreparedStatement,
|
||||
* populating it via the given callback.
|
||||
*/
|
||||
protected Object createLob(PreparedStatement ps, boolean clob, LobCallback callback)
|
||||
throws SQLException {
|
||||
|
||||
Connection con = null;
|
||||
try {
|
||||
con = getOracleConnection(ps);
|
||||
initOracleDriverClasses(con);
|
||||
Object lob = prepareLob(con, clob ? clobClass : blobClass);
|
||||
callback.populateLob(lob);
|
||||
lob.getClass().getMethod("close", (Class[]) null).invoke(lob, (Object[]) null);
|
||||
this.temporaryLobs.add(lob);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Created new Oracle " + (clob ? "CLOB" : "BLOB"));
|
||||
}
|
||||
return lob;
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
if (ex.getTargetException() instanceof SQLException) {
|
||||
throw (SQLException) ex.getTargetException();
|
||||
}
|
||||
else if (con != null && ex.getTargetException() instanceof ClassCastException) {
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
"OracleLobCreator needs to work on [oracle.jdbc.OracleConnection], not on [" +
|
||||
con.getClass().getName() + "]: specify a corresponding NativeJdbcExtractor",
|
||||
ex.getTargetException());
|
||||
}
|
||||
else {
|
||||
throw new DataAccessResourceFailureException("Could not create Oracle LOB",
|
||||
ex.getTargetException());
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DataAccessResourceFailureException("Could not create Oracle LOB", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the underlying OracleConnection, using a NativeJdbcExtractor if set.
|
||||
*/
|
||||
protected Connection getOracleConnection(PreparedStatement ps)
|
||||
throws SQLException, ClassNotFoundException {
|
||||
|
||||
return (nativeJdbcExtractor != null ?
|
||||
nativeJdbcExtractor.getNativeConnectionFromStatement(ps) : ps.getConnection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and open an oracle.sql.BLOB/CLOB instance via reflection.
|
||||
*/
|
||||
protected Object prepareLob(Connection con, Class<?> lobClass) throws Exception {
|
||||
/*
|
||||
BLOB blob = BLOB.createTemporary(con, false, BLOB.DURATION_SESSION);
|
||||
blob.open(BLOB.MODE_READWRITE);
|
||||
return blob;
|
||||
*/
|
||||
Method createTemporary = lobClass.getMethod(
|
||||
"createTemporary", Connection.class, boolean.class, int.class);
|
||||
Object lob = createTemporary.invoke(null, con, cache, durationSessionConstants.get(lobClass));
|
||||
Method open = lobClass.getMethod("open", int.class);
|
||||
open.invoke(lob, modeReadWriteConstants.get(lobClass));
|
||||
return lob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free all temporary BLOBs and CLOBs created by this creator.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
for (Iterator<?> it = this.temporaryLobs.iterator(); it.hasNext();) {
|
||||
/*
|
||||
BLOB blob = (BLOB) it.next();
|
||||
blob.freeTemporary();
|
||||
*/
|
||||
Object lob = it.next();
|
||||
Method freeTemporary = lob.getClass().getMethod("freeTemporary");
|
||||
freeTemporary.invoke(lob);
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
logger.error("Could not free Oracle LOB", ex.getTargetException());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new DataAccessResourceFailureException("Could not free Oracle LOB", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal callback interface for use with createLob.
|
||||
*/
|
||||
protected interface LobCallback {
|
||||
|
||||
/**
|
||||
* Populate the given BLOB or CLOB instance with content.
|
||||
* @throws Exception any exception including InvocationTargetException
|
||||
*/
|
||||
void populateLob(Object lob) throws Exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.jdbc.support.nativejdbc;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link NativeJdbcExtractor} interface for the
|
||||
* Apache Commons DBCP connection pool, version 1.1 or higher.
|
||||
*
|
||||
* <p>Returns the underlying native Connection, Statement, etc to application
|
||||
* code instead of DBCP's wrapper implementations. The returned JDBC classes
|
||||
* can then safely be cast, e.g. to {@code oracle.jdbc.OracleConnection}.
|
||||
*
|
||||
* <p>This NativeJdbcExtractor can be set just to <i>allow</i> working with a
|
||||
* Commons DBCP DataSource: If a given object is not a Commons DBCP wrapper,
|
||||
* it will be returned as-is.
|
||||
*
|
||||
* <p>Note that this version of CommonsDbcpNativeJdbcExtractor will work
|
||||
* against the original Commons DBCP in {@code org.apache.commons.dbcp}
|
||||
* as well as against Tomcat 5.5's relocated Commons DBCP version in the
|
||||
* {@code org.apache.tomcat.dbcp.dbcp} package.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 25.08.2003
|
||||
* @deprecated as of Spring 4.2, in favor of Commons DBCP 2.x and JDBC 4.x
|
||||
*/
|
||||
@Deprecated
|
||||
public class CommonsDbcpNativeJdbcExtractor extends NativeJdbcExtractorAdapter {
|
||||
|
||||
private static final String GET_INNERMOST_DELEGATE_METHOD_NAME = "getInnermostDelegate";
|
||||
|
||||
|
||||
/**
|
||||
* Extracts the innermost delegate from the given Commons DBCP object.
|
||||
* Falls back to the given object if no underlying object found.
|
||||
* @param obj the Commons DBCP Connection/Statement/ResultSet
|
||||
* @return the underlying native Connection/Statement/ResultSet
|
||||
*/
|
||||
private static Object getInnermostDelegate(Object obj) throws SQLException {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Class<?> classToAnalyze = obj.getClass();
|
||||
while (!Modifier.isPublic(classToAnalyze.getModifiers())) {
|
||||
classToAnalyze = classToAnalyze.getSuperclass();
|
||||
if (classToAnalyze == null) {
|
||||
// No public provider class found -> fall back to given object.
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
Method getInnermostDelegate = classToAnalyze.getMethod(GET_INNERMOST_DELEGATE_METHOD_NAME, (Class[]) null);
|
||||
Object delegate = ReflectionUtils.invokeJdbcMethod(getInnermostDelegate, obj);
|
||||
return (delegate != null ? delegate : obj);
|
||||
}
|
||||
catch (NoSuchMethodException ex) {
|
||||
return obj;
|
||||
}
|
||||
catch (SecurityException ex) {
|
||||
throw new IllegalStateException("Commons DBCP getInnermostDelegate method is not accessible: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Connection doGetNativeConnection(Connection con) throws SQLException {
|
||||
return (Connection) getInnermostDelegate(con);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statement getNativeStatement(Statement stmt) throws SQLException {
|
||||
return (Statement) getInnermostDelegate(stmt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException {
|
||||
return (PreparedStatement) getNativeStatement(ps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException {
|
||||
return (CallableStatement) getNativeStatement(cs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getNativeResultSet(ResultSet rs) throws SQLException {
|
||||
return (ResultSet) getInnermostDelegate(rs);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -75,30 +75,4 @@ public class NativeJdbcExtractorTests {
|
|||
assertEquals(nativeRs, rs);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void commonsDbcpNativeJdbcExtractor() throws SQLException {
|
||||
org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor extractor = new org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor();
|
||||
assertFalse(extractor.isNativeConnectionNecessaryForNativeStatements());
|
||||
|
||||
Connection con = mock(Connection.class);
|
||||
Statement stmt = mock(Statement.class);
|
||||
given(stmt.getConnection()).willReturn(con);
|
||||
|
||||
Connection nativeConnection = extractor.getNativeConnection(con);
|
||||
assertEquals(con, nativeConnection);
|
||||
|
||||
nativeConnection = extractor.getNativeConnectionFromStatement(stmt);
|
||||
assertEquals(con, nativeConnection);
|
||||
assertEquals(stmt, extractor.getNativeStatement(stmt));
|
||||
|
||||
PreparedStatement ps = mock(PreparedStatement.class);
|
||||
assertEquals(ps, extractor.getNativePreparedStatement(ps));
|
||||
|
||||
CallableStatement cs = mock(CallableStatement.class);
|
||||
assertEquals(cs, extractor.getNativePreparedStatement(cs));
|
||||
|
||||
ResultSet rs = mock(ResultSet.class);
|
||||
assertEquals(rs, extractor.getNativeResultSet(rs));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<property name="entityManagerFactory" ref="entityManagerFactory"/>
|
||||
</bean>
|
||||
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
|
||||
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
|
||||
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="url" value="jdbc:hsqldb:mem:xdb"/>
|
||||
<property name="username" value="sa"/>
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.jca.work.glassfish;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.resource.spi.work.WorkManager;
|
||||
|
||||
import org.springframework.jca.work.WorkManagerTaskExecutor;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Spring TaskExecutor adapter for the GlassFish JCA WorkManager.
|
||||
* Can be defined in web applications to make a TaskExecutor reference
|
||||
* available, talking to the GlassFish WorkManager (thread pool) underneath.
|
||||
*
|
||||
* <p>This is the GlassFish equivalent of the CommonJ
|
||||
* {@link org.springframework.scheduling.commonj.WorkManagerTaskExecutor}
|
||||
* adapter for WebLogic and WebSphere.
|
||||
*
|
||||
* <p>Note: On GlassFish 4 and higher, a
|
||||
* {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor}
|
||||
* should be preferred, following JSR-236 support in Java EE 7.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.2
|
||||
*/
|
||||
public class GlassFishWorkManagerTaskExecutor extends WorkManagerTaskExecutor {
|
||||
|
||||
private static final String WORK_MANAGER_FACTORY_CLASS = "com.sun.enterprise.connectors.work.WorkManagerFactory";
|
||||
|
||||
private final Method getWorkManagerMethod;
|
||||
|
||||
|
||||
public GlassFishWorkManagerTaskExecutor() {
|
||||
try {
|
||||
Class<?> wmf = getClass().getClassLoader().loadClass(WORK_MANAGER_FACTORY_CLASS);
|
||||
this.getWorkManagerMethod = wmf.getMethod("getWorkManager", String.class);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize GlassFishWorkManagerTaskExecutor because GlassFish API is not available", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Identify a specific GlassFish thread pool to talk to.
|
||||
* <p>The thread pool name matches the resource adapter name
|
||||
* in default RAR deployment scenarios.
|
||||
*/
|
||||
public void setThreadPoolName(String threadPoolName) {
|
||||
WorkManager wm = (WorkManager) ReflectionUtils.invokeMethod(this.getWorkManagerMethod, null, threadPoolName);
|
||||
if (wm == null) {
|
||||
throw new IllegalArgumentException("Specified thread pool name '" + threadPoolName +
|
||||
"' does not correspond to an actual pool definition in GlassFish. Check your configuration!");
|
||||
}
|
||||
setWorkManager(wm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains GlassFish's default thread pool.
|
||||
*/
|
||||
@Override
|
||||
protected WorkManager getDefaultWorkManager() {
|
||||
return (WorkManager) ReflectionUtils.invokeMethod(this.getWorkManagerMethod, null, new Object[] {null});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
/**
|
||||
* Convenience package for obtaining a GlassFish JCA WorkManager for use in
|
||||
* web applications. Provides a Spring TaskExecutor adapter for GlassFish.
|
||||
*/
|
||||
package org.springframework.jca.work.glassfish;
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.jca.work.jboss;
|
||||
|
||||
import javax.resource.spi.work.WorkManager;
|
||||
|
||||
import org.springframework.jca.work.WorkManagerTaskExecutor;
|
||||
|
||||
/**
|
||||
* Spring TaskExecutor adapter for the JBoss JCA WorkManager.
|
||||
* Can be defined in web applications to make a TaskExecutor reference
|
||||
* available, talking to the JBoss WorkManager (thread pool) underneath.
|
||||
*
|
||||
* <p>This is the JBoss equivalent of the CommonJ
|
||||
* {@link org.springframework.scheduling.commonj.WorkManagerTaskExecutor}
|
||||
* adapter for WebLogic and WebSphere.
|
||||
*
|
||||
* <p>This class does not work on JBoss 7 or higher. There is no known
|
||||
* immediate replacement, since JBoss does not want its JCA WorkManager
|
||||
* to be exposed anymore. As of JBoss/WildFly 8, a
|
||||
* {@link org.springframework.scheduling.concurrent.DefaultManagedTaskExecutor}
|
||||
* may be used, following JSR-236 support in Java EE 7.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.2
|
||||
* @see org.jboss.resource.work.JBossWorkManagerMBean
|
||||
* @deprecated as of Spring 4.0, since there are no fully supported versions
|
||||
* of JBoss that this class works with anymore
|
||||
*/
|
||||
@Deprecated
|
||||
public class JBossWorkManagerTaskExecutor extends WorkManagerTaskExecutor {
|
||||
|
||||
/**
|
||||
* Identify a specific JBossWorkManagerMBean to talk to,
|
||||
* through its JMX object name.
|
||||
* <p>The default MBean name is "jboss.jca:service=WorkManager".
|
||||
* @see JBossWorkManagerUtils#getWorkManager(String)
|
||||
*/
|
||||
public void setWorkManagerMBeanName(String mbeanName) {
|
||||
setWorkManager(JBossWorkManagerUtils.getWorkManager(mbeanName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the default JBoss JCA WorkManager through a JMX lookup
|
||||
* for the JBossWorkManagerMBean.
|
||||
* @see JBossWorkManagerUtils#getWorkManager()
|
||||
*/
|
||||
@Override
|
||||
protected WorkManager getDefaultWorkManager() {
|
||||
return JBossWorkManagerUtils.getWorkManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.jca.work.jboss;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MBeanServerInvocationHandler;
|
||||
import javax.management.ObjectName;
|
||||
import javax.naming.InitialContext;
|
||||
import javax.resource.spi.work.WorkManager;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Utility class for obtaining the JBoss JCA WorkManager,
|
||||
* typically for use in web applications.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.2
|
||||
* @deprecated as of Spring 4.0, since there are no fully supported versions
|
||||
* of JBoss that this class works with anymore
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class JBossWorkManagerUtils {
|
||||
|
||||
private static final String JBOSS_WORK_MANAGER_MBEAN_CLASS_NAME = "org.jboss.resource.work.JBossWorkManagerMBean";
|
||||
|
||||
private static final String MBEAN_SERVER_CONNECTION_JNDI_NAME = "jmx/invoker/RMIAdaptor";
|
||||
|
||||
private static final String DEFAULT_WORK_MANAGER_MBEAN_NAME = "jboss.jca:service=WorkManager";
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the default JBoss JCA WorkManager through a JMX lookup
|
||||
* for the default JBossWorkManagerMBean.
|
||||
* @see org.jboss.resource.work.JBossWorkManagerMBean
|
||||
*/
|
||||
public static WorkManager getWorkManager() {
|
||||
return getWorkManager(DEFAULT_WORK_MANAGER_MBEAN_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the default JBoss JCA WorkManager through a JMX lookup
|
||||
* for the JBossWorkManagerMBean.
|
||||
* @param mbeanName the JMX object name to use
|
||||
* @see org.jboss.resource.work.JBossWorkManagerMBean
|
||||
*/
|
||||
public static WorkManager getWorkManager(String mbeanName) {
|
||||
Assert.hasLength(mbeanName, "JBossWorkManagerMBean name must not be empty");
|
||||
try {
|
||||
Class<?> mbeanClass = JBossWorkManagerUtils.class.getClassLoader().loadClass(JBOSS_WORK_MANAGER_MBEAN_CLASS_NAME);
|
||||
InitialContext jndiContext = new InitialContext();
|
||||
MBeanServerConnection mconn = (MBeanServerConnection) jndiContext.lookup(MBEAN_SERVER_CONNECTION_JNDI_NAME);
|
||||
ObjectName objectName = ObjectName.getInstance(mbeanName);
|
||||
Object workManagerMBean = MBeanServerInvocationHandler.newProxyInstance(mconn, objectName, mbeanClass, false);
|
||||
Method getInstanceMethod = workManagerMBean.getClass().getMethod("getInstance");
|
||||
return (WorkManager) getInstanceMethod.invoke(workManagerMBean);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize JBossWorkManagerTaskExecutor because JBoss API is not available", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
/**
|
||||
* Convenience package for obtaining a JBoss JCA WorkManager for use in
|
||||
* web applications. Provides a Spring TaskExecutor adapter for JBoss.
|
||||
*/
|
||||
package org.springframework.jca.work.jboss;
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.remoting.caucho;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import com.caucho.burlap.client.BurlapProxyFactory;
|
||||
import com.caucho.burlap.client.BurlapRuntimeException;
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.remoting.RemoteAccessException;
|
||||
import org.springframework.remoting.RemoteConnectFailureException;
|
||||
import org.springframework.remoting.RemoteLookupFailureException;
|
||||
import org.springframework.remoting.RemoteProxyFailureException;
|
||||
import org.springframework.remoting.support.UrlBasedRemoteAccessor;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link org.aopalliance.intercept.MethodInterceptor} for accessing a Burlap service.
|
||||
* Supports authentication via username and password.
|
||||
* The service URL must be an HTTP URL exposing a Burlap service.
|
||||
*
|
||||
* <p>Burlap is a slim, XML-based RPC protocol.
|
||||
* For information on Burlap, see the
|
||||
* <a href="http://www.caucho.com/burlap">Burlap website</a>
|
||||
*
|
||||
* <p>Note: There is no requirement for services accessed with this proxy factory
|
||||
* to have been exported using Spring's {@link BurlapServiceExporter}, as there is
|
||||
* no special handling involved. As a consequence, you can also access services that
|
||||
* have been exported using Caucho's {@link com.caucho.burlap.server.BurlapServlet}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 29.09.2003
|
||||
* @see #setServiceInterface
|
||||
* @see #setServiceUrl
|
||||
* @see #setUsername
|
||||
* @see #setPassword
|
||||
* @see BurlapServiceExporter
|
||||
* @see BurlapProxyFactoryBean
|
||||
* @see com.caucho.burlap.client.BurlapProxyFactory
|
||||
* @see com.caucho.burlap.server.BurlapServlet
|
||||
* @deprecated as of Spring 4.0, since Burlap hasn't evolved in years
|
||||
* and is effectively retired (in contrast to its sibling Hessian)
|
||||
*/
|
||||
@Deprecated
|
||||
public class BurlapClientInterceptor extends UrlBasedRemoteAccessor implements MethodInterceptor {
|
||||
|
||||
private BurlapProxyFactory proxyFactory = new BurlapProxyFactory();
|
||||
|
||||
private Object burlapProxy;
|
||||
|
||||
|
||||
/**
|
||||
* Set the BurlapProxyFactory instance to use.
|
||||
* If not specified, a default BurlapProxyFactory will be created.
|
||||
* <p>Allows to use an externally configured factory instance,
|
||||
* in particular a custom BurlapProxyFactory subclass.
|
||||
*/
|
||||
public void setProxyFactory(BurlapProxyFactory proxyFactory) {
|
||||
this.proxyFactory = (proxyFactory != null ? proxyFactory : new BurlapProxyFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username that this factory should use to access the remote service.
|
||||
* Default is none.
|
||||
* <p>The username will be sent by Burlap via HTTP Basic Authentication.
|
||||
* @see com.caucho.burlap.client.BurlapProxyFactory#setUser
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
this.proxyFactory.setUser(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password that this factory should use to access the remote service.
|
||||
* Default is none.
|
||||
* <p>The password will be sent by Burlap via HTTP Basic Authentication.
|
||||
* @see com.caucho.burlap.client.BurlapProxyFactory#setPassword
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
this.proxyFactory.setPassword(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether overloaded methods should be enabled for remote invocations.
|
||||
* Default is "false".
|
||||
* @see com.caucho.burlap.client.BurlapProxyFactory#setOverloadEnabled
|
||||
*/
|
||||
public void setOverloadEnabled(boolean overloadEnabled) {
|
||||
this.proxyFactory.setOverloadEnabled(overloadEnabled);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
prepare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the Burlap proxy for this interceptor.
|
||||
* @throws RemoteLookupFailureException if the service URL is invalid
|
||||
*/
|
||||
public void prepare() throws RemoteLookupFailureException {
|
||||
try {
|
||||
this.burlapProxy = createBurlapProxy(this.proxyFactory);
|
||||
}
|
||||
catch (MalformedURLException ex) {
|
||||
throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Burlap proxy that is wrapped by this interceptor.
|
||||
* @param proxyFactory the proxy factory to use
|
||||
* @return the Burlap proxy
|
||||
* @throws MalformedURLException if thrown by the proxy factory
|
||||
* @see com.caucho.burlap.client.BurlapProxyFactory#create
|
||||
*/
|
||||
protected Object createBurlapProxy(BurlapProxyFactory proxyFactory) throws MalformedURLException {
|
||||
Assert.notNull(getServiceInterface(), "Property 'serviceInterface' is required");
|
||||
return proxyFactory.create(getServiceInterface(), getServiceUrl());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
if (this.burlapProxy == null) {
|
||||
throw new IllegalStateException("BurlapClientInterceptor is not properly initialized - " +
|
||||
"invoke 'prepare' before attempting any operations");
|
||||
}
|
||||
|
||||
ClassLoader originalClassLoader = overrideThreadContextClassLoader();
|
||||
try {
|
||||
return invocation.getMethod().invoke(this.burlapProxy, invocation.getArguments());
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
Throwable targetEx = ex.getTargetException();
|
||||
if (targetEx instanceof BurlapRuntimeException) {
|
||||
Throwable cause = targetEx.getCause();
|
||||
throw convertBurlapAccessException(cause != null ? cause : targetEx);
|
||||
}
|
||||
else if (targetEx instanceof UndeclaredThrowableException) {
|
||||
UndeclaredThrowableException utex = (UndeclaredThrowableException) targetEx;
|
||||
throw convertBurlapAccessException(utex.getUndeclaredThrowable());
|
||||
}
|
||||
else {
|
||||
throw targetEx;
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new RemoteProxyFailureException(
|
||||
"Failed to invoke Burlap proxy for remote service [" + getServiceUrl() + "]", ex);
|
||||
}
|
||||
finally {
|
||||
resetThreadContextClassLoader(originalClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given Burlap access exception to an appropriate
|
||||
* Spring RemoteAccessException.
|
||||
* @param ex the exception to convert
|
||||
* @return the RemoteAccessException to throw
|
||||
*/
|
||||
protected RemoteAccessException convertBurlapAccessException(Throwable ex) {
|
||||
if (ex instanceof ConnectException) {
|
||||
return new RemoteConnectFailureException(
|
||||
"Cannot connect to Burlap remote service at [" + getServiceUrl() + "]", ex);
|
||||
}
|
||||
else {
|
||||
return new RemoteAccessException(
|
||||
"Cannot access Burlap remote service at [" + getServiceUrl() + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.remoting.caucho;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.caucho.burlap.io.BurlapInput;
|
||||
import com.caucho.burlap.io.BurlapOutput;
|
||||
import com.caucho.burlap.server.BurlapSkeleton;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.remoting.support.RemoteExporter;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* General stream-based protocol exporter for a Burlap endpoint.
|
||||
*
|
||||
* <p>Burlap is a slim, XML-based RPC protocol.
|
||||
* For information on Burlap, see the
|
||||
* <a href="http://www.caucho.com/burlap">Burlap website</a>.
|
||||
* This exporter requires Burlap 3.x.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.1
|
||||
* @see #invoke(java.io.InputStream, java.io.OutputStream)
|
||||
* @see BurlapServiceExporter
|
||||
* @see SimpleBurlapServiceExporter
|
||||
* @deprecated as of Spring 4.0, since Burlap hasn't evolved in years
|
||||
* and is effectively retired (in contrast to its sibling Hessian)
|
||||
*/
|
||||
@Deprecated
|
||||
public class BurlapExporter extends RemoteExporter implements InitializingBean {
|
||||
|
||||
private BurlapSkeleton skeleton;
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
prepare();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this service exporter.
|
||||
*/
|
||||
public void prepare() {
|
||||
checkService();
|
||||
checkServiceInterface();
|
||||
this.skeleton = new BurlapSkeleton(getProxyForService(), getServiceInterface());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform an invocation on the exported object.
|
||||
* @param inputStream the request stream
|
||||
* @param outputStream the response stream
|
||||
* @throws Throwable if invocation failed
|
||||
*/
|
||||
public void invoke(InputStream inputStream, OutputStream outputStream) throws Throwable {
|
||||
Assert.notNull(this.skeleton, "Burlap exporter has not been initialized");
|
||||
ClassLoader originalClassLoader = overrideThreadContextClassLoader();
|
||||
try {
|
||||
this.skeleton.invoke(new BurlapInput(inputStream), new BurlapOutput(outputStream));
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
try {
|
||||
outputStream.close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
resetThreadContextClassLoader(originalClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.remoting.caucho;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} for Burlap proxies. Exposes the proxied service
|
||||
* for use as a bean reference, using the specified service interface.
|
||||
*
|
||||
* <p>Burlap is a slim, XML-based RPC protocol.
|
||||
* For information on Burlap, see the
|
||||
* <a href="http://www.caucho.com/burlap">Burlap website</a>
|
||||
*
|
||||
* <p>The service URL must be an HTTP URL exposing a Burlap service.
|
||||
* For details, see the {@link BurlapClientInterceptor} javadoc.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 13.05.2003
|
||||
* @see #setServiceInterface
|
||||
* @see #setServiceUrl
|
||||
* @see BurlapClientInterceptor
|
||||
* @see BurlapServiceExporter
|
||||
* @see org.springframework.remoting.caucho.HessianProxyFactoryBean
|
||||
* @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
|
||||
* @see org.springframework.remoting.rmi.RmiProxyFactoryBean
|
||||
* @deprecated as of Spring 4.0, since Burlap hasn't evolved in years
|
||||
* and is effectively retired (in contrast to its sibling Hessian)
|
||||
*/
|
||||
@Deprecated
|
||||
public class BurlapProxyFactoryBean extends BurlapClientInterceptor implements FactoryBean<Object> {
|
||||
|
||||
private Object serviceProxy;
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
super.afterPropertiesSet();
|
||||
this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object getObject() {
|
||||
return this.serviceProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return getServiceInterface();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.remoting.caucho;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.util.NestedServletException;
|
||||
|
||||
/**
|
||||
* Servlet-API-based HTTP request handler that exports the specified service bean
|
||||
* as Burlap service endpoint, accessible via a Burlap proxy.
|
||||
*
|
||||
* <p><b>Note:</b> Spring also provides an alternative version of this exporter,
|
||||
* for Sun's JRE 1.6 HTTP server: {@link SimpleBurlapServiceExporter}.
|
||||
*
|
||||
* <p>Burlap is a slim, XML-based RPC protocol.
|
||||
* For information on Burlap, see the
|
||||
* <a href="http://www.caucho.com/burlap">Burlap website</a>.
|
||||
* This exporter requires Burlap 3.x.
|
||||
*
|
||||
* <p>Note: Burlap services exported with this class can be accessed by
|
||||
* any Burlap client, as there isn't any special handling involved.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 13.05.2003
|
||||
* @see BurlapClientInterceptor
|
||||
* @see BurlapProxyFactoryBean
|
||||
* @see org.springframework.remoting.caucho.HessianServiceExporter
|
||||
* @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
|
||||
* @see org.springframework.remoting.rmi.RmiServiceExporter
|
||||
* @deprecated as of Spring 4.0, since Burlap hasn't evolved in years
|
||||
* and is effectively retired (in contrast to its sibling Hessian)
|
||||
*/
|
||||
@Deprecated
|
||||
public class BurlapServiceExporter extends BurlapExporter implements HttpRequestHandler {
|
||||
|
||||
/**
|
||||
* Processes the incoming Burlap request and creates a Burlap response.
|
||||
*/
|
||||
@Override
|
||||
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
|
||||
if (!"POST".equals(request.getMethod())) {
|
||||
throw new HttpRequestMethodNotSupportedException(request.getMethod(),
|
||||
new String[] {"POST"}, "BurlapServiceExporter only supports POST requests");
|
||||
}
|
||||
|
||||
try {
|
||||
invoke(request.getInputStream(), response.getOutputStream());
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new NestedServletException("Burlap skeleton invocation failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* 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.remoting.caucho;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import com.sun.net.httpserver.HttpHandler;
|
||||
|
||||
import org.springframework.lang.UsesSunHttpServer;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* HTTP request handler that exports the specified service bean as
|
||||
* Burlap service endpoint, accessible via a Burlap proxy.
|
||||
* Designed for Sun's JRE 1.6 HTTP server, implementing the
|
||||
* {@link com.sun.net.httpserver.HttpHandler} interface.
|
||||
*
|
||||
* <p>Burlap is a slim, XML-based RPC protocol.
|
||||
* For information on Burlap, see the
|
||||
* <a href="http://www.caucho.com/burlap">Burlap website</a>.
|
||||
* This exporter requires Burlap 3.x.
|
||||
*
|
||||
* <p>Note: Burlap services exported with this class can be accessed by
|
||||
* any Burlap client, as there isn't any special handling involved.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.1
|
||||
* @see org.springframework.remoting.caucho.BurlapClientInterceptor
|
||||
* @see org.springframework.remoting.caucho.BurlapProxyFactoryBean
|
||||
* @see SimpleHessianServiceExporter
|
||||
* @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter
|
||||
* @deprecated as of Spring 4.0, since Burlap hasn't evolved in years
|
||||
* and is effectively retired (in contrast to its sibling Hessian)
|
||||
*/
|
||||
@Deprecated
|
||||
@UsesSunHttpServer
|
||||
public class SimpleBurlapServiceExporter extends BurlapExporter implements HttpHandler {
|
||||
|
||||
/**
|
||||
* Processes the incoming Burlap request and creates a Burlap response.
|
||||
*/
|
||||
@Override
|
||||
public void handle(HttpExchange exchange) throws IOException {
|
||||
if (!"POST".equals(exchange.getRequestMethod())) {
|
||||
exchange.getResponseHeaders().set("Allow", "POST");
|
||||
exchange.sendResponseHeaders(405, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
invoke(exchange.getRequestBody(), output);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
exchange.sendResponseHeaders(500, -1);
|
||||
logger.error("Burlap skeleton invocation failed", ex);
|
||||
}
|
||||
|
||||
exchange.sendResponseHeaders(200, output.size());
|
||||
FileCopyUtils.copy(output.toByteArray(), exchange.getResponseBody());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 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.request;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.NDC;
|
||||
|
||||
import org.springframework.ui.ModelMap;
|
||||
|
||||
/**
|
||||
* Request logging interceptor that adds a request context message to the
|
||||
* Log4J nested diagnostic context (NDC) before the request is processed,
|
||||
* removing it again after the request is processed.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5
|
||||
* @see org.apache.log4j.NDC#push(String)
|
||||
* @see org.apache.log4j.NDC#pop()
|
||||
* @deprecated as of Spring 4.2.1, in favor of Apache Log4j 2
|
||||
* (following Apache's EOL declaration for log4j 1.x)
|
||||
*/
|
||||
@Deprecated
|
||||
public class Log4jNestedDiagnosticContextInterceptor implements AsyncWebRequestInterceptor {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Logger log4jLogger = Logger.getLogger(getClass());
|
||||
|
||||
private boolean includeClientInfo = false;
|
||||
|
||||
|
||||
/**
|
||||
* Set whether or not the session id and user name should be included
|
||||
* in the log message.
|
||||
*/
|
||||
public void setIncludeClientInfo(boolean includeClientInfo) {
|
||||
this.includeClientInfo = includeClientInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the session id and user name should be included
|
||||
* in the log message.
|
||||
*/
|
||||
protected boolean isIncludeClientInfo() {
|
||||
return this.includeClientInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a message the Log4J NDC before the request is processed.
|
||||
*/
|
||||
@Override
|
||||
public void preHandle(WebRequest request) throws Exception {
|
||||
NDC.push(getNestedDiagnosticContextMessage(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the message to be pushed onto the Log4J nested diagnostic context.
|
||||
* <p>Default is the request object's {@code getDescription} result.
|
||||
* @param request current HTTP request
|
||||
* @return the message to be pushed onto the Log4J NDC
|
||||
* @see WebRequest#getDescription
|
||||
* @see #isIncludeClientInfo()
|
||||
*/
|
||||
protected String getNestedDiagnosticContextMessage(WebRequest request) {
|
||||
return request.getDescription(isIncludeClientInfo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postHandle(WebRequest request, ModelMap model) throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the log message from the Log4J NDC after the request is processed.
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
|
||||
NDC.pop();
|
||||
if (NDC.getDepth() == 0) {
|
||||
NDC.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the log message from the Log4J NDC when the processing thread is
|
||||
* exited after the start of asynchronous request handling.
|
||||
*/
|
||||
@Override
|
||||
public void afterConcurrentHandlingStarted(WebRequest request) {
|
||||
NDC.pop();
|
||||
if (NDC.getDepth() == 0) {
|
||||
NDC.remove();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2008 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.filter;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.log4j.NDC;
|
||||
|
||||
/**
|
||||
* Request logging filter that adds the request log message to the Log4J
|
||||
* nested diagnostic context (NDC) before the request is processed,
|
||||
* removing it again after the request is processed.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @since 1.2.5
|
||||
* @see #setIncludeQueryString
|
||||
* @see #setBeforeMessagePrefix
|
||||
* @see #setBeforeMessageSuffix
|
||||
* @see #setAfterMessagePrefix
|
||||
* @see #setAfterMessageSuffix
|
||||
* @see org.apache.log4j.NDC#push(String)
|
||||
* @see org.apache.log4j.NDC#pop()
|
||||
* @deprecated as of Spring 4.2.1, in favor of Apache Log4j 2
|
||||
* (following Apache's EOL declaration for log4j 1.x)
|
||||
*/
|
||||
@Deprecated
|
||||
public class Log4jNestedDiagnosticContextFilter extends AbstractRequestLoggingFilter {
|
||||
|
||||
/** Logger available to subclasses */
|
||||
protected final Logger log4jLogger = Logger.getLogger(getClass());
|
||||
|
||||
|
||||
/**
|
||||
* Logs the before-request message through Log4J and
|
||||
* adds a message the Log4J NDC before the request is processed.
|
||||
*/
|
||||
@Override
|
||||
protected void beforeRequest(HttpServletRequest request, String message) {
|
||||
if (log4jLogger.isDebugEnabled()) {
|
||||
log4jLogger.debug(message);
|
||||
}
|
||||
NDC.push(getNestedDiagnosticContextMessage(request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the message to be pushed onto the Log4J nested diagnostic context.
|
||||
* <p>Default is a plain request log message without prefix or suffix.
|
||||
* @param request current HTTP request
|
||||
* @return the message to be pushed onto the Log4J NDC
|
||||
* @see #createMessage
|
||||
*/
|
||||
protected String getNestedDiagnosticContextMessage(HttpServletRequest request) {
|
||||
return createMessage(request, "", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the log message from the Log4J NDC after the request is processed
|
||||
* and logs the after-request message through Log4J.
|
||||
*/
|
||||
@Override
|
||||
protected void afterRequest(HttpServletRequest request, String message) {
|
||||
NDC.pop();
|
||||
if (NDC.getDepth() == 0) {
|
||||
NDC.remove();
|
||||
}
|
||||
if (log4jLogger.isDebugEnabled()) {
|
||||
log4jLogger.debug(message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 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.util;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
/**
|
||||
* Bootstrap listener for custom log4j initialization in a web environment.
|
||||
* Delegates to {@link Log4jWebConfigurer} (see its javadoc for configuration details).
|
||||
*
|
||||
* <b>WARNING: Assumes an expanded WAR file</b>, both for loading the configuration
|
||||
* file and for writing the log files. If you want to keep your WAR unexpanded or
|
||||
* don't need application-specific log files within the WAR directory, don't use
|
||||
* log4j setup within the application (thus, don't use Log4jConfigListener or
|
||||
* Log4jConfigServlet). Instead, use a global, VM-wide log4j setup (for example,
|
||||
* in JBoss) or JDK 1.4's {@code java.util.logging} (which is global too).
|
||||
*
|
||||
* <p>This listener should be registered before ContextLoaderListener in {@code web.xml}
|
||||
* when using custom log4j initialization.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 13.03.2003
|
||||
* @see Log4jWebConfigurer
|
||||
* @see org.springframework.web.context.ContextLoaderListener
|
||||
* @see WebAppRootListener
|
||||
* @deprecated as of Spring 4.2.1, in favor of Apache Log4j 2
|
||||
* (following Apache's EOL declaration for log4j 1.x)
|
||||
*/
|
||||
@Deprecated
|
||||
public class Log4jConfigListener implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent event) {
|
||||
Log4jWebConfigurer.initLogging(event.getServletContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent event) {
|
||||
Log4jWebConfigurer.shutdownLogging(event.getServletContext());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Convenience class that performs custom log4j initialization for web environments,
|
||||
* allowing for log file paths within the web application, with the option to
|
||||
* perform automatic refresh checks (for runtime changes in logging configuration).
|
||||
*
|
||||
* <p><b>WARNING: Assumes an expanded WAR file</b>, both for loading the configuration
|
||||
* file and for writing the log files. If you want to keep your WAR unexpanded or
|
||||
* don't need application-specific log files within the WAR directory, don't use
|
||||
* log4j setup within the application (thus, don't use Log4jConfigListener or
|
||||
* Log4jConfigServlet). Instead, use a global, VM-wide log4j setup (for example,
|
||||
* in JBoss) or JDK 1.4's {@code java.util.logging} (which is global too).
|
||||
*
|
||||
* <p>Supports three init parameters at the servlet context level (that is,
|
||||
* context-param entries in web.xml):
|
||||
*
|
||||
* <ul>
|
||||
* <li><i>"log4jConfigLocation":</i><br>
|
||||
* Location of the log4j config file; either a "classpath:" location (e.g.
|
||||
* "classpath:myLog4j.properties"), an absolute file URL (e.g. "file:C:/log4j.properties),
|
||||
* or a plain path relative to the web application root directory (e.g.
|
||||
* "/WEB-INF/log4j.properties"). If not specified, default log4j initialization
|
||||
* will apply ("log4j.properties" or "log4j.xml" in the class path; see the
|
||||
* log4j documentation for details).
|
||||
* <li><i>"log4jRefreshInterval":</i><br>
|
||||
* Interval between config file refresh checks, in milliseconds. If not specified,
|
||||
* no refresh checks will happen, which avoids starting log4j's watchdog thread.
|
||||
* <li><i>"log4jExposeWebAppRoot":</i><br>
|
||||
* Whether the web app root system property should be exposed, allowing for log
|
||||
* file paths relative to the web application root directory. Default is "true";
|
||||
* specify "false" to suppress expose of the web app root system property. See
|
||||
* below for details on how to use this system property in log file locations.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Note: {@code initLogging} should be called before any other Spring activity
|
||||
* (when using log4j), for proper initialization before any Spring logging attempts.
|
||||
*
|
||||
* <p>Log4j's watchdog thread will asynchronously check whether the timestamp
|
||||
* of the config file has changed, using the given interval between checks.
|
||||
* A refresh interval of 1000 milliseconds (one second), which allows to
|
||||
* do on-demand log level changes with immediate effect, is not unfeasible.
|
||||
|
||||
* <p><b>WARNING:</b> Log4j's watchdog thread does not terminate until VM shutdown;
|
||||
* in particular, it does not terminate on LogManager shutdown. Therefore, it is
|
||||
* recommended to <i>not</i> use config file refreshing in a production J2EE
|
||||
* environment; the watchdog thread would not stop on application shutdown there.
|
||||
*
|
||||
* <p>By default, this configurer automatically sets the web app root system property,
|
||||
* for "${key}" substitutions within log file locations in the log4j config file,
|
||||
* allowing for log file paths relative to the web application root directory.
|
||||
* The default system property key is "webapp.root", to be used in a log4j config
|
||||
* file like as follows:
|
||||
*
|
||||
* <p>{@code log4j.appender.myfile.File=${webapp.root}/WEB-INF/demo.log}
|
||||
*
|
||||
* <p>Alternatively, specify a unique context-param "webAppRootKey" per web application.
|
||||
* For example, with "webAppRootKey = "demo.root":
|
||||
*
|
||||
* <p>{@code log4j.appender.myfile.File=${demo.root}/WEB-INF/demo.log}
|
||||
*
|
||||
* <p><b>WARNING:</b> Some containers (like Tomcat) do <i>not</i> keep system properties
|
||||
* separate per web app. You have to use unique "webAppRootKey" context-params per web
|
||||
* app then, to avoid clashes. Other containers like Resin do isolate each web app's
|
||||
* system properties: Here you can use the default key (i.e. no "webAppRootKey"
|
||||
* context-param at all) without worrying.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Marten Deinum
|
||||
* @since 12.08.2003
|
||||
* @see org.springframework.util.Log4jConfigurer
|
||||
* @see Log4jConfigListener
|
||||
* @deprecated as of Spring 4.2.1, in favor of Apache Log4j 2
|
||||
* (following Apache's EOL declaration for log4j 1.x)
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class Log4jWebConfigurer {
|
||||
|
||||
/** Parameter specifying the location of the log4j config file */
|
||||
public static final String CONFIG_LOCATION_PARAM = "log4jConfigLocation";
|
||||
|
||||
/** Parameter specifying the refresh interval for checking the log4j config file */
|
||||
public static final String REFRESH_INTERVAL_PARAM = "log4jRefreshInterval";
|
||||
|
||||
/** Parameter specifying whether to expose the web app root system property */
|
||||
public static final String EXPOSE_WEB_APP_ROOT_PARAM = "log4jExposeWebAppRoot";
|
||||
|
||||
|
||||
/**
|
||||
* Initialize log4j, including setting the web app root system property.
|
||||
* @param servletContext the current ServletContext
|
||||
* @see WebUtils#setWebAppRootSystemProperty
|
||||
*/
|
||||
public static void initLogging(ServletContext servletContext) {
|
||||
// Expose the web app root system property.
|
||||
if (exposeWebAppRoot(servletContext)) {
|
||||
WebUtils.setWebAppRootSystemProperty(servletContext);
|
||||
}
|
||||
|
||||
// Only perform custom log4j initialization in case of a config file.
|
||||
String location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
|
||||
if (location != null) {
|
||||
// Perform actual log4j initialization; else rely on log4j's default initialization.
|
||||
try {
|
||||
// Resolve property placeholders before potentially resolving a real path.
|
||||
location = ServletContextPropertyUtils.resolvePlaceholders(location, servletContext);
|
||||
|
||||
// Leave a URL (e.g. "classpath:" or "file:") as-is.
|
||||
if (!ResourceUtils.isUrl(location)) {
|
||||
// Consider a plain file path as relative to the web application root directory.
|
||||
location = WebUtils.getRealPath(servletContext, location);
|
||||
}
|
||||
|
||||
// Write log message to server log.
|
||||
servletContext.log("Initializing log4j from [" + location + "]");
|
||||
|
||||
// Check whether refresh interval was specified.
|
||||
String intervalString = servletContext.getInitParameter(REFRESH_INTERVAL_PARAM);
|
||||
if (StringUtils.hasText(intervalString)) {
|
||||
// Initialize with refresh interval, i.e. with log4j's watchdog thread,
|
||||
// checking the file in the background.
|
||||
try {
|
||||
long refreshInterval = Long.parseLong(intervalString);
|
||||
org.springframework.util.Log4jConfigurer.initLogging(location, refreshInterval);
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalArgumentException("Invalid 'log4jRefreshInterval' parameter: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Initialize without refresh check, i.e. without log4j's watchdog thread.
|
||||
org.springframework.util.Log4jConfigurer.initLogging(location);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException ex) {
|
||||
throw new IllegalArgumentException("Invalid 'log4jConfigLocation' parameter: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shut down log4j, properly releasing all file locks
|
||||
* and resetting the web app root system property.
|
||||
* @param servletContext the current ServletContext
|
||||
* @see WebUtils#removeWebAppRootSystemProperty
|
||||
*/
|
||||
public static void shutdownLogging(ServletContext servletContext) {
|
||||
servletContext.log("Shutting down log4j");
|
||||
try {
|
||||
org.springframework.util.Log4jConfigurer.shutdownLogging();
|
||||
}
|
||||
finally {
|
||||
// Remove the web app root system property.
|
||||
if (exposeWebAppRoot(servletContext)) {
|
||||
WebUtils.removeWebAppRootSystemProperty(servletContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether to expose the web app root system property,
|
||||
* checking the corresponding ServletContext init parameter.
|
||||
* @see #EXPOSE_WEB_APP_ROOT_PARAM
|
||||
*/
|
||||
private static boolean exposeWebAppRoot(ServletContext servletContext) {
|
||||
String exposeWebAppRootParam = servletContext.getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);
|
||||
return (exposeWebAppRootParam == null || Boolean.valueOf(exposeWebAppRootParam));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
|
|
@ -19,6 +19,8 @@ package org.springframework.remoting.caucho;
|
|||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
|
@ -29,11 +31,6 @@ import org.springframework.tests.sample.beans.ITestBean;
|
|||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
import com.caucho.burlap.client.BurlapProxyFactory;
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
|
||||
import com.sun.net.httpserver.HttpServer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
|
|
@ -111,63 +108,6 @@ public class CauchoRemotingTests {
|
|||
bean.setName("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void burlapProxyFactoryBeanWithAccessError() throws Exception {
|
||||
BurlapProxyFactoryBean factory = new BurlapProxyFactoryBean();
|
||||
factory.setServiceInterface(ITestBean.class);
|
||||
factory.setServiceUrl("http://localhosta/testbean");
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
assertTrue("Correct singleton value", factory.isSingleton());
|
||||
assertTrue(factory.getObject() instanceof ITestBean);
|
||||
ITestBean bean = (ITestBean) factory.getObject();
|
||||
|
||||
exception.expect(RemoteAccessException.class);
|
||||
bean.setName("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void burlapProxyFactoryBeanWithAuthenticationAndAccessError() throws Exception {
|
||||
BurlapProxyFactoryBean factory = new BurlapProxyFactoryBean();
|
||||
factory.setServiceInterface(ITestBean.class);
|
||||
factory.setServiceUrl("http://localhosta/testbean");
|
||||
factory.setUsername("test");
|
||||
factory.setPassword("bean");
|
||||
factory.setOverloadEnabled(true);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
assertTrue("Correct singleton value", factory.isSingleton());
|
||||
assertTrue(factory.getObject() instanceof ITestBean);
|
||||
ITestBean bean = (ITestBean) factory.getObject();
|
||||
|
||||
exception.expect(RemoteAccessException.class);
|
||||
bean.setName("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void burlapProxyFactoryBeanWithCustomProxyFactory() throws Exception {
|
||||
TestBurlapProxyFactory proxyFactory = new TestBurlapProxyFactory();
|
||||
BurlapProxyFactoryBean factory = new BurlapProxyFactoryBean();
|
||||
factory.setServiceInterface(ITestBean.class);
|
||||
factory.setServiceUrl("http://localhosta/testbean");
|
||||
factory.setProxyFactory(proxyFactory);
|
||||
factory.setUsername("test");
|
||||
factory.setPassword("bean");
|
||||
factory.setOverloadEnabled(true);
|
||||
factory.afterPropertiesSet();
|
||||
|
||||
assertTrue("Correct singleton value", factory.isSingleton());
|
||||
assertTrue(factory.getObject() instanceof ITestBean);
|
||||
ITestBean bean = (ITestBean) factory.getObject();
|
||||
|
||||
assertEquals(proxyFactory.user, "test");
|
||||
assertEquals(proxyFactory.password, "bean");
|
||||
assertTrue(proxyFactory.overloadEnabled);
|
||||
|
||||
exception.expect(RemoteAccessException.class);
|
||||
bean.setName("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleHessianServiceExporter() throws IOException {
|
||||
final int port = SocketUtils.findAvailableTcpPort();
|
||||
|
|
@ -221,27 +161,4 @@ public class CauchoRemotingTests {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private static class TestBurlapProxyFactory extends BurlapProxyFactory {
|
||||
|
||||
private String user;
|
||||
private String password;
|
||||
private boolean overloadEnabled;
|
||||
|
||||
@Override
|
||||
public void setUser(String user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverloadEnabled(boolean overloadEnabled) {
|
||||
this.overloadEnabled = overloadEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,143 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.util;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.io.FileSystemResourceLoader;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assume.*;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @author Sam Brannen
|
||||
* @since 21.02.2005
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Log4jWebConfigurerTests {
|
||||
|
||||
private static final String TESTLOG4J_PROPERTIES = "testlog4j.properties";
|
||||
private static final String PROPERTIES_LOCATION = "org/springframework/web/util/testlog4j.properties";
|
||||
private static final String CLASSPATH_RESOURCE = "classpath:" + PROPERTIES_LOCATION;
|
||||
private static final String RELATIVE_PATH = "src/test/resources/" + PROPERTIES_LOCATION;
|
||||
|
||||
@Test
|
||||
public void initLoggingWithClasspathResource() {
|
||||
initLogging(CLASSPATH_RESOURCE, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithClasspathResourceAndRefreshInterval() {
|
||||
initLogging(CLASSPATH_RESOURCE, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithRelativeFilePath() {
|
||||
initLogging(RELATIVE_PATH, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithRelativeFilePathAndRefreshInterval() {
|
||||
initLogging(RELATIVE_PATH, true);
|
||||
}
|
||||
|
||||
@Test // See SPR-9417
|
||||
public void initLoggingWithPlaceholderResolvingToValidUrl() {
|
||||
initLogging("${some.prop.name:classpath:}" + PROPERTIES_LOCATION, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithUrl() {
|
||||
URL url = Log4jWebConfigurerTests.class.getResource(TESTLOG4J_PROPERTIES);
|
||||
initLogging(url.toString(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithUrlAndRefreshInterval() {
|
||||
URL url = Log4jWebConfigurerTests.class.getResource(TESTLOG4J_PROPERTIES);
|
||||
initLogging(url.toString(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initLoggingWithAbsoluteFilePathAndRefreshInterval() {
|
||||
// Only works on MS Windows
|
||||
assumeThat(System.getProperty("os.name"), containsString("Windows"));
|
||||
|
||||
URL url = Log4jWebConfigurerTests.class.getResource(TESTLOG4J_PROPERTIES);
|
||||
initLogging(url.getFile(), true);
|
||||
}
|
||||
|
||||
private void initLogging(String location, boolean refreshInterval) {
|
||||
MockServletContext sc = new MockServletContext("", new FileSystemResourceLoader());
|
||||
sc.addInitParameter(Log4jWebConfigurer.CONFIG_LOCATION_PARAM, location);
|
||||
if (refreshInterval) {
|
||||
sc.addInitParameter(Log4jWebConfigurer.REFRESH_INTERVAL_PARAM, "10");
|
||||
}
|
||||
Log4jWebConfigurer.initLogging(sc);
|
||||
|
||||
try {
|
||||
assertLogOutput();
|
||||
}
|
||||
finally {
|
||||
Log4jWebConfigurer.shutdownLogging(sc);
|
||||
}
|
||||
assertTrue(MockLog4jAppender.closeCalled);
|
||||
}
|
||||
|
||||
private void assertLogOutput() {
|
||||
Log log = LogFactory.getLog(this.getClass());
|
||||
log.debug("debug");
|
||||
log.info("info");
|
||||
log.warn("warn");
|
||||
log.error("error");
|
||||
log.fatal("fatal");
|
||||
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("debug"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("info"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("warn"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("error"));
|
||||
assertTrue(MockLog4jAppender.loggingStrings.contains("fatal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLog4jConfigListener() {
|
||||
Log4jConfigListener listener = new Log4jConfigListener();
|
||||
|
||||
MockServletContext sc = new MockServletContext("", new FileSystemResourceLoader());
|
||||
sc.addInitParameter(Log4jWebConfigurer.CONFIG_LOCATION_PARAM, RELATIVE_PATH);
|
||||
listener.contextInitialized(new ServletContextEvent(sc));
|
||||
|
||||
try {
|
||||
assertLogOutput();
|
||||
}
|
||||
finally {
|
||||
listener.contextDestroyed(new ServletContextEvent(sc));
|
||||
}
|
||||
assertTrue(MockLog4jAppender.closeCalled);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.AppenderSkeleton;
|
||||
import org.apache.log4j.spi.LoggingEvent;
|
||||
|
||||
/**
|
||||
* @author Alef Arendsen
|
||||
*/
|
||||
public class MockLog4jAppender extends AppenderSkeleton {
|
||||
|
||||
public static final List<Object> loggingStrings = new ArrayList<Object>();
|
||||
|
||||
public static boolean closeCalled = false;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent)
|
||||
*/
|
||||
@Override
|
||||
protected void append(LoggingEvent evt) {
|
||||
//System.out.println("Adding " + evt.getMessage());
|
||||
loggingStrings.add(evt.getMessage());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.log4j.Appender#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
closeCalled = true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.log4j.Appender#requiresLayout()
|
||||
*/
|
||||
@Override
|
||||
public boolean requiresLayout() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.servlet.view.document;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.LocalizedResourceHelper;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
/**
|
||||
* Convenient superclass for Excel document views.
|
||||
* Compatible with Apache POI 3.5 and higher, as of Spring 4.0.
|
||||
*
|
||||
* <p>Properties:
|
||||
* <ul>
|
||||
* <li>url (optional): The url of an existing Excel document to pick as a starting point.
|
||||
* It is done without localization part nor the ".xls" extension.
|
||||
* </ul>
|
||||
*
|
||||
* <p>The file will be searched with locations in the following order:
|
||||
* <ul>
|
||||
* <li>[url]_[language]_[country].xls
|
||||
* <li>[url]_[language].xls
|
||||
* <li>[url].xls
|
||||
* </ul>
|
||||
*
|
||||
* <p>For working with the workbook in the subclass, see
|
||||
* <a href="http://poi.apache.org">Apache's POI site</a>
|
||||
*
|
||||
* <p>As an example, you can try this snippet:
|
||||
*
|
||||
* <pre class="code">
|
||||
* protected void buildExcelDocument(
|
||||
* Map<String, Object> model, HSSFWorkbook workbook,
|
||||
* HttpServletRequest request, HttpServletResponse response) {
|
||||
*
|
||||
* // Go to the first sheet.
|
||||
* // getSheetAt: only if workbook is created from an existing document
|
||||
* // HSSFSheet sheet = workbook.getSheetAt(0);
|
||||
* HSSFSheet sheet = workbook.createSheet("Spring");
|
||||
* sheet.setDefaultColumnWidth(12);
|
||||
*
|
||||
* // Write a text at A1.
|
||||
* HSSFCell cell = getCell(sheet, 0, 0);
|
||||
* setText(cell, "Spring POI test");
|
||||
*
|
||||
* // Write the current date at A2.
|
||||
* HSSFCellStyle dateStyle = workbook.createCellStyle();
|
||||
* dateStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy"));
|
||||
* cell = getCell(sheet, 1, 0);
|
||||
* cell.setCellValue(new Date());
|
||||
* cell.setCellStyle(dateStyle);
|
||||
*
|
||||
* // Write a number at A3
|
||||
* getCell(sheet, 2, 0).setCellValue(458);
|
||||
*
|
||||
* // Write a range of numbers.
|
||||
* HSSFRow sheetRow = sheet.createRow(3);
|
||||
* for (short i = 0; i < 10; i++) {
|
||||
* sheetRow.createCell(i).setCellValue(i * 10);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* This class is similar to the AbstractPdfView class in usage style.
|
||||
*
|
||||
* @author Jean-Pierre Pawlak
|
||||
* @author Juergen Hoeller
|
||||
* @see AbstractPdfView
|
||||
* @deprecated as of Spring 4.2, in favor of {@link AbstractXlsView} and its
|
||||
* {@link AbstractXlsxView} and {@link AbstractXlsxStreamingView} variants
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractExcelView extends AbstractView {
|
||||
|
||||
/** The content type for an Excel response */
|
||||
private static final String CONTENT_TYPE = "application/vnd.ms-excel";
|
||||
|
||||
/** The extension to look for existing templates */
|
||||
private static final String EXTENSION = ".xls";
|
||||
|
||||
|
||||
private String url;
|
||||
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
* Sets the content type of the view to "application/vnd.ms-excel".
|
||||
*/
|
||||
public AbstractExcelView() {
|
||||
setContentType(CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URL of the Excel workbook source, without localization part nor extension.
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean generatesDownloadContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Excel view, given the specified model.
|
||||
*/
|
||||
@Override
|
||||
protected final void renderMergedOutputModel(
|
||||
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
HSSFWorkbook workbook;
|
||||
if (this.url != null) {
|
||||
workbook = getTemplateSource(this.url, request);
|
||||
}
|
||||
else {
|
||||
workbook = new HSSFWorkbook();
|
||||
logger.debug("Created Excel Workbook from scratch");
|
||||
}
|
||||
|
||||
buildExcelDocument(model, workbook, request, response);
|
||||
|
||||
// Set the content type.
|
||||
response.setContentType(getContentType());
|
||||
|
||||
// Should we set the content length here?
|
||||
// response.setContentLength(workbook.getBytes().length);
|
||||
|
||||
// Flush byte array to servlet output stream.
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
workbook.write(out);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the workbook from an existing XLS document.
|
||||
* @param url the URL of the Excel template without localization part nor extension
|
||||
* @param request current HTTP request
|
||||
* @return the HSSFWorkbook
|
||||
* @throws Exception in case of failure
|
||||
*/
|
||||
protected HSSFWorkbook getTemplateSource(String url, HttpServletRequest request) throws Exception {
|
||||
LocalizedResourceHelper helper = new LocalizedResourceHelper(getApplicationContext());
|
||||
Locale userLocale = RequestContextUtils.getLocale(request);
|
||||
Resource inputFile = helper.findLocalizedResource(url, EXTENSION, userLocale);
|
||||
|
||||
// Create the Excel document from the source.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loading Excel workbook from " + inputFile);
|
||||
}
|
||||
return new HSSFWorkbook(inputFile.getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to create an Excel HSSFWorkbook document,
|
||||
* given the model.
|
||||
* @param model the model Map
|
||||
* @param workbook the Excel workbook to complete
|
||||
* @param request in case we need locale etc. Shouldn't look at attributes.
|
||||
* @param response in case we need to set cookies. Shouldn't write to it.
|
||||
*/
|
||||
protected abstract void buildExcelDocument(
|
||||
Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception;
|
||||
|
||||
|
||||
/**
|
||||
* Convenient method to obtain the cell in the given sheet, row and column.
|
||||
* <p>Creates the row and the cell if they still doesn't already exist.
|
||||
* Thus, the column can be passed as an int, the method making the needed downcasts.
|
||||
* @param sheet a sheet object. The first sheet is usually obtained by workbook.getSheetAt(0)
|
||||
* @param row the row number
|
||||
* @param col the column number
|
||||
* @return the HSSFCell
|
||||
*/
|
||||
protected HSSFCell getCell(HSSFSheet sheet, int row, int col) {
|
||||
HSSFRow sheetRow = sheet.getRow(row);
|
||||
if (sheetRow == null) {
|
||||
sheetRow = sheet.createRow(row);
|
||||
}
|
||||
HSSFCell cell = sheetRow.getCell(col);
|
||||
if (cell == null) {
|
||||
cell = sheetRow.createCell(col);
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method to set a String as text content in a cell.
|
||||
* @param cell the cell in which the text must be put
|
||||
* @param text the text to put in the cell
|
||||
*/
|
||||
protected void setText(HSSFCell cell, String text) {
|
||||
cell.setCellType(HSSFCell.CELL_TYPE_STRING);
|
||||
cell.setCellValue(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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.servlet.view.document;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import jxl.Workbook;
|
||||
import jxl.write.WritableWorkbook;
|
||||
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.LocalizedResourceHelper;
|
||||
import org.springframework.web.servlet.support.RequestContextUtils;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
/**
|
||||
* Convenient superclass for Excel document views.
|
||||
*
|
||||
* <p>This class uses the <i>JExcelAPI</i> instead of <i>POI</i>.
|
||||
* More information on <i>JExcelAPI</i> can be found on their
|
||||
* <a href="http://www.andykhan.com/jexcelapi/" target="_blank">website</a>.
|
||||
*
|
||||
* <p>Properties:
|
||||
* <ul>
|
||||
* <li>url (optional): The url of an existing Excel document to pick as a
|
||||
* starting point. It is done without localization part nor the .xls extension.
|
||||
* </ul>
|
||||
*
|
||||
* <p>The file will be searched with locations in the following order:
|
||||
* <ul>
|
||||
* <li>[url]_[language]_[country].xls
|
||||
* <li>[url]_[language].xls
|
||||
* <li>[url].xls
|
||||
* </ul>
|
||||
*
|
||||
* <p>For working with the workbook in the subclass, see <a
|
||||
* href="http://www.andykhan.com/jexcelapi/">Java Excel API site</a>
|
||||
*
|
||||
* <p>As an example, you can try this snippet:
|
||||
*
|
||||
* <pre class="code">
|
||||
* protected void buildExcelDocument(
|
||||
* Map<String, Object> model, WritableWorkbook workbook,
|
||||
* HttpServletRequest request, HttpServletResponse response) {
|
||||
*
|
||||
* if (workbook.getNumberOfSheets() == 0) {
|
||||
* workbook.createSheet("Spring", 0);
|
||||
* }
|
||||
*
|
||||
* WritableSheet sheet = workbook.getSheet("Spring");
|
||||
* Label label = new Label(0, 0, "This is a nice label");
|
||||
* sheet.addCell(label);
|
||||
* }</pre>
|
||||
*
|
||||
* The use of this view is close to the {@link AbstractExcelView} class,
|
||||
* just using the JExcel API instead of the Apache POI API.
|
||||
*
|
||||
* @author Bram Smeets
|
||||
* @author Alef Arendsen
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.2.5
|
||||
* @see AbstractExcelView
|
||||
* @see AbstractPdfView
|
||||
* @deprecated as of Spring 4.0, since JExcelAPI is an abandoned project
|
||||
* (no release since 2009, with serious bugs remaining)
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class AbstractJExcelView extends AbstractView {
|
||||
|
||||
/** The content type for an Excel response */
|
||||
private static final String CONTENT_TYPE = "application/vnd.ms-excel";
|
||||
|
||||
/** The extension to look for existing templates */
|
||||
private static final String EXTENSION = ".xls";
|
||||
|
||||
|
||||
/** The url at which the template to use is located */
|
||||
private String url;
|
||||
|
||||
|
||||
/**
|
||||
* Default Constructor.
|
||||
* Sets the content type of the view to "application/vnd.ms-excel".
|
||||
*/
|
||||
public AbstractJExcelView() {
|
||||
setContentType(CONTENT_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the URL of the Excel workbook source, without localization part nor extension.
|
||||
*/
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean generatesDownloadContent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Excel view, given the specified model.
|
||||
*/
|
||||
@Override
|
||||
protected final void renderMergedOutputModel(
|
||||
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
|
||||
// Set the content type and get the output stream.
|
||||
response.setContentType(getContentType());
|
||||
OutputStream out = response.getOutputStream();
|
||||
|
||||
WritableWorkbook workbook;
|
||||
if (this.url != null) {
|
||||
Workbook template = getTemplateSource(this.url, request);
|
||||
workbook = Workbook.createWorkbook(out, template);
|
||||
}
|
||||
else {
|
||||
logger.debug("Creating Excel Workbook from scratch");
|
||||
workbook = Workbook.createWorkbook(out);
|
||||
}
|
||||
|
||||
buildExcelDocument(model, workbook, request, response);
|
||||
|
||||
// Should we set the content length here?
|
||||
// response.setContentLength(workbook.getBytes().length);
|
||||
|
||||
workbook.write();
|
||||
out.flush();
|
||||
workbook.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the workbook from an existing XLS document.
|
||||
* @param url the URL of the Excel template without localization part nor extension
|
||||
* @param request current HTTP request
|
||||
* @return the template workbook
|
||||
* @throws Exception in case of failure
|
||||
*/
|
||||
protected Workbook getTemplateSource(String url, HttpServletRequest request) throws Exception {
|
||||
LocalizedResourceHelper helper = new LocalizedResourceHelper(getApplicationContext());
|
||||
Locale userLocale = RequestContextUtils.getLocale(request);
|
||||
Resource inputFile = helper.findLocalizedResource(url, EXTENSION, userLocale);
|
||||
|
||||
// Create the Excel document from the source.
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loading Excel workbook from " + inputFile);
|
||||
}
|
||||
return Workbook.getWorkbook(inputFile.getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses must implement this method to create an Excel Workbook
|
||||
* document, given the model.
|
||||
* @param model the model Map
|
||||
* @param workbook the Excel workbook to complete
|
||||
* @param request in case we need locale etc. Shouldn't look at attributes.
|
||||
* @param response in case we need to set cookies. Shouldn't write to it.
|
||||
* @throws Exception in case of failure
|
||||
*/
|
||||
protected abstract void buildExcelDocument(Map<String, Object> model, WritableWorkbook workbook,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception;
|
||||
|
||||
}
|
||||
|
|
@ -101,7 +101,6 @@ import org.springframework.web.servlet.handler.ConversionServiceExposingIntercep
|
|||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor;
|
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
||||
|
|
@ -143,8 +142,8 @@ import org.springframework.web.servlet.view.tiles3.TilesConfigurer;
|
|||
import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
|
|
@ -307,7 +306,7 @@ public class MvcNamespaceTests {
|
|||
|
||||
@Test
|
||||
public void testInterceptors() throws Exception {
|
||||
loadBeanDefinitions("mvc-config-interceptors.xml", 21);
|
||||
loadBeanDefinitions("mvc-config-interceptors.xml", 18);
|
||||
|
||||
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
|
||||
assertNotNull(mapping);
|
||||
|
|
@ -319,26 +318,23 @@ public class MvcNamespaceTests {
|
|||
request.addParameter("theme", "green");
|
||||
|
||||
HandlerExecutionChain chain = mapping.getHandler(request);
|
||||
assertEquals(5, chain.getInterceptors().length);
|
||||
assertEquals(4, chain.getInterceptors().length);
|
||||
assertTrue(chain.getInterceptors()[0] instanceof ConversionServiceExposingInterceptor);
|
||||
assertTrue(chain.getInterceptors()[1] instanceof LocaleChangeInterceptor);
|
||||
assertTrue(chain.getInterceptors()[2] instanceof WebRequestHandlerInterceptorAdapter);
|
||||
assertTrue(chain.getInterceptors()[3] instanceof ThemeChangeInterceptor);
|
||||
assertTrue(chain.getInterceptors()[4] instanceof UserRoleAuthorizationInterceptor);
|
||||
assertTrue(chain.getInterceptors()[2] instanceof ThemeChangeInterceptor);
|
||||
assertTrue(chain.getInterceptors()[3] instanceof UserRoleAuthorizationInterceptor);
|
||||
|
||||
request.setRequestURI("/admin/users");
|
||||
chain = mapping.getHandler(request);
|
||||
assertEquals(3, chain.getInterceptors().length);
|
||||
assertEquals(2, chain.getInterceptors().length);
|
||||
|
||||
request.setRequestURI("/logged/accounts/12345");
|
||||
chain = mapping.getHandler(request);
|
||||
assertEquals(5, chain.getInterceptors().length);
|
||||
assertTrue(chain.getInterceptors()[4] instanceof WebRequestHandlerInterceptorAdapter);
|
||||
assertEquals(3, chain.getInterceptors().length);
|
||||
|
||||
request.setRequestURI("/foo/logged");
|
||||
chain = mapping.getHandler(request);
|
||||
assertEquals(5, chain.getInterceptors().length);
|
||||
assertTrue(chain.getInterceptors()[4] instanceof WebRequestHandlerInterceptorAdapter);
|
||||
assertEquals(3, chain.getInterceptors().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1017,6 +1013,11 @@ public class MvcNamespaceTests {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVirtualServerName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestCallableProcessingInterceptor extends CallableProcessingInterceptorAdapter {
|
||||
|
|
|
|||
|
|
@ -1,349 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 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.servlet.view.document;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import jxl.Cell;
|
||||
import jxl.Sheet;
|
||||
import jxl.Workbook;
|
||||
import jxl.WorkbookSettings;
|
||||
import jxl.read.biff.WorkbookParser;
|
||||
import jxl.write.Label;
|
||||
import jxl.write.WritableSheet;
|
||||
import jxl.write.WritableWorkbook;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.test.MockServletContext;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests for the AbstractExcelView and the AbstractJExcelView classes.
|
||||
*
|
||||
* @author Alef Arendsen
|
||||
* @author Bram Smeets
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ExcelViewTests {
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
private StaticWebApplicationContext webAppCtx;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockServletContext servletCtx = new MockServletContext("org/springframework/web/servlet/view/document");
|
||||
request = new MockHttpServletRequest(servletCtx);
|
||||
response = new MockHttpServletResponse();
|
||||
webAppCtx = new StaticWebApplicationContext();
|
||||
webAppCtx.setServletContext(servletCtx);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testExcel() throws Exception {
|
||||
AbstractExcelView excelView = new AbstractExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
HSSFSheet sheet = wb.createSheet("Test Sheet");
|
||||
// test all possible permutation of row or column not existing
|
||||
HSSFCell cell = getCell(sheet, 2, 4);
|
||||
cell.setCellValue("Test Value");
|
||||
cell = getCell(sheet, 2, 3);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 3, 4);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 2, 4);
|
||||
setText(cell, "Test Value");
|
||||
}
|
||||
};
|
||||
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
assertEquals("Test Sheet", wb.getSheetName(0));
|
||||
HSSFSheet sheet = wb.getSheet("Test Sheet");
|
||||
HSSFRow row = sheet.getRow(2);
|
||||
HSSFCell cell = row.getCell(4);
|
||||
assertEquals("Test Value", cell.getStringCellValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcelWithTemplateNoLoc() throws Exception {
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE,
|
||||
newDummyLocaleResolver("nl", "nl"));
|
||||
|
||||
AbstractExcelView excelView = new AbstractExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
HSSFSheet sheet = wb.getSheet("Sheet1");
|
||||
// test all possible permutation of row or column not existing
|
||||
HSSFCell cell = getCell(sheet, 2, 4);
|
||||
cell.setCellValue("Test Value");
|
||||
cell = getCell(sheet, 2, 3);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 3, 4);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 2, 4);
|
||||
setText(cell, "Test Value");
|
||||
}
|
||||
};
|
||||
|
||||
excelView.setApplicationContext(webAppCtx);
|
||||
excelView.setUrl("template");
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
HSSFSheet sheet = wb.getSheet("Sheet1");
|
||||
HSSFRow row = sheet.getRow(0);
|
||||
HSSFCell cell = row.getCell(0);
|
||||
assertEquals("Test Template", cell.getStringCellValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcelWithTemplateAndCountryAndLanguage() throws Exception {
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE,
|
||||
newDummyLocaleResolver("en", "US"));
|
||||
|
||||
AbstractExcelView excelView = new AbstractExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
HSSFSheet sheet = wb.getSheet("Sheet1");
|
||||
// test all possible permutation of row or column not existing
|
||||
HSSFCell cell = getCell(sheet, 2, 4);
|
||||
cell.setCellValue("Test Value");
|
||||
cell = getCell(sheet, 2, 3);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 3, 4);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 2, 4);
|
||||
setText(cell, "Test Value");
|
||||
}
|
||||
};
|
||||
|
||||
excelView.setApplicationContext(webAppCtx);
|
||||
excelView.setUrl("template");
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
HSSFSheet sheet = wb.getSheet("Sheet1");
|
||||
HSSFRow row = sheet.getRow(0);
|
||||
HSSFCell cell = row.getCell(0);
|
||||
assertEquals("Test Template American English", cell.getStringCellValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExcelWithTemplateAndLanguage() throws Exception {
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE,
|
||||
newDummyLocaleResolver("de", ""));
|
||||
|
||||
AbstractExcelView excelView = new AbstractExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
HSSFSheet sheet = wb.getSheet("Sheet1");
|
||||
// test all possible permutation of row or column not existing
|
||||
HSSFCell cell = getCell(sheet, 2, 4);
|
||||
cell.setCellValue("Test Value");
|
||||
cell = getCell(sheet, 2, 3);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 3, 4);
|
||||
setText(cell, "Test Value");
|
||||
cell = getCell(sheet, 2, 4);
|
||||
setText(cell, "Test Value");
|
||||
}
|
||||
};
|
||||
|
||||
excelView.setApplicationContext(webAppCtx);
|
||||
excelView.setUrl("template");
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
HSSFWorkbook wb = new HSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
HSSFSheet sheet = wb.getSheet("Sheet1");
|
||||
HSSFRow row = sheet.getRow(0);
|
||||
HSSFCell cell = row.getCell(0);
|
||||
assertEquals("Test Template auf Deutsch", cell.getStringCellValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJExcel() throws Exception {
|
||||
AbstractJExcelView excelView = new UnixSafeAbstractJExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
WritableSheet sheet = wb.createSheet("Test Sheet", 0);
|
||||
// test all possible permutation of row or column not existing
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 3, "Test Value"));
|
||||
sheet.addCell(new Label(3, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
}
|
||||
};
|
||||
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
Workbook wb = Workbook.getWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
assertEquals("Test Sheet", wb.getSheet(0).getName());
|
||||
Sheet sheet = wb.getSheet("Test Sheet");
|
||||
Cell cell = sheet.getCell(2, 4);
|
||||
assertEquals("Test Value", cell.getContents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJExcelWithTemplateNoLoc() throws Exception {
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE,
|
||||
newDummyLocaleResolver("nl", "nl"));
|
||||
|
||||
AbstractJExcelView excelView = new UnixSafeAbstractJExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
WritableSheet sheet = wb.getSheet("Sheet1");
|
||||
// test all possible permutation of row or column not existing
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 3, "Test Value"));
|
||||
sheet.addCell(new Label(3, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
}
|
||||
};
|
||||
|
||||
excelView.setApplicationContext(webAppCtx);
|
||||
excelView.setUrl("template");
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
Workbook wb = Workbook.getWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
Sheet sheet = wb.getSheet("Sheet1");
|
||||
Cell cell = sheet.getCell(0, 0);
|
||||
assertEquals("Test Template", cell.getContents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJExcelWithTemplateAndCountryAndLanguage() throws Exception {
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE,
|
||||
newDummyLocaleResolver("en", "US"));
|
||||
|
||||
AbstractJExcelView excelView = new UnixSafeAbstractJExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
WritableSheet sheet = wb.getSheet("Sheet1");
|
||||
// test all possible permutation of row or column not existing
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 3, "Test Value"));
|
||||
sheet.addCell(new Label(3, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
}
|
||||
};
|
||||
|
||||
excelView.setApplicationContext(webAppCtx);
|
||||
excelView.setUrl("template");
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
Workbook wb = Workbook.getWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
Sheet sheet = wb.getSheet("Sheet1");
|
||||
Cell cell = sheet.getCell(0, 0);
|
||||
assertEquals("Test Template American English", cell.getContents());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJExcelWithTemplateAndLanguage() throws Exception {
|
||||
request.setAttribute(DispatcherServlet.LOCALE_RESOLVER_ATTRIBUTE,
|
||||
newDummyLocaleResolver("de", ""));
|
||||
|
||||
AbstractJExcelView excelView = new UnixSafeAbstractJExcelView() {
|
||||
@Override
|
||||
protected void buildExcelDocument(Map<String, Object> model, WritableWorkbook wb,
|
||||
HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
WritableSheet sheet = wb.getSheet("Sheet1");
|
||||
// test all possible permutation of row or column not existing
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 3, "Test Value"));
|
||||
sheet.addCell(new Label(3, 4, "Test Value"));
|
||||
sheet.addCell(new Label(2, 4, "Test Value"));
|
||||
}
|
||||
};
|
||||
|
||||
excelView.setApplicationContext(webAppCtx);
|
||||
excelView.setUrl("template");
|
||||
excelView.render(new HashMap<String, Object>(), request, response);
|
||||
|
||||
Workbook wb = Workbook.getWorkbook(new ByteArrayInputStream(response.getContentAsByteArray()));
|
||||
Sheet sheet = wb.getSheet("Sheet1");
|
||||
Cell cell = sheet.getCell(0, 0);
|
||||
assertEquals("Test Template auf Deutsch", cell.getContents());
|
||||
}
|
||||
|
||||
|
||||
private LocaleResolver newDummyLocaleResolver(final String lang, final String country) {
|
||||
return new LocaleResolver() {
|
||||
@Override
|
||||
public Locale resolveLocale(HttpServletRequest request) {
|
||||
return new Locale(lang, country);
|
||||
}
|
||||
@Override
|
||||
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
|
||||
// not supported
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Workaround JXL bug that causes ArrayIndexOutOfBounds exceptions when running in
|
||||
* *nix machines. Same bug as reported at http://jira.pentaho.com/browse/PDI-5031.
|
||||
* <p>We want to use the latest JXL code because it doesn't include log4j config files
|
||||
* inside the jar. Since the project appears to be abandoned, AbstractJExcelView is
|
||||
* deprecated as of Spring 4.0.
|
||||
*/
|
||||
private static abstract class UnixSafeAbstractJExcelView extends AbstractJExcelView {
|
||||
|
||||
@Override
|
||||
protected Workbook getTemplateSource(String url, HttpServletRequest request) throws Exception {
|
||||
Workbook workbook = super.getTemplateSource(url, request);
|
||||
Field field = WorkbookParser.class.getDeclaredField("settings");
|
||||
field.setAccessible(true);
|
||||
WorkbookSettings settings = (WorkbookSettings) ReflectionUtils.getField(field, workbook);
|
||||
settings.setWriteAccess(null);
|
||||
return workbook;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,31 +8,22 @@
|
|||
<mvc:annotation-driven />
|
||||
|
||||
<mvc:interceptors>
|
||||
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
|
||||
<ref bean="log4jInterceptor"/>
|
||||
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
|
||||
<mvc:interceptor>
|
||||
<mvc:mapping path="/**" />
|
||||
<mvc:exclude-mapping path="/admin/**" />
|
||||
<mvc:exclude-mapping path="/images/**" />
|
||||
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" />
|
||||
</mvc:interceptor>
|
||||
<mvc:interceptor>
|
||||
<mvc:mapping path="/logged/**" />
|
||||
<mvc:mapping path="/foo/logged" />
|
||||
<ref bean="log4jInterceptor"/>
|
||||
<bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor"/>
|
||||
</mvc:interceptor>
|
||||
</mvc:interceptors>
|
||||
|
||||
<bean id="log4jInterceptor"
|
||||
class="org.springframework.web.context.request.Log4jNestedDiagnosticContextInterceptor" />
|
||||
|
||||
<mvc:interceptors path-matcher="pathMatcher">
|
||||
<mvc:interceptor>
|
||||
<mvc:mapping path="/accounts/[0-9]*" />
|
||||
<bean class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor" />
|
||||
<bean class="org.springframework.web.servlet.handler.UserRoleAuthorizationInterceptor"/>
|
||||
</mvc:interceptor>
|
||||
</mvc:interceptors>
|
||||
|
||||
<bean id="pathMatcher" class="org.springframework.web.servlet.config.MvcNamespaceTests$TestPathMatcher" />
|
||||
<bean id="pathMatcher" class="org.springframework.web.servlet.config.MvcNamespaceTests$TestPathMatcher"/>
|
||||
|
||||
</beans>
|
||||
|
|
|
|||
Loading…
Reference in New Issue