Convert CRLF (dos) to LF (unix)
Prior to this change, roughly 5% (~300 out of 6000+) of files under the source tree had CRLF line endings as opposed to the majority which have LF endings. This change normalizes these files to LF for consistency going forward. Command used: $ git ls-files | xargs file | grep CRLF | cut -d":" -f1 | xargs dos2unix Issue: SPR-5608
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# common dependency versions
|
# common dependency versions
|
||||||
aspectj.version=1.6.8.RELEASE
|
aspectj.version=1.6.8.RELEASE
|
||||||
junit.version=4.9.0
|
junit.version=4.9.0
|
||||||
testng.version=5.12.1
|
testng.version=5.12.1
|
||||||
|
|||||||
@@ -1,103 +1,103 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.aop.interceptor;
|
package org.springframework.aop.interceptor;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.aopalliance.intercept.MethodInterceptor;
|
import org.aopalliance.intercept.MethodInterceptor;
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.task.AsyncTaskExecutor;
|
import org.springframework.core.task.AsyncTaskExecutor;
|
||||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AOP Alliance <code>MethodInterceptor</code> that processes method invocations
|
* AOP Alliance <code>MethodInterceptor</code> that processes method invocations
|
||||||
* asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}.
|
* asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}.
|
||||||
* Typically used with the {@link org.springframework.context.task.Async} annotation.
|
* Typically used with the {@link org.springframework.context.task.Async} annotation.
|
||||||
*
|
*
|
||||||
* <p>In terms of target method signatures, any parameter types are supported.
|
* <p>In terms of target method signatures, any parameter types are supported.
|
||||||
* However, the return type is constrained to either <code>void</code> or
|
* However, the return type is constrained to either <code>void</code> or
|
||||||
* <code>java.util.concurrent.Future</code>. In the latter case, the Future handle
|
* <code>java.util.concurrent.Future</code>. In the latter case, the Future handle
|
||||||
* returned from the proxy will be an actual asynchronous Future that can be used
|
* returned from the proxy will be an actual asynchronous Future that can be used
|
||||||
* to track the result of the asynchronous method execution. However, since the
|
* to track the result of the asynchronous method execution. However, since the
|
||||||
* target method needs to implement the same signature, it will have to return
|
* target method needs to implement the same signature, it will have to return
|
||||||
* a temporary Future handle that just passes the return value through
|
* a temporary Future handle that just passes the return value through
|
||||||
* (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult}
|
* (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult}
|
||||||
* or EJB 3.1's <code>javax.ejb.AsyncResult</code>).
|
* or EJB 3.1's <code>javax.ejb.AsyncResult</code>).
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.scheduling.annotation.Async
|
* @see org.springframework.scheduling.annotation.Async
|
||||||
* @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor
|
* @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor
|
||||||
*/
|
*/
|
||||||
public class AsyncExecutionInterceptor implements MethodInterceptor, Ordered {
|
public class AsyncExecutionInterceptor implements MethodInterceptor, Ordered {
|
||||||
|
|
||||||
private final AsyncTaskExecutor asyncExecutor;
|
private final AsyncTaskExecutor asyncExecutor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new AsyncExecutionInterceptor.
|
* Create a new AsyncExecutionInterceptor.
|
||||||
* @param asyncExecutor the Spring AsyncTaskExecutor to delegate to
|
* @param asyncExecutor the Spring AsyncTaskExecutor to delegate to
|
||||||
*/
|
*/
|
||||||
public AsyncExecutionInterceptor(AsyncTaskExecutor asyncExecutor) {
|
public AsyncExecutionInterceptor(AsyncTaskExecutor asyncExecutor) {
|
||||||
Assert.notNull(asyncExecutor, "TaskExecutor must not be null");
|
Assert.notNull(asyncExecutor, "TaskExecutor must not be null");
|
||||||
this.asyncExecutor = asyncExecutor;
|
this.asyncExecutor = asyncExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new AsyncExecutionInterceptor.
|
* Create a new AsyncExecutionInterceptor.
|
||||||
* @param asyncExecutor the <code>java.util.concurrent</code> Executor
|
* @param asyncExecutor the <code>java.util.concurrent</code> Executor
|
||||||
* to delegate to (typically a {@link java.util.concurrent.ExecutorService}
|
* to delegate to (typically a {@link java.util.concurrent.ExecutorService}
|
||||||
*/
|
*/
|
||||||
public AsyncExecutionInterceptor(Executor asyncExecutor) {
|
public AsyncExecutionInterceptor(Executor asyncExecutor) {
|
||||||
this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor);
|
this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||||
Future result = this.asyncExecutor.submit(new Callable<Object>() {
|
Future result = this.asyncExecutor.submit(new Callable<Object>() {
|
||||||
public Object call() throws Exception {
|
public Object call() throws Exception {
|
||||||
try {
|
try {
|
||||||
Object result = invocation.proceed();
|
Object result = invocation.proceed();
|
||||||
if (result instanceof Future) {
|
if (result instanceof Future) {
|
||||||
return ((Future) result).get();
|
return ((Future) result).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
ReflectionUtils.rethrowException(ex);
|
ReflectionUtils.rethrowException(ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {
|
if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return Ordered.HIGHEST_PRECEDENCE;
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,174 +1,174 @@
|
|||||||
package org.springframework.aop.aspectj;
|
package org.springframework.aop.aspectj;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Inherited;
|
import java.lang.annotation.Inherited;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.aop.Advisor;
|
import org.springframework.aop.Advisor;
|
||||||
import org.springframework.aop.MethodBeforeAdvice;
|
import org.springframework.aop.MethodBeforeAdvice;
|
||||||
import org.springframework.aop.ThrowsAdvice;
|
import org.springframework.aop.ThrowsAdvice;
|
||||||
import org.springframework.aop.framework.ProxyFactory;
|
import org.springframework.aop.framework.ProxyFactory;
|
||||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||||
import org.springframework.core.OverridingClassLoader;
|
import org.springframework.core.OverridingClassLoader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*/
|
*/
|
||||||
public class TrickyAspectJPointcutExpressionTests {
|
public class TrickyAspectJPointcutExpressionTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManualProxyJavaWithUnconditionalPointcut() throws Exception {
|
public void testManualProxyJavaWithUnconditionalPointcut() throws Exception {
|
||||||
TestService target = new TestServiceImpl();
|
TestService target = new TestServiceImpl();
|
||||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||||
testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "TestServiceImpl");
|
testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "TestServiceImpl");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManualProxyJavaWithStaticPointcut() throws Exception {
|
public void testManualProxyJavaWithStaticPointcut() throws Exception {
|
||||||
TestService target = new TestServiceImpl();
|
TestService target = new TestServiceImpl();
|
||||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||||
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
||||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManualProxyJavaWithDynamicPointcut() throws Exception {
|
public void testManualProxyJavaWithDynamicPointcut() throws Exception {
|
||||||
TestService target = new TestServiceImpl();
|
TestService target = new TestServiceImpl();
|
||||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||||
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
||||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManualProxyJavaWithDynamicPointcutAndProxyTargetClass() throws Exception {
|
public void testManualProxyJavaWithDynamicPointcutAndProxyTargetClass() throws Exception {
|
||||||
TestService target = new TestServiceImpl();
|
TestService target = new TestServiceImpl();
|
||||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||||
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
||||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl", true);
|
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testManualProxyJavaWithStaticPointcutAndTwoClassLoaders() throws Exception {
|
public void testManualProxyJavaWithStaticPointcutAndTwoClassLoaders() throws Exception {
|
||||||
|
|
||||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||||
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
||||||
|
|
||||||
// Test with default class loader first...
|
// Test with default class loader first...
|
||||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, new TestServiceImpl(), "TestServiceImpl");
|
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, new TestServiceImpl(), "TestServiceImpl");
|
||||||
|
|
||||||
// Then try again with a different class loader on the target...
|
// Then try again with a different class loader on the target...
|
||||||
SimpleThrowawayClassLoader loader = new SimpleThrowawayClassLoader(new TestServiceImpl().getClass().getClassLoader());
|
SimpleThrowawayClassLoader loader = new SimpleThrowawayClassLoader(new TestServiceImpl().getClass().getClassLoader());
|
||||||
// Make sure the interface is loaded from the parent class loader
|
// Make sure the interface is loaded from the parent class loader
|
||||||
loader.excludeClass(TestService.class.getName());
|
loader.excludeClass(TestService.class.getName());
|
||||||
loader.excludeClass(TestException.class.getName());
|
loader.excludeClass(TestException.class.getName());
|
||||||
TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance();
|
TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance();
|
||||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl");
|
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message)
|
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
testAdvice(advisor, logAdvice, target, message, false);
|
testAdvice(advisor, logAdvice, target, message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message,
|
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message,
|
||||||
boolean proxyTargetClass) throws Exception {
|
boolean proxyTargetClass) throws Exception {
|
||||||
|
|
||||||
logAdvice.reset();
|
logAdvice.reset();
|
||||||
|
|
||||||
ProxyFactory factory = new ProxyFactory(target);
|
ProxyFactory factory = new ProxyFactory(target);
|
||||||
factory.setProxyTargetClass(proxyTargetClass);
|
factory.setProxyTargetClass(proxyTargetClass);
|
||||||
factory.addAdvisor(advisor);
|
factory.addAdvisor(advisor);
|
||||||
TestService bean = (TestService) factory.getProxy();
|
TestService bean = (TestService) factory.getProxy();
|
||||||
|
|
||||||
assertEquals(0, logAdvice.getCountThrows());
|
assertEquals(0, logAdvice.getCountThrows());
|
||||||
try {
|
try {
|
||||||
bean.sayHello();
|
bean.sayHello();
|
||||||
fail("Expected exception");
|
fail("Expected exception");
|
||||||
} catch (TestException e) {
|
} catch (TestException e) {
|
||||||
assertEquals(message, e.getMessage());
|
assertEquals(message, e.getMessage());
|
||||||
}
|
}
|
||||||
assertEquals(1, logAdvice.getCountThrows());
|
assertEquals(1, logAdvice.getCountThrows());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
|
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SimpleThrowawayClassLoader for the given class loader.
|
* Create a new SimpleThrowawayClassLoader for the given class loader.
|
||||||
* @param parent the ClassLoader to build a throwaway ClassLoader for
|
* @param parent the ClassLoader to build a throwaway ClassLoader for
|
||||||
*/
|
*/
|
||||||
public SimpleThrowawayClassLoader(ClassLoader parent) {
|
public SimpleThrowawayClassLoader(ClassLoader parent) {
|
||||||
super(parent);
|
super(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestException extends RuntimeException {
|
public static class TestException extends RuntimeException {
|
||||||
|
|
||||||
public TestException(String string) {
|
public TestException(String string) {
|
||||||
super(string);
|
super(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Inherited
|
@Inherited
|
||||||
public static @interface Log {
|
public static @interface Log {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface TestService {
|
public static interface TestService {
|
||||||
public String sayHello();
|
public String sayHello();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log
|
@Log
|
||||||
public static class TestServiceImpl implements TestService{
|
public static class TestServiceImpl implements TestService{
|
||||||
public String sayHello() {
|
public String sayHello() {
|
||||||
throw new TestException("TestServiceImpl");
|
throw new TestException("TestServiceImpl");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
|
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
|
||||||
|
|
||||||
private int countBefore = 0;
|
private int countBefore = 0;
|
||||||
|
|
||||||
private int countThrows = 0;
|
private int countThrows = 0;
|
||||||
|
|
||||||
public void before(Method method, Object[] objects, Object o) throws Throwable {
|
public void before(Method method, Object[] objects, Object o) throws Throwable {
|
||||||
countBefore++;
|
countBefore++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterThrowing(Exception e) throws Throwable {
|
public void afterThrowing(Exception e) throws Throwable {
|
||||||
countThrows++;
|
countThrows++;
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCountBefore() {
|
public int getCountBefore() {
|
||||||
return countBefore;
|
return countBefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCountThrows() {
|
public int getCountThrows() {
|
||||||
return countThrows;
|
return countThrows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
countThrows = 0;
|
countThrows = 0;
|
||||||
countBefore = 0;
|
countBefore = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.aop.support;
|
package org.springframework.aop.support;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.springframework.aop.framework.ProxyFactory;
|
import org.springframework.aop.framework.ProxyFactory;
|
||||||
import test.beans.TestBean;
|
import test.beans.TestBean;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Colin Sampaleanu
|
* @author Colin Sampaleanu
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Rick Evans
|
* @author Rick Evans
|
||||||
*/
|
*/
|
||||||
public class ClassUtilsTests extends TestCase {
|
public class ClassUtilsTests extends TestCase {
|
||||||
|
|
||||||
public void testGetShortNameForCglibClass() {
|
public void testGetShortNameForCglibClass() {
|
||||||
TestBean tb = new TestBean();
|
TestBean tb = new TestBean();
|
||||||
ProxyFactory pf = new ProxyFactory();
|
ProxyFactory pf = new ProxyFactory();
|
||||||
pf.setTarget(tb);
|
pf.setTarget(tb);
|
||||||
pf.setProxyTargetClass(true);
|
pf.setProxyTargetClass(true);
|
||||||
TestBean proxy = (TestBean) pf.getProxy();
|
TestBean proxy = (TestBean) pf.getProxy();
|
||||||
String className = ClassUtils.getShortName(proxy.getClass());
|
String className = ClassUtils.getShortName(proxy.getClass());
|
||||||
assertEquals("Class name did not match", "TestBean", className);
|
assertEquals("Class name did not match", "TestBean", className);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +1,54 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2008 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.aspectj;
|
package org.springframework.beans.factory.aspectj;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic-based dependency injection aspect.
|
* Generic-based dependency injection aspect.
|
||||||
* <p>
|
* <p>
|
||||||
* This aspect allows users to implement efficient, type-safe dependency injection without
|
* This aspect allows users to implement efficient, type-safe dependency injection without
|
||||||
* the use of the @Configurable annotation.
|
* the use of the @Configurable annotation.
|
||||||
*
|
*
|
||||||
* The subaspect of this aspect doesn't need to include any AOP constructs.
|
* The subaspect of this aspect doesn't need to include any AOP constructs.
|
||||||
* For example, here is a subaspect that configures the <code>PricingStrategyClient</code> objects.
|
* For example, here is a subaspect that configures the <code>PricingStrategyClient</code> objects.
|
||||||
* <pre>
|
* <pre>
|
||||||
* aspect PricingStrategyDependencyInjectionAspect
|
* aspect PricingStrategyDependencyInjectionAspect
|
||||||
* extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> {
|
* extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> {
|
||||||
* private PricingStrategy pricingStrategy;
|
* private PricingStrategy pricingStrategy;
|
||||||
*
|
*
|
||||||
* public void configure(PricingStrategyClient bean) {
|
* public void configure(PricingStrategyClient bean) {
|
||||||
* bean.setPricingStrategy(pricingStrategy);
|
* bean.setPricingStrategy(pricingStrategy);
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* public void setPricingStrategy(PricingStrategy pricingStrategy) {
|
* public void setPricingStrategy(PricingStrategy pricingStrategy) {
|
||||||
* this.pricingStrategy = pricingStrategy;
|
* this.pricingStrategy = pricingStrategy;
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect {
|
public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect {
|
||||||
declare parents: I implements ConfigurableObject;
|
declare parents: I implements ConfigurableObject;
|
||||||
|
|
||||||
public pointcut inConfigurableBean() : within(I+);
|
public pointcut inConfigurableBean() : within(I+);
|
||||||
|
|
||||||
public final void configureBean(Object bean) {
|
public final void configureBean(Object bean) {
|
||||||
configure((I)bean);
|
configure((I)bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unfortunately, erasure used with generics won't allow to use the same named method
|
// Unfortunately, erasure used with generics won't allow to use the same named method
|
||||||
protected abstract void configure(I bean);
|
protected abstract void configure(I bean);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.aspectj;
|
package org.springframework.cache.aspectj;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springframework.cache.interceptor.CacheAspectSupport;
|
import org.springframework.cache.interceptor.CacheAspectSupport;
|
||||||
import org.springframework.cache.interceptor.CacheOperationSource;
|
import org.springframework.cache.interceptor.CacheOperationSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract superaspect for AspectJ cache aspects. Concrete subaspects will implement the
|
* Abstract superaspect for AspectJ cache aspects. Concrete subaspects will implement the
|
||||||
* {@link #cacheMethodExecution} pointcut using a strategy such as Java 5 annotations.
|
* {@link #cacheMethodExecution} pointcut using a strategy such as Java 5 annotations.
|
||||||
*
|
*
|
||||||
* <p>Suitable for use inside or outside the Spring IoC container. Set the
|
* <p>Suitable for use inside or outside the Spring IoC container. Set the
|
||||||
* {@link #setCacheManager cacheManager} property appropriately, allowing use of any cache
|
* {@link #setCacheManager cacheManager} property appropriately, allowing use of any cache
|
||||||
* implementation supported by Spring.
|
* implementation supported by Spring.
|
||||||
*
|
*
|
||||||
* <p><b>NB:</b> If a method implements an interface that is itself cache annotated, the
|
* <p><b>NB:</b> If a method implements an interface that is itself cache annotated, the
|
||||||
* relevant Spring cache definition will <i>not</i> be resolved.
|
* relevant Spring cache definition will <i>not</i> be resolved.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public abstract aspect AbstractCacheAspect extends CacheAspectSupport {
|
public abstract aspect AbstractCacheAspect extends CacheAspectSupport {
|
||||||
|
|
||||||
protected AbstractCacheAspect() {
|
protected AbstractCacheAspect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct object using the given caching metadata retrieval strategy.
|
* Construct object using the given caching metadata retrieval strategy.
|
||||||
* @param cos {@link CacheOperationSource} implementation, retrieving Spring cache
|
* @param cos {@link CacheOperationSource} implementation, retrieving Spring cache
|
||||||
* metadata for each joinpoint.
|
* metadata for each joinpoint.
|
||||||
*/
|
*/
|
||||||
protected AbstractCacheAspect(CacheOperationSource... cos) {
|
protected AbstractCacheAspect(CacheOperationSource... cos) {
|
||||||
setCacheOperationSources(cos);
|
setCacheOperationSources(cos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressAjWarnings("adviceDidNotMatch")
|
@SuppressAjWarnings("adviceDidNotMatch")
|
||||||
Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) {
|
Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) {
|
||||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||||
Method method = methodSignature.getMethod();
|
Method method = methodSignature.getMethod();
|
||||||
|
|
||||||
Invoker aspectJInvoker = new Invoker() {
|
Invoker aspectJInvoker = new Invoker() {
|
||||||
public Object invoke() {
|
public Object invoke() {
|
||||||
return proceed(cachedObject);
|
return proceed(cachedObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
|
return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete subaspects must implement this pointcut, to identify cached methods.
|
* Concrete subaspects must implement this pointcut, to identify cached methods.
|
||||||
*/
|
*/
|
||||||
protected abstract pointcut cacheMethodExecution(Object cachedObject);
|
protected abstract pointcut cacheMethodExecution(Object cachedObject);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,116 +1,116 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.aspectj;
|
package org.springframework.cache.aspectj;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.CachePut;
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.cache.annotation.Caching;
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete AspectJ cache aspect using Spring's @{@link Cacheable} annotation.
|
* Concrete AspectJ cache aspect using Spring's @{@link Cacheable} annotation.
|
||||||
*
|
*
|
||||||
* <p>When using this aspect, you <i>must</i> annotate the implementation class (and/or
|
* <p>When using this aspect, you <i>must</i> annotate the implementation class (and/or
|
||||||
* methods within that class), <i>not</i> the interface (if any) that the class
|
* methods within that class), <i>not</i> the interface (if any) that the class
|
||||||
* implements. AspectJ follows Java's rule that annotations on interfaces are <i>not</i>
|
* implements. AspectJ follows Java's rule that annotations on interfaces are <i>not</i>
|
||||||
* inherited.
|
* inherited.
|
||||||
*
|
*
|
||||||
* <p>A {@code @Cacheable} annotation on a class specifies the default caching semantics
|
* <p>A {@code @Cacheable} annotation on a class specifies the default caching semantics
|
||||||
* for the execution of any <b>public</b> operation in the class.
|
* for the execution of any <b>public</b> operation in the class.
|
||||||
*
|
*
|
||||||
* <p>A {@code @Cacheable} annotation on a method within the class overrides the default
|
* <p>A {@code @Cacheable} annotation on a method within the class overrides the default
|
||||||
* caching semantics given by the class annotation (if present). Any method may be
|
* caching semantics given by the class annotation (if present). Any method may be
|
||||||
* annotated (regardless of visibility). Annotating non-public methods directly is the
|
* annotated (regardless of visibility). Annotating non-public methods directly is the
|
||||||
* only way to get caching demarcation for the execution of such operations.
|
* only way to get caching demarcation for the execution of such operations.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
||||||
|
|
||||||
public AnnotationCacheAspect() {
|
public AnnotationCacheAspect() {
|
||||||
super(new AnnotationCacheOperationSource(false));
|
super(new AnnotationCacheOperationSource(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any public method in a type with the @{@link Cacheable}
|
* Matches the execution of any public method in a type with the @{@link Cacheable}
|
||||||
* annotation, or any subtype of a type with the {@code @Cacheable} annotation.
|
* annotation, or any subtype of a type with the {@code @Cacheable} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfAnyPublicMethodInAtCacheableType() :
|
private pointcut executionOfAnyPublicMethodInAtCacheableType() :
|
||||||
execution(public * ((@Cacheable *)+).*(..)) && within(@Cacheable *);
|
execution(public * ((@Cacheable *)+).*(..)) && within(@Cacheable *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any public method in a type with the @{@link CacheEvict}
|
* Matches the execution of any public method in a type with the @{@link CacheEvict}
|
||||||
* annotation, or any subtype of a type with the {@code CacheEvict} annotation.
|
* annotation, or any subtype of a type with the {@code CacheEvict} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
|
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
|
||||||
execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *);
|
execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any public method in a type with the @{@link CachePut}
|
* Matches the execution of any public method in a type with the @{@link CachePut}
|
||||||
* annotation, or any subtype of a type with the {@code CachePut} annotation.
|
* annotation, or any subtype of a type with the {@code CachePut} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfAnyPublicMethodInAtCachePutType() :
|
private pointcut executionOfAnyPublicMethodInAtCachePutType() :
|
||||||
execution(public * ((@CachePut *)+).*(..)) && within(@CachePut *);
|
execution(public * ((@CachePut *)+).*(..)) && within(@CachePut *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any public method in a type with the @{@link Caching}
|
* Matches the execution of any public method in a type with the @{@link Caching}
|
||||||
* annotation, or any subtype of a type with the {@code Caching} annotation.
|
* annotation, or any subtype of a type with the {@code Caching} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfAnyPublicMethodInAtCachingType() :
|
private pointcut executionOfAnyPublicMethodInAtCachingType() :
|
||||||
execution(public * ((@Caching *)+).*(..)) && within(@Caching *);
|
execution(public * ((@Caching *)+).*(..)) && within(@Caching *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any method with the @{@link Cacheable} annotation.
|
* Matches the execution of any method with the @{@link Cacheable} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfCacheableMethod() :
|
private pointcut executionOfCacheableMethod() :
|
||||||
execution(@Cacheable * *(..));
|
execution(@Cacheable * *(..));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any method with the @{@link CacheEvict} annotation.
|
* Matches the execution of any method with the @{@link CacheEvict} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfCacheEvictMethod() :
|
private pointcut executionOfCacheEvictMethod() :
|
||||||
execution(@CacheEvict * *(..));
|
execution(@CacheEvict * *(..));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any method with the @{@link CachePut} annotation.
|
* Matches the execution of any method with the @{@link CachePut} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfCachePutMethod() :
|
private pointcut executionOfCachePutMethod() :
|
||||||
execution(@CachePut * *(..));
|
execution(@CachePut * *(..));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any method with the @{@link Caching} annotation.
|
* Matches the execution of any method with the @{@link Caching} annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfCachingMethod() :
|
private pointcut executionOfCachingMethod() :
|
||||||
execution(@Caching * *(..));
|
execution(@Caching * *(..));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of pointcut from super aspect - matched join points will have Spring
|
* Definition of pointcut from super aspect - matched join points will have Spring
|
||||||
* cache management applied.
|
* cache management applied.
|
||||||
*/
|
*/
|
||||||
protected pointcut cacheMethodExecution(Object cachedObject) :
|
protected pointcut cacheMethodExecution(Object cachedObject) :
|
||||||
(executionOfAnyPublicMethodInAtCacheableType()
|
(executionOfAnyPublicMethodInAtCacheableType()
|
||||||
|| executionOfAnyPublicMethodInAtCacheEvictType()
|
|| executionOfAnyPublicMethodInAtCacheEvictType()
|
||||||
|| executionOfAnyPublicMethodInAtCachePutType()
|
|| executionOfAnyPublicMethodInAtCachePutType()
|
||||||
|| executionOfAnyPublicMethodInAtCachingType()
|
|| executionOfAnyPublicMethodInAtCachingType()
|
||||||
|| executionOfCacheableMethod()
|
|| executionOfCacheableMethod()
|
||||||
|| executionOfCacheEvictMethod()
|
|| executionOfCacheEvictMethod()
|
||||||
|| executionOfCachePutMethod()
|
|| executionOfCachePutMethod()
|
||||||
|| executionOfCachingMethod())
|
|| executionOfCachingMethod())
|
||||||
&& this(cachedObject);
|
&& this(cachedObject);
|
||||||
}
|
}
|
||||||
@@ -1,197 +1,197 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract aspect to enable mocking of methods picked out by a pointcut.
|
* Abstract aspect to enable mocking of methods picked out by a pointcut.
|
||||||
* Sub-aspects must define the mockStaticsTestMethod() pointcut to
|
* Sub-aspects must define the mockStaticsTestMethod() pointcut to
|
||||||
* indicate call stacks when mocking should be triggered, and the
|
* indicate call stacks when mocking should be triggered, and the
|
||||||
* methodToMock() pointcut to pick out a method invocations to mock.
|
* methodToMock() pointcut to pick out a method invocations to mock.
|
||||||
*
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
*/
|
*/
|
||||||
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
|
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
|
||||||
|
|
||||||
protected abstract pointcut mockStaticsTestMethod();
|
protected abstract pointcut mockStaticsTestMethod();
|
||||||
|
|
||||||
protected abstract pointcut methodToMock();
|
protected abstract pointcut methodToMock();
|
||||||
|
|
||||||
private boolean recording = true;
|
private boolean recording = true;
|
||||||
|
|
||||||
static enum CallResponse { nothing, return_, throw_ };
|
static enum CallResponse { nothing, return_, throw_ };
|
||||||
|
|
||||||
// Represents a list of expected calls to static entity methods
|
// Represents a list of expected calls to static entity methods
|
||||||
// Public to allow inserted code to access: is this normal??
|
// Public to allow inserted code to access: is this normal??
|
||||||
public class Expectations {
|
public class Expectations {
|
||||||
|
|
||||||
// Represents an expected call to a static entity method
|
// Represents an expected call to a static entity method
|
||||||
private class Call {
|
private class Call {
|
||||||
private final String signature;
|
private final String signature;
|
||||||
private final Object[] args;
|
private final Object[] args;
|
||||||
|
|
||||||
private Object responseObject; // return value or throwable
|
private Object responseObject; // return value or throwable
|
||||||
private CallResponse responseType = CallResponse.nothing;
|
private CallResponse responseType = CallResponse.nothing;
|
||||||
|
|
||||||
public Call(String name, Object[] args) {
|
public Call(String name, Object[] args) {
|
||||||
this.signature = name;
|
this.signature = name;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasResponseSpecified() {
|
public boolean hasResponseSpecified() {
|
||||||
return responseType != CallResponse.nothing;
|
return responseType != CallResponse.nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReturnVal(Object retVal) {
|
public void setReturnVal(Object retVal) {
|
||||||
this.responseObject = retVal;
|
this.responseObject = retVal;
|
||||||
responseType = CallResponse.return_;
|
responseType = CallResponse.return_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setThrow(Throwable throwable) {
|
public void setThrow(Throwable throwable) {
|
||||||
this.responseObject = throwable;
|
this.responseObject = throwable;
|
||||||
responseType = CallResponse.throw_;
|
responseType = CallResponse.throw_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object returnValue(String lastSig, Object[] args) {
|
public Object returnValue(String lastSig, Object[] args) {
|
||||||
checkSignature(lastSig, args);
|
checkSignature(lastSig, args);
|
||||||
return responseObject;
|
return responseObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object throwException(String lastSig, Object[] args) {
|
public Object throwException(String lastSig, Object[] args) {
|
||||||
checkSignature(lastSig, args);
|
checkSignature(lastSig, args);
|
||||||
throw (RuntimeException)responseObject;
|
throw (RuntimeException)responseObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSignature(String lastSig, Object[] args) {
|
private void checkSignature(String lastSig, Object[] args) {
|
||||||
if (!signature.equals(lastSig)) {
|
if (!signature.equals(lastSig)) {
|
||||||
throw new IllegalArgumentException("Signature doesn't match");
|
throw new IllegalArgumentException("Signature doesn't match");
|
||||||
}
|
}
|
||||||
if (!Arrays.equals(this.args, args)) {
|
if (!Arrays.equals(this.args, args)) {
|
||||||
throw new IllegalArgumentException("Arguments don't match");
|
throw new IllegalArgumentException("Arguments don't match");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Call> calls = new LinkedList<Call>();
|
private List<Call> calls = new LinkedList<Call>();
|
||||||
|
|
||||||
// Calls already verified
|
// Calls already verified
|
||||||
private int verified;
|
private int verified;
|
||||||
|
|
||||||
public void verify() {
|
public void verify() {
|
||||||
if (verified != calls.size()) {
|
if (verified != calls.size()) {
|
||||||
throw new IllegalStateException("Expected " + calls.size()
|
throw new IllegalStateException("Expected " + calls.size()
|
||||||
+ " calls, received " + verified);
|
+ " calls, received " + verified);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the call and provide the expected return value
|
* Validate the call and provide the expected return value
|
||||||
* @param lastSig
|
* @param lastSig
|
||||||
* @param args
|
* @param args
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Object respond(String lastSig, Object[] args) {
|
public Object respond(String lastSig, Object[] args) {
|
||||||
Call call = nextCall();
|
Call call = nextCall();
|
||||||
CallResponse responseType = call.responseType;
|
CallResponse responseType = call.responseType;
|
||||||
if (responseType == CallResponse.return_) {
|
if (responseType == CallResponse.return_) {
|
||||||
return call.returnValue(lastSig, args);
|
return call.returnValue(lastSig, args);
|
||||||
} else if(responseType == CallResponse.throw_) {
|
} else if(responseType == CallResponse.throw_) {
|
||||||
return (RuntimeException)call.throwException(lastSig, args);
|
return (RuntimeException)call.throwException(lastSig, args);
|
||||||
} else if(responseType == CallResponse.nothing) {
|
} else if(responseType == CallResponse.nothing) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Behavior of " + call + " not specified");
|
throw new IllegalStateException("Behavior of " + call + " not specified");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Call nextCall() {
|
private Call nextCall() {
|
||||||
if (verified > calls.size() - 1) {
|
if (verified > calls.size() - 1) {
|
||||||
throw new IllegalStateException("Expected " + calls.size()
|
throw new IllegalStateException("Expected " + calls.size()
|
||||||
+ " calls, received " + verified);
|
+ " calls, received " + verified);
|
||||||
}
|
}
|
||||||
return calls.get(verified++);
|
return calls.get(verified++);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectCall(String lastSig, Object lastArgs[]) {
|
public void expectCall(String lastSig, Object lastArgs[]) {
|
||||||
Call call = new Call(lastSig, lastArgs);
|
Call call = new Call(lastSig, lastArgs);
|
||||||
calls.add(call);
|
calls.add(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCalls() {
|
public boolean hasCalls() {
|
||||||
return !calls.isEmpty();
|
return !calls.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectReturn(Object retVal) {
|
public void expectReturn(Object retVal) {
|
||||||
Call call = calls.get(calls.size() - 1);
|
Call call = calls.get(calls.size() - 1);
|
||||||
if (call.hasResponseSpecified()) {
|
if (call.hasResponseSpecified()) {
|
||||||
throw new IllegalStateException("No static method invoked before setting return value");
|
throw new IllegalStateException("No static method invoked before setting return value");
|
||||||
}
|
}
|
||||||
call.setReturnVal(retVal);
|
call.setReturnVal(retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectThrow(Throwable throwable) {
|
public void expectThrow(Throwable throwable) {
|
||||||
Call call = calls.get(calls.size() - 1);
|
Call call = calls.get(calls.size() - 1);
|
||||||
if (call.hasResponseSpecified()) {
|
if (call.hasResponseSpecified()) {
|
||||||
throw new IllegalStateException("No static method invoked before setting throwable");
|
throw new IllegalStateException("No static method invoked before setting throwable");
|
||||||
}
|
}
|
||||||
call.setThrow(throwable);
|
call.setThrow(throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expectations expectations = new Expectations();
|
private Expectations expectations = new Expectations();
|
||||||
|
|
||||||
after() returning : mockStaticsTestMethod() {
|
after() returning : mockStaticsTestMethod() {
|
||||||
if (recording && (expectations.hasCalls())) {
|
if (recording && (expectations.hasCalls())) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Calls recorded, yet playback state never reached: Create expectations then call "
|
"Calls recorded, yet playback state never reached: Create expectations then call "
|
||||||
+ this.getClass().getSimpleName() + ".playback()");
|
+ this.getClass().getSimpleName() + ".playback()");
|
||||||
}
|
}
|
||||||
expectations.verify();
|
expectations.verify();
|
||||||
}
|
}
|
||||||
|
|
||||||
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
|
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
|
||||||
if (recording) {
|
if (recording) {
|
||||||
expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||||
// Return value doesn't matter
|
// Return value doesn't matter
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return expectations.respond(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
return expectations.respond(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectReturnInternal(Object retVal) {
|
public void expectReturnInternal(Object retVal) {
|
||||||
if (!recording) {
|
if (!recording) {
|
||||||
throw new IllegalStateException("Not recording: Cannot set return value");
|
throw new IllegalStateException("Not recording: Cannot set return value");
|
||||||
}
|
}
|
||||||
expectations.expectReturn(retVal);
|
expectations.expectReturn(retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expectThrowInternal(Throwable throwable) {
|
public void expectThrowInternal(Throwable throwable) {
|
||||||
if (!recording) {
|
if (!recording) {
|
||||||
throw new IllegalStateException("Not recording: Cannot set throwable value");
|
throw new IllegalStateException("Not recording: Cannot set throwable value");
|
||||||
}
|
}
|
||||||
expectations.expectThrow(throwable);
|
expectations.expectThrow(throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void playbackInternal() {
|
public void playbackInternal() {
|
||||||
recording = false;
|
recording = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,68 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation-based aspect to use in test build to enable mocking static methods
|
* Annotation-based aspect to use in test build to enable mocking static methods
|
||||||
* on JPA-annotated <code>@Entity</code> classes, as used by Roo for finders.
|
* on JPA-annotated <code>@Entity</code> classes, as used by Roo for finders.
|
||||||
*
|
*
|
||||||
* <p>Mocking will occur in the call stack of any method in a class (typically a test class)
|
* <p>Mocking will occur in the call stack of any method in a class (typically a test class)
|
||||||
* that is annotated with the @MockStaticEntityMethods annotation.
|
* that is annotated with the @MockStaticEntityMethods annotation.
|
||||||
*
|
*
|
||||||
* <p>Also provides static methods to simplify the programming model for
|
* <p>Also provides static methods to simplify the programming model for
|
||||||
* entering playback mode and setting expected return values.
|
* entering playback mode and setting expected return values.
|
||||||
*
|
*
|
||||||
* <p>Usage:
|
* <p>Usage:
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>Annotate a test class with @MockStaticEntityMethods.
|
* <li>Annotate a test class with @MockStaticEntityMethods.
|
||||||
* <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode.
|
* <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode.
|
||||||
* Invoke static methods on Entity classes, with each recording-mode invocation
|
* Invoke static methods on Entity classes, with each recording-mode invocation
|
||||||
* being followed by an invocation to the static expectReturn() or expectThrow()
|
* being followed by an invocation to the static expectReturn() or expectThrow()
|
||||||
* method on AnnotationDrivenStaticEntityMockingControl.
|
* method on AnnotationDrivenStaticEntityMockingControl.
|
||||||
* <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method.
|
* <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method.
|
||||||
* <li>Call the code you wish to test that uses the static methods. Verification will
|
* <li>Call the code you wish to test that uses the static methods. Verification will
|
||||||
* occur automatically.
|
* occur automatically.
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
* @see MockStaticEntityMethods
|
* @see MockStaticEntityMethods
|
||||||
*/
|
*/
|
||||||
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
|
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop recording mock calls and enter playback state
|
* Stop recording mock calls and enter playback state
|
||||||
*/
|
*/
|
||||||
public static void playback() {
|
public static void playback() {
|
||||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
|
AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void expectReturn(Object retVal) {
|
public static void expectReturn(Object retVal) {
|
||||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
|
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void expectThrow(Throwable throwable) {
|
public static void expectThrow(Throwable throwable) {
|
||||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
|
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only matches directly annotated @Test methods, to allow methods in
|
// Only matches directly annotated @Test methods, to allow methods in
|
||||||
// @MockStatics classes to invoke each other without resetting the mocking environment
|
// @MockStatics classes to invoke each other without resetting the mocking environment
|
||||||
protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));
|
protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));
|
||||||
|
|
||||||
protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));
|
protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation to indicate a test class for whose @Test methods
|
* Annotation to indicate a test class for whose @Test methods
|
||||||
* static methods on Entity classes should be mocked.
|
* static methods on Entity classes should be mocked.
|
||||||
*
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @see AbstractMethodMockingControl
|
* @see AbstractMethodMockingControl
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
public @interface MockStaticEntityMethods {
|
public @interface MockStaticEntityMethods {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,75 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.aspectj;
|
package org.springframework.scheduling.aspectj;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springframework.core.task.AsyncTaskExecutor;
|
import org.springframework.core.task.AsyncTaskExecutor;
|
||||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract aspect that routes selected methods asynchronously.
|
* Abstract aspect that routes selected methods asynchronously.
|
||||||
*
|
*
|
||||||
* <p>This aspect needs to be injected with an implementation of
|
* <p>This aspect needs to be injected with an implementation of
|
||||||
* {@link Executor} to activate it for a specific thread pool.
|
* {@link Executor} to activate it for a specific thread pool.
|
||||||
* Otherwise it will simply delegate all calls synchronously.
|
* Otherwise it will simply delegate all calls synchronously.
|
||||||
*
|
*
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0.5
|
* @since 3.0.5
|
||||||
*/
|
*/
|
||||||
public abstract aspect AbstractAsyncExecutionAspect {
|
public abstract aspect AbstractAsyncExecutionAspect {
|
||||||
|
|
||||||
private AsyncTaskExecutor asyncExecutor;
|
private AsyncTaskExecutor asyncExecutor;
|
||||||
|
|
||||||
public void setExecutor(Executor executor) {
|
public void setExecutor(Executor executor) {
|
||||||
if (executor instanceof AsyncTaskExecutor) {
|
if (executor instanceof AsyncTaskExecutor) {
|
||||||
this.asyncExecutor = (AsyncTaskExecutor) executor;
|
this.asyncExecutor = (AsyncTaskExecutor) executor;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.asyncExecutor = new TaskExecutorAdapter(executor);
|
this.asyncExecutor = new TaskExecutorAdapter(executor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object around() : asyncMethod() {
|
Object around() : asyncMethod() {
|
||||||
if (this.asyncExecutor == null) {
|
if (this.asyncExecutor == null) {
|
||||||
return proceed();
|
return proceed();
|
||||||
}
|
}
|
||||||
Callable<Object> callable = new Callable<Object>() {
|
Callable<Object> callable = new Callable<Object>() {
|
||||||
public Object call() throws Exception {
|
public Object call() throws Exception {
|
||||||
Object result = proceed();
|
Object result = proceed();
|
||||||
if (result instanceof Future) {
|
if (result instanceof Future) {
|
||||||
return ((Future<?>) result).get();
|
return ((Future<?>) result).get();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}};
|
}};
|
||||||
Future<?> result = this.asyncExecutor.submit(callable);
|
Future<?> result = this.asyncExecutor.submit(callable);
|
||||||
if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) {
|
if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract pointcut asyncMethod();
|
public abstract pointcut asyncMethod();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +1,54 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.aspectj;
|
package org.springframework.scheduling.aspectj;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Aspect to route methods based on the {@link Async} annotation.
|
* Aspect to route methods based on the {@link Async} annotation.
|
||||||
*
|
*
|
||||||
* <p>This aspect routes methods marked with the {@link Async} annotation
|
* <p>This aspect routes methods marked with the {@link Async} annotation
|
||||||
* as well as methods in classes marked with the same. Any method expected
|
* as well as methods in classes marked with the same. Any method expected
|
||||||
* to be routed asynchronously must return either void, {@link Future},
|
* to be routed asynchronously must return either void, {@link Future},
|
||||||
* or a subtype of {@link Future}. This aspect, therefore, will produce
|
* or a subtype of {@link Future}. This aspect, therefore, will produce
|
||||||
* a compile-time error for methods that violate this constraint on the return type.
|
* a compile-time error for methods that violate this constraint on the return type.
|
||||||
* If, however, a class marked with <code>@Async</code> contains a method that
|
* If, however, a class marked with <code>@Async</code> contains a method that
|
||||||
* violates this constraint, it produces only a warning.
|
* violates this constraint, it produces only a warning.
|
||||||
*
|
*
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
* @since 3.0.5
|
* @since 3.0.5
|
||||||
*/
|
*/
|
||||||
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect {
|
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect {
|
||||||
|
|
||||||
private pointcut asyncMarkedMethod()
|
private pointcut asyncMarkedMethod()
|
||||||
: execution(@Async (void || Future+) *(..));
|
: execution(@Async (void || Future+) *(..));
|
||||||
|
|
||||||
private pointcut asyncTypeMarkedMethod()
|
private pointcut asyncTypeMarkedMethod()
|
||||||
: execution((void || Future+) (@Async *).*(..));
|
: execution((void || Future+) (@Async *).*(..));
|
||||||
|
|
||||||
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod();
|
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod();
|
||||||
|
|
||||||
declare error:
|
declare error:
|
||||||
execution(@Async !(void||Future) *(..)):
|
execution(@Async !(void||Future) *(..)):
|
||||||
"Only methods that return void or Future may have an @Async annotation";
|
"Only methods that return void or Future may have an @Async annotation";
|
||||||
|
|
||||||
declare warning:
|
declare warning:
|
||||||
execution(!(void||Future) (@Async *).*(..)):
|
execution(!(void||Future) (@Async *).*(..)):
|
||||||
"Methods in a class marked with @Async that do not return void or Future will be routed synchronously";
|
"Methods in a class marked with @Async that do not return void or Future will be routed synchronously";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,93 +1,93 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract superaspect for AspectJ transaction aspects. Concrete
|
* Abstract superaspect for AspectJ transaction aspects. Concrete
|
||||||
* subaspects will implement the <code>transactionalMethodExecution()</code>
|
* subaspects will implement the <code>transactionalMethodExecution()</code>
|
||||||
* pointcut using a strategy such as Java 5 annotations.
|
* pointcut using a strategy such as Java 5 annotations.
|
||||||
*
|
*
|
||||||
* <p>Suitable for use inside or outside the Spring IoC container.
|
* <p>Suitable for use inside or outside the Spring IoC container.
|
||||||
* Set the "transactionManager" property appropriately, allowing
|
* Set the "transactionManager" property appropriately, allowing
|
||||||
* use of any transaction implementation supported by Spring.
|
* use of any transaction implementation supported by Spring.
|
||||||
*
|
*
|
||||||
* <p><b>NB:</b> If a method implements an interface that is itself
|
* <p><b>NB:</b> If a method implements an interface that is itself
|
||||||
* transactionally annotated, the relevant Spring transaction attribute
|
* transactionally annotated, the relevant Spring transaction attribute
|
||||||
* will <i>not</i> be resolved. This behavior will vary from that of Spring AOP
|
* will <i>not</i> be resolved. This behavior will vary from that of Spring AOP
|
||||||
* if proxying an interface (but not when proxying a class). We recommend that
|
* if proxying an interface (but not when proxying a class). We recommend that
|
||||||
* transaction annotations should be added to classes, rather than business
|
* transaction annotations should be added to classes, rather than business
|
||||||
* interfaces, as they are an implementation detail rather than a contract
|
* interfaces, as they are an implementation detail rather than a contract
|
||||||
* specification validation.
|
* specification validation.
|
||||||
*
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {
|
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct object using the given transaction metadata retrieval strategy.
|
* Construct object using the given transaction metadata retrieval strategy.
|
||||||
* @param tas TransactionAttributeSource implementation, retrieving Spring
|
* @param tas TransactionAttributeSource implementation, retrieving Spring
|
||||||
* transaction metadata for each joinpoint. Write the subclass to pass in null
|
* transaction metadata for each joinpoint. Write the subclass to pass in null
|
||||||
* if it's intended to be configured by Setter Injection.
|
* if it's intended to be configured by Setter Injection.
|
||||||
*/
|
*/
|
||||||
protected AbstractTransactionAspect(TransactionAttributeSource tas) {
|
protected AbstractTransactionAspect(TransactionAttributeSource tas) {
|
||||||
setTransactionAttributeSource(tas);
|
setTransactionAttributeSource(tas);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressAjWarnings("adviceDidNotMatch")
|
@SuppressAjWarnings("adviceDidNotMatch")
|
||||||
before(Object txObject) : transactionalMethodExecution(txObject) {
|
before(Object txObject) : transactionalMethodExecution(txObject) {
|
||||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||||
Method method = methodSignature.getMethod();
|
Method method = methodSignature.getMethod();
|
||||||
TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
|
TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressAjWarnings("adviceDidNotMatch")
|
@SuppressAjWarnings("adviceDidNotMatch")
|
||||||
after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
|
after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
|
||||||
try {
|
try {
|
||||||
completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
|
completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
|
||||||
}
|
}
|
||||||
catch (Throwable t2) {
|
catch (Throwable t2) {
|
||||||
logger.error("Failed to close transaction after throwing in a transactional method", t2);
|
logger.error("Failed to close transaction after throwing in a transactional method", t2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressAjWarnings("adviceDidNotMatch")
|
@SuppressAjWarnings("adviceDidNotMatch")
|
||||||
after(Object txObject) returning() : transactionalMethodExecution(txObject) {
|
after(Object txObject) returning() : transactionalMethodExecution(txObject) {
|
||||||
commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
|
commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressAjWarnings("adviceDidNotMatch")
|
@SuppressAjWarnings("adviceDidNotMatch")
|
||||||
after(Object txObject) : transactionalMethodExecution(txObject) {
|
after(Object txObject) : transactionalMethodExecution(txObject) {
|
||||||
cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo());
|
cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete subaspects must implement this pointcut, to identify
|
* Concrete subaspects must implement this pointcut, to identify
|
||||||
* transactional methods. For each selected joinpoint, TransactionMetadata
|
* transactional methods. For each selected joinpoint, TransactionMetadata
|
||||||
* will be retrieved using Spring's TransactionAttributeSource interface.
|
* will be retrieved using Spring's TransactionAttributeSource interface.
|
||||||
*/
|
*/
|
||||||
protected abstract pointcut transactionalMethodExecution(Object txObject);
|
protected abstract pointcut transactionalMethodExecution(Object txObject);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,75 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
|
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
|
||||||
*
|
*
|
||||||
* <p>When using this aspect, you <i>must</i> annotate the implementation class
|
* <p>When using this aspect, you <i>must</i> annotate the implementation class
|
||||||
* (and/or methods within that class), <i>not</i> the interface (if any) that
|
* (and/or methods within that class), <i>not</i> the interface (if any) that
|
||||||
* the class implements. AspectJ follows Java's rule that annotations on
|
* the class implements. AspectJ follows Java's rule that annotations on
|
||||||
* interfaces are <i>not</i> inherited.
|
* interfaces are <i>not</i> inherited.
|
||||||
*
|
*
|
||||||
* <p>An @Transactional annotation on a class specifies the default transaction
|
* <p>An @Transactional annotation on a class specifies the default transaction
|
||||||
* semantics for the execution of any <b>public</b> operation in the class.
|
* semantics for the execution of any <b>public</b> operation in the class.
|
||||||
*
|
*
|
||||||
* <p>An @Transactional annotation on a method within the class overrides the
|
* <p>An @Transactional annotation on a method within the class overrides the
|
||||||
* default transaction semantics given by the class annotation (if present).
|
* default transaction semantics given by the class annotation (if present).
|
||||||
* Any method may be annotated (regardless of visibility).
|
* Any method may be annotated (regardless of visibility).
|
||||||
* Annotating non-public methods directly is the only way
|
* Annotating non-public methods directly is the only way
|
||||||
* to get transaction demarcation for the execution of such operations.
|
* to get transaction demarcation for the execution of such operations.
|
||||||
*
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
* @author Adrian Colyer
|
* @author Adrian Colyer
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
* @see org.springframework.transaction.annotation.Transactional
|
* @see org.springframework.transaction.annotation.Transactional
|
||||||
*/
|
*/
|
||||||
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
||||||
|
|
||||||
public AnnotationTransactionAspect() {
|
public AnnotationTransactionAspect() {
|
||||||
super(new AnnotationTransactionAttributeSource(false));
|
super(new AnnotationTransactionAttributeSource(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any public method in a type with the
|
* Matches the execution of any public method in a type with the
|
||||||
* Transactional annotation, or any subtype of a type with the
|
* Transactional annotation, or any subtype of a type with the
|
||||||
* Transactional annotation.
|
* Transactional annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
|
private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
|
||||||
execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
|
execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matches the execution of any method with the
|
* Matches the execution of any method with the
|
||||||
* Transactional annotation.
|
* Transactional annotation.
|
||||||
*/
|
*/
|
||||||
private pointcut executionOfTransactionalMethod() :
|
private pointcut executionOfTransactionalMethod() :
|
||||||
execution(@Transactional * *(..));
|
execution(@Transactional * *(..));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of pointcut from super aspect - matched join points
|
* Definition of pointcut from super aspect - matched join points
|
||||||
* will have Spring transaction management applied.
|
* will have Spring transaction management applied.
|
||||||
*/
|
*/
|
||||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||||
|| executionOfTransactionalMethod() )
|
|| executionOfTransactionalMethod() )
|
||||||
&& this(txObject);
|
&& this(txObject);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2007 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.aop.aspectj.autoproxy;
|
package org.springframework.aop.aspectj.autoproxy;
|
||||||
|
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Colyer
|
* @author Adrian Colyer
|
||||||
*/
|
*/
|
||||||
public class AutoProxyWithCodeStyleAspectsTests extends TestCase {
|
public class AutoProxyWithCodeStyleAspectsTests extends TestCase {
|
||||||
|
|
||||||
public void testNoAutoproxyingOfAjcCompiledAspects() {
|
public void testNoAutoproxyingOfAjcCompiledAspects() {
|
||||||
new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml");
|
new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.aop.aspectj.autoproxy;
|
package org.springframework.aop.aspectj.autoproxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Colyer
|
* @author Adrian Colyer
|
||||||
*/
|
*/
|
||||||
public aspect CodeStyleAspect {
|
public aspect CodeStyleAspect {
|
||||||
|
|
||||||
private String foo;
|
private String foo;
|
||||||
|
|
||||||
pointcut somePC() : call(* someMethod());
|
pointcut somePC() : call(* someMethod());
|
||||||
|
|
||||||
before() : somePC() {
|
before() : somePC() {
|
||||||
System.out.println("match");
|
System.out.println("match");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFoo(String foo) {
|
public void setFoo(String foo) {
|
||||||
this.foo = foo;
|
this.foo = foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006 the original author or authors.
|
* Copyright 2002-2006 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.aspectj;
|
package org.springframework.beans.factory.aspectj;
|
||||||
|
|
||||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
public class SpringConfiguredWithAutoProxyingTests extends TestCase {
|
public class SpringConfiguredWithAutoProxyingTests extends TestCase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSpringConfiguredAndAutoProxyUsedTogether() {
|
public void testSpringConfiguredAndAutoProxyUsedTogether() {
|
||||||
; // set up is sufficient to trigger failure if this is going to fail...
|
; // set up is sufficient to trigger failure if this is going to fail...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.aspectj;
|
package org.springframework.cache.aspectj;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class AspectJAnnotationTest extends AbstractAnnotationTest {
|
public class AspectJAnnotationTest extends AbstractAnnotationTest {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ApplicationContext getApplicationContext() {
|
protected ApplicationContext getApplicationContext() {
|
||||||
return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml");
|
return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,138 +1,138 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.config;
|
package org.springframework.cache.config;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.CachePut;
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.cache.annotation.Caching;
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||||
|
|
||||||
private final AtomicLong counter = new AtomicLong();
|
private final AtomicLong counter = new AtomicLong();
|
||||||
public static final AtomicLong nullInvocations = new AtomicLong();
|
public static final AtomicLong nullInvocations = new AtomicLong();
|
||||||
|
|
||||||
public Object cache(Object arg1) {
|
public Object cache(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object conditional(int field) {
|
public Object conditional(int field) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict("default")
|
@CacheEvict("default")
|
||||||
public void invalidate(Object arg1) {
|
public void invalidate(Object arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict("default")
|
@CacheEvict("default")
|
||||||
public void evictWithException(Object arg1) {
|
public void evictWithException(Object arg1) {
|
||||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", allEntries = true)
|
@CacheEvict(value = "default", allEntries = true)
|
||||||
public void evictAll(Object arg1) {
|
public void evictAll(Object arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", beforeInvocation = true)
|
@CacheEvict(value = "default", beforeInvocation = true)
|
||||||
public void evictEarly(Object arg1) {
|
public void evictEarly(Object arg1) {
|
||||||
throw new RuntimeException("exception thrown - evict should still occur");
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", key = "#p0")
|
@CacheEvict(value = "default", key = "#p0")
|
||||||
public void evict(Object arg1, Object arg2) {
|
public void evict(Object arg1, Object arg2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||||
public void invalidateEarly(Object arg1, Object arg2) {
|
public void invalidateEarly(Object arg1, Object arg2) {
|
||||||
throw new RuntimeException("exception thrown - evict should still occur");
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#p0")
|
@Cacheable(value = "default", key = "#p0")
|
||||||
public Object key(Object arg1, Object arg2) {
|
public Object key(Object arg1, Object arg2) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name")
|
@Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name")
|
||||||
public Object name(Object arg1) {
|
public Object name(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||||
public Object rootVars(Object arg1) {
|
public Object rootVars(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@CachePut("default")
|
@CachePut("default")
|
||||||
public Object update(Object arg1) {
|
public Object update(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||||
public Object conditionalUpdate(Object arg) {
|
public Object conditionalUpdate(Object arg) {
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object nullValue(Object arg1) {
|
public Object nullValue(Object arg1) {
|
||||||
nullInvocations.incrementAndGet();
|
nullInvocations.incrementAndGet();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number nullInvocations() {
|
public Number nullInvocations() {
|
||||||
return nullInvocations.get();
|
return nullInvocations.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long throwChecked(Object arg1) throws Exception {
|
public Long throwChecked(Object arg1) throws Exception {
|
||||||
throw new UnsupportedOperationException(arg1.toString());
|
throw new UnsupportedOperationException(arg1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long throwUnchecked(Object arg1) {
|
public Long throwUnchecked(Object arg1) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// multi annotations
|
// multi annotations
|
||||||
|
|
||||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||||
public Object multiCache(Object arg1) {
|
public Object multiCache(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||||
public Object multiEvict(Object arg1) {
|
public Object multiEvict(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||||
public Object multiCacheAndEvict(Object arg1) {
|
public Object multiCacheAndEvict(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||||
public Object multiConditionalCacheAndEvict(Object arg1) {
|
public Object multiConditionalCacheAndEvict(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||||
public Object multiUpdate(Object arg1) {
|
public Object multiUpdate(Object arg1) {
|
||||||
return arg1;
|
return arg1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,70 +1,70 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.config;
|
package org.springframework.cache.config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic service interface.
|
* Basic service interface.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public interface CacheableService<T> {
|
public interface CacheableService<T> {
|
||||||
|
|
||||||
T cache(Object arg1);
|
T cache(Object arg1);
|
||||||
|
|
||||||
void invalidate(Object arg1);
|
void invalidate(Object arg1);
|
||||||
|
|
||||||
void evictEarly(Object arg1);
|
void evictEarly(Object arg1);
|
||||||
|
|
||||||
void evictAll(Object arg1);
|
void evictAll(Object arg1);
|
||||||
|
|
||||||
void evictWithException(Object arg1);
|
void evictWithException(Object arg1);
|
||||||
|
|
||||||
void evict(Object arg1, Object arg2);
|
void evict(Object arg1, Object arg2);
|
||||||
|
|
||||||
void invalidateEarly(Object arg1, Object arg2);
|
void invalidateEarly(Object arg1, Object arg2);
|
||||||
|
|
||||||
T conditional(int field);
|
T conditional(int field);
|
||||||
|
|
||||||
T key(Object arg1, Object arg2);
|
T key(Object arg1, Object arg2);
|
||||||
|
|
||||||
T name(Object arg1);
|
T name(Object arg1);
|
||||||
|
|
||||||
T nullValue(Object arg1);
|
T nullValue(Object arg1);
|
||||||
|
|
||||||
T update(Object arg1);
|
T update(Object arg1);
|
||||||
|
|
||||||
T conditionalUpdate(Object arg2);
|
T conditionalUpdate(Object arg2);
|
||||||
|
|
||||||
Number nullInvocations();
|
Number nullInvocations();
|
||||||
|
|
||||||
T rootVars(Object arg1);
|
T rootVars(Object arg1);
|
||||||
|
|
||||||
T throwChecked(Object arg1) throws Exception;
|
T throwChecked(Object arg1) throws Exception;
|
||||||
|
|
||||||
T throwUnchecked(Object arg1);
|
T throwUnchecked(Object arg1);
|
||||||
|
|
||||||
// multi annotations
|
// multi annotations
|
||||||
T multiCache(Object arg1);
|
T multiCache(Object arg1);
|
||||||
|
|
||||||
T multiEvict(Object arg1);
|
T multiEvict(Object arg1);
|
||||||
|
|
||||||
T multiCacheAndEvict(Object arg1);
|
T multiCacheAndEvict(Object arg1);
|
||||||
|
|
||||||
T multiConditionalCacheAndEvict(Object arg1);
|
T multiConditionalCacheAndEvict(Object arg1);
|
||||||
|
|
||||||
T multiUpdate(Object arg1);
|
T multiUpdate(Object arg1);
|
||||||
}
|
}
|
||||||
@@ -1,144 +1,144 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2011 the original author or authors.
|
* Copyright 2010-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.config;
|
package org.springframework.cache.config;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.cache.annotation.CachePut;
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.cache.annotation.Caching;
|
import org.springframework.cache.annotation.Caching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple cacheable service
|
* Simple cacheable service
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class DefaultCacheableService implements CacheableService<Long> {
|
public class DefaultCacheableService implements CacheableService<Long> {
|
||||||
|
|
||||||
private final AtomicLong counter = new AtomicLong();
|
private final AtomicLong counter = new AtomicLong();
|
||||||
private final AtomicLong nullInvocations = new AtomicLong();
|
private final AtomicLong nullInvocations = new AtomicLong();
|
||||||
|
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public Long cache(Object arg1) {
|
public Long cache(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict("default")
|
@CacheEvict("default")
|
||||||
public void invalidate(Object arg1) {
|
public void invalidate(Object arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict("default")
|
@CacheEvict("default")
|
||||||
public void evictWithException(Object arg1) {
|
public void evictWithException(Object arg1) {
|
||||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", allEntries = true)
|
@CacheEvict(value = "default", allEntries = true)
|
||||||
public void evictAll(Object arg1) {
|
public void evictAll(Object arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", beforeInvocation = true)
|
@CacheEvict(value = "default", beforeInvocation = true)
|
||||||
public void evictEarly(Object arg1) {
|
public void evictEarly(Object arg1) {
|
||||||
throw new RuntimeException("exception thrown - evict should still occur");
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", key = "#p0")
|
@CacheEvict(value = "default", key = "#p0")
|
||||||
public void evict(Object arg1, Object arg2) {
|
public void evict(Object arg1, Object arg2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||||
public void invalidateEarly(Object arg1, Object arg2) {
|
public void invalidateEarly(Object arg1, Object arg2) {
|
||||||
throw new RuntimeException("exception thrown - evict should still occur");
|
throw new RuntimeException("exception thrown - evict should still occur");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", condition = "#classField == 3")
|
@Cacheable(value = "default", condition = "#classField == 3")
|
||||||
public Long conditional(int classField) {
|
public Long conditional(int classField) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#p0")
|
@Cacheable(value = "default", key = "#p0")
|
||||||
public Long key(Object arg1, Object arg2) {
|
public Long key(Object arg1, Object arg2) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#root.methodName")
|
@Cacheable(value = "default", key = "#root.methodName")
|
||||||
public Long name(Object arg1) {
|
public Long name(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||||
public Long rootVars(Object arg1) {
|
public Long rootVars(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@CachePut("default")
|
@CachePut("default")
|
||||||
public Long update(Object arg1) {
|
public Long update(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||||
public Long conditionalUpdate(Object arg) {
|
public Long conditionalUpdate(Object arg) {
|
||||||
return Long.valueOf(arg.toString());
|
return Long.valueOf(arg.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public Long nullValue(Object arg1) {
|
public Long nullValue(Object arg1) {
|
||||||
nullInvocations.incrementAndGet();
|
nullInvocations.incrementAndGet();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number nullInvocations() {
|
public Number nullInvocations() {
|
||||||
return nullInvocations.get();
|
return nullInvocations.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public Long throwChecked(Object arg1) throws Exception {
|
public Long throwChecked(Object arg1) throws Exception {
|
||||||
throw new Exception(arg1.toString());
|
throw new Exception(arg1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Cacheable("default")
|
@Cacheable("default")
|
||||||
public Long throwUnchecked(Object arg1) {
|
public Long throwUnchecked(Object arg1) {
|
||||||
throw new UnsupportedOperationException(arg1.toString());
|
throw new UnsupportedOperationException(arg1.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// multi annotations
|
// multi annotations
|
||||||
|
|
||||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||||
public Long multiCache(Object arg1) {
|
public Long multiCache(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||||
public Long multiEvict(Object arg1) {
|
public Long multiEvict(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||||
public Long multiCacheAndEvict(Object arg1) {
|
public Long multiCacheAndEvict(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||||
public Long multiConditionalCacheAndEvict(Object arg1) {
|
public Long multiConditionalCacheAndEvict(Object arg1) {
|
||||||
return counter.getAndIncrement();
|
return counter.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||||
public Long multiUpdate(Object arg1) {
|
public Long multiUpdate(Object arg1) {
|
||||||
return Long.valueOf(arg1.toString());
|
return Long.valueOf(arg1.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,146 +1,146 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for static entity mocking framework.
|
* Test for static entity mocking framework.
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@MockStaticEntityMethods
|
@MockStaticEntityMethods
|
||||||
@RunWith(JUnit4.class)
|
@RunWith(JUnit4.class)
|
||||||
public class AnnotationDrivenStaticEntityMockingControlTest {
|
public class AnnotationDrivenStaticEntityMockingControlTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoArgIntReturn() {
|
public void testNoArgIntReturn() {
|
||||||
int expectedCount = 13;
|
int expectedCount = 13;
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
expectReturn(expectedCount);
|
expectReturn(expectedCount);
|
||||||
playback();
|
playback();
|
||||||
Assert.assertEquals(expectedCount, Person.countPeople());
|
Assert.assertEquals(expectedCount, Person.countPeople());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=PersistenceException.class)
|
@Test(expected=PersistenceException.class)
|
||||||
public void testNoArgThrows() {
|
public void testNoArgThrows() {
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
expectThrow(new PersistenceException());
|
expectThrow(new PersistenceException());
|
||||||
playback();
|
playback();
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArgMethodMatches() {
|
public void testArgMethodMatches() {
|
||||||
long id = 13;
|
long id = 13;
|
||||||
Person found = new Person();
|
Person found = new Person();
|
||||||
Person.findPerson(id);
|
Person.findPerson(id);
|
||||||
expectReturn(found);
|
expectReturn(found);
|
||||||
playback();
|
playback();
|
||||||
Assert.assertEquals(found, Person.findPerson(id));
|
Assert.assertEquals(found, Person.findPerson(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLongSeriesOfCalls() {
|
public void testLongSeriesOfCalls() {
|
||||||
long id1 = 13;
|
long id1 = 13;
|
||||||
long id2 = 24;
|
long id2 = 24;
|
||||||
Person found1 = new Person();
|
Person found1 = new Person();
|
||||||
Person.findPerson(id1);
|
Person.findPerson(id1);
|
||||||
expectReturn(found1);
|
expectReturn(found1);
|
||||||
Person found2 = new Person();
|
Person found2 = new Person();
|
||||||
Person.findPerson(id2);
|
Person.findPerson(id2);
|
||||||
expectReturn(found2);
|
expectReturn(found2);
|
||||||
Person.findPerson(id1);
|
Person.findPerson(id1);
|
||||||
expectReturn(found1);
|
expectReturn(found1);
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
expectReturn(0);
|
expectReturn(0);
|
||||||
playback();
|
playback();
|
||||||
|
|
||||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||||
Assert.assertEquals(found2, Person.findPerson(id2));
|
Assert.assertEquals(found2, Person.findPerson(id2));
|
||||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||||
Assert.assertEquals(0, Person.countPeople());
|
Assert.assertEquals(0, Person.countPeople());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note delegation is used when tests are invalid and should fail, as otherwise
|
// Note delegation is used when tests are invalid and should fail, as otherwise
|
||||||
// the failure will occur on the verify() method in the aspect after
|
// the failure will occur on the verify() method in the aspect after
|
||||||
// this method returns, failing the test case
|
// this method returns, failing the test case
|
||||||
@Test
|
@Test
|
||||||
public void testArgMethodNoMatchExpectReturn() {
|
public void testArgMethodNoMatchExpectReturn() {
|
||||||
try {
|
try {
|
||||||
new Delegate().testArgMethodNoMatchExpectReturn();
|
new Delegate().testArgMethodNoMatchExpectReturn();
|
||||||
Assert.fail();
|
Assert.fail();
|
||||||
} catch (IllegalArgumentException expected) {
|
} catch (IllegalArgumentException expected) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IllegalArgumentException.class)
|
@Test(expected=IllegalArgumentException.class)
|
||||||
public void testArgMethodNoMatchExpectThrow() {
|
public void testArgMethodNoMatchExpectThrow() {
|
||||||
new Delegate().testArgMethodNoMatchExpectThrow();
|
new Delegate().testArgMethodNoMatchExpectThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void called(Person found, long id) {
|
private void called(Person found, long id) {
|
||||||
Assert.assertEquals(found, Person.findPerson(id));
|
Assert.assertEquals(found, Person.findPerson(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReentrant() {
|
public void testReentrant() {
|
||||||
long id = 13;
|
long id = 13;
|
||||||
Person found = new Person();
|
Person found = new Person();
|
||||||
Person.findPerson(id);
|
Person.findPerson(id);
|
||||||
expectReturn(found);
|
expectReturn(found);
|
||||||
playback();
|
playback();
|
||||||
called(found, id);
|
called(found, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IllegalStateException.class)
|
@Test(expected=IllegalStateException.class)
|
||||||
public void testRejectUnexpectedCall() {
|
public void testRejectUnexpectedCall() {
|
||||||
new Delegate().rejectUnexpectedCall();
|
new Delegate().rejectUnexpectedCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IllegalStateException.class)
|
@Test(expected=IllegalStateException.class)
|
||||||
public void testFailTooFewCalls() {
|
public void testFailTooFewCalls() {
|
||||||
new Delegate().failTooFewCalls();
|
new Delegate().failTooFewCalls();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEmpty() {
|
public void testEmpty() {
|
||||||
// Test that verification check doesn't blow up if no replay() call happened
|
// Test that verification check doesn't blow up if no replay() call happened
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IllegalStateException.class)
|
@Test(expected=IllegalStateException.class)
|
||||||
public void testDoesntEverReplay() {
|
public void testDoesntEverReplay() {
|
||||||
new Delegate().doesntEverReplay();
|
new Delegate().doesntEverReplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=IllegalStateException.class)
|
@Test(expected=IllegalStateException.class)
|
||||||
public void testDoesntEverSetReturn() {
|
public void testDoesntEverSetReturn() {
|
||||||
new Delegate().doesntEverSetReturn();
|
new Delegate().doesntEverSetReturn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,92 +1,92 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
|
|
||||||
import javax.persistence.PersistenceException;
|
import javax.persistence.PersistenceException;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
||||||
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
||||||
|
|
||||||
//Used because verification failures occur after method returns,
|
//Used because verification failures occur after method returns,
|
||||||
//so we can't test for them in the test case itself
|
//so we can't test for them in the test case itself
|
||||||
@MockStaticEntityMethods
|
@MockStaticEntityMethods
|
||||||
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
||||||
public class Delegate {
|
public class Delegate {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArgMethodNoMatchExpectReturn() {
|
public void testArgMethodNoMatchExpectReturn() {
|
||||||
long id = 13;
|
long id = 13;
|
||||||
Person found = new Person();
|
Person found = new Person();
|
||||||
Person.findPerson(id);
|
Person.findPerson(id);
|
||||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testArgMethodNoMatchExpectThrow() {
|
public void testArgMethodNoMatchExpectThrow() {
|
||||||
long id = 13;
|
long id = 13;
|
||||||
Person found = new Person();
|
Person found = new Person();
|
||||||
Person.findPerson(id);
|
Person.findPerson(id);
|
||||||
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
||||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void failTooFewCalls() {
|
public void failTooFewCalls() {
|
||||||
long id = 13;
|
long id = 13;
|
||||||
Person found = new Person();
|
Person found = new Person();
|
||||||
Person.findPerson(id);
|
Person.findPerson(id);
|
||||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
||||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||||
Assert.assertEquals(found, Person.findPerson(id));
|
Assert.assertEquals(found, Person.findPerson(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doesntEverReplay() {
|
public void doesntEverReplay() {
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void doesntEverSetReturn() {
|
public void doesntEverSetReturn() {
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rejectUnexpectedCall() {
|
public void rejectUnexpectedCall() {
|
||||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected=RemoteException.class)
|
@Test(expected=RemoteException.class)
|
||||||
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
||||||
Person.countPeople();
|
Person.countPeople();
|
||||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||||
// No calls to allow verification failure
|
// No calls to allow verification failure
|
||||||
throw new RemoteException();
|
throw new RemoteException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Person {
|
public class Person {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,100 +1,100 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.mock.staticmock;
|
package org.springframework.mock.staticmock;
|
||||||
|
|
||||||
privileged aspect Person_Roo_Entity {
|
privileged aspect Person_Roo_Entity {
|
||||||
|
|
||||||
@javax.persistence.PersistenceContext
|
@javax.persistence.PersistenceContext
|
||||||
transient javax.persistence.EntityManager Person.entityManager;
|
transient javax.persistence.EntityManager Person.entityManager;
|
||||||
|
|
||||||
@javax.persistence.Id
|
@javax.persistence.Id
|
||||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
||||||
@javax.persistence.Column(name = "id")
|
@javax.persistence.Column(name = "id")
|
||||||
private java.lang.Long Person.id;
|
private java.lang.Long Person.id;
|
||||||
|
|
||||||
@javax.persistence.Version
|
@javax.persistence.Version
|
||||||
@javax.persistence.Column(name = "version")
|
@javax.persistence.Column(name = "version")
|
||||||
private java.lang.Integer Person.version;
|
private java.lang.Integer Person.version;
|
||||||
|
|
||||||
public java.lang.Long Person.getId() {
|
public java.lang.Long Person.getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Person.setId(java.lang.Long id) {
|
public void Person.setId(java.lang.Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.lang.Integer Person.getVersion() {
|
public java.lang.Integer Person.getVersion() {
|
||||||
return this.version;
|
return this.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Person.setVersion(java.lang.Integer version) {
|
public void Person.setVersion(java.lang.Integer version) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
@org.springframework.transaction.annotation.Transactional
|
@org.springframework.transaction.annotation.Transactional
|
||||||
public void Person.persist() {
|
public void Person.persist() {
|
||||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
this.entityManager.persist(this);
|
this.entityManager.persist(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@org.springframework.transaction.annotation.Transactional
|
@org.springframework.transaction.annotation.Transactional
|
||||||
public void Person.remove() {
|
public void Person.remove() {
|
||||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
this.entityManager.remove(this);
|
this.entityManager.remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@org.springframework.transaction.annotation.Transactional
|
@org.springframework.transaction.annotation.Transactional
|
||||||
public void Person.flush() {
|
public void Person.flush() {
|
||||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
this.entityManager.flush();
|
this.entityManager.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@org.springframework.transaction.annotation.Transactional
|
@org.springframework.transaction.annotation.Transactional
|
||||||
public void Person.merge() {
|
public void Person.merge() {
|
||||||
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (this.entityManager == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
Person merged = this.entityManager.merge(this);
|
Person merged = this.entityManager.merge(this);
|
||||||
this.entityManager.flush();
|
this.entityManager.flush();
|
||||||
this.id = merged.getId();
|
this.id = merged.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long Person.countPeople() {
|
public static long Person.countPeople() {
|
||||||
javax.persistence.EntityManager em = new Person().entityManager;
|
javax.persistence.EntityManager em = new Person().entityManager;
|
||||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static java.util.List<Person> Person.findAllPeople() {
|
public static java.util.List<Person> Person.findAllPeople() {
|
||||||
javax.persistence.EntityManager em = new Person().entityManager;
|
javax.persistence.EntityManager em = new Person().entityManager;
|
||||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
return em.createQuery("select o from Person o").getResultList();
|
return em.createQuery("select o from Person o").getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Person Person.findPerson(java.lang.Long id) {
|
public static Person Person.findPerson(java.lang.Long id) {
|
||||||
if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person");
|
if (id == null) throw new IllegalArgumentException("An identifier is required to retrieve an instance of Person");
|
||||||
javax.persistence.EntityManager em = new Person().entityManager;
|
javax.persistence.EntityManager em = new Person().entityManager;
|
||||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
return em.find(Person.class, id);
|
return em.find(Person.class, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
||||||
javax.persistence.EntityManager em = new Person().entityManager;
|
javax.persistence.EntityManager em = new Person().entityManager;
|
||||||
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
if (em == null) throw new IllegalStateException("Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
|
||||||
return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
|
return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,178 +1,178 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.aspectj;
|
package org.springframework.scheduling.aspectj;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import static junit.framework.Assert.*;
|
import static junit.framework.Assert.*;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.scheduling.annotation.AsyncResult;
|
import org.springframework.scheduling.annotation.AsyncResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
*/
|
*/
|
||||||
public class AnnotationAsyncExecutionAspectTests {
|
public class AnnotationAsyncExecutionAspectTests {
|
||||||
|
|
||||||
private static final long WAIT_TIME = 1000; //milli seconds
|
private static final long WAIT_TIME = 1000; //milli seconds
|
||||||
|
|
||||||
private CountingExecutor executor;
|
private CountingExecutor executor;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
executor = new CountingExecutor();
|
executor = new CountingExecutor();
|
||||||
AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor);
|
AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void asyncMethodGetsRoutedAsynchronously() {
|
public void asyncMethodGetsRoutedAsynchronously() {
|
||||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||||
obj.incrementAsync();
|
obj.incrementAsync();
|
||||||
executor.waitForCompletion();
|
executor.waitForCompletion();
|
||||||
assertEquals(1, obj.counter);
|
assertEquals(1, obj.counter);
|
||||||
assertEquals(1, executor.submitStartCounter);
|
assertEquals(1, executor.submitStartCounter);
|
||||||
assertEquals(1, executor.submitCompleteCounter);
|
assertEquals(1, executor.submitCompleteCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||||
Future<Integer> future = obj.incrementReturningAFuture();
|
Future<Integer> future = obj.incrementReturningAFuture();
|
||||||
// No need to executor.waitForCompletion() as future.get() will have the same effect
|
// No need to executor.waitForCompletion() as future.get() will have the same effect
|
||||||
assertEquals(5, future.get().intValue());
|
assertEquals(5, future.get().intValue());
|
||||||
assertEquals(1, obj.counter);
|
assertEquals(1, obj.counter);
|
||||||
assertEquals(1, executor.submitStartCounter);
|
assertEquals(1, executor.submitStartCounter);
|
||||||
assertEquals(1, executor.submitCompleteCounter);
|
assertEquals(1, executor.submitCompleteCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void syncMethodGetsRoutedSynchronously() {
|
public void syncMethodGetsRoutedSynchronously() {
|
||||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||||
obj.increment();
|
obj.increment();
|
||||||
assertEquals(1, obj.counter);
|
assertEquals(1, obj.counter);
|
||||||
assertEquals(0, executor.submitStartCounter);
|
assertEquals(0, executor.submitStartCounter);
|
||||||
assertEquals(0, executor.submitCompleteCounter);
|
assertEquals(0, executor.submitCompleteCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void voidMethodInAsyncClassGetsRoutedAsynchronously() {
|
public void voidMethodInAsyncClassGetsRoutedAsynchronously() {
|
||||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||||
obj.increment();
|
obj.increment();
|
||||||
executor.waitForCompletion();
|
executor.waitForCompletion();
|
||||||
assertEquals(1, obj.counter);
|
assertEquals(1, obj.counter);
|
||||||
assertEquals(1, executor.submitStartCounter);
|
assertEquals(1, executor.submitStartCounter);
|
||||||
assertEquals(1, executor.submitCompleteCounter);
|
assertEquals(1, executor.submitCompleteCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||||
Future<Integer> future = obj.incrementReturningAFuture();
|
Future<Integer> future = obj.incrementReturningAFuture();
|
||||||
assertEquals(5, future.get().intValue());
|
assertEquals(5, future.get().intValue());
|
||||||
assertEquals(1, obj.counter);
|
assertEquals(1, obj.counter);
|
||||||
assertEquals(1, executor.submitStartCounter);
|
assertEquals(1, executor.submitStartCounter);
|
||||||
assertEquals(1, executor.submitCompleteCounter);
|
assertEquals(1, executor.submitCompleteCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() {
|
public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() {
|
||||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||||
int returnValue = obj.return5();
|
int returnValue = obj.return5();
|
||||||
assertEquals(5, returnValue);
|
assertEquals(5, returnValue);
|
||||||
assertEquals(0, executor.submitStartCounter);
|
assertEquals(0, executor.submitStartCounter);
|
||||||
assertEquals(0, executor.submitCompleteCounter);
|
assertEquals(0, executor.submitCompleteCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
private static class CountingExecutor extends SimpleAsyncTaskExecutor {
|
private static class CountingExecutor extends SimpleAsyncTaskExecutor {
|
||||||
int submitStartCounter;
|
int submitStartCounter;
|
||||||
int submitCompleteCounter;
|
int submitCompleteCounter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> Future<T> submit(Callable<T> task) {
|
public <T> Future<T> submit(Callable<T> task) {
|
||||||
submitStartCounter++;
|
submitStartCounter++;
|
||||||
Future<T> future = super.submit(task);
|
Future<T> future = super.submit(task);
|
||||||
submitCompleteCounter++;
|
submitCompleteCounter++;
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
notifyAll();
|
notifyAll();
|
||||||
}
|
}
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void waitForCompletion() {
|
public synchronized void waitForCompletion() {
|
||||||
try {
|
try {
|
||||||
wait(WAIT_TIME);
|
wait(WAIT_TIME);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class ClassWithoutAsyncAnnotation {
|
static class ClassWithoutAsyncAnnotation {
|
||||||
int counter;
|
int counter;
|
||||||
|
|
||||||
@Async public void incrementAsync() {
|
@Async public void incrementAsync() {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increment() {
|
public void increment() {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Async public Future<Integer> incrementReturningAFuture() {
|
@Async public Future<Integer> incrementReturningAFuture() {
|
||||||
counter++;
|
counter++;
|
||||||
return new AsyncResult<Integer>(5);
|
return new AsyncResult<Integer>(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// It should be an error to attach @Async to a method that returns a non-void
|
// It should be an error to attach @Async to a method that returns a non-void
|
||||||
// or non-Future.
|
// or non-Future.
|
||||||
// We need to keep this commented out, otherwise there will be a compile-time error.
|
// We need to keep this commented out, otherwise there will be a compile-time error.
|
||||||
// Please uncomment and re-comment this periodically to check that the compiler
|
// Please uncomment and re-comment this periodically to check that the compiler
|
||||||
// produces an error message due to the 'declare error' statement
|
// produces an error message due to the 'declare error' statement
|
||||||
// in AnnotationAsyncExecutionAspect
|
// in AnnotationAsyncExecutionAspect
|
||||||
// @Async public int getInt() {
|
// @Async public int getInt() {
|
||||||
// return 0;
|
// return 0;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
static class ClassWithAsyncAnnotation {
|
static class ClassWithAsyncAnnotation {
|
||||||
int counter;
|
int counter;
|
||||||
|
|
||||||
public void increment() {
|
public void increment() {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect
|
// Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect
|
||||||
public int return5() {
|
public int return5() {
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Future<Integer> incrementReturningAFuture() {
|
public Future<Integer> incrementReturningAFuture() {
|
||||||
counter++;
|
counter++;
|
||||||
return new AsyncResult<Integer>(5);
|
return new AsyncResult<Integer>(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006 the original author or authors.
|
* Copyright 2002-2006 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Created on 11 Sep 2006 by Adrian Colyer
|
* Created on 11 Sep 2006 by Adrian Colyer
|
||||||
*/
|
*/
|
||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Colyer
|
* @author Adrian Colyer
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public class ClassWithPrivateAnnotatedMember {
|
public class ClassWithPrivateAnnotatedMember {
|
||||||
|
|
||||||
public void doSomething() {
|
public void doSomething() {
|
||||||
doInTransaction();
|
doInTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
private void doInTransaction() {}
|
private void doInTransaction() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2006 the original author or authors.
|
* Copyright 2002-2006 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Created on 11 Sep 2006 by Adrian Colyer
|
* Created on 11 Sep 2006 by Adrian Colyer
|
||||||
*/
|
*/
|
||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Colyer
|
* @author Adrian Colyer
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public class ClassWithProtectedAnnotatedMember {
|
public class ClassWithProtectedAnnotatedMember {
|
||||||
|
|
||||||
public void doSomething() {
|
public void doSomething() {
|
||||||
doInTransaction();
|
doInTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
protected void doInTransaction() {}
|
protected void doInTransaction() {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public interface ITransactional {
|
public interface ITransactional {
|
||||||
|
|
||||||
Object echo(Throwable t) throws Throwable;
|
Object echo(Throwable t) throws Throwable;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
public class MethodAnnotationOnClassWithNoInterface {
|
public class MethodAnnotationOnClassWithNoInterface {
|
||||||
|
|
||||||
@Transactional(rollbackFor=InterruptedException.class)
|
@Transactional(rollbackFor=InterruptedException.class)
|
||||||
public Object echo(Throwable t) throws Throwable {
|
public Object echo(Throwable t) throws Throwable {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void noTransactionAttribute() {
|
public void noTransactionAttribute() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,261 +1,261 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2007 the original author or authors.
|
* Copyright 2002-2007 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
|
|
||||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||||
import org.springframework.transaction.CallCountingTransactionManager;
|
import org.springframework.transaction.CallCountingTransactionManager;
|
||||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||||
import org.springframework.transaction.interceptor.TransactionAttribute;
|
import org.springframework.transaction.interceptor.TransactionAttribute;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Ramnivas Laddad
|
* @author Ramnivas Laddad
|
||||||
*/
|
*/
|
||||||
public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests {
|
public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests {
|
||||||
|
|
||||||
private TransactionAspectSupport transactionAspect;
|
private TransactionAspectSupport transactionAspect;
|
||||||
|
|
||||||
private CallCountingTransactionManager txManager;
|
private CallCountingTransactionManager txManager;
|
||||||
|
|
||||||
private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
|
private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
|
||||||
|
|
||||||
private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
|
private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
|
||||||
|
|
||||||
private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
|
private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
|
||||||
|
|
||||||
private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
|
private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
|
||||||
|
|
||||||
|
|
||||||
public void setAnnotationOnlyOnClassWithNoInterface(
|
public void setAnnotationOnlyOnClassWithNoInterface(
|
||||||
TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
|
TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
|
||||||
this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
|
this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
|
public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
|
||||||
this.beanWithAnnotatedProtectedMethod = aBean;
|
this.beanWithAnnotatedProtectedMethod = aBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
|
public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
|
||||||
this.beanWithAnnotatedPrivateMethod = aBean;
|
this.beanWithAnnotatedPrivateMethod = aBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
|
public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
|
||||||
this.transactionAspect = transactionAspect;
|
this.transactionAspect = transactionAspect;
|
||||||
this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
|
this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransactionAspectSupport getTransactionAspect() {
|
public TransactionAspectSupport getTransactionAspect() {
|
||||||
return this.transactionAspect;
|
return this.transactionAspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getConfigPath() {
|
protected String getConfigPath() {
|
||||||
return "TransactionAspectTests-context.xml";
|
return "TransactionAspectTests-context.xml";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testCommitOnAnnotatedClass() throws Throwable {
|
public void testCommitOnAnnotatedClass() throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
annotationOnlyOnClassWithNoInterface.echo(null);
|
annotationOnlyOnClassWithNoInterface.echo(null);
|
||||||
assertEquals(1, txManager.commits);
|
assertEquals(1, txManager.commits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
|
public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
beanWithAnnotatedProtectedMethod.doInTransaction();
|
beanWithAnnotatedProtectedMethod.doInTransaction();
|
||||||
assertEquals(1, txManager.commits);
|
assertEquals(1, txManager.commits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
|
public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
beanWithAnnotatedPrivateMethod.doSomething();
|
beanWithAnnotatedPrivateMethod.doSomething();
|
||||||
assertEquals(1, txManager.commits);
|
assertEquals(1, txManager.commits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
|
public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0,txManager.begun);
|
assertEquals(0,txManager.begun);
|
||||||
annotationOnlyOnClassWithNoInterface.nonTransactionalMethod();
|
annotationOnlyOnClassWithNoInterface.nonTransactionalMethod();
|
||||||
assertEquals(0,txManager.begun);
|
assertEquals(0,txManager.begun);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCommitOnAnnotatedMethod() throws Throwable {
|
public void testCommitOnAnnotatedMethod() throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
methodAnnotationOnly.echo(null);
|
methodAnnotationOnly.echo(null);
|
||||||
assertEquals(1, txManager.commits);
|
assertEquals(1, txManager.commits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class NotTransactional {
|
public static class NotTransactional {
|
||||||
public void noop() {
|
public void noop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNotTransactional() throws Throwable {
|
public void testNotTransactional() throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
new NotTransactional().noop();
|
new NotTransactional().noop();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testDefaultCommitOnAnnotatedClass() throws Throwable {
|
public void testDefaultCommitOnAnnotatedClass() throws Throwable {
|
||||||
testRollback(new TransactionOperationCallback() {
|
testRollback(new TransactionOperationCallback() {
|
||||||
public Object performTransactionalOperation() throws Throwable {
|
public Object performTransactionalOperation() throws Throwable {
|
||||||
return annotationOnlyOnClassWithNoInterface.echo(new Exception());
|
return annotationOnlyOnClassWithNoInterface.echo(new Exception());
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
|
public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
|
||||||
testRollback(new TransactionOperationCallback() {
|
testRollback(new TransactionOperationCallback() {
|
||||||
public Object performTransactionalOperation() throws Throwable {
|
public Object performTransactionalOperation() throws Throwable {
|
||||||
return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException());
|
return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException());
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
|
public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
||||||
testRollback(new TransactionOperationCallback() {
|
testRollback(new TransactionOperationCallback() {
|
||||||
public Object performTransactionalOperation() throws Throwable {
|
public Object performTransactionalOperation() throws Throwable {
|
||||||
return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception());
|
return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception());
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
|
public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
||||||
testRollback(new TransactionOperationCallback() {
|
testRollback(new TransactionOperationCallback() {
|
||||||
public Object performTransactionalOperation() throws Throwable {
|
public Object performTransactionalOperation() throws Throwable {
|
||||||
return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception());
|
return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception());
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ImplementsAnnotatedInterface implements ITransactional {
|
public static class ImplementsAnnotatedInterface implements ITransactional {
|
||||||
public Object echo(Throwable t) throws Throwable {
|
public Object echo(Throwable t) throws Throwable {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||||
// testRollback(new TransactionOperationCallback() {
|
// testRollback(new TransactionOperationCallback() {
|
||||||
// public Object performTransactionalOperation() throws Throwable {
|
// public Object performTransactionalOperation() throws Throwable {
|
||||||
// return new ImplementsAnnotatedInterface().echo(new Exception());
|
// return new ImplementsAnnotatedInterface().echo(new Exception());
|
||||||
// }
|
// }
|
||||||
// }, false);
|
// }, false);
|
||||||
|
|
||||||
final Exception ex = new Exception();
|
final Exception ex = new Exception();
|
||||||
testNotTransactional(new TransactionOperationCallback() {
|
testNotTransactional(new TransactionOperationCallback() {
|
||||||
public Object performTransactionalOperation() throws Throwable {
|
public Object performTransactionalOperation() throws Throwable {
|
||||||
return new ImplementsAnnotatedInterface().echo(ex);
|
return new ImplementsAnnotatedInterface().echo(ex);
|
||||||
}
|
}
|
||||||
}, ex);
|
}, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note: resolution does not occur. Thus we can't make a class transactional if
|
* Note: resolution does not occur. Thus we can't make a class transactional if
|
||||||
* it implements a transactionally annotated interface. This behaviour could only
|
* it implements a transactionally annotated interface. This behaviour could only
|
||||||
* be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
|
* be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
|
||||||
* @throws SecurityException
|
* @throws SecurityException
|
||||||
* @throws NoSuchMethodException
|
* @throws NoSuchMethodException
|
||||||
*/
|
*/
|
||||||
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException {
|
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException {
|
||||||
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
|
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
|
||||||
Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
|
Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
|
||||||
TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
|
TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
|
||||||
assertNull(ta);
|
assertNull(ta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||||
// testRollback(new TransactionOperationCallback() {
|
// testRollback(new TransactionOperationCallback() {
|
||||||
// public Object performTransactionalOperation() throws Throwable {
|
// public Object performTransactionalOperation() throws Throwable {
|
||||||
// return new ImplementsAnnotatedInterface().echo(new RuntimeException());
|
// return new ImplementsAnnotatedInterface().echo(new RuntimeException());
|
||||||
// }
|
// }
|
||||||
// }, true);
|
// }, true);
|
||||||
|
|
||||||
final Exception rollbackProvokingException = new RuntimeException();
|
final Exception rollbackProvokingException = new RuntimeException();
|
||||||
testNotTransactional(new TransactionOperationCallback() {
|
testNotTransactional(new TransactionOperationCallback() {
|
||||||
public Object performTransactionalOperation() throws Throwable {
|
public Object performTransactionalOperation() throws Throwable {
|
||||||
return new ImplementsAnnotatedInterface().echo(rollbackProvokingException);
|
return new ImplementsAnnotatedInterface().echo(rollbackProvokingException);
|
||||||
}
|
}
|
||||||
}, rollbackProvokingException);
|
}, rollbackProvokingException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable {
|
protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
try {
|
try {
|
||||||
toc.performTransactionalOperation();
|
toc.performTransactionalOperation();
|
||||||
assertEquals(1, txManager.commits);
|
assertEquals(1, txManager.commits);
|
||||||
}
|
}
|
||||||
catch (Throwable caught) {
|
catch (Throwable caught) {
|
||||||
if (caught instanceof AssertionFailedError) {
|
if (caught instanceof AssertionFailedError) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rollback) {
|
if (rollback) {
|
||||||
assertEquals(1, txManager.rollbacks);
|
assertEquals(1, txManager.rollbacks);
|
||||||
}
|
}
|
||||||
assertEquals(1, txManager.begun);
|
assertEquals(1, txManager.begun);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
||||||
txManager.clear();
|
txManager.clear();
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
try {
|
try {
|
||||||
toc.performTransactionalOperation();
|
toc.performTransactionalOperation();
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable t) {
|
||||||
if (expected == null) {
|
if (expected == null) {
|
||||||
fail("Expected " + expected);
|
fail("Expected " + expected);
|
||||||
}
|
}
|
||||||
assertSame(expected, t);
|
assertSame(expected, t);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
assertEquals(0, txManager.begun);
|
assertEquals(0, txManager.begun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private interface TransactionOperationCallback {
|
private interface TransactionOperationCallback {
|
||||||
|
|
||||||
Object performTransactionalOperation() throws Throwable;
|
Object performTransactionalOperation() throws Throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
package org.springframework.transaction.aspectj;
|
package org.springframework.transaction.aspectj;
|
||||||
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public class TransactionalAnnotationOnlyOnClassWithNoInterface {
|
public class TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||||
|
|
||||||
public Object echo(Throwable t) throws Throwable {
|
public Object echo(Throwable t) throws Throwable {
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nonTransactionalMethod() {
|
void nonTransactionalMethod() {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
Bundle-SymbolicName: org.springframework.aspects
|
Bundle-SymbolicName: org.springframework.aspects
|
||||||
Bundle-Name: Spring Aspects
|
Bundle-Name: Spring Aspects
|
||||||
Bundle-Vendor: SpringSource
|
Bundle-Vendor: SpringSource
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Import-Template:
|
Import-Template:
|
||||||
javax.persistence;version="[1.0.0,3.0.0)";resolution:=optional,
|
javax.persistence;version="[1.0.0,3.0.0)";resolution:=optional,
|
||||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||||
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
||||||
org.springframework.context.*;version=${spring.osgi.range},
|
org.springframework.context.*;version=${spring.osgi.range},
|
||||||
org.springframework.beans.*;version=${spring.osgi.range},
|
org.springframework.beans.*;version=${spring.osgi.range},
|
||||||
org.springframework.cache.*;version=${spring.osgi.range};resolution:=optional,
|
org.springframework.cache.*;version=${spring.osgi.range};resolution:=optional,
|
||||||
org.springframework.core.*;version=${spring.osgi.range},
|
org.springframework.core.*;version=${spring.osgi.range},
|
||||||
org.springframework.dao.*;version=${spring.osgi.range};resolution:=optional,
|
org.springframework.dao.*;version=${spring.osgi.range};resolution:=optional,
|
||||||
org.springframework.orm.*;version=${spring.osgi.range};resolution:=optional,
|
org.springframework.orm.*;version=${spring.osgi.range};resolution:=optional,
|
||||||
org.springframework.scheduling.*;version=${spring.osgi.range};resolution:=optional,
|
org.springframework.scheduling.*;version=${spring.osgi.range};resolution:=optional,
|
||||||
org.springframework.transaction.*;version=${spring.osgi.range};resolution:=optional
|
org.springframework.transaction.*;version=${spring.osgi.range};resolution:=optional
|
||||||
Ignored-Existing-Headers:
|
Ignored-Existing-Headers:
|
||||||
Bnd-LastModified,
|
Bnd-LastModified,
|
||||||
Import-Package,
|
Import-Package,
|
||||||
Tool
|
Tool
|
||||||
|
|||||||
@@ -1,61 +1,61 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.annotation;
|
package org.springframework.beans.factory.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation at the field or method/constructor parameter level
|
* Annotation at the field or method/constructor parameter level
|
||||||
* that indicates a default value expression for the affected argument.
|
* that indicates a default value expression for the affected argument.
|
||||||
*
|
*
|
||||||
* <p>Typically used for expression-driven dependency injection. Also supported
|
* <p>Typically used for expression-driven dependency injection. Also supported
|
||||||
* for dynamic resolution of handler method parameters, e.g. in Spring MVC.
|
* for dynamic resolution of handler method parameters, e.g. in Spring MVC.
|
||||||
*
|
*
|
||||||
* <p>A common use case is to assign default field values using
|
* <p>A common use case is to assign default field values using
|
||||||
* "#{systemProperties.myProp}" style expressions.
|
* "#{systemProperties.myProp}" style expressions.
|
||||||
*
|
*
|
||||||
* <p>Note that actual processing of the {@code @Value} annotation is performed
|
* <p>Note that actual processing of the {@code @Value} annotation is performed
|
||||||
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
|
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||||
* BeanPostProcessor} which in turn means that you <em>cannot</em> use
|
* BeanPostProcessor} which in turn means that you <em>cannot</em> use
|
||||||
* {@code @Value} within
|
* {@code @Value} within
|
||||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor
|
* {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||||
* BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please
|
* BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please
|
||||||
* consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
|
* consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
|
||||||
* class (which, by default, checks for the presence of this annotation).
|
* class (which, by default, checks for the presence of this annotation).
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see AutowiredAnnotationBeanPostProcessor
|
* @see AutowiredAnnotationBeanPostProcessor
|
||||||
* @see Autowired
|
* @see Autowired
|
||||||
* @see org.springframework.beans.factory.config.BeanExpressionResolver
|
* @see org.springframework.beans.factory.config.BeanExpressionResolver
|
||||||
* @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue
|
* @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
|
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface Value {
|
public @interface Value {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual value expression: e.g. "#{systemProperties.myProp}".
|
* The actual value expression: e.g. "#{systemProperties.myProp}".
|
||||||
*/
|
*/
|
||||||
String value();
|
String value();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,84 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.config;
|
package org.springframework.beans.factory.config;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context object for evaluating an expression within a bean definition.
|
* Context object for evaluating an expression within a bean definition.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class BeanExpressionContext {
|
public class BeanExpressionContext {
|
||||||
|
|
||||||
private final ConfigurableBeanFactory beanFactory;
|
private final ConfigurableBeanFactory beanFactory;
|
||||||
|
|
||||||
private final Scope scope;
|
private final Scope scope;
|
||||||
|
|
||||||
|
|
||||||
public BeanExpressionContext(ConfigurableBeanFactory beanFactory, Scope scope) {
|
public BeanExpressionContext(ConfigurableBeanFactory beanFactory, Scope scope) {
|
||||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final ConfigurableBeanFactory getBeanFactory() {
|
public final ConfigurableBeanFactory getBeanFactory() {
|
||||||
return this.beanFactory;
|
return this.beanFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Scope getScope() {
|
public final Scope getScope() {
|
||||||
return this.scope;
|
return this.scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean containsObject(String key) {
|
public boolean containsObject(String key) {
|
||||||
return (this.beanFactory.containsBean(key) ||
|
return (this.beanFactory.containsBean(key) ||
|
||||||
(this.scope != null && this.scope.resolveContextualObject(key) != null));
|
(this.scope != null && this.scope.resolveContextualObject(key) != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getObject(String key) {
|
public Object getObject(String key) {
|
||||||
if (this.beanFactory.containsBean(key)) {
|
if (this.beanFactory.containsBean(key)) {
|
||||||
return this.beanFactory.getBean(key);
|
return this.beanFactory.getBean(key);
|
||||||
}
|
}
|
||||||
else if (this.scope != null){
|
else if (this.scope != null){
|
||||||
return this.scope.resolveContextualObject(key);
|
return this.scope.resolveContextualObject(key);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (this == other) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(other instanceof BeanExpressionContext)) {
|
if (!(other instanceof BeanExpressionContext)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
BeanExpressionContext otherContext = (BeanExpressionContext) other;
|
BeanExpressionContext otherContext = (BeanExpressionContext) other;
|
||||||
return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope);
|
return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return this.beanFactory.hashCode();
|
return this.beanFactory.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2008 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.config;
|
package org.springframework.beans.factory.config;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strategy interface for resolving a value through evaluating it
|
* Strategy interface for resolving a value through evaluating it
|
||||||
* as an expression, if applicable.
|
* as an expression, if applicable.
|
||||||
*
|
*
|
||||||
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
||||||
* contain a default implementation of this strategy. However,
|
* contain a default implementation of this strategy. However,
|
||||||
* {@link org.springframework.context.ApplicationContext} implementations
|
* {@link org.springframework.context.ApplicationContext} implementations
|
||||||
* will provide expression support out of the box.
|
* will provide expression support out of the box.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public interface BeanExpressionResolver {
|
public interface BeanExpressionResolver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluate the given value as an expression, if applicable;
|
* Evaluate the given value as an expression, if applicable;
|
||||||
* return the value as-is otherwise.
|
* return the value as-is otherwise.
|
||||||
* @param value the value to check
|
* @param value the value to check
|
||||||
* @param evalContext the evaluation context
|
* @param evalContext the evaluation context
|
||||||
* @return the resolved value (potentially the given value as-is)
|
* @return the resolved value (potentially the given value as-is)
|
||||||
* @throws BeansException if evaluation failed
|
* @throws BeansException if evaluation failed
|
||||||
*/
|
*/
|
||||||
Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException;
|
Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,95 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.config;
|
package org.springframework.beans.factory.config;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link org.springframework.beans.factory.FactoryBean} implementation that
|
* A {@link org.springframework.beans.factory.FactoryBean} implementation that
|
||||||
* returns a value which is a JSR-330 {@link javax.inject.Provider} that in turn
|
* returns a value which is a JSR-330 {@link javax.inject.Provider} that in turn
|
||||||
* returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}.
|
* returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}.
|
||||||
*
|
*
|
||||||
* <p>This is basically a JSR-330 compliant variant of Spring's good old
|
* <p>This is basically a JSR-330 compliant variant of Spring's good old
|
||||||
* {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional
|
* {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional
|
||||||
* external dependency injection configuration that targets a property or
|
* external dependency injection configuration that targets a property or
|
||||||
* constructor argument of type <code>javax.inject.Provider</code>, as an
|
* constructor argument of type <code>javax.inject.Provider</code>, as an
|
||||||
* alternative to JSR-330's <code>@Inject</code> annotation-driven approach.
|
* alternative to JSR-330's <code>@Inject</code> annotation-driven approach.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0.2
|
* @since 3.0.2
|
||||||
* @see javax.inject.Provider
|
* @see javax.inject.Provider
|
||||||
* @see ObjectFactoryCreatingFactoryBean
|
* @see ObjectFactoryCreatingFactoryBean
|
||||||
*/
|
*/
|
||||||
public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> {
|
public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> {
|
||||||
|
|
||||||
private String targetBeanName;
|
private String targetBeanName;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the name of the target bean.
|
* Set the name of the target bean.
|
||||||
* <p>The target does not <i>have</> to be a non-singleton bean, but realisticially
|
* <p>The target does not <i>have</> to be a non-singleton bean, but realisticially
|
||||||
* always will be (because if the target bean were a singleton, then said singleton
|
* always will be (because if the target bean were a singleton, then said singleton
|
||||||
* bean could simply be injected straight into the dependent object, thus obviating
|
* bean could simply be injected straight into the dependent object, thus obviating
|
||||||
* the need for the extra level of indirection afforded by this factory approach).
|
* the need for the extra level of indirection afforded by this factory approach).
|
||||||
*/
|
*/
|
||||||
public void setTargetBeanName(String targetBeanName) {
|
public void setTargetBeanName(String targetBeanName) {
|
||||||
this.targetBeanName = targetBeanName;
|
this.targetBeanName = targetBeanName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
|
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
|
||||||
super.afterPropertiesSet();
|
super.afterPropertiesSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class getObjectType() {
|
public Class getObjectType() {
|
||||||
return Provider.class;
|
return Provider.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Provider createInstance() {
|
protected Provider createInstance() {
|
||||||
return new TargetBeanProvider(getBeanFactory(), this.targetBeanName);
|
return new TargetBeanProvider(getBeanFactory(), this.targetBeanName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Independent inner class - for serialization purposes.
|
* Independent inner class - for serialization purposes.
|
||||||
*/
|
*/
|
||||||
private static class TargetBeanProvider implements Provider, Serializable {
|
private static class TargetBeanProvider implements Provider, Serializable {
|
||||||
|
|
||||||
private final BeanFactory beanFactory;
|
private final BeanFactory beanFactory;
|
||||||
|
|
||||||
private final String targetBeanName;
|
private final String targetBeanName;
|
||||||
|
|
||||||
public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) {
|
public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) {
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
this.targetBeanName = targetBeanName;
|
this.targetBeanName = targetBeanName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get() throws BeansException {
|
public Object get() throws BeansException {
|
||||||
return this.beanFactory.getBean(this.targetBeanName);
|
return this.beanFactory.getBean(this.targetBeanName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.support;
|
package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tag collection class used to hold managed array elements, which may
|
* Tag collection class used to hold managed array elements, which may
|
||||||
* include runtime bean references (to be resolved into bean objects).
|
* include runtime bean references (to be resolved into bean objects).
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class ManagedArray extends ManagedList<Object> {
|
public class ManagedArray extends ManagedList<Object> {
|
||||||
|
|
||||||
/** Resolved element type for runtime creation of the target array */
|
/** Resolved element type for runtime creation of the target array */
|
||||||
volatile Class resolvedElementType;
|
volatile Class resolvedElementType;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new managed array placeholder.
|
* Create a new managed array placeholder.
|
||||||
* @param elementTypeName the target element type as a class name
|
* @param elementTypeName the target element type as a class name
|
||||||
* @param size the size of the array
|
* @param size the size of the array
|
||||||
*/
|
*/
|
||||||
public ManagedArray(String elementTypeName, int size) {
|
public ManagedArray(String elementTypeName, int size) {
|
||||||
super(size);
|
super(size);
|
||||||
Assert.notNull(elementTypeName, "elementTypeName must not be null");
|
Assert.notNull(elementTypeName, "elementTypeName must not be null");
|
||||||
setElementTypeName(elementTypeName);
|
setElementTypeName(elementTypeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.support;
|
package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
import java.security.AccessControlContext;
|
import java.security.AccessControlContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provider of the security context of the code running inside the bean factory.
|
* Provider of the security context of the code running inside the bean factory.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public interface SecurityContextProvider {
|
public interface SecurityContextProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a security access control context relevant to a bean factory.
|
* Provides a security access control context relevant to a bean factory.
|
||||||
* @return bean factory security control context
|
* @return bean factory security control context
|
||||||
*/
|
*/
|
||||||
AccessControlContext getAccessControlContext();
|
AccessControlContext getAccessControlContext();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,58 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.factory.support;
|
package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
import java.security.AccessControlContext;
|
import java.security.AccessControlContext;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple {@link SecurityContextProvider} implementation.
|
* Simple {@link SecurityContextProvider} implementation.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class SimpleSecurityContextProvider implements SecurityContextProvider {
|
public class SimpleSecurityContextProvider implements SecurityContextProvider {
|
||||||
|
|
||||||
private final AccessControlContext acc;
|
private final AccessControlContext acc;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
||||||
* <p>The security context will be retrieved on each call from the current
|
* <p>The security context will be retrieved on each call from the current
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
public SimpleSecurityContextProvider() {
|
public SimpleSecurityContextProvider() {
|
||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
||||||
* <p>If the given control context is null, the security context will be
|
* <p>If the given control context is null, the security context will be
|
||||||
* retrieved on each call from the current thread.
|
* retrieved on each call from the current thread.
|
||||||
* @param acc access control context (can be <code>null</code>)
|
* @param acc access control context (can be <code>null</code>)
|
||||||
* @see AccessController#getContext()
|
* @see AccessController#getContext()
|
||||||
*/
|
*/
|
||||||
public SimpleSecurityContextProvider(AccessControlContext acc) {
|
public SimpleSecurityContextProvider(AccessControlContext acc) {
|
||||||
this.acc = acc;
|
this.acc = acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public AccessControlContext getAccessControlContext() {
|
public AccessControlContext getAccessControlContext() {
|
||||||
return (this.acc != null ? acc : AccessController.getContext());
|
return (this.acc != null ? acc : AccessController.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,151 +1,151 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.xml;
|
package org.springframework.beans.factory.xml;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||||
import org.springframework.core.Conventions;
|
import org.springframework.core.Conventions;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.w3c.dom.Attr;
|
import org.w3c.dom.Attr;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple <code>NamespaceHandler</code> implementation that maps custom
|
* Simple <code>NamespaceHandler</code> implementation that maps custom
|
||||||
* attributes directly through to bean properties. An important point to note is
|
* attributes directly through to bean properties. An important point to note is
|
||||||
* that this <code>NamespaceHandler</code> does not have a corresponding schema
|
* that this <code>NamespaceHandler</code> does not have a corresponding schema
|
||||||
* since there is no way to know in advance all possible attribute names.
|
* since there is no way to know in advance all possible attribute names.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* An example of the usage of this <code>NamespaceHandler</code> is shown below:
|
* An example of the usage of this <code>NamespaceHandler</code> is shown below:
|
||||||
*
|
*
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
* <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/>
|
* <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/>
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Here the '<code>c:name</code>' corresponds directly to the '<code>name</code>
|
* Here the '<code>c:name</code>' corresponds directly to the '<code>name</code>
|
||||||
* ' argument declared on the constructor of class '<code>TestBean</code>'. The
|
* ' argument declared on the constructor of class '<code>TestBean</code>'. The
|
||||||
* '<code>c:work-ref</code>' attributes corresponds to the '<code>work</code>'
|
* '<code>c:work-ref</code>' attributes corresponds to the '<code>work</code>'
|
||||||
* argument and, rather than being the concrete value, it contains the name of
|
* argument and, rather than being the concrete value, it contains the name of
|
||||||
* the bean that will be considered as a parameter.
|
* the bean that will be considered as a parameter.
|
||||||
*
|
*
|
||||||
* <b>Note</b>: This implementation supports only named parameters - there is no
|
* <b>Note</b>: This implementation supports only named parameters - there is no
|
||||||
* support for indexes or types. Further more, the names are used as hints by
|
* support for indexes or types. Further more, the names are used as hints by
|
||||||
* the container which, by default, does type introspection.
|
* the container which, by default, does type introspection.
|
||||||
*
|
*
|
||||||
* @see SimplePropertyNamespaceHandler
|
* @see SimplePropertyNamespaceHandler
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||||
|
|
||||||
private static final String REF_SUFFIX = "-ref";
|
private static final String REF_SUFFIX = "-ref";
|
||||||
private static final String DELIMITER_PREFIX = "_";
|
private static final String DELIMITER_PREFIX = "_";
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||||
parserContext.getReaderContext().error(
|
parserContext.getReaderContext().error(
|
||||||
"Class [" + getClass().getName() + "] does not support custom elements.", element);
|
"Class [" + getClass().getName() + "] does not support custom elements.", element);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
||||||
if (node instanceof Attr) {
|
if (node instanceof Attr) {
|
||||||
Attr attr = (Attr) node;
|
Attr attr = (Attr) node;
|
||||||
String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
|
String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
|
||||||
String argValue = StringUtils.trimWhitespace(attr.getValue());
|
String argValue = StringUtils.trimWhitespace(attr.getValue());
|
||||||
|
|
||||||
ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
|
ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
|
||||||
boolean ref = false;
|
boolean ref = false;
|
||||||
|
|
||||||
// handle -ref arguments
|
// handle -ref arguments
|
||||||
if (argName.endsWith(REF_SUFFIX)) {
|
if (argName.endsWith(REF_SUFFIX)) {
|
||||||
ref = true;
|
ref = true;
|
||||||
argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
|
argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
|
ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
|
||||||
valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));
|
valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));
|
||||||
|
|
||||||
// handle "escaped"/"_" arguments
|
// handle "escaped"/"_" arguments
|
||||||
if (argName.startsWith(DELIMITER_PREFIX)) {
|
if (argName.startsWith(DELIMITER_PREFIX)) {
|
||||||
String arg = argName.substring(1).trim();
|
String arg = argName.substring(1).trim();
|
||||||
|
|
||||||
// fast default check
|
// fast default check
|
||||||
if (!StringUtils.hasText(arg)) {
|
if (!StringUtils.hasText(arg)) {
|
||||||
cvs.addGenericArgumentValue(valueHolder);
|
cvs.addGenericArgumentValue(valueHolder);
|
||||||
}
|
}
|
||||||
// assume an index otherwise
|
// assume an index otherwise
|
||||||
else {
|
else {
|
||||||
int index = -1;
|
int index = -1;
|
||||||
try {
|
try {
|
||||||
index = Integer.parseInt(arg);
|
index = Integer.parseInt(arg);
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
parserContext.getReaderContext().error(
|
parserContext.getReaderContext().error(
|
||||||
"Constructor argument '" + argName + "' specifies an invalid integer", attr);
|
"Constructor argument '" + argName + "' specifies an invalid integer", attr);
|
||||||
}
|
}
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
parserContext.getReaderContext().error(
|
parserContext.getReaderContext().error(
|
||||||
"Constructor argument '" + argName + "' specifies a negative index", attr);
|
"Constructor argument '" + argName + "' specifies a negative index", attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cvs.hasIndexedArgumentValue(index)){
|
if (cvs.hasIndexedArgumentValue(index)){
|
||||||
parserContext.getReaderContext().error(
|
parserContext.getReaderContext().error(
|
||||||
"Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." +
|
"Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." +
|
||||||
" Only one approach may be used per argument.", attr);
|
" Only one approach may be used per argument.", attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvs.addIndexedArgumentValue(index, valueHolder);
|
cvs.addIndexedArgumentValue(index, valueHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// no escaping -> ctr name
|
// no escaping -> ctr name
|
||||||
else {
|
else {
|
||||||
String name = Conventions.attributeNameToPropertyName(argName);
|
String name = Conventions.attributeNameToPropertyName(argName);
|
||||||
if (containsArgWithName(name, cvs)){
|
if (containsArgWithName(name, cvs)){
|
||||||
parserContext.getReaderContext().error(
|
parserContext.getReaderContext().error(
|
||||||
"Constructor argument '" + argName + "' already defined using <constructor-arg>." +
|
"Constructor argument '" + argName + "' already defined using <constructor-arg>." +
|
||||||
" Only one approach may be used per argument.", attr);
|
" Only one approach may be used per argument.", attr);
|
||||||
}
|
}
|
||||||
valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
|
valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
|
||||||
cvs.addGenericArgumentValue(valueHolder);
|
cvs.addGenericArgumentValue(valueHolder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) {
|
private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) {
|
||||||
if (!checkName(name, cvs.getGenericArgumentValues())) {
|
if (!checkName(name, cvs.getGenericArgumentValues())) {
|
||||||
return checkName(name, cvs.getIndexedArgumentValues().values());
|
return checkName(name, cvs.getIndexedArgumentValues().values());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkName(String name, Collection<ValueHolder> values) {
|
private boolean checkName(String name, Collection<ValueHolder> values) {
|
||||||
for (ValueHolder holder : values) {
|
for (ValueHolder holder : values) {
|
||||||
if (name.equals(holder.getName())) {
|
if (name.equals(holder.getName())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,43 +1,43 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.propertyeditors;
|
package org.springframework.beans.propertyeditors;
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.util.Currency;
|
import java.util.Currency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor for <code>java.util.Currency</code>, translating currency codes into Currency
|
* Editor for <code>java.util.Currency</code>, translating currency codes into Currency
|
||||||
* objects. Exposes the currency code as text representation of a Currency object.
|
* objects. Exposes the currency code as text representation of a Currency object.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see java.util.Currency
|
* @see java.util.Currency
|
||||||
*/
|
*/
|
||||||
public class CurrencyEditor extends PropertyEditorSupport {
|
public class CurrencyEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
setValue(Currency.getInstance(text));
|
setValue(Currency.getInstance(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAsText() {
|
public String getAsText() {
|
||||||
Currency value = (Currency) getValue();
|
Currency value = (Currency) getValue();
|
||||||
return (value != null ? value.getCurrencyCode() : "");
|
return (value != null ? value.getCurrencyCode() : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.propertyeditors;
|
package org.springframework.beans.propertyeditors;
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor for <code>java.util.TimeZone</code>, translating timezone IDs into
|
* Editor for <code>java.util.TimeZone</code>, translating timezone IDs into
|
||||||
* TimeZone objects. Does not expose a text representation for TimeZone objects.
|
* TimeZone objects. Does not expose a text representation for TimeZone objects.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see java.util.TimeZone
|
* @see java.util.TimeZone
|
||||||
*/
|
*/
|
||||||
public class TimeZoneEditor extends PropertyEditorSupport {
|
public class TimeZoneEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
setValue(TimeZone.getTimeZone(text));
|
setValue(TimeZone.getTimeZone(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation returns <code>null</code> to indicate that
|
* This implementation returns <code>null</code> to indicate that
|
||||||
* there is no appropriate text representation.
|
* there is no appropriate text representation.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getAsText() {
|
public String getAsText() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.beans.propertyeditors;
|
package org.springframework.beans.propertyeditors;
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Editor for <code>java.util.UUID</code>, translating UUID
|
* Editor for <code>java.util.UUID</code>, translating UUID
|
||||||
* String representations into UUID objects and back.
|
* String representations into UUID objects and back.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0.1
|
* @since 3.0.1
|
||||||
* @see java.util.UUID
|
* @see java.util.UUID
|
||||||
*/
|
*/
|
||||||
public class UUIDEditor extends PropertyEditorSupport {
|
public class UUIDEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
if (StringUtils.hasText(text)) {
|
if (StringUtils.hasText(text)) {
|
||||||
setValue(UUID.fromString(text));
|
setValue(UUID.fromString(text));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
setValue(null);
|
setValue(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getAsText() {
|
public String getAsText() {
|
||||||
UUID value = (UUID) getValue();
|
UUID value = (UUID) getValue();
|
||||||
return (value != null ? value.toString() : "");
|
return (value != null ? value.toString() : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
package com.foo;
|
package com.foo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Component {
|
public class Component {
|
||||||
private String name;
|
private String name;
|
||||||
private List<Component> components = new ArrayList<Component>();
|
private List<Component> components = new ArrayList<Component>();
|
||||||
|
|
||||||
// mmm, there is no setter method for the 'components'
|
// mmm, there is no setter method for the 'components'
|
||||||
public void addComponent(Component component) {
|
public void addComponent(Component component) {
|
||||||
this.components.add(component);
|
this.components.add(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Component> getComponents() {
|
public List<Component> getComponents() {
|
||||||
return components;
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
package com.foo;
|
package com.foo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
import org.springframework.beans.factory.support.ManagedList;
|
||||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
import org.springframework.util.xml.DomUtils;
|
import org.springframework.util.xml.DomUtils;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||||
|
|
||||||
protected AbstractBeanDefinition parseInternal(Element element,
|
protected AbstractBeanDefinition parseInternal(Element element,
|
||||||
ParserContext parserContext) {
|
ParserContext parserContext) {
|
||||||
return parseComponentElement(element);
|
return parseComponentElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AbstractBeanDefinition parseComponentElement(Element element) {
|
private static AbstractBeanDefinition parseComponentElement(Element element) {
|
||||||
BeanDefinitionBuilder factory = BeanDefinitionBuilder
|
BeanDefinitionBuilder factory = BeanDefinitionBuilder
|
||||||
.rootBeanDefinition(ComponentFactoryBean.class);
|
.rootBeanDefinition(ComponentFactoryBean.class);
|
||||||
|
|
||||||
factory.addPropertyValue("parent", parseComponent(element));
|
factory.addPropertyValue("parent", parseComponent(element));
|
||||||
|
|
||||||
List<Element> childElements = DomUtils.getChildElementsByTagName(
|
List<Element> childElements = DomUtils.getChildElementsByTagName(
|
||||||
element, "component");
|
element, "component");
|
||||||
if (childElements != null && childElements.size() > 0) {
|
if (childElements != null && childElements.size() > 0) {
|
||||||
parseChildComponents(childElements, factory);
|
parseChildComponents(childElements, factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
return factory.getBeanDefinition();
|
return factory.getBeanDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BeanDefinition parseComponent(Element element) {
|
private static BeanDefinition parseComponent(Element element) {
|
||||||
BeanDefinitionBuilder component = BeanDefinitionBuilder
|
BeanDefinitionBuilder component = BeanDefinitionBuilder
|
||||||
.rootBeanDefinition(Component.class);
|
.rootBeanDefinition(Component.class);
|
||||||
component.addPropertyValue("name", element.getAttribute("name"));
|
component.addPropertyValue("name", element.getAttribute("name"));
|
||||||
return component.getBeanDefinition();
|
return component.getBeanDefinition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseChildComponents(List<Element> childElements,
|
private static void parseChildComponents(List<Element> childElements,
|
||||||
BeanDefinitionBuilder factory) {
|
BeanDefinitionBuilder factory) {
|
||||||
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>(
|
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>(
|
||||||
childElements.size());
|
childElements.size());
|
||||||
for (Element element : childElements) {
|
for (Element element : childElements) {
|
||||||
children.add(parseComponentElement(element));
|
children.add(parseComponentElement(element));
|
||||||
}
|
}
|
||||||
factory.addPropertyValue("children", children);
|
factory.addPropertyValue("children", children);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2010 the original author or authors.
|
* Copyright 2006-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.foo;
|
package com.foo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.hamcrest.CoreMatchers.*;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class ComponentBeanDefinitionParserTest {
|
public class ComponentBeanDefinitionParserTest {
|
||||||
|
|
||||||
private static XmlBeanFactory bf;
|
private static XmlBeanFactory bf;
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpBeforeClass() throws Exception {
|
public static void setUpBeforeClass() throws Exception {
|
||||||
bf = new XmlBeanFactory(new ClassPathResource(
|
bf = new XmlBeanFactory(new ClassPathResource(
|
||||||
"com/foo/component-config.xml"));
|
"com/foo/component-config.xml"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void tearDownAfterClass() throws Exception {
|
public static void tearDownAfterClass() throws Exception {
|
||||||
bf.destroySingletons();
|
bf.destroySingletons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component getBionicFamily() {
|
private Component getBionicFamily() {
|
||||||
return bf.getBean("bionic-family", Component.class);
|
return bf.getBean("bionic-family", Component.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBionicBasic() throws Exception {
|
public void testBionicBasic() throws Exception {
|
||||||
Component cp = getBionicFamily();
|
Component cp = getBionicFamily();
|
||||||
assertThat("Bionic-1", equalTo(cp.getName()));
|
assertThat("Bionic-1", equalTo(cp.getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBionicFirstLevelChildren() throws Exception {
|
public void testBionicFirstLevelChildren() throws Exception {
|
||||||
Component cp = getBionicFamily();
|
Component cp = getBionicFamily();
|
||||||
List<Component> components = cp.getComponents();
|
List<Component> components = cp.getComponents();
|
||||||
assertThat(2, equalTo(components.size()));
|
assertThat(2, equalTo(components.size()));
|
||||||
assertThat("Mother-1", equalTo(components.get(0).getName()));
|
assertThat("Mother-1", equalTo(components.get(0).getName()));
|
||||||
assertThat("Rock-1", equalTo(components.get(1).getName()));
|
assertThat("Rock-1", equalTo(components.get(1).getName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBionicSecondLevenChildren() throws Exception {
|
public void testBionicSecondLevenChildren() throws Exception {
|
||||||
Component cp = getBionicFamily();
|
Component cp = getBionicFamily();
|
||||||
List<Component> components = cp.getComponents().get(0).getComponents();
|
List<Component> components = cp.getComponents().get(0).getComponents();
|
||||||
assertThat(2, equalTo(components.size()));
|
assertThat(2, equalTo(components.size()));
|
||||||
assertThat("Karate-1", equalTo(components.get(0).getName()));
|
assertThat("Karate-1", equalTo(components.get(0).getName()));
|
||||||
assertThat("Sport-1", equalTo(components.get(1).getName()));
|
assertThat("Sport-1", equalTo(components.get(1).getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,35 +1,35 @@
|
|||||||
package com.foo;
|
package com.foo;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
|
||||||
public class ComponentFactoryBean implements FactoryBean<Component> {
|
public class ComponentFactoryBean implements FactoryBean<Component> {
|
||||||
private Component parent;
|
private Component parent;
|
||||||
private List<Component> children;
|
private List<Component> children;
|
||||||
|
|
||||||
public void setParent(Component parent) {
|
public void setParent(Component parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChildren(List<Component> children) {
|
public void setChildren(List<Component> children) {
|
||||||
this.children = children;
|
this.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getObject() throws Exception {
|
public Component getObject() throws Exception {
|
||||||
if (this.children != null && this.children.size() > 0) {
|
if (this.children != null && this.children.size() > 0) {
|
||||||
for (Component child : children) {
|
for (Component child : children) {
|
||||||
this.parent.addComponent(child);
|
this.parent.addComponent(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this.parent;
|
return this.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class<Component> getObjectType() {
|
public Class<Component> getObjectType() {
|
||||||
return Component.class;
|
return Component.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSingleton() {
|
public boolean isSingleton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.foo;
|
package com.foo;
|
||||||
|
|
||||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||||
|
|
||||||
public class ComponentNamespaceHandler extends NamespaceHandlerSupport {
|
public class ComponentNamespaceHandler extends NamespaceHandlerSupport {
|
||||||
public void init() {
|
public void init() {
|
||||||
registerBeanDefinitionParser("component",
|
registerBeanDefinitionParser("component",
|
||||||
new ComponentBeanDefinitionParser());
|
new ComponentBeanDefinitionParser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
|||||||
grant {
|
grant {
|
||||||
permission java.security.AllPermission;
|
permission java.security.AllPermission;
|
||||||
};
|
};
|
||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class ConstructorBean {
|
public class ConstructorBean {
|
||||||
|
|
||||||
public ConstructorBean() {
|
public ConstructorBean() {
|
||||||
System.getProperties();
|
System.getProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstructorBean(Object obj) {
|
public ConstructorBean(Object obj) {
|
||||||
System.out.println("Received object " + obj);
|
System.out.println("Received object " + obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class CustomCallbackBean {
|
public class CustomCallbackBean {
|
||||||
|
|
||||||
public void init() {
|
public void init() {
|
||||||
System.getProperties();
|
System.getProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
System.setProperty("security.destroy", "true");
|
System.setProperty("security.destroy", "true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class CustomFactoryBean implements FactoryBean<Object> {
|
public class CustomFactoryBean implements FactoryBean<Object> {
|
||||||
|
|
||||||
public Object getObject() throws Exception {
|
public Object getObject() throws Exception {
|
||||||
return System.getProperties();
|
return System.getProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class getObjectType() {
|
public Class getObjectType() {
|
||||||
System.setProperty("factory.object.type", "true");
|
System.setProperty("factory.object.type", "true");
|
||||||
return Properties.class;
|
return Properties.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSingleton() {
|
public boolean isSingleton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class DestroyBean implements DisposableBean {
|
public class DestroyBean implements DisposableBean {
|
||||||
|
|
||||||
public void destroy() throws Exception {
|
public void destroy() throws Exception {
|
||||||
System.setProperty("security.destroy", "true");
|
System.setProperty("security.destroy", "true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class FactoryBean {
|
public class FactoryBean {
|
||||||
|
|
||||||
public static Object makeStaticInstance() {
|
public static Object makeStaticInstance() {
|
||||||
System.getProperties();
|
System.getProperties();
|
||||||
return new Object();
|
return new Object();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Object protectedStaticInstance() {
|
protected static Object protectedStaticInstance() {
|
||||||
return "protectedStaticInstance";
|
return "protectedStaticInstance";
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object makeInstance() {
|
public Object makeInstance() {
|
||||||
System.getProperties();
|
System.getProperties();
|
||||||
return new Object();
|
return new Object();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class InitBean implements InitializingBean {
|
public class InitBean implements InitializingBean {
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
System.getProperties();
|
System.getProperties();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.beans.factory.support.security.support;
|
package org.springframework.beans.factory.support.security.support;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class PropertyBean {
|
public class PropertyBean {
|
||||||
|
|
||||||
public void setSecurityProperty(Object property) {
|
public void setSecurityProperty(Object property) {
|
||||||
System.getProperties();
|
System.getProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProperty(Object property) {
|
public void setProperty(Object property) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,68 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 the original author or authors.
|
* Copyright 2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package test.beans;
|
package test.beans;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
public class DummyBean {
|
public class DummyBean {
|
||||||
|
|
||||||
private Object value;
|
private Object value;
|
||||||
private String name;
|
private String name;
|
||||||
private int age;
|
private int age;
|
||||||
private TestBean spouse;
|
private TestBean spouse;
|
||||||
|
|
||||||
public DummyBean(Object value) {
|
public DummyBean(Object value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DummyBean(String name, int age) {
|
public DummyBean(String name, int age) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DummyBean(int ageRef, String nameRef) {
|
public DummyBean(int ageRef, String nameRef) {
|
||||||
this.name = nameRef;
|
this.name = nameRef;
|
||||||
this.age = ageRef;
|
this.age = ageRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DummyBean(String name, TestBean spouse) {
|
public DummyBean(String name, TestBean spouse) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.spouse = spouse;
|
this.spouse = spouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DummyBean(String name, Object value, int age) {
|
public DummyBean(String name, Object value, int age) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.age = age;
|
this.age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getValue() {
|
public Object getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAge() {
|
public int getAge() {
|
||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestBean getSpouse() {
|
public TestBean getSpouse() {
|
||||||
return spouse;
|
return spouse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#Wed Mar 31 18:40:01 EEST 2010
|
#Wed Mar 31 18:40:01 EEST 2010
|
||||||
eclipse.preferences.version=1
|
eclipse.preferences.version=1
|
||||||
formatter_profile=_Spring
|
formatter_profile=_Spring
|
||||||
formatter_settings_version=11
|
formatter_settings_version=11
|
||||||
|
|||||||
@@ -1,163 +1,163 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.commonj;
|
package org.springframework.scheduling.commonj;
|
||||||
|
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
|
|
||||||
import commonj.timers.TimerManager;
|
import commonj.timers.TimerManager;
|
||||||
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.context.Lifecycle;
|
import org.springframework.context.Lifecycle;
|
||||||
import org.springframework.jndi.JndiLocatorSupport;
|
import org.springframework.jndi.JndiLocatorSupport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager}
|
* Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager}
|
||||||
* Defines common configuration settings and common lifecycle handling.
|
* Defines common configuration settings and common lifecycle handling.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see commonj.timers.TimerManager
|
* @see commonj.timers.TimerManager
|
||||||
*/
|
*/
|
||||||
public abstract class TimerManagerAccessor extends JndiLocatorSupport
|
public abstract class TimerManagerAccessor extends JndiLocatorSupport
|
||||||
implements InitializingBean, DisposableBean, Lifecycle {
|
implements InitializingBean, DisposableBean, Lifecycle {
|
||||||
|
|
||||||
private TimerManager timerManager;
|
private TimerManager timerManager;
|
||||||
|
|
||||||
private String timerManagerName;
|
private String timerManagerName;
|
||||||
|
|
||||||
private boolean shared = false;
|
private boolean shared = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the CommonJ TimerManager to delegate to.
|
* Specify the CommonJ TimerManager to delegate to.
|
||||||
* <p>Note that the given TimerManager's lifecycle will be managed
|
* <p>Note that the given TimerManager's lifecycle will be managed
|
||||||
* by this FactoryBean.
|
* by this FactoryBean.
|
||||||
* <p>Alternatively (and typically), you can specify the JNDI name
|
* <p>Alternatively (and typically), you can specify the JNDI name
|
||||||
* of the target TimerManager.
|
* of the target TimerManager.
|
||||||
* @see #setTimerManagerName
|
* @see #setTimerManagerName
|
||||||
*/
|
*/
|
||||||
public void setTimerManager(TimerManager timerManager) {
|
public void setTimerManager(TimerManager timerManager) {
|
||||||
this.timerManager = timerManager;
|
this.timerManager = timerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the JNDI name of the CommonJ TimerManager.
|
* Set the JNDI name of the CommonJ TimerManager.
|
||||||
* <p>This can either be a fully qualified JNDI name, or the JNDI name relative
|
* <p>This can either be a fully qualified JNDI name, or the JNDI name relative
|
||||||
* to the current environment naming context if "resourceRef" is set to "true".
|
* to the current environment naming context if "resourceRef" is set to "true".
|
||||||
* @see #setTimerManager
|
* @see #setTimerManager
|
||||||
* @see #setResourceRef
|
* @see #setResourceRef
|
||||||
*/
|
*/
|
||||||
public void setTimerManagerName(String timerManagerName) {
|
public void setTimerManagerName(String timerManagerName) {
|
||||||
this.timerManagerName = timerManagerName;
|
this.timerManagerName = timerManagerName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether the TimerManager obtained by this FactoryBean
|
* Specify whether the TimerManager obtained by this FactoryBean
|
||||||
* is a shared instance ("true") or an independent instance ("false").
|
* is a shared instance ("true") or an independent instance ("false").
|
||||||
* The lifecycle of the former is supposed to be managed by the application
|
* The lifecycle of the former is supposed to be managed by the application
|
||||||
* server, while the lifecycle of the latter is up to the application.
|
* server, while the lifecycle of the latter is up to the application.
|
||||||
* <p>Default is "false", i.e. managing an independent TimerManager instance.
|
* <p>Default is "false", i.e. managing an independent TimerManager instance.
|
||||||
* This is what the CommonJ specification suggests that application servers
|
* This is what the CommonJ specification suggests that application servers
|
||||||
* are supposed to offer via JNDI lookups, typically declared as a
|
* are supposed to offer via JNDI lookups, typically declared as a
|
||||||
* <code>resource-ref</code> of type <code>commonj.timers.TimerManager</code>
|
* <code>resource-ref</code> of type <code>commonj.timers.TimerManager</code>
|
||||||
* in <code>web.xml<code>, with <code>res-sharing-scope</code> set to 'Unshareable'.
|
* in <code>web.xml<code>, with <code>res-sharing-scope</code> set to 'Unshareable'.
|
||||||
* <p>Switch this flag to "true" if you are obtaining a shared TimerManager,
|
* <p>Switch this flag to "true" if you are obtaining a shared TimerManager,
|
||||||
* typically through specifying the JNDI location of a TimerManager that
|
* typically through specifying the JNDI location of a TimerManager that
|
||||||
* has been explicitly declared as 'Shareable'. Note that WebLogic's
|
* has been explicitly declared as 'Shareable'. Note that WebLogic's
|
||||||
* cluster-aware Job Scheduler is a shared TimerManager too.
|
* cluster-aware Job Scheduler is a shared TimerManager too.
|
||||||
* <p>The sole difference between this FactoryBean being in shared or
|
* <p>The sole difference between this FactoryBean being in shared or
|
||||||
* non-shared mode is that it will only attempt to suspend / resume / stop
|
* non-shared mode is that it will only attempt to suspend / resume / stop
|
||||||
* the underlying TimerManager in case of an independent (non-shared) instance.
|
* the underlying TimerManager in case of an independent (non-shared) instance.
|
||||||
* This only affects the {@link org.springframework.context.Lifecycle} support
|
* This only affects the {@link org.springframework.context.Lifecycle} support
|
||||||
* as well as application context shutdown.
|
* as well as application context shutdown.
|
||||||
* @see #stop()
|
* @see #stop()
|
||||||
* @see #start()
|
* @see #start()
|
||||||
* @see #destroy()
|
* @see #destroy()
|
||||||
* @see commonj.timers.TimerManager
|
* @see commonj.timers.TimerManager
|
||||||
*/
|
*/
|
||||||
public void setShared(boolean shared) {
|
public void setShared(boolean shared) {
|
||||||
this.shared = shared;
|
this.shared = shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws NamingException {
|
public void afterPropertiesSet() throws NamingException {
|
||||||
if (this.timerManager == null) {
|
if (this.timerManager == null) {
|
||||||
if (this.timerManagerName == null) {
|
if (this.timerManagerName == null) {
|
||||||
throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified");
|
throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified");
|
||||||
}
|
}
|
||||||
this.timerManager = lookup(this.timerManagerName, TimerManager.class);
|
this.timerManager = lookup(this.timerManagerName, TimerManager.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final TimerManager getTimerManager() {
|
protected final TimerManager getTimerManager() {
|
||||||
return this.timerManager;
|
return this.timerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of Lifecycle interface
|
// Implementation of Lifecycle interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resumes the underlying TimerManager (if not shared).
|
* Resumes the underlying TimerManager (if not shared).
|
||||||
* @see commonj.timers.TimerManager#resume()
|
* @see commonj.timers.TimerManager#resume()
|
||||||
*/
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
if (!this.shared) {
|
if (!this.shared) {
|
||||||
this.timerManager.resume();
|
this.timerManager.resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspends the underlying TimerManager (if not shared).
|
* Suspends the underlying TimerManager (if not shared).
|
||||||
* @see commonj.timers.TimerManager#suspend()
|
* @see commonj.timers.TimerManager#suspend()
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (!this.shared) {
|
if (!this.shared) {
|
||||||
this.timerManager.suspend();
|
this.timerManager.suspend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Considers the underlying TimerManager as running if it is
|
* Considers the underlying TimerManager as running if it is
|
||||||
* neither suspending nor stopping.
|
* neither suspending nor stopping.
|
||||||
* @see commonj.timers.TimerManager#isSuspending()
|
* @see commonj.timers.TimerManager#isSuspending()
|
||||||
* @see commonj.timers.TimerManager#isStopping()
|
* @see commonj.timers.TimerManager#isStopping()
|
||||||
*/
|
*/
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return (!this.timerManager.isSuspending() && !this.timerManager.isStopping());
|
return (!this.timerManager.isSuspending() && !this.timerManager.isStopping());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// Implementation of DisposableBean interface
|
// Implementation of DisposableBean interface
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the underlying TimerManager (if not shared).
|
* Stops the underlying TimerManager (if not shared).
|
||||||
* @see commonj.timers.TimerManager#stop()
|
* @see commonj.timers.TimerManager#stop()
|
||||||
*/
|
*/
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
// Stop the entire TimerManager, if necessary.
|
// Stop the entire TimerManager, if necessary.
|
||||||
if (!this.shared) {
|
if (!this.shared) {
|
||||||
// May return early, but at least we already cancelled all known Timers.
|
// May return early, but at least we already cancelled all known Timers.
|
||||||
this.timerManager.stop();
|
this.timerManager.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,174 +1,174 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.commonj;
|
package org.springframework.scheduling.commonj;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.Delayed;
|
import java.util.concurrent.Delayed;
|
||||||
import java.util.concurrent.FutureTask;
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import commonj.timers.Timer;
|
import commonj.timers.Timer;
|
||||||
import commonj.timers.TimerListener;
|
import commonj.timers.TimerListener;
|
||||||
|
|
||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||||
import org.springframework.scheduling.support.TaskUtils;
|
import org.springframework.scheduling.support.TaskUtils;
|
||||||
import org.springframework.util.ErrorHandler;
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
||||||
* a CommonJ {@link commonj.timers.TimerManager}.
|
* a CommonJ {@link commonj.timers.TimerManager}.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler {
|
public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler {
|
||||||
|
|
||||||
private volatile ErrorHandler errorHandler;
|
private volatile ErrorHandler errorHandler;
|
||||||
|
|
||||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||||
return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule();
|
return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false));
|
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false));
|
||||||
Timer timer = getTimerManager().schedule(futureTask, startTime);
|
Timer timer = getTimerManager().schedule(futureTask, startTime);
|
||||||
futureTask.setTimer(timer);
|
futureTask.setTimer(timer);
|
||||||
return futureTask;
|
return futureTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||||
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period);
|
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period);
|
||||||
futureTask.setTimer(timer);
|
futureTask.setTimer(timer);
|
||||||
return futureTask;
|
return futureTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||||
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period);
|
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period);
|
||||||
futureTask.setTimer(timer);
|
futureTask.setTimer(timer);
|
||||||
return futureTask;
|
return futureTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||||
Timer timer = getTimerManager().schedule(futureTask, startTime, delay);
|
Timer timer = getTimerManager().schedule(futureTask, startTime, delay);
|
||||||
futureTask.setTimer(timer);
|
futureTask.setTimer(timer);
|
||||||
return futureTask;
|
return futureTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||||
Timer timer = getTimerManager().schedule(futureTask, 0, delay);
|
Timer timer = getTimerManager().schedule(futureTask, 0, delay);
|
||||||
futureTask.setTimer(timer);
|
futureTask.setTimer(timer);
|
||||||
return futureTask;
|
return futureTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) {
|
private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) {
|
||||||
return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask);
|
return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ScheduledFuture adapter that wraps a CommonJ Timer.
|
* ScheduledFuture adapter that wraps a CommonJ Timer.
|
||||||
*/
|
*/
|
||||||
private static class TimerScheduledFuture extends FutureTask<Object> implements TimerListener, ScheduledFuture<Object> {
|
private static class TimerScheduledFuture extends FutureTask<Object> implements TimerListener, ScheduledFuture<Object> {
|
||||||
|
|
||||||
protected transient Timer timer;
|
protected transient Timer timer;
|
||||||
|
|
||||||
protected transient boolean cancelled = false;
|
protected transient boolean cancelled = false;
|
||||||
|
|
||||||
public TimerScheduledFuture(Runnable runnable) {
|
public TimerScheduledFuture(Runnable runnable) {
|
||||||
super(runnable, null);
|
super(runnable, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimer(Timer timer) {
|
public void setTimer(Timer timer) {
|
||||||
this.timer = timer;
|
this.timer = timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void timerExpired(Timer timer) {
|
public void timerExpired(Timer timer) {
|
||||||
runAndReset();
|
runAndReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||||
boolean result = super.cancel(mayInterruptIfRunning);
|
boolean result = super.cancel(mayInterruptIfRunning);
|
||||||
this.timer.cancel();
|
this.timer.cancel();
|
||||||
this.cancelled = true;
|
this.cancelled = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDelay(TimeUnit unit) {
|
public long getDelay(TimeUnit unit) {
|
||||||
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
|
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(Delayed other) {
|
public int compareTo(Delayed other) {
|
||||||
if (this == other) {
|
if (this == other) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
||||||
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ScheduledFuture adapter for trigger-based rescheduling.
|
* ScheduledFuture adapter for trigger-based rescheduling.
|
||||||
*/
|
*/
|
||||||
private class ReschedulingTimerListener extends TimerScheduledFuture {
|
private class ReschedulingTimerListener extends TimerScheduledFuture {
|
||||||
|
|
||||||
private final Trigger trigger;
|
private final Trigger trigger;
|
||||||
|
|
||||||
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||||
|
|
||||||
private volatile Date scheduledExecutionTime;
|
private volatile Date scheduledExecutionTime;
|
||||||
|
|
||||||
public ReschedulingTimerListener(Runnable runnable, Trigger trigger) {
|
public ReschedulingTimerListener(Runnable runnable, Trigger trigger) {
|
||||||
super(runnable);
|
super(runnable);
|
||||||
this.trigger = trigger;
|
this.trigger = trigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture schedule() {
|
public ScheduledFuture schedule() {
|
||||||
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
||||||
if (this.scheduledExecutionTime == null) {
|
if (this.scheduledExecutionTime == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime));
|
setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void timerExpired(Timer timer) {
|
public void timerExpired(Timer timer) {
|
||||||
Date actualExecutionTime = new Date();
|
Date actualExecutionTime = new Date();
|
||||||
super.timerExpired(timer);
|
super.timerExpired(timer);
|
||||||
Date completionTime = new Date();
|
Date completionTime = new Date();
|
||||||
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
||||||
if (!this.cancelled) {
|
if (!this.cancelled) {
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context;
|
package org.springframework.context;
|
||||||
|
|
||||||
import org.springframework.beans.factory.Aware;
|
import org.springframework.beans.factory.Aware;
|
||||||
import org.springframework.util.StringValueResolver;
|
import org.springframework.util.StringValueResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to be implemented by any object that wishes to be notified of a
|
* Interface to be implemented by any object that wishes to be notified of a
|
||||||
* <b>StringValueResolver</b> for the <b> resolution of embedded definition values.
|
* <b>StringValueResolver</b> for the <b> resolution of embedded definition values.
|
||||||
*
|
*
|
||||||
* <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
|
* <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
|
||||||
* ApplicationContextAware/BeanFactoryAware interfaces.
|
* ApplicationContextAware/BeanFactoryAware interfaces.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @since 3.0.3
|
* @since 3.0.3
|
||||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
|
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
|
||||||
*/
|
*/
|
||||||
public interface EmbeddedValueResolverAware extends Aware {
|
public interface EmbeddedValueResolverAware extends Aware {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the StringValueResolver to use for resolving embedded definition values.
|
* Set the StringValueResolver to use for resolving embedded definition values.
|
||||||
*/
|
*/
|
||||||
void setEmbeddedValueResolver(StringValueResolver resolver);
|
void setEmbeddedValueResolver(StringValueResolver resolver);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,177 +1,177 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.core.env.EnvironmentCapable;
|
import org.springframework.core.env.EnvironmentCapable;
|
||||||
import org.springframework.core.env.StandardEnvironment;
|
import org.springframework.core.env.StandardEnvironment;
|
||||||
import org.springframework.core.type.AnnotationMetadata;
|
import org.springframework.core.type.AnnotationMetadata;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenient adapter for programmatic registration of annotated bean classes.
|
* Convenient adapter for programmatic registration of annotated bean classes.
|
||||||
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
|
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
|
||||||
* the same resolution of annotations but for explicitly registered classes only.
|
* the same resolution of annotations but for explicitly registered classes only.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @author Sam Brannen
|
* @author Sam Brannen
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see AnnotationConfigApplicationContext#register
|
* @see AnnotationConfigApplicationContext#register
|
||||||
*/
|
*/
|
||||||
public class AnnotatedBeanDefinitionReader {
|
public class AnnotatedBeanDefinitionReader {
|
||||||
|
|
||||||
private final BeanDefinitionRegistry registry;
|
private final BeanDefinitionRegistry registry;
|
||||||
|
|
||||||
private Environment environment;
|
private Environment environment;
|
||||||
|
|
||||||
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
|
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
|
||||||
|
|
||||||
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
|
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
|
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
|
||||||
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
|
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
|
||||||
* the {@link Environment} will be inherited, otherwise a new
|
* the {@link Environment} will be inherited, otherwise a new
|
||||||
* {@link StandardEnvironment} will be created and used.
|
* {@link StandardEnvironment} will be created and used.
|
||||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||||
* in the form of a {@code BeanDefinitionRegistry}
|
* in the form of a {@code BeanDefinitionRegistry}
|
||||||
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
|
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
|
||||||
* @see #setEnvironment(Environment)
|
* @see #setEnvironment(Environment)
|
||||||
*/
|
*/
|
||||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||||||
this(registry, getOrCreateEnvironment(registry));
|
this(registry, getOrCreateEnvironment(registry));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
|
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
|
||||||
* the given {@link Environment}.
|
* the given {@link Environment}.
|
||||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||||
* in the form of a {@code BeanDefinitionRegistry}
|
* in the form of a {@code BeanDefinitionRegistry}
|
||||||
* @param environment the {@code Environment} to use when evaluating bean definition
|
* @param environment the {@code Environment} to use when evaluating bean definition
|
||||||
* profiles.
|
* profiles.
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
|
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
|
||||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||||
Assert.notNull(environment, "Environment must not be null");
|
Assert.notNull(environment, "Environment must not be null");
|
||||||
|
|
||||||
this.registry = registry;
|
this.registry = registry;
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
|
|
||||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
|
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the BeanDefinitionRegistry that this scanner operates on.
|
* Return the BeanDefinitionRegistry that this scanner operates on.
|
||||||
*/
|
*/
|
||||||
public final BeanDefinitionRegistry getRegistry() {
|
public final BeanDefinitionRegistry getRegistry() {
|
||||||
return this.registry;
|
return this.registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Environment to use when evaluating whether
|
* Set the Environment to use when evaluating whether
|
||||||
* {@link Profile @Profile}-annotated component classes should be registered.
|
* {@link Profile @Profile}-annotated component classes should be registered.
|
||||||
* <p>The default is a {@link StandardEnvironment}.
|
* <p>The default is a {@link StandardEnvironment}.
|
||||||
* @see #registerBean(Class, String, Class...)
|
* @see #registerBean(Class, String, Class...)
|
||||||
*/
|
*/
|
||||||
public void setEnvironment(Environment environment) {
|
public void setEnvironment(Environment environment) {
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the BeanNameGenerator to use for detected bean classes.
|
* Set the BeanNameGenerator to use for detected bean classes.
|
||||||
* <p>The default is a {@link AnnotationBeanNameGenerator}.
|
* <p>The default is a {@link AnnotationBeanNameGenerator}.
|
||||||
*/
|
*/
|
||||||
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
||||||
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
|
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the ScopeMetadataResolver to use for detected bean classes.
|
* Set the ScopeMetadataResolver to use for detected bean classes.
|
||||||
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
|
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
|
||||||
*/
|
*/
|
||||||
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
|
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
|
||||||
this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver
|
this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver
|
||||||
: new AnnotationScopeMetadataResolver());
|
: new AnnotationScopeMetadataResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(Class<?>... annotatedClasses) {
|
public void register(Class<?>... annotatedClasses) {
|
||||||
for (Class<?> annotatedClass : annotatedClasses) {
|
for (Class<?> annotatedClass : annotatedClasses) {
|
||||||
registerBean(annotatedClass);
|
registerBean(annotatedClass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBean(Class<?> annotatedClass) {
|
public void registerBean(Class<?> annotatedClass) {
|
||||||
registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
|
registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
|
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
|
||||||
registerBean(annotatedClass, null, qualifiers);
|
registerBean(annotatedClass, null, qualifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
|
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
|
||||||
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
|
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
|
||||||
AnnotationMetadata metadata = abd.getMetadata();
|
AnnotationMetadata metadata = abd.getMetadata();
|
||||||
|
|
||||||
if (ProfileHelper.isProfileAnnotationPresent(metadata)) {
|
if (ProfileHelper.isProfileAnnotationPresent(metadata)) {
|
||||||
if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) {
|
if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
|
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
|
||||||
abd.setScope(scopeMetadata.getScopeName());
|
abd.setScope(scopeMetadata.getScopeName());
|
||||||
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
|
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
|
||||||
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
|
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
|
||||||
if (qualifiers != null) {
|
if (qualifiers != null) {
|
||||||
for (Class<? extends Annotation> qualifier : qualifiers) {
|
for (Class<? extends Annotation> qualifier : qualifiers) {
|
||||||
if (Primary.class.equals(qualifier)) {
|
if (Primary.class.equals(qualifier)) {
|
||||||
abd.setPrimary(true);
|
abd.setPrimary(true);
|
||||||
} else if (Lazy.class.equals(qualifier)) {
|
} else if (Lazy.class.equals(qualifier)) {
|
||||||
abd.setLazyInit(true);
|
abd.setLazyInit(true);
|
||||||
} else {
|
} else {
|
||||||
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
|
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
|
||||||
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
|
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
|
||||||
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
|
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the Environment from the given registry if possible, otherwise return a new
|
* Get the Environment from the given registry if possible, otherwise return a new
|
||||||
* StandardEnvironment.
|
* StandardEnvironment.
|
||||||
*/
|
*/
|
||||||
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
|
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
|
||||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||||
if (registry instanceof EnvironmentCapable) {
|
if (registry instanceof EnvironmentCapable) {
|
||||||
return ((EnvironmentCapable) registry).getEnvironment();
|
return ((EnvironmentCapable) registry).getEnvironment();
|
||||||
}
|
}
|
||||||
return new StandardEnvironment();
|
return new StandardEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +1,54 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Inherited;
|
import java.lang.annotation.Inherited;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Beans on which the current bean depends. Any beans specified are guaranteed to be
|
* Beans on which the current bean depends. Any beans specified are guaranteed to be
|
||||||
* created by the container before this bean. Used infrequently in cases where a bean
|
* created by the container before this bean. Used infrequently in cases where a bean
|
||||||
* does not explicitly depend on another through properties or constructor arguments,
|
* does not explicitly depend on another through properties or constructor arguments,
|
||||||
* but rather depends on the side effects of another bean's initialization.
|
* but rather depends on the side effects of another bean's initialization.
|
||||||
* <p>Note: This attribute will not be inherited by child bean definitions,
|
* <p>Note: This attribute will not be inherited by child bean definitions,
|
||||||
* hence it needs to be specified per concrete bean definition.
|
* hence it needs to be specified per concrete bean definition.
|
||||||
*
|
*
|
||||||
* <p>May be used on any class directly or indirectly annotated with
|
* <p>May be used on any class directly or indirectly annotated with
|
||||||
* {@link org.springframework.stereotype.Component} or on methods annotated
|
* {@link org.springframework.stereotype.Component} or on methods annotated
|
||||||
* with {@link Bean}.
|
* with {@link Bean}.
|
||||||
*
|
*
|
||||||
* <p>Using {@link DependsOn} at the class level has no effect unless component-scanning
|
* <p>Using {@link DependsOn} at the class level has no effect unless component-scanning
|
||||||
* is being used. If a {@link DependsOn}-annotated class is declared via XML,
|
* is being used. If a {@link DependsOn}-annotated class is declared via XML,
|
||||||
* {@link DependsOn} annotation metadata is ignored, and
|
* {@link DependsOn} annotation metadata is ignored, and
|
||||||
* {@code <bean depends-on="..."/>} is respected instead.
|
* {@code <bean depends-on="..."/>} is respected instead.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Inherited
|
@Inherited
|
||||||
@Documented
|
@Documented
|
||||||
public @interface DependsOn {
|
public @interface DependsOn {
|
||||||
|
|
||||||
String[] value() default {};
|
String[] value() default {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,111 +1,111 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules:
|
* Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules:
|
||||||
* defaulting to prototype scope unless {@link javax.inject.Singleton} is present.
|
* defaulting to prototype scope unless {@link javax.inject.Singleton} is present.
|
||||||
*
|
*
|
||||||
* <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and
|
* <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and
|
||||||
* {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However,
|
* {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However,
|
||||||
* in practice, you will typically use Spring's rich default scoping instead - or extend
|
* in practice, you will typically use Spring's rich default scoping instead - or extend
|
||||||
* this resolver with custom scoping annotations that point to extended Spring scopes.
|
* this resolver with custom scoping annotations that point to extended Spring scopes.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see #registerScope
|
* @see #registerScope
|
||||||
* @see #resolveScopeName
|
* @see #resolveScopeName
|
||||||
* @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
|
* @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
|
||||||
* @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
|
* @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
|
||||||
*/
|
*/
|
||||||
public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
|
public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
|
||||||
|
|
||||||
private final Map<String, String> scopeMap = new HashMap<String, String>();
|
private final Map<String, String> scopeMap = new HashMap<String, String>();
|
||||||
|
|
||||||
|
|
||||||
public Jsr330ScopeMetadataResolver() {
|
public Jsr330ScopeMetadataResolver() {
|
||||||
registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON);
|
registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an extended JSR-330 scope annotation, mapping it onto a
|
* Register an extended JSR-330 scope annotation, mapping it onto a
|
||||||
* specific Spring scope by name.
|
* specific Spring scope by name.
|
||||||
* @param annotationType the JSR-330 annotation type as a Class
|
* @param annotationType the JSR-330 annotation type as a Class
|
||||||
* @param scopeName the Spring scope name
|
* @param scopeName the Spring scope name
|
||||||
*/
|
*/
|
||||||
public final void registerScope(Class annotationType, String scopeName) {
|
public final void registerScope(Class annotationType, String scopeName) {
|
||||||
this.scopeMap.put(annotationType.getName(), scopeName);
|
this.scopeMap.put(annotationType.getName(), scopeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register an extended JSR-330 scope annotation, mapping it onto a
|
* Register an extended JSR-330 scope annotation, mapping it onto a
|
||||||
* specific Spring scope by name.
|
* specific Spring scope by name.
|
||||||
* @param annotationType the JSR-330 annotation type by name
|
* @param annotationType the JSR-330 annotation type by name
|
||||||
* @param scopeName the Spring scope name
|
* @param scopeName the Spring scope name
|
||||||
*/
|
*/
|
||||||
public final void registerScope(String annotationType, String scopeName) {
|
public final void registerScope(String annotationType, String scopeName) {
|
||||||
this.scopeMap.put(annotationType, scopeName);
|
this.scopeMap.put(annotationType, scopeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the given annotation type into a named Spring scope.
|
* Resolve the given annotation type into a named Spring scope.
|
||||||
* <p>The default implementation simply checks against registered scopes.
|
* <p>The default implementation simply checks against registered scopes.
|
||||||
* Can be overridden for custom mapping rules, e.g. naming conventions.
|
* Can be overridden for custom mapping rules, e.g. naming conventions.
|
||||||
* @param annotationType the JSR-330 annotation type
|
* @param annotationType the JSR-330 annotation type
|
||||||
* @return the Spring scope name
|
* @return the Spring scope name
|
||||||
*/
|
*/
|
||||||
protected String resolveScopeName(String annotationType) {
|
protected String resolveScopeName(String annotationType) {
|
||||||
return this.scopeMap.get(annotationType);
|
return this.scopeMap.get(annotationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
|
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
|
||||||
ScopeMetadata metadata = new ScopeMetadata();
|
ScopeMetadata metadata = new ScopeMetadata();
|
||||||
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
|
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
|
||||||
if (definition instanceof AnnotatedBeanDefinition) {
|
if (definition instanceof AnnotatedBeanDefinition) {
|
||||||
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
||||||
Set<String> annTypes = annDef.getMetadata().getAnnotationTypes();
|
Set<String> annTypes = annDef.getMetadata().getAnnotationTypes();
|
||||||
String found = null;
|
String found = null;
|
||||||
for (String annType : annTypes) {
|
for (String annType : annTypes) {
|
||||||
Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType);
|
Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType);
|
||||||
if (metaAnns.contains("javax.inject.Scope")) {
|
if (metaAnns.contains("javax.inject.Scope")) {
|
||||||
if (found != null) {
|
if (found != null) {
|
||||||
throw new IllegalStateException("Found ambiguous scope annotations on bean class [" +
|
throw new IllegalStateException("Found ambiguous scope annotations on bean class [" +
|
||||||
definition.getBeanClassName() + "]: " + found + ", " + annType);
|
definition.getBeanClassName() + "]: " + found + ", " + annType);
|
||||||
}
|
}
|
||||||
found = annType;
|
found = annType;
|
||||||
String scopeName = resolveScopeName(annType);
|
String scopeName = resolveScopeName(annType);
|
||||||
if (scopeName == null) {
|
if (scopeName == null) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Unsupported scope annotation - not mapped onto Spring scope name: " + annType);
|
"Unsupported scope annotation - not mapped onto Spring scope name: " + annType);
|
||||||
}
|
}
|
||||||
metadata.setScopeName(scopeName);
|
metadata.setScopeName(scopeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.annotation;
|
package org.springframework.context.annotation;
|
||||||
|
|
||||||
import org.springframework.aop.scope.ScopedProxyUtils;
|
import org.springframework.aop.scope.ScopedProxyUtils;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegate factory class used to just introduce an AOP framework dependency
|
* Delegate factory class used to just introduce an AOP framework dependency
|
||||||
* when actually creating a scoped proxy.
|
* when actually creating a scoped proxy.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy
|
* @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy
|
||||||
*/
|
*/
|
||||||
class ScopedProxyCreator {
|
class ScopedProxyCreator {
|
||||||
|
|
||||||
public static BeanDefinitionHolder createScopedProxy(
|
public static BeanDefinitionHolder createScopedProxy(
|
||||||
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
|
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
|
||||||
|
|
||||||
return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
|
return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getTargetBeanName(String originalBeanName) {
|
public static String getTargetBeanName(String originalBeanName) {
|
||||||
return ScopedProxyUtils.getTargetBeanName(originalBeanName);
|
return ScopedProxyUtils.getTargetBeanName(originalBeanName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.event;
|
package org.springframework.context.event;
|
||||||
|
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.core.GenericTypeResolver;
|
import org.springframework.core.GenericTypeResolver;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link SmartApplicationListener} adapter that determines supported event types
|
* {@link SmartApplicationListener} adapter that determines supported event types
|
||||||
* through introspecting the generically declared type of the target listener.
|
* through introspecting the generically declared type of the target listener.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent
|
* @see org.springframework.context.ApplicationListener#onApplicationEvent
|
||||||
*/
|
*/
|
||||||
public class GenericApplicationListenerAdapter implements SmartApplicationListener {
|
public class GenericApplicationListenerAdapter implements SmartApplicationListener {
|
||||||
|
|
||||||
private final ApplicationListener delegate;
|
private final ApplicationListener delegate;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GenericApplicationListener for the given delegate.
|
* Create a new GenericApplicationListener for the given delegate.
|
||||||
* @param delegate the delegate listener to be invoked
|
* @param delegate the delegate listener to be invoked
|
||||||
*/
|
*/
|
||||||
public GenericApplicationListenerAdapter(ApplicationListener delegate) {
|
public GenericApplicationListenerAdapter(ApplicationListener delegate) {
|
||||||
Assert.notNull(delegate, "Delegate listener must not be null");
|
Assert.notNull(delegate, "Delegate listener must not be null");
|
||||||
this.delegate = delegate;
|
this.delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void onApplicationEvent(ApplicationEvent event) {
|
public void onApplicationEvent(ApplicationEvent event) {
|
||||||
this.delegate.onApplicationEvent(event);
|
this.delegate.onApplicationEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||||
Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class);
|
Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class);
|
||||||
if (typeArg == null || typeArg.equals(ApplicationEvent.class)) {
|
if (typeArg == null || typeArg.equals(ApplicationEvent.class)) {
|
||||||
Class targetClass = AopUtils.getTargetClass(this.delegate);
|
Class targetClass = AopUtils.getTargetClass(this.delegate);
|
||||||
if (targetClass != this.delegate.getClass()) {
|
if (targetClass != this.delegate.getClass()) {
|
||||||
typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class);
|
typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (typeArg == null || typeArg.isAssignableFrom(eventType));
|
return (typeArg == null || typeArg.isAssignableFrom(eventType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean supportsSourceType(Class<?> sourceType) {
|
public boolean supportsSourceType(Class<?> sourceType) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE);
|
return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.event;
|
package org.springframework.context.event;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationEvent;
|
import org.springframework.context.ApplicationEvent;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extended variant of the standard {@link ApplicationListener} interface,
|
* Extended variant of the standard {@link ApplicationListener} interface,
|
||||||
* exposing further metadata such as the supported event type.
|
* exposing further metadata such as the supported event type.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
|
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether this listener actually supports the given event type.
|
* Determine whether this listener actually supports the given event type.
|
||||||
*/
|
*/
|
||||||
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
|
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether this listener actually supports the given source type.
|
* Determine whether this listener actually supports the given source type.
|
||||||
*/
|
*/
|
||||||
boolean supportsSourceType(Class<?> sourceType);
|
boolean supportsSourceType(Class<?> sourceType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.expression;
|
package org.springframework.context.expression;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.PropertyAccessor;
|
import org.springframework.expression.PropertyAccessor;
|
||||||
import org.springframework.expression.TypedValue;
|
import org.springframework.expression.TypedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL property accessor that knows how to traverse the beans and contextual objects
|
* EL property accessor that knows how to traverse the beans and contextual objects
|
||||||
* of a Spring {@link org.springframework.beans.factory.config.BeanExpressionContext}.
|
* of a Spring {@link org.springframework.beans.factory.config.BeanExpressionContext}.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class BeanExpressionContextAccessor implements PropertyAccessor {
|
public class BeanExpressionContextAccessor implements PropertyAccessor {
|
||||||
|
|
||||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return ((BeanExpressionContext) target).containsObject(name);
|
return ((BeanExpressionContext) target).containsObject(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return new TypedValue(((BeanExpressionContext) target).getObject(name));
|
return new TypedValue(((BeanExpressionContext) target).getObject(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||||
throw new AccessException("Beans in a BeanFactory are read-only");
|
throw new AccessException("Beans in a BeanFactory are read-only");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getSpecificTargetClasses() {
|
public Class[] getSpecificTargetClasses() {
|
||||||
return new Class[] {BeanExpressionContext.class};
|
return new Class[] {BeanExpressionContext.class};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.expression;
|
package org.springframework.context.expression;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.PropertyAccessor;
|
import org.springframework.expression.PropertyAccessor;
|
||||||
import org.springframework.expression.TypedValue;
|
import org.springframework.expression.TypedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL property accessor that knows how to traverse the beans of a
|
* EL property accessor that knows how to traverse the beans of a
|
||||||
* Spring {@link org.springframework.beans.factory.BeanFactory}.
|
* Spring {@link org.springframework.beans.factory.BeanFactory}.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class BeanFactoryAccessor implements PropertyAccessor {
|
public class BeanFactoryAccessor implements PropertyAccessor {
|
||||||
|
|
||||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return (((BeanFactory) target).containsBean(name));
|
return (((BeanFactory) target).containsBean(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return new TypedValue(((BeanFactory) target).getBean(name));
|
return new TypedValue(((BeanFactory) target).getBean(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||||
throw new AccessException("Beans in a BeanFactory are read-only");
|
throw new AccessException("Beans in a BeanFactory are read-only");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getSpecificTargetClasses() {
|
public Class[] getSpecificTargetClasses() {
|
||||||
return new Class[] {BeanFactory.class};
|
return new Class[] {BeanFactory.class};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,51 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.expression;
|
package org.springframework.context.expression;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.BeanResolver;
|
import org.springframework.expression.BeanResolver;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL bean resolver that operates against a Spring
|
* EL bean resolver that operates against a Spring
|
||||||
* {@link org.springframework.beans.factory.BeanFactory}.
|
* {@link org.springframework.beans.factory.BeanFactory}.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0.4
|
* @since 3.0.4
|
||||||
*/
|
*/
|
||||||
public class BeanFactoryResolver implements BeanResolver {
|
public class BeanFactoryResolver implements BeanResolver {
|
||||||
|
|
||||||
private final BeanFactory beanFactory;
|
private final BeanFactory beanFactory;
|
||||||
|
|
||||||
public BeanFactoryResolver(BeanFactory beanFactory) {
|
public BeanFactoryResolver(BeanFactory beanFactory) {
|
||||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
|
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
|
||||||
try {
|
try {
|
||||||
return this.beanFactory.getBean(beanName);
|
return this.beanFactory.getBean(beanName);
|
||||||
}
|
}
|
||||||
catch (BeansException ex) {
|
catch (BeansException ex) {
|
||||||
throw new AccessException("Could not resolve bean reference against BeanFactory", ex);
|
throw new AccessException("Could not resolve bean reference against BeanFactory", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,84 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.expression;
|
package org.springframework.context.expression;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.expression.AccessException;
|
import org.springframework.expression.AccessException;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
import org.springframework.expression.PropertyAccessor;
|
import org.springframework.expression.PropertyAccessor;
|
||||||
import org.springframework.expression.TypedValue;
|
import org.springframework.expression.TypedValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EL property accessor that knows how to traverse the keys
|
* EL property accessor that knows how to traverse the keys
|
||||||
* of a standard {@link java.util.Map}.
|
* of a standard {@link java.util.Map}.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class MapAccessor implements PropertyAccessor {
|
public class MapAccessor implements PropertyAccessor {
|
||||||
|
|
||||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
Map map = (Map) target;
|
Map map = (Map) target;
|
||||||
return map.containsKey(name);
|
return map.containsKey(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
Map map = (Map) target;
|
Map map = (Map) target;
|
||||||
Object value = map.get(name);
|
Object value = map.get(name);
|
||||||
if (value == null && !map.containsKey(name)) {
|
if (value == null && !map.containsKey(name)) {
|
||||||
throw new MapAccessException(name);
|
throw new MapAccessException(name);
|
||||||
}
|
}
|
||||||
return new TypedValue(value);
|
return new TypedValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||||
Map map = (Map) target;
|
Map map = (Map) target;
|
||||||
map.put(name, newValue);
|
map.put(name, newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class[] getSpecificTargetClasses() {
|
public Class[] getSpecificTargetClasses() {
|
||||||
return new Class[] {Map.class};
|
return new Class[] {Map.class};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown from <code>read</code> in order to reset a cached
|
* Exception thrown from <code>read</code> in order to reset a cached
|
||||||
* PropertyAccessor, allowing other accessors to have a try.
|
* PropertyAccessor, allowing other accessors to have a try.
|
||||||
*/
|
*/
|
||||||
private static class MapAccessException extends AccessException {
|
private static class MapAccessException extends AccessException {
|
||||||
|
|
||||||
private final String key;
|
private final String key;
|
||||||
|
|
||||||
public MapAccessException(String key) {
|
public MapAccessException(String key) {
|
||||||
super(null);
|
super(null);
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return "Map does not contain a value for key '" + this.key + "'";
|
return "Map does not contain a value for key '" + this.key + "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,153 +1,153 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.expression;
|
package org.springframework.context.expression;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanExpressionException;
|
import org.springframework.beans.factory.BeanExpressionException;
|
||||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.ExpressionParser;
|
import org.springframework.expression.ExpressionParser;
|
||||||
import org.springframework.expression.ParserContext;
|
import org.springframework.expression.ParserContext;
|
||||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard implementation of the
|
* Standard implementation of the
|
||||||
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
|
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
|
||||||
* interface, parsing and evaluating Spring EL using Spring's expression module.
|
* interface, parsing and evaluating Spring EL using Spring's expression module.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.expression.ExpressionParser
|
* @see org.springframework.expression.ExpressionParser
|
||||||
* @see org.springframework.expression.spel.standard.SpelExpressionParser
|
* @see org.springframework.expression.spel.standard.SpelExpressionParser
|
||||||
* @see org.springframework.expression.spel.support.StandardEvaluationContext
|
* @see org.springframework.expression.spel.support.StandardEvaluationContext
|
||||||
*/
|
*/
|
||||||
public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||||
|
|
||||||
/** Default expression prefix: "#{" */
|
/** Default expression prefix: "#{" */
|
||||||
public static final String DEFAULT_EXPRESSION_PREFIX = "#{";
|
public static final String DEFAULT_EXPRESSION_PREFIX = "#{";
|
||||||
|
|
||||||
/** Default expression suffix: "}" */
|
/** Default expression suffix: "}" */
|
||||||
public static final String DEFAULT_EXPRESSION_SUFFIX = "}";
|
public static final String DEFAULT_EXPRESSION_SUFFIX = "}";
|
||||||
|
|
||||||
|
|
||||||
private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;
|
private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;
|
||||||
|
|
||||||
private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;
|
private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;
|
||||||
|
|
||||||
private ExpressionParser expressionParser = new SpelExpressionParser();
|
private ExpressionParser expressionParser = new SpelExpressionParser();
|
||||||
|
|
||||||
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();
|
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();
|
||||||
|
|
||||||
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
||||||
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>();
|
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>();
|
||||||
|
|
||||||
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
||||||
public boolean isTemplate() {
|
public boolean isTemplate() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public String getExpressionPrefix() {
|
public String getExpressionPrefix() {
|
||||||
return expressionPrefix;
|
return expressionPrefix;
|
||||||
}
|
}
|
||||||
public String getExpressionSuffix() {
|
public String getExpressionSuffix() {
|
||||||
return expressionSuffix;
|
return expressionSuffix;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the prefix that an expression string starts with.
|
* Set the prefix that an expression string starts with.
|
||||||
* The default is "#{".
|
* The default is "#{".
|
||||||
* @see #DEFAULT_EXPRESSION_PREFIX
|
* @see #DEFAULT_EXPRESSION_PREFIX
|
||||||
*/
|
*/
|
||||||
public void setExpressionPrefix(String expressionPrefix) {
|
public void setExpressionPrefix(String expressionPrefix) {
|
||||||
Assert.hasText(expressionPrefix, "Expression prefix must not be empty");
|
Assert.hasText(expressionPrefix, "Expression prefix must not be empty");
|
||||||
this.expressionPrefix = expressionPrefix;
|
this.expressionPrefix = expressionPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the suffix that an expression string ends with.
|
* Set the suffix that an expression string ends with.
|
||||||
* The default is "}".
|
* The default is "}".
|
||||||
* @see #DEFAULT_EXPRESSION_SUFFIX
|
* @see #DEFAULT_EXPRESSION_SUFFIX
|
||||||
*/
|
*/
|
||||||
public void setExpressionSuffix(String expressionSuffix) {
|
public void setExpressionSuffix(String expressionSuffix) {
|
||||||
Assert.hasText(expressionSuffix, "Expression suffix must not be empty");
|
Assert.hasText(expressionSuffix, "Expression suffix must not be empty");
|
||||||
this.expressionSuffix = expressionSuffix;
|
this.expressionSuffix = expressionSuffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the EL parser to use for expression parsing.
|
* Specify the EL parser to use for expression parsing.
|
||||||
* <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser},
|
* <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser},
|
||||||
* compatible with standard Unified EL style expression syntax.
|
* compatible with standard Unified EL style expression syntax.
|
||||||
*/
|
*/
|
||||||
public void setExpressionParser(ExpressionParser expressionParser) {
|
public void setExpressionParser(ExpressionParser expressionParser) {
|
||||||
Assert.notNull(expressionParser, "ExpressionParser must not be null");
|
Assert.notNull(expressionParser, "ExpressionParser must not be null");
|
||||||
this.expressionParser = expressionParser;
|
this.expressionParser = expressionParser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException {
|
public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException {
|
||||||
if (!StringUtils.hasLength(value)) {
|
if (!StringUtils.hasLength(value)) {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Expression expr = this.expressionCache.get(value);
|
Expression expr = this.expressionCache.get(value);
|
||||||
if (expr == null) {
|
if (expr == null) {
|
||||||
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
|
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
|
||||||
this.expressionCache.put(value, expr);
|
this.expressionCache.put(value, expr);
|
||||||
}
|
}
|
||||||
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
||||||
if (sec == null) {
|
if (sec == null) {
|
||||||
sec = new StandardEvaluationContext();
|
sec = new StandardEvaluationContext();
|
||||||
sec.setRootObject(evalContext);
|
sec.setRootObject(evalContext);
|
||||||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||||
sec.addPropertyAccessor(new MapAccessor());
|
sec.addPropertyAccessor(new MapAccessor());
|
||||||
sec.addPropertyAccessor(new EnvironmentAccessor());
|
sec.addPropertyAccessor(new EnvironmentAccessor());
|
||||||
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
|
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
|
||||||
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
||||||
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
|
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
|
||||||
if (conversionService != null) {
|
if (conversionService != null) {
|
||||||
sec.setTypeConverter(new StandardTypeConverter(conversionService));
|
sec.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||||
}
|
}
|
||||||
customizeEvaluationContext(sec);
|
customizeEvaluationContext(sec);
|
||||||
this.evaluationCache.put(evalContext, sec);
|
this.evaluationCache.put(evalContext, sec);
|
||||||
}
|
}
|
||||||
return expr.getValue(sec);
|
return expr.getValue(sec);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new BeanExpressionException("Expression parsing failed", ex);
|
throw new BeanExpressionException("Expression parsing failed", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Template method for customizing the expression evaluation context.
|
* Template method for customizing the expression evaluation context.
|
||||||
* <p>The default implementation is empty.
|
* <p>The default implementation is empty.
|
||||||
*/
|
*/
|
||||||
protected void customizeEvaluationContext(StandardEvaluationContext evalContext) {
|
protected void customizeEvaluationContext(StandardEvaluationContext evalContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,134 +1,134 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.context.support;
|
package org.springframework.context.support;
|
||||||
|
|
||||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
import org.springframework.core.env.ConfigurableEnvironment;
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenient application context with built-in XML support.
|
* Convenient application context with built-in XML support.
|
||||||
* This is a flexible alternative to {@link ClassPathXmlApplicationContext}
|
* This is a flexible alternative to {@link ClassPathXmlApplicationContext}
|
||||||
* and {@link FileSystemXmlApplicationContext}, to be configured via setters,
|
* and {@link FileSystemXmlApplicationContext}, to be configured via setters,
|
||||||
* with an eventual {@link #refresh()} call activating the context.
|
* with an eventual {@link #refresh()} call activating the context.
|
||||||
*
|
*
|
||||||
* <p>In case of multiple configuration files, bean definitions in later files
|
* <p>In case of multiple configuration files, bean definitions in later files
|
||||||
* will override those defined in earlier files. This can be leveraged to
|
* will override those defined in earlier files. This can be leveraged to
|
||||||
* deliberately override certain bean definitions via an extra configuration file.
|
* deliberately override certain bean definitions via an extra configuration file.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see #load
|
* @see #load
|
||||||
* @see XmlBeanDefinitionReader
|
* @see XmlBeanDefinitionReader
|
||||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||||
*/
|
*/
|
||||||
public class GenericXmlApplicationContext extends GenericApplicationContext {
|
public class GenericXmlApplicationContext extends GenericApplicationContext {
|
||||||
|
|
||||||
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
|
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GenericXmlApplicationContext that needs to be
|
* Create a new GenericXmlApplicationContext that needs to be
|
||||||
* {@linkplain #load loaded} and then manually {@link #refresh refreshed}.
|
* {@linkplain #load loaded} and then manually {@link #refresh refreshed}.
|
||||||
*/
|
*/
|
||||||
public GenericXmlApplicationContext() {
|
public GenericXmlApplicationContext() {
|
||||||
reader.setEnvironment(this.getEnvironment());
|
reader.setEnvironment(this.getEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||||
* from the given resources and automatically refreshing the context.
|
* from the given resources and automatically refreshing the context.
|
||||||
* @param resources the resources to load from
|
* @param resources the resources to load from
|
||||||
*/
|
*/
|
||||||
public GenericXmlApplicationContext(Resource... resources) {
|
public GenericXmlApplicationContext(Resource... resources) {
|
||||||
load(resources);
|
load(resources);
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||||
* from the given resource locations and automatically refreshing the context.
|
* from the given resource locations and automatically refreshing the context.
|
||||||
* @param resourceLocations the resources to load from
|
* @param resourceLocations the resources to load from
|
||||||
*/
|
*/
|
||||||
public GenericXmlApplicationContext(String... resourceLocations) {
|
public GenericXmlApplicationContext(String... resourceLocations) {
|
||||||
load(resourceLocations);
|
load(resourceLocations);
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||||
* from the given resource locations and automatically refreshing the context.
|
* from the given resource locations and automatically refreshing the context.
|
||||||
* @param relativeClass class whose package will be used as a prefix when
|
* @param relativeClass class whose package will be used as a prefix when
|
||||||
* loading each specified resource name
|
* loading each specified resource name
|
||||||
* @param resourceNames relatively-qualified names of resources to load
|
* @param resourceNames relatively-qualified names of resources to load
|
||||||
*/
|
*/
|
||||||
public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) {
|
public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) {
|
||||||
load(relativeClass, resourceNames);
|
load(relativeClass, resourceNames);
|
||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether to use XML validation. Default is <code>true</code>.
|
* Set whether to use XML validation. Default is <code>true</code>.
|
||||||
*/
|
*/
|
||||||
public void setValidating(boolean validating) {
|
public void setValidating(boolean validating) {
|
||||||
this.reader.setValidating(validating);
|
this.reader.setValidating(validating);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}.
|
* <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}.
|
||||||
* Should be called before any call to {@link #load}.
|
* Should be called before any call to {@link #load}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setEnvironment(ConfigurableEnvironment environment) {
|
public void setEnvironment(ConfigurableEnvironment environment) {
|
||||||
super.setEnvironment(environment);
|
super.setEnvironment(environment);
|
||||||
this.reader.setEnvironment(this.getEnvironment());
|
this.reader.setEnvironment(this.getEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load bean definitions from the given XML resources.
|
* Load bean definitions from the given XML resources.
|
||||||
* @param resources one or more resources to load from
|
* @param resources one or more resources to load from
|
||||||
*/
|
*/
|
||||||
public void load(Resource... resources) {
|
public void load(Resource... resources) {
|
||||||
this.reader.loadBeanDefinitions(resources);
|
this.reader.loadBeanDefinitions(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load bean definitions from the given XML resources.
|
* Load bean definitions from the given XML resources.
|
||||||
* @param resourceLocations one or more resource locations to load from
|
* @param resourceLocations one or more resource locations to load from
|
||||||
*/
|
*/
|
||||||
public void load(String... resourceLocations) {
|
public void load(String... resourceLocations) {
|
||||||
this.reader.loadBeanDefinitions(resourceLocations);
|
this.reader.loadBeanDefinitions(resourceLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load bean definitions from the given XML resources.
|
* Load bean definitions from the given XML resources.
|
||||||
* @param relativeClass class whose package will be used as a prefix when
|
* @param relativeClass class whose package will be used as a prefix when
|
||||||
* loading each specified resource name
|
* loading each specified resource name
|
||||||
* @param resourceNames relatively-qualified names of resources to load
|
* @param resourceNames relatively-qualified names of resources to load
|
||||||
*/
|
*/
|
||||||
public void load(Class<?> relativeClass, String... resourceNames) {
|
public void load(Class<?> relativeClass, String... resourceNames) {
|
||||||
Resource[] resources = new Resource[resourceNames.length];
|
Resource[] resources = new Resource[resourceNames.length];
|
||||||
for (int i = 0; i < resourceNames.length; i++) {
|
for (int i = 0; i < resourceNames.length; i++) {
|
||||||
resources[i] = new ClassPathResource(resourceNames[i], relativeClass);
|
resources[i] = new ClassPathResource(resourceNames[i], relativeClass);
|
||||||
}
|
}
|
||||||
this.load(resources);
|
this.load(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,74 +1,74 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.format.number;
|
package org.springframework.format.number;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.ParsePosition;
|
import java.text.ParsePosition;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.springframework.format.Formatter;
|
import org.springframework.format.Formatter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract formatter for Numbers,
|
* Abstract formatter for Numbers,
|
||||||
* providing a {@link #getNumberFormat(java.util.Locale)} template method.
|
* providing a {@link #getNumberFormat(java.util.Locale)} template method.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNumberFormatter implements Formatter<Number> {
|
public abstract class AbstractNumberFormatter implements Formatter<Number> {
|
||||||
|
|
||||||
private boolean lenient = false;
|
private boolean lenient = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether or not parsing is to be lenient. Default is false.
|
* Specify whether or not parsing is to be lenient. Default is false.
|
||||||
* <p>With lenient parsing, the parser may allow inputs that do not precisely match the format.
|
* <p>With lenient parsing, the parser may allow inputs that do not precisely match the format.
|
||||||
* With strict parsing, inputs must match the format exactly.
|
* With strict parsing, inputs must match the format exactly.
|
||||||
*/
|
*/
|
||||||
public void setLenient(boolean lenient) {
|
public void setLenient(boolean lenient) {
|
||||||
this.lenient = lenient;
|
this.lenient = lenient;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String print(Number number, Locale locale) {
|
public String print(Number number, Locale locale) {
|
||||||
return getNumberFormat(locale).format(number);
|
return getNumberFormat(locale).format(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number parse(String text, Locale locale) throws ParseException {
|
public Number parse(String text, Locale locale) throws ParseException {
|
||||||
NumberFormat format = getNumberFormat(locale);
|
NumberFormat format = getNumberFormat(locale);
|
||||||
ParsePosition position = new ParsePosition(0);
|
ParsePosition position = new ParsePosition(0);
|
||||||
Number number = format.parse(text, position);
|
Number number = format.parse(text, position);
|
||||||
if (position.getErrorIndex() != -1) {
|
if (position.getErrorIndex() != -1) {
|
||||||
throw new ParseException(text, position.getIndex());
|
throw new ParseException(text, position.getIndex());
|
||||||
}
|
}
|
||||||
if (!this.lenient) {
|
if (!this.lenient) {
|
||||||
if (text.length() != position.getIndex()) {
|
if (text.length() != position.getIndex()) {
|
||||||
// indicates a part of the string that was not parsed
|
// indicates a part of the string that was not parsed
|
||||||
throw new ParseException(text, position.getIndex());
|
throw new ParseException(text, position.getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return number;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a concrete NumberFormat for the specified locale.
|
* Obtain a concrete NumberFormat for the specified locale.
|
||||||
* @param locale the current locale
|
* @param locale the current locale
|
||||||
* @return the NumberFormat instance (never <code>null</code>)
|
* @return the NumberFormat instance (never <code>null</code>)
|
||||||
*/
|
*/
|
||||||
protected abstract NumberFormat getNumberFormat(Locale locale);
|
protected abstract NumberFormat getNumberFormat(Locale locale);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,128 +1,128 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.instrument.classloading.glassfish;
|
package org.springframework.instrument.classloading.glassfish;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflective wrapper around the GlassFish class loader. Used to
|
* Reflective wrapper around the GlassFish class loader. Used to
|
||||||
* encapsulate the classloader-specific methods (discovered and
|
* encapsulate the classloader-specific methods (discovered and
|
||||||
* called through reflection) from the load-time weaver.
|
* called through reflection) from the load-time weaver.
|
||||||
*
|
*
|
||||||
* <p>Supports GlassFish V1, V2 and V3 (currently in beta).
|
* <p>Supports GlassFish V1, V2 and V3 (currently in beta).
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
class GlassFishClassLoaderAdapter {
|
class GlassFishClassLoaderAdapter {
|
||||||
|
|
||||||
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2 = "com.sun.enterprise.loader.InstrumentableClassLoader";
|
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2 = "com.sun.enterprise.loader.InstrumentableClassLoader";
|
||||||
|
|
||||||
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3 = "org.glassfish.api.deployment.InstrumentableClassLoader";
|
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3 = "org.glassfish.api.deployment.InstrumentableClassLoader";
|
||||||
|
|
||||||
private static final String CLASS_TRANSFORMER = "javax.persistence.spi.ClassTransformer";
|
private static final String CLASS_TRANSFORMER = "javax.persistence.spi.ClassTransformer";
|
||||||
|
|
||||||
|
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
|
|
||||||
private final Method addTransformer;
|
private final Method addTransformer;
|
||||||
|
|
||||||
private final Method copy;
|
private final Method copy;
|
||||||
|
|
||||||
private final boolean glassFishV3;
|
private final boolean glassFishV3;
|
||||||
|
|
||||||
|
|
||||||
public GlassFishClassLoaderAdapter(ClassLoader classLoader) {
|
public GlassFishClassLoaderAdapter(ClassLoader classLoader) {
|
||||||
Class<?> instrumentableLoaderClass;
|
Class<?> instrumentableLoaderClass;
|
||||||
boolean glassV3 = false;
|
boolean glassV3 = false;
|
||||||
try {
|
try {
|
||||||
// try the V1/V2 API first
|
// try the V1/V2 API first
|
||||||
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2);
|
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2);
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException ex) {
|
catch (ClassNotFoundException ex) {
|
||||||
// fall back to V3
|
// fall back to V3
|
||||||
try {
|
try {
|
||||||
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3);
|
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3);
|
||||||
glassV3 = true;
|
glassV3 = true;
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassNotFoundException cnfe) {
|
||||||
throw new IllegalStateException("Could not initialize GlassFish LoadTimeWeaver because " +
|
throw new IllegalStateException("Could not initialize GlassFish LoadTimeWeaver because " +
|
||||||
"GlassFish (V1, V2 or V3) API classes are not available", ex);
|
"GlassFish (V1, V2 or V3) API classes are not available", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Class<?> classTransformerClass =
|
Class<?> classTransformerClass =
|
||||||
(glassV3 ? ClassFileTransformer.class : classLoader.loadClass(CLASS_TRANSFORMER));
|
(glassV3 ? ClassFileTransformer.class : classLoader.loadClass(CLASS_TRANSFORMER));
|
||||||
|
|
||||||
this.addTransformer = instrumentableLoaderClass.getMethod("addTransformer", classTransformerClass);
|
this.addTransformer = instrumentableLoaderClass.getMethod("addTransformer", classTransformerClass);
|
||||||
this.copy = instrumentableLoaderClass.getMethod("copy");
|
this.copy = instrumentableLoaderClass.getMethod("copy");
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not initialize GlassFish LoadTimeWeaver because GlassFish API classes are not available", ex);
|
"Could not initialize GlassFish LoadTimeWeaver because GlassFish API classes are not available", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassLoader clazzLoader = null;
|
ClassLoader clazzLoader = null;
|
||||||
// Detect transformation-aware ClassLoader by traversing the hierarchy
|
// Detect transformation-aware ClassLoader by traversing the hierarchy
|
||||||
// (as in GlassFish, Spring can be loaded by the WebappClassLoader).
|
// (as in GlassFish, Spring can be loaded by the WebappClassLoader).
|
||||||
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
||||||
if (instrumentableLoaderClass.isInstance(cl)) {
|
if (instrumentableLoaderClass.isInstance(cl)) {
|
||||||
clazzLoader = cl;
|
clazzLoader = cl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clazzLoader == null) {
|
if (clazzLoader == null) {
|
||||||
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" +
|
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" +
|
||||||
instrumentableLoaderClass.getName() + "] implementation is required.");
|
instrumentableLoaderClass.getName() + "] implementation is required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.classLoader = clazzLoader;
|
this.classLoader = clazzLoader;
|
||||||
this.glassFishV3 = glassV3;
|
this.glassFishV3 = glassV3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
try {
|
try {
|
||||||
this.addTransformer.invoke(this.classLoader,
|
this.addTransformer.invoke(this.classLoader,
|
||||||
(this.glassFishV3 ? transformer : new ClassTransformerAdapter(transformer)));
|
(this.glassFishV3 ? transformer : new ClassTransformerAdapter(transformer)));
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException ex) {
|
catch (InvocationTargetException ex) {
|
||||||
throw new IllegalStateException("GlassFish addTransformer method threw exception ", ex.getCause());
|
throw new IllegalStateException("GlassFish addTransformer method threw exception ", ex.getCause());
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not invoke GlassFish addTransformer method", ex);
|
throw new IllegalStateException("Could not invoke GlassFish addTransformer method", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return this.classLoader;
|
return this.classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getThrowawayClassLoader() {
|
public ClassLoader getThrowawayClassLoader() {
|
||||||
try {
|
try {
|
||||||
return (ClassLoader) this.copy.invoke(this.classLoader);
|
return (ClassLoader) this.copy.invoke(this.classLoader);
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException ex) {
|
catch (InvocationTargetException ex) {
|
||||||
throw new IllegalStateException("GlassFish copy method threw exception ", ex.getCause());
|
throw new IllegalStateException("GlassFish copy method threw exception ", ex.getCause());
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not invoke GlassFish copy method", ex);
|
throw new IllegalStateException("Could not invoke GlassFish copy method", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.instrument.classloading.jboss;
|
package org.springframework.instrument.classloading.jboss;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple interface used for handling the different JBoss class loader adapters.
|
* Simple interface used for handling the different JBoss class loader adapters.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
interface JBossClassLoaderAdapter {
|
interface JBossClassLoaderAdapter {
|
||||||
|
|
||||||
void addTransformer(ClassFileTransformer transformer);
|
void addTransformer(ClassFileTransformer transformer);
|
||||||
|
|
||||||
ClassLoader getInstrumentableClassLoader();
|
ClassLoader getInstrumentableClassLoader();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +1,91 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.instrument.classloading.jboss;
|
package org.springframework.instrument.classloading.jboss;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
|
|
||||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||||
import org.springframework.instrument.classloading.SimpleThrowawayClassLoader;
|
import org.springframework.instrument.classloading.SimpleThrowawayClassLoader;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader.
|
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader.
|
||||||
* Autodetects the specific JBoss version at runtime: currently supports
|
* Autodetects the specific JBoss version at runtime: currently supports
|
||||||
* JBoss AS 5, 6 and 7 (as of Spring 3.1).
|
* JBoss AS 5, 6 and 7 (as of Spring 3.1).
|
||||||
*
|
*
|
||||||
* <p><b>NOTE:</b> On JBoss 6.0, to avoid the container loading the classes before the
|
* <p><b>NOTE:</b> On JBoss 6.0, to avoid the container loading the classes before the
|
||||||
* application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt>
|
* application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt>
|
||||||
* file to the application archive - with the following content:
|
* file to the application archive - with the following content:
|
||||||
* <pre><scanning xmlns="urn:jboss:scanning:1.0"/></pre>
|
* <pre><scanning xmlns="urn:jboss:scanning:1.0"/></pre>
|
||||||
*
|
*
|
||||||
* <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
|
* <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
||||||
|
|
||||||
private final JBossClassLoaderAdapter adapter;
|
private final JBossClassLoaderAdapter adapter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
||||||
* the default {@link ClassLoader class loader}.
|
* the default {@link ClassLoader class loader}.
|
||||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||||
*/
|
*/
|
||||||
public JBossLoadTimeWeaver() {
|
public JBossLoadTimeWeaver() {
|
||||||
this(ClassUtils.getDefaultClassLoader());
|
this(ClassUtils.getDefaultClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
||||||
* the supplied {@link ClassLoader}.
|
* the supplied {@link ClassLoader}.
|
||||||
* @param classLoader the <code>ClassLoader</code> to delegate to for
|
* @param classLoader the <code>ClassLoader</code> to delegate to for
|
||||||
* weaving (must not be <code>null</code>)
|
* weaving (must not be <code>null</code>)
|
||||||
*/
|
*/
|
||||||
public JBossLoadTimeWeaver(ClassLoader classLoader) {
|
public JBossLoadTimeWeaver(ClassLoader classLoader) {
|
||||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||||
String loaderClassName = classLoader.getClass().getName();
|
String loaderClassName = classLoader.getClass().getName();
|
||||||
|
|
||||||
if (loaderClassName.startsWith("org.jboss.classloader")) {
|
if (loaderClassName.startsWith("org.jboss.classloader")) {
|
||||||
// JBoss AS 5 or JBoss AS 6
|
// JBoss AS 5 or JBoss AS 6
|
||||||
this.adapter = new JBossMCAdapter(classLoader);
|
this.adapter = new JBossMCAdapter(classLoader);
|
||||||
}
|
}
|
||||||
else if (loaderClassName.startsWith("org.jboss.modules")) {
|
else if (loaderClassName.startsWith("org.jboss.modules")) {
|
||||||
// JBoss AS 7
|
// JBoss AS 7
|
||||||
this.adapter = new JBossModulesAdapter(classLoader);
|
this.adapter = new JBossModulesAdapter(classLoader);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException("Unexpected ClassLoader type: " + loaderClassName);
|
throw new IllegalArgumentException("Unexpected ClassLoader type: " + loaderClassName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
this.adapter.addTransformer(transformer);
|
this.adapter.addTransformer(transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getInstrumentableClassLoader() {
|
public ClassLoader getInstrumentableClassLoader() {
|
||||||
return this.adapter.getInstrumentableClassLoader();
|
return this.adapter.getInstrumentableClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getThrowawayClassLoader() {
|
public ClassLoader getThrowawayClassLoader() {
|
||||||
return new SimpleThrowawayClassLoader(getInstrumentableClassLoader());
|
return new SimpleThrowawayClassLoader(getInstrumentableClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,145 +1,145 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.jboss;
|
package org.springframework.instrument.classloading.jboss;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflective wrapper around a JBoss 5 and 6 class loader methods (discovered and called
|
* Reflective wrapper around a JBoss 5 and 6 class loader methods (discovered and called
|
||||||
* through reflection) for load time weaving.
|
* through reflection) for load time weaving.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class JBossMCAdapter implements JBossClassLoaderAdapter {
|
class JBossMCAdapter implements JBossClassLoaderAdapter {
|
||||||
|
|
||||||
private static final String TRANSLATOR_NAME = "org.jboss.util.loading.Translator";
|
private static final String TRANSLATOR_NAME = "org.jboss.util.loading.Translator";
|
||||||
private static final String POLICY_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderPolicy";
|
private static final String POLICY_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderPolicy";
|
||||||
private static final String DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain";
|
private static final String DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain";
|
||||||
private static final String DEDICATED_SYSTEM = "org.jboss.classloader.spi.ClassLoaderSystem";
|
private static final String DEDICATED_SYSTEM = "org.jboss.classloader.spi.ClassLoaderSystem";
|
||||||
private static final String LOADER_NAME = "org.jboss.classloader.spi.base.BaseClassLoader";
|
private static final String LOADER_NAME = "org.jboss.classloader.spi.base.BaseClassLoader";
|
||||||
private static final String GET_POLICY = "getPolicy";
|
private static final String GET_POLICY = "getPolicy";
|
||||||
private static final String GET_DOMAIN = "getClassLoaderDomain";
|
private static final String GET_DOMAIN = "getClassLoaderDomain";
|
||||||
private static final String GET_SYSTEM = "getClassLoaderSystem";
|
private static final String GET_SYSTEM = "getClassLoaderSystem";
|
||||||
|
|
||||||
// available since JBoss AS 5.1.0 / MC 2.0.6 (allows multiple transformers to be added)
|
// available since JBoss AS 5.1.0 / MC 2.0.6 (allows multiple transformers to be added)
|
||||||
private static final String ADD_TRANSLATOR_NAME = "addTranslator";
|
private static final String ADD_TRANSLATOR_NAME = "addTranslator";
|
||||||
// available since JBoss AS 5.0.0 / MC 2.0.1 (allows only one transformer to be added)
|
// available since JBoss AS 5.0.0 / MC 2.0.1 (allows only one transformer to be added)
|
||||||
private static final String SET_TRANSLATOR_NAME = "setTranslator";
|
private static final String SET_TRANSLATOR_NAME = "setTranslator";
|
||||||
|
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
private final Class<?> translatorClass;
|
private final Class<?> translatorClass;
|
||||||
|
|
||||||
private final Method addTranslator;
|
private final Method addTranslator;
|
||||||
private final Object target;
|
private final Object target;
|
||||||
|
|
||||||
JBossMCAdapter(ClassLoader classLoader) {
|
JBossMCAdapter(ClassLoader classLoader) {
|
||||||
Class<?> clazzLoaderType = null;
|
Class<?> clazzLoaderType = null;
|
||||||
try {
|
try {
|
||||||
// resolve BaseClassLoader.class
|
// resolve BaseClassLoader.class
|
||||||
clazzLoaderType = classLoader.loadClass(LOADER_NAME);
|
clazzLoaderType = classLoader.loadClass(LOADER_NAME);
|
||||||
|
|
||||||
ClassLoader clazzLoader = null;
|
ClassLoader clazzLoader = null;
|
||||||
// walk the hierarchy to detect the instrumentation aware classloader
|
// walk the hierarchy to detect the instrumentation aware classloader
|
||||||
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
||||||
if (clazzLoaderType.isInstance(cl)) {
|
if (clazzLoaderType.isInstance(cl)) {
|
||||||
clazzLoader = cl;
|
clazzLoader = cl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clazzLoader == null) {
|
if (clazzLoader == null) {
|
||||||
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: "
|
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: "
|
||||||
+ "A [" + LOADER_NAME + "] implementation is required.");
|
+ "A [" + LOADER_NAME + "] implementation is required.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.classLoader = clazzLoader;
|
this.classLoader = clazzLoader;
|
||||||
// use the classloader that loaded the classloader to load
|
// use the classloader that loaded the classloader to load
|
||||||
// the types for reflection purposes
|
// the types for reflection purposes
|
||||||
classLoader = clazzLoader.getClass().getClassLoader();
|
classLoader = clazzLoader.getClass().getClassLoader();
|
||||||
|
|
||||||
// BaseClassLoader#getPolicy
|
// BaseClassLoader#getPolicy
|
||||||
Method method = clazzLoaderType.getDeclaredMethod(GET_POLICY);
|
Method method = clazzLoaderType.getDeclaredMethod(GET_POLICY);
|
||||||
ReflectionUtils.makeAccessible(method);
|
ReflectionUtils.makeAccessible(method);
|
||||||
Object policy = method.invoke(this.classLoader);
|
Object policy = method.invoke(this.classLoader);
|
||||||
|
|
||||||
Object addTarget = null;
|
Object addTarget = null;
|
||||||
Method addMethod = null;
|
Method addMethod = null;
|
||||||
|
|
||||||
// try the 5.1.x hooks
|
// try the 5.1.x hooks
|
||||||
// check existence of BaseClassLoaderPolicy#addTranslator(Translator)
|
// check existence of BaseClassLoaderPolicy#addTranslator(Translator)
|
||||||
this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME);
|
this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME);
|
||||||
Class<?> clazz = classLoader.loadClass(POLICY_NAME);
|
Class<?> clazz = classLoader.loadClass(POLICY_NAME);
|
||||||
try {
|
try {
|
||||||
addMethod = clazz.getDeclaredMethod(ADD_TRANSLATOR_NAME, translatorClass);
|
addMethod = clazz.getDeclaredMethod(ADD_TRANSLATOR_NAME, translatorClass);
|
||||||
addTarget = policy;
|
addTarget = policy;
|
||||||
} catch (NoSuchMethodException ex) {
|
} catch (NoSuchMethodException ex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// fall back to 5.0.x method
|
// fall back to 5.0.x method
|
||||||
if (addMethod == null) {
|
if (addMethod == null) {
|
||||||
|
|
||||||
// BaseClassLoaderPolicy#getClassLoaderDomain
|
// BaseClassLoaderPolicy#getClassLoaderDomain
|
||||||
method = clazz.getDeclaredMethod(GET_DOMAIN);
|
method = clazz.getDeclaredMethod(GET_DOMAIN);
|
||||||
ReflectionUtils.makeAccessible(method);
|
ReflectionUtils.makeAccessible(method);
|
||||||
Object domain = method.invoke(policy);
|
Object domain = method.invoke(policy);
|
||||||
|
|
||||||
// BaseClassLoaderDomain#getClassLoaderSystem
|
// BaseClassLoaderDomain#getClassLoaderSystem
|
||||||
clazz = classLoader.loadClass(DOMAIN_NAME);
|
clazz = classLoader.loadClass(DOMAIN_NAME);
|
||||||
method = clazz.getDeclaredMethod(GET_SYSTEM);
|
method = clazz.getDeclaredMethod(GET_SYSTEM);
|
||||||
ReflectionUtils.makeAccessible(method);
|
ReflectionUtils.makeAccessible(method);
|
||||||
Object system = method.invoke(domain);
|
Object system = method.invoke(domain);
|
||||||
|
|
||||||
// resolve ClassLoaderSystem
|
// resolve ClassLoaderSystem
|
||||||
clazz = classLoader.loadClass(DEDICATED_SYSTEM);
|
clazz = classLoader.loadClass(DEDICATED_SYSTEM);
|
||||||
Assert.isInstanceOf(clazz, system, "JBoss LoadTimeWeaver requires JBoss loader system of type "
|
Assert.isInstanceOf(clazz, system, "JBoss LoadTimeWeaver requires JBoss loader system of type "
|
||||||
+ clazz.getName() + " on JBoss 5.0.x");
|
+ clazz.getName() + " on JBoss 5.0.x");
|
||||||
|
|
||||||
// ClassLoaderSystem#setTranslator
|
// ClassLoaderSystem#setTranslator
|
||||||
addMethod = clazz.getDeclaredMethod(SET_TRANSLATOR_NAME, translatorClass);
|
addMethod = clazz.getDeclaredMethod(SET_TRANSLATOR_NAME, translatorClass);
|
||||||
addTarget = system;
|
addTarget = system;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addTranslator = addMethod;
|
this.addTranslator = addMethod;
|
||||||
this.target = addTarget;
|
this.target = addTarget;
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available", ex);
|
"Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer);
|
InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer);
|
||||||
Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(),
|
Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(),
|
||||||
new Class[] { this.translatorClass }, adapter);
|
new Class[] { this.translatorClass }, adapter);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
addTranslator.invoke(target, adapterInstance);
|
addTranslator.invoke(target, adapterInstance);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not add transformer on JBoss 5/6 classloader " + classLoader, ex);
|
throw new IllegalStateException("Could not add transformer on JBoss 5/6 classloader " + classLoader, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getInstrumentableClassLoader() {
|
public ClassLoader getInstrumentableClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,82 +1,82 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.jboss;
|
package org.springframework.instrument.classloading.jboss;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that implements JBoss Translator interface, delegating to a
|
* Adapter that implements JBoss Translator interface, delegating to a
|
||||||
* standard JDK {@link ClassFileTransformer} underneath.
|
* standard JDK {@link ClassFileTransformer} underneath.
|
||||||
*
|
*
|
||||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||||
* being used.
|
* being used.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class JBossMCTranslatorAdapter implements InvocationHandler {
|
class JBossMCTranslatorAdapter implements InvocationHandler {
|
||||||
|
|
||||||
private final ClassFileTransformer transformer;
|
private final ClassFileTransformer transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link JBossMCTranslatorAdapter}.
|
* Creates a new {@link JBossMCTranslatorAdapter}.
|
||||||
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
||||||
* not be <code>null</code>)
|
* not be <code>null</code>)
|
||||||
*/
|
*/
|
||||||
public JBossMCTranslatorAdapter(ClassFileTransformer transformer) {
|
public JBossMCTranslatorAdapter(ClassFileTransformer transformer) {
|
||||||
this.transformer = transformer;
|
this.transformer = transformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
String name = method.getName();
|
String name = method.getName();
|
||||||
|
|
||||||
if ("equals".equals(name)) {
|
if ("equals".equals(name)) {
|
||||||
return (Boolean.valueOf(proxy == args[0]));
|
return (Boolean.valueOf(proxy == args[0]));
|
||||||
} else if ("hashCode".equals(name)) {
|
} else if ("hashCode".equals(name)) {
|
||||||
return hashCode();
|
return hashCode();
|
||||||
} else if ("toString".equals(name)) {
|
} else if ("toString".equals(name)) {
|
||||||
return toString();
|
return toString();
|
||||||
} else if ("transform".equals(name)) {
|
} else if ("transform".equals(name)) {
|
||||||
return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3],
|
return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3],
|
||||||
(byte[]) args[4]);
|
(byte[]) args[4]);
|
||||||
} else if ("unregisterClassLoader".equals(name)) {
|
} else if ("unregisterClassLoader".equals(name)) {
|
||||||
unregisterClassLoader((ClassLoader) args[0]);
|
unregisterClassLoader((ClassLoader) args[0]);
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unknown method: " + method);
|
throw new IllegalArgumentException("Unknown method: " + method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
|
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||||
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception {
|
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception {
|
||||||
return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
|
return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterClassLoader(ClassLoader loader) {
|
public void unregisterClassLoader(ClassLoader loader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||||
builder.append(" for transformer: ");
|
builder.append(" for transformer: ");
|
||||||
builder.append(this.transformer);
|
builder.append(this.transformer);
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,71 +1,71 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.instrument.classloading.jboss;
|
package org.springframework.instrument.classloading.jboss;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JBoss 7 adapter.
|
* JBoss 7 adapter.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class JBossModulesAdapter implements JBossClassLoaderAdapter {
|
class JBossModulesAdapter implements JBossClassLoaderAdapter {
|
||||||
|
|
||||||
private static final String TRANSFORMER_FIELD_NAME = "transformer";
|
private static final String TRANSFORMER_FIELD_NAME = "transformer";
|
||||||
private static final String TRANSFORMER_ADD_METHOD_NAME = "addTransformer";
|
private static final String TRANSFORMER_ADD_METHOD_NAME = "addTransformer";
|
||||||
private static final String DELEGATING_TRANSFORMER_CLASS_NAME = "org.jboss.as.server.deployment.module.DelegatingClassFileTransformer";
|
private static final String DELEGATING_TRANSFORMER_CLASS_NAME = "org.jboss.as.server.deployment.module.DelegatingClassFileTransformer";
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
private final Method addTransformer;
|
private final Method addTransformer;
|
||||||
private final Object delegatingTransformer;
|
private final Object delegatingTransformer;
|
||||||
|
|
||||||
public JBossModulesAdapter(ClassLoader loader) {
|
public JBossModulesAdapter(ClassLoader loader) {
|
||||||
this.classLoader = loader;
|
this.classLoader = loader;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME);
|
Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME);
|
||||||
transformers.setAccessible(true);
|
transformers.setAccessible(true);
|
||||||
|
|
||||||
delegatingTransformer = transformers.get(classLoader);
|
delegatingTransformer = transformers.get(classLoader);
|
||||||
|
|
||||||
Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME),
|
Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME),
|
||||||
"Transformer not of the expected type: " + delegatingTransformer.getClass().getName());
|
"Transformer not of the expected type: " + delegatingTransformer.getClass().getName());
|
||||||
addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME,
|
addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME,
|
||||||
ClassFileTransformer.class);
|
ClassFileTransformer.class);
|
||||||
addTransformer.setAccessible(true);
|
addTransformer.setAccessible(true);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex);
|
throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
try {
|
try {
|
||||||
addTransformer.invoke(delegatingTransformer, transformer);
|
addTransformer.invoke(delegatingTransformer, transformer);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex);
|
throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getInstrumentableClassLoader() {
|
public ClassLoader getInstrumentableClassLoader() {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x.
|
* Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.jboss;
|
package org.springframework.instrument.classloading.jboss;
|
||||||
|
|
||||||
|
|||||||
@@ -1,88 +1,88 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.oc4j;
|
package org.springframework.instrument.classloading.oc4j;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflective wrapper around a OC4J class loader. Used to
|
* Reflective wrapper around a OC4J class loader. Used to
|
||||||
* encapsulate the classloader-specific methods (discovered and
|
* encapsulate the classloader-specific methods (discovered and
|
||||||
* called through reflection) from the load-time weaver.
|
* called through reflection) from the load-time weaver.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
class OC4JClassLoaderAdapter {
|
class OC4JClassLoaderAdapter {
|
||||||
|
|
||||||
private static final String CL_UTILS = "oracle.classloader.util.ClassLoaderUtilities";
|
private static final String CL_UTILS = "oracle.classloader.util.ClassLoaderUtilities";
|
||||||
private static final String PREPROCESS_UTILS = "oracle.classloader.util.ClassPreprocessor";
|
private static final String PREPROCESS_UTILS = "oracle.classloader.util.ClassPreprocessor";
|
||||||
|
|
||||||
private final ClassLoader classLoader;
|
private final ClassLoader classLoader;
|
||||||
private final Class<?> processorClass;
|
private final Class<?> processorClass;
|
||||||
private final Method addTransformer;
|
private final Method addTransformer;
|
||||||
private final Method copy;
|
private final Method copy;
|
||||||
|
|
||||||
public OC4JClassLoaderAdapter(ClassLoader classLoader) {
|
public OC4JClassLoaderAdapter(ClassLoader classLoader) {
|
||||||
try {
|
try {
|
||||||
// Since OC4J 10.1.3's PolicyClassLoader is going to be removed,
|
// Since OC4J 10.1.3's PolicyClassLoader is going to be removed,
|
||||||
// we rely on the ClassLoaderUtilities API instead.
|
// we rely on the ClassLoaderUtilities API instead.
|
||||||
Class<?> utilClass = classLoader.loadClass(CL_UTILS);
|
Class<?> utilClass = classLoader.loadClass(CL_UTILS);
|
||||||
this.processorClass = classLoader.loadClass(PREPROCESS_UTILS);
|
this.processorClass = classLoader.loadClass(PREPROCESS_UTILS);
|
||||||
|
|
||||||
this.addTransformer = utilClass.getMethod("addPreprocessor", new Class[] { ClassLoader.class,
|
this.addTransformer = utilClass.getMethod("addPreprocessor", new Class[] { ClassLoader.class,
|
||||||
this.processorClass });
|
this.processorClass });
|
||||||
this.copy = utilClass.getMethod("copy", new Class[] { ClassLoader.class });
|
this.copy = utilClass.getMethod("copy", new Class[] { ClassLoader.class });
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not initialize OC4J LoadTimeWeaver because OC4J API classes are not available", ex);
|
"Could not initialize OC4J LoadTimeWeaver because OC4J API classes are not available", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
||||||
try {
|
try {
|
||||||
OC4JClassPreprocessorAdapter adapter = new OC4JClassPreprocessorAdapter(transformer);
|
OC4JClassPreprocessorAdapter adapter = new OC4JClassPreprocessorAdapter(transformer);
|
||||||
Object adapterInstance = Proxy.newProxyInstance(this.processorClass.getClassLoader(),
|
Object adapterInstance = Proxy.newProxyInstance(this.processorClass.getClassLoader(),
|
||||||
new Class[] { this.processorClass }, adapter);
|
new Class[] { this.processorClass }, adapter);
|
||||||
this.addTransformer.invoke(null, new Object[] { this.classLoader, adapterInstance });
|
this.addTransformer.invoke(null, new Object[] { this.classLoader, adapterInstance });
|
||||||
} catch (InvocationTargetException ex) {
|
} catch (InvocationTargetException ex) {
|
||||||
throw new IllegalStateException("OC4J addPreprocessor method threw exception", ex.getCause());
|
throw new IllegalStateException("OC4J addPreprocessor method threw exception", ex.getCause());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not invoke OC4J addPreprocessor method", ex);
|
throw new IllegalStateException("Could not invoke OC4J addPreprocessor method", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return this.classLoader;
|
return this.classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getThrowawayClassLoader() {
|
public ClassLoader getThrowawayClassLoader() {
|
||||||
try {
|
try {
|
||||||
return (ClassLoader) this.copy.invoke(null, new Object[] { this.classLoader });
|
return (ClassLoader) this.copy.invoke(null, new Object[] { this.classLoader });
|
||||||
} catch (InvocationTargetException ex) {
|
} catch (InvocationTargetException ex) {
|
||||||
throw new IllegalStateException("OC4J copy method failed", ex.getCause());
|
throw new IllegalStateException("OC4J copy method failed", ex.getCause());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not copy OC4J classloader", ex);
|
throw new IllegalStateException("Could not copy OC4J classloader", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,95 +1,95 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2006-2009 the original author or authors.
|
* Copyright 2006-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.oc4j;
|
package org.springframework.instrument.classloading.oc4j;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.instrument.IllegalClassFormatException;
|
import java.lang.instrument.IllegalClassFormatException;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that implements OC4J ClassPreProcessor interface, delegating to a
|
* Adapter that implements OC4J ClassPreProcessor interface, delegating to a
|
||||||
* standard JDK {@link ClassFileTransformer} underneath.
|
* standard JDK {@link ClassFileTransformer} underneath.
|
||||||
*
|
*
|
||||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||||
* being used.
|
* being used.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
*/
|
*/
|
||||||
class OC4JClassPreprocessorAdapter implements InvocationHandler {
|
class OC4JClassPreprocessorAdapter implements InvocationHandler {
|
||||||
|
|
||||||
private final ClassFileTransformer transformer;
|
private final ClassFileTransformer transformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link OC4JClassPreprocessorAdapter}.
|
* Creates a new {@link OC4JClassPreprocessorAdapter}.
|
||||||
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
||||||
* not be <code>null</code>)
|
* not be <code>null</code>)
|
||||||
*/
|
*/
|
||||||
public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) {
|
public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) {
|
||||||
this.transformer = transformer;
|
this.transformer = transformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
String name = method.getName();
|
String name = method.getName();
|
||||||
|
|
||||||
if ("equals".equals(name)) {
|
if ("equals".equals(name)) {
|
||||||
return (Boolean.valueOf(proxy == args[0]));
|
return (Boolean.valueOf(proxy == args[0]));
|
||||||
} else if ("hashCode".equals(name)) {
|
} else if ("hashCode".equals(name)) {
|
||||||
return hashCode();
|
return hashCode();
|
||||||
} else if ("toString".equals(name)) {
|
} else if ("toString".equals(name)) {
|
||||||
return toString();
|
return toString();
|
||||||
} else if ("initialize".equals(name)) {
|
} else if ("initialize".equals(name)) {
|
||||||
initialize(proxy, (ClassLoader) args[0]);
|
initialize(proxy, (ClassLoader) args[0]);
|
||||||
return null;
|
return null;
|
||||||
} else if ("processClass".equals(name)) {
|
} else if ("processClass".equals(name)) {
|
||||||
return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3],
|
return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3],
|
||||||
(ProtectionDomain) args[4], (ClassLoader) args[5]);
|
(ProtectionDomain) args[4], (ClassLoader) args[5]);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unknown method: " + method);
|
throw new IllegalArgumentException("Unknown method: " + method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// maps to oracle.classloader.util.ClassPreprocessor#initialize
|
// maps to oracle.classloader.util.ClassPreprocessor#initialize
|
||||||
// the proxy is passed since it implements the Oracle interface which
|
// the proxy is passed since it implements the Oracle interface which
|
||||||
// is asked as a return type
|
// is asked as a return type
|
||||||
public Object initialize(Object proxy, ClassLoader loader) {
|
public Object initialize(Object proxy, ClassLoader loader) {
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd,
|
public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd,
|
||||||
ClassLoader loader) {
|
ClassLoader loader) {
|
||||||
try {
|
try {
|
||||||
byte[] tempArray = new byte[length];
|
byte[] tempArray = new byte[length];
|
||||||
System.arraycopy(origClassBytes, offset, tempArray, 0, length);
|
System.arraycopy(origClassBytes, offset, tempArray, 0, length);
|
||||||
|
|
||||||
// NB: OC4J passes className as "." without class while the
|
// NB: OC4J passes className as "." without class while the
|
||||||
// transformer expects a VM, "/" format
|
// transformer expects a VM, "/" format
|
||||||
byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray);
|
byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray);
|
||||||
return (result != null ? result : origClassBytes);
|
return (result != null ? result : origClassBytes);
|
||||||
} catch (IllegalClassFormatException ex) {
|
} catch (IllegalClassFormatException ex) {
|
||||||
throw new IllegalStateException("Cannot transform because of illegal class format", ex);
|
throw new IllegalStateException("Cannot transform because of illegal class format", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||||
builder.append(" for transformer: ");
|
builder.append(" for transformer: ");
|
||||||
builder.append(this.transformer);
|
builder.append(this.transformer);
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,111 +1,111 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.instrument.classloading.websphere;
|
package org.springframework.instrument.classloading.websphere;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Reflective wrapper around a WebSphere 7 class loader. Used to
|
* Reflective wrapper around a WebSphere 7 class loader. Used to
|
||||||
* encapsulate the classloader-specific methods (discovered and
|
* encapsulate the classloader-specific methods (discovered and
|
||||||
* called through reflection) from the load-time weaver.
|
* called through reflection) from the load-time weaver.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class WebSphereClassLoaderAdapter {
|
class WebSphereClassLoaderAdapter {
|
||||||
|
|
||||||
private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader";
|
private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader";
|
||||||
private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin";
|
private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin";
|
||||||
private static final String PLUGINS_FIELD = "preDefinePlugins";
|
private static final String PLUGINS_FIELD = "preDefinePlugins";
|
||||||
|
|
||||||
private ClassLoader classLoader;
|
private ClassLoader classLoader;
|
||||||
private Class<?> wsPreProcessorClass;
|
private Class<?> wsPreProcessorClass;
|
||||||
private Method addPreDefinePlugin;
|
private Method addPreDefinePlugin;
|
||||||
private Constructor<? extends ClassLoader> cloneConstructor;
|
private Constructor<? extends ClassLoader> cloneConstructor;
|
||||||
private Field transformerList;
|
private Field transformerList;
|
||||||
|
|
||||||
public WebSphereClassLoaderAdapter(ClassLoader classLoader) {
|
public WebSphereClassLoaderAdapter(ClassLoader classLoader) {
|
||||||
Class<?> wsCompoundClassLoaderClass = null;
|
Class<?> wsCompoundClassLoaderClass = null;
|
||||||
try {
|
try {
|
||||||
wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME);
|
wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME);
|
||||||
cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
|
cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
|
||||||
cloneConstructor.setAccessible(true);
|
cloneConstructor.setAccessible(true);
|
||||||
|
|
||||||
wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
|
wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
|
||||||
addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass);
|
addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass);
|
||||||
transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
|
transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
|
||||||
transformerList.setAccessible(true);
|
transformerList.setAccessible(true);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available",
|
"Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available",
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader,
|
Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader,
|
||||||
"ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]");
|
"ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]");
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getClassLoader() {
|
public ClassLoader getClassLoader() {
|
||||||
return this.classLoader;
|
return this.classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
||||||
try {
|
try {
|
||||||
InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);
|
InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);
|
||||||
Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(),
|
Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(),
|
||||||
new Class[] { this.wsPreProcessorClass }, adapter);
|
new Class[] { this.wsPreProcessorClass }, adapter);
|
||||||
this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance);
|
this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException ex) {
|
catch (InvocationTargetException ex) {
|
||||||
throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());
|
throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex);
|
throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ClassLoader getThrowawayClassLoader() {
|
public ClassLoader getThrowawayClassLoader() {
|
||||||
try {
|
try {
|
||||||
ClassLoader loader = (ClassLoader) cloneConstructor.newInstance(getClassLoader());
|
ClassLoader loader = (ClassLoader) cloneConstructor.newInstance(getClassLoader());
|
||||||
// clear out the transformers (copied as well)
|
// clear out the transformers (copied as well)
|
||||||
List list = (List) transformerList.get(loader);
|
List list = (List) transformerList.get(loader);
|
||||||
list.clear();
|
list.clear();
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException ex) {
|
catch (InvocationTargetException ex) {
|
||||||
throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause());
|
throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause());
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex);
|
throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,100 +1,100 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.websphere;
|
package org.springframework.instrument.classloading.websphere;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.security.CodeSource;
|
import java.security.CodeSource;
|
||||||
|
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface,
|
* Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface,
|
||||||
* delegating to a standard JDK {@link ClassFileTransformer} underneath.
|
* delegating to a standard JDK {@link ClassFileTransformer} underneath.
|
||||||
*
|
*
|
||||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||||
* being used.
|
* being used.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
class WebSphereClassPreDefinePlugin implements InvocationHandler {
|
class WebSphereClassPreDefinePlugin implements InvocationHandler {
|
||||||
|
|
||||||
private final ClassFileTransformer transformer;
|
private final ClassFileTransformer transformer;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link WebSphereClassPreDefinePlugin}.
|
* Create a new {@link WebSphereClassPreDefinePlugin}.
|
||||||
* @param transformer the {@link ClassFileTransformer} to be adapted
|
* @param transformer the {@link ClassFileTransformer} to be adapted
|
||||||
* (must not be <code>null</code>)
|
* (must not be <code>null</code>)
|
||||||
*/
|
*/
|
||||||
public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) {
|
public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) {
|
||||||
this.transformer = transformer;
|
this.transformer = transformer;
|
||||||
ClassLoader classLoader = transformer.getClass().getClassLoader();
|
ClassLoader classLoader = transformer.getClass().getClassLoader();
|
||||||
|
|
||||||
// first force the full class loading of the weaver by invoking transformation on a dummy class
|
// first force the full class loading of the weaver by invoking transformation on a dummy class
|
||||||
try {
|
try {
|
||||||
String dummyClass = Dummy.class.getName().replace('.', '/');
|
String dummyClass = Dummy.class.getName().replace('.', '/');
|
||||||
byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));
|
byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));
|
||||||
transformer.transform(classLoader, dummyClass, null, null, bytes);
|
transformer.transform(classLoader, dummyClass, null, null, bytes);
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
throw new IllegalArgumentException("Cannot load transformer", ex);
|
throw new IllegalArgumentException("Cannot load transformer", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
String name = method.getName();
|
String name = method.getName();
|
||||||
if ("equals".equals(name)) {
|
if ("equals".equals(name)) {
|
||||||
return (proxy == args[0]);
|
return (proxy == args[0]);
|
||||||
}
|
}
|
||||||
else if ("hashCode".equals(name)) {
|
else if ("hashCode".equals(name)) {
|
||||||
return hashCode();
|
return hashCode();
|
||||||
}
|
}
|
||||||
else if ("toString".equals(name)) {
|
else if ("toString".equals(name)) {
|
||||||
return toString();
|
return toString();
|
||||||
}
|
}
|
||||||
else if ("transformClass".equals(name)) {
|
else if ("transformClass".equals(name)) {
|
||||||
return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]);
|
return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalArgumentException("Unknown method: " + method);
|
throw new IllegalArgumentException("Unknown method: " + method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader)
|
protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
// NB: WebSphere passes className as "." without class while the transformer expects a VM, "/" format
|
// NB: WebSphere passes className as "." without class while the transformer expects a VM, "/" format
|
||||||
byte[] result = transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer);
|
byte[] result = transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer);
|
||||||
return (result != null ? result : classfileBuffer);
|
return (result != null ? result : classfileBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||||
builder.append(" for transformer: ");
|
builder.append(" for transformer: ");
|
||||||
builder.append(this.transformer);
|
builder.append(this.transformer);
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class Dummy {
|
private static class Dummy {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,70 +1,70 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.instrument.classloading.websphere;
|
package org.springframework.instrument.classloading.websphere;
|
||||||
|
|
||||||
import java.lang.instrument.ClassFileTransformer;
|
import java.lang.instrument.ClassFileTransformer;
|
||||||
|
|
||||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader.
|
* {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader.
|
||||||
* Compatible with WebSphere 7 as well as 8.
|
* Compatible with WebSphere 7 as well as 8.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class WebSphereLoadTimeWeaver implements LoadTimeWeaver {
|
public class WebSphereLoadTimeWeaver implements LoadTimeWeaver {
|
||||||
|
|
||||||
private final WebSphereClassLoaderAdapter classLoader;
|
private final WebSphereClassLoaderAdapter classLoader;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
||||||
* the default {@link ClassLoader class loader}.
|
* the default {@link ClassLoader class loader}.
|
||||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||||
*/
|
*/
|
||||||
public WebSphereLoadTimeWeaver() {
|
public WebSphereLoadTimeWeaver() {
|
||||||
this(ClassUtils.getDefaultClassLoader());
|
this(ClassUtils.getDefaultClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
||||||
* the supplied {@link ClassLoader}.
|
* the supplied {@link ClassLoader}.
|
||||||
* @param classLoader the <code>ClassLoader</code> to delegate to for weaving
|
* @param classLoader the <code>ClassLoader</code> to delegate to for weaving
|
||||||
* (must not be <code>null</code>)
|
* (must not be <code>null</code>)
|
||||||
*/
|
*/
|
||||||
public WebSphereLoadTimeWeaver(ClassLoader classLoader) {
|
public WebSphereLoadTimeWeaver(ClassLoader classLoader) {
|
||||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||||
this.classLoader = new WebSphereClassLoaderAdapter(classLoader);
|
this.classLoader = new WebSphereClassLoaderAdapter(classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void addTransformer(ClassFileTransformer transformer) {
|
public void addTransformer(ClassFileTransformer transformer) {
|
||||||
this.classLoader.addTransformer(transformer);
|
this.classLoader.addTransformer(transformer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getInstrumentableClassLoader() {
|
public ClassLoader getInstrumentableClassLoader() {
|
||||||
return this.classLoader.getClassLoader();
|
return this.classLoader.getClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoader getThrowawayClassLoader() {
|
public ClassLoader getThrowawayClassLoader() {
|
||||||
return this.classLoader.getThrowawayClassLoader();
|
return this.classLoader.getThrowawayClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Support for class instrumentation on IBM WebSphere Application Server 7.
|
* Support for class instrumentation on IBM WebSphere Application Server 7.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package org.springframework.instrument.classloading.websphere;
|
package org.springframework.instrument.classloading.websphere;
|
||||||
|
|
||||||
|
|||||||
@@ -1,69 +1,69 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.jndi;
|
package org.springframework.jndi;
|
||||||
|
|
||||||
import javax.naming.InitialContext;
|
import javax.naming.InitialContext;
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JndiLocatorSupport} subclass with public lookup methods,
|
* {@link JndiLocatorSupport} subclass with public lookup methods,
|
||||||
* for convenient use as a delegate.
|
* for convenient use as a delegate.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0.1
|
* @since 3.0.1
|
||||||
*/
|
*/
|
||||||
public class JndiLocatorDelegate extends JndiLocatorSupport {
|
public class JndiLocatorDelegate extends JndiLocatorSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object lookup(String jndiName) throws NamingException {
|
public Object lookup(String jndiName) throws NamingException {
|
||||||
return super.lookup(jndiName);
|
return super.lookup(jndiName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException {
|
public <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException {
|
||||||
return super.lookup(jndiName, requiredType);
|
return super.lookup(jndiName, requiredType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure a {@code JndiLocatorDelegate} with its "resourceRef" property set to
|
* Configure a {@code JndiLocatorDelegate} with its "resourceRef" property set to
|
||||||
* <code>true</code>, meaning that all names will be prefixed with "java:comp/env/".
|
* <code>true</code>, meaning that all names will be prefixed with "java:comp/env/".
|
||||||
* @see #setResourceRef
|
* @see #setResourceRef
|
||||||
*/
|
*/
|
||||||
public static JndiLocatorDelegate createDefaultResourceRefLocator() {
|
public static JndiLocatorDelegate createDefaultResourceRefLocator() {
|
||||||
JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
|
JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
|
||||||
jndiLocator.setResourceRef(true);
|
jndiLocator.setResourceRef(true);
|
||||||
return jndiLocator;
|
return jndiLocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether a default JNDI environment, as in a J2EE environment,
|
* Check whether a default JNDI environment, as in a J2EE environment,
|
||||||
* is available on this JVM.
|
* is available on this JVM.
|
||||||
* @return <code>true</code> if a default InitialContext can be used,
|
* @return <code>true</code> if a default InitialContext can be used,
|
||||||
* <code>false</code> if not
|
* <code>false</code> if not
|
||||||
*/
|
*/
|
||||||
public static boolean isDefaultJndiEnvironmentAvailable() {
|
public static boolean isDefaultJndiEnvironmentAvailable() {
|
||||||
try {
|
try {
|
||||||
new InitialContext();
|
new InitialContext();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +1,139 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling;
|
package org.springframework.scheduling;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task scheduler interface that abstracts the scheduling of
|
* Task scheduler interface that abstracts the scheduling of
|
||||||
* {@link Runnable Runnables} based on different kinds of triggers.
|
* {@link Runnable Runnables} based on different kinds of triggers.
|
||||||
*
|
*
|
||||||
* <p>This interface is separate from {@link SchedulingTaskExecutor} since it
|
* <p>This interface is separate from {@link SchedulingTaskExecutor} since it
|
||||||
* usually represents for a different kind of backend, i.e. a thread pool with
|
* usually represents for a different kind of backend, i.e. a thread pool with
|
||||||
* different characteristics and capabilities. Implementations may implement
|
* different characteristics and capabilities. Implementations may implement
|
||||||
* both interfaces if they can handle both kinds of execution characteristics.
|
* both interfaces if they can handle both kinds of execution characteristics.
|
||||||
*
|
*
|
||||||
* <p>The 'default' implementation is
|
* <p>The 'default' implementation is
|
||||||
* {@link org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler},
|
* {@link org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler},
|
||||||
* wrapping a native {@link java.util.concurrent.ScheduledExecutorService}
|
* wrapping a native {@link java.util.concurrent.ScheduledExecutorService}
|
||||||
* and adding extended trigger capabilities.
|
* and adding extended trigger capabilities.
|
||||||
*
|
*
|
||||||
* <p>This interface is roughly equivalent to a JSR-236
|
* <p>This interface is roughly equivalent to a JSR-236
|
||||||
* <code>ManagedScheduledExecutorService</code> as supported in Java EE 6
|
* <code>ManagedScheduledExecutorService</code> as supported in Java EE 6
|
||||||
* environments. However, at the time of the Spring 3.0 release, the
|
* environments. However, at the time of the Spring 3.0 release, the
|
||||||
* JSR-236 interfaces have not been released in official form yet.
|
* JSR-236 interfaces have not been released in official form yet.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.core.task.TaskExecutor
|
* @see org.springframework.core.task.TaskExecutor
|
||||||
* @see java.util.concurrent.ScheduledExecutorService
|
* @see java.util.concurrent.ScheduledExecutorService
|
||||||
* @see org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
|
* @see org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
|
||||||
*/
|
*/
|
||||||
public interface TaskScheduler {
|
public interface TaskScheduler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule the given {@link Runnable}, invoking it whenever the trigger
|
* Schedule the given {@link Runnable}, invoking it whenever the trigger
|
||||||
* indicates a next execution time.
|
* indicates a next execution time.
|
||||||
* <p>Execution will end once the scheduler shuts down or the returned
|
* <p>Execution will end once the scheduler shuts down or the returned
|
||||||
* {@link ScheduledFuture} gets cancelled.
|
* {@link ScheduledFuture} gets cancelled.
|
||||||
* @param task the Runnable to execute whenever the trigger fires
|
* @param task the Runnable to execute whenever the trigger fires
|
||||||
* @param trigger an implementation of the {@link Trigger} interface,
|
* @param trigger an implementation of the {@link Trigger} interface,
|
||||||
* e.g. a {@link org.springframework.scheduling.support.CronTrigger} object
|
* e.g. a {@link org.springframework.scheduling.support.CronTrigger} object
|
||||||
* wrapping a cron expression
|
* wrapping a cron expression
|
||||||
* @return a {@link ScheduledFuture} representing pending completion of the task,
|
* @return a {@link ScheduledFuture} representing pending completion of the task,
|
||||||
* or <code>null</code> if the given Trigger object never fires (i.e. returns
|
* or <code>null</code> if the given Trigger object never fires (i.e. returns
|
||||||
* <code>null</code> from {@link Trigger#nextExecutionTime})
|
* <code>null</code> from {@link Trigger#nextExecutionTime})
|
||||||
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
||||||
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
||||||
* @see org.springframework.scheduling.support.CronTrigger
|
* @see org.springframework.scheduling.support.CronTrigger
|
||||||
*/
|
*/
|
||||||
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time.
|
* Schedule the given {@link Runnable}, invoking it at the specified execution time.
|
||||||
* <p>Execution will end once the scheduler shuts down or the returned
|
* <p>Execution will end once the scheduler shuts down or the returned
|
||||||
* {@link ScheduledFuture} gets cancelled.
|
* {@link ScheduledFuture} gets cancelled.
|
||||||
* @param task the Runnable to execute whenever the trigger fires
|
* @param task the Runnable to execute whenever the trigger fires
|
||||||
* @param startTime the desired execution time for the task
|
* @param startTime the desired execution time for the task
|
||||||
* (if this is in the past, the task will be executed immediately, i.e. as soon as possible)
|
* (if this is in the past, the task will be executed immediately, i.e. as soon as possible)
|
||||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||||
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
||||||
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
||||||
*/
|
*/
|
||||||
ScheduledFuture schedule(Runnable task, Date startTime);
|
ScheduledFuture schedule(Runnable task, Date startTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time
|
* Schedule the given {@link Runnable}, invoking it at the specified execution time
|
||||||
* and subsequently with the given period.
|
* and subsequently with the given period.
|
||||||
* <p>Execution will end once the scheduler shuts down or the returned
|
* <p>Execution will end once the scheduler shuts down or the returned
|
||||||
* {@link ScheduledFuture} gets cancelled.
|
* {@link ScheduledFuture} gets cancelled.
|
||||||
* @param task the Runnable to execute whenever the trigger fires
|
* @param task the Runnable to execute whenever the trigger fires
|
||||||
* @param startTime the desired first execution time for the task
|
* @param startTime the desired first execution time for the task
|
||||||
* (if this is in the past, the task will be executed immediately, i.e. as soon as possible)
|
* (if this is in the past, the task will be executed immediately, i.e. as soon as possible)
|
||||||
* @param period the interval between successive executions of the task (in milliseconds)
|
* @param period the interval between successive executions of the task (in milliseconds)
|
||||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||||
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
||||||
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
||||||
*/
|
*/
|
||||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
|
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule the given {@link Runnable}, starting as soon as possible and
|
* Schedule the given {@link Runnable}, starting as soon as possible and
|
||||||
* invoking it with the given period.
|
* invoking it with the given period.
|
||||||
* <p>Execution will end once the scheduler shuts down or the returned
|
* <p>Execution will end once the scheduler shuts down or the returned
|
||||||
* {@link ScheduledFuture} gets cancelled.
|
* {@link ScheduledFuture} gets cancelled.
|
||||||
* @param task the Runnable to execute whenever the trigger fires
|
* @param task the Runnable to execute whenever the trigger fires
|
||||||
* @param period the interval between successive executions of the task (in milliseconds)
|
* @param period the interval between successive executions of the task (in milliseconds)
|
||||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||||
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
||||||
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
||||||
*/
|
*/
|
||||||
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
|
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time
|
* Schedule the given {@link Runnable}, invoking it at the specified execution time
|
||||||
* and subsequently with the given delay between the completion of one execution
|
* and subsequently with the given delay between the completion of one execution
|
||||||
* and the start of the next.
|
* and the start of the next.
|
||||||
* <p>Execution will end once the scheduler shuts down or the returned
|
* <p>Execution will end once the scheduler shuts down or the returned
|
||||||
* {@link ScheduledFuture} gets cancelled.
|
* {@link ScheduledFuture} gets cancelled.
|
||||||
* @param task the Runnable to execute whenever the trigger fires
|
* @param task the Runnable to execute whenever the trigger fires
|
||||||
* @param startTime the desired first execution time for the task
|
* @param startTime the desired first execution time for the task
|
||||||
* (if this is in the past, the task will be executed immediately, i.e. as soon as possible)
|
* (if this is in the past, the task will be executed immediately, i.e. as soon as possible)
|
||||||
* @param delay the delay between the completion of one execution and the start
|
* @param delay the delay between the completion of one execution and the start
|
||||||
* of the next (in milliseconds)
|
* of the next (in milliseconds)
|
||||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||||
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
||||||
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
||||||
*/
|
*/
|
||||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedule the given {@link Runnable}, starting as soon as possible and
|
* Schedule the given {@link Runnable}, starting as soon as possible and
|
||||||
* invoking it with the given delay between the completion of one execution
|
* invoking it with the given delay between the completion of one execution
|
||||||
* and the start of the next.
|
* and the start of the next.
|
||||||
* <p>Execution will end once the scheduler shuts down or the returned
|
* <p>Execution will end once the scheduler shuts down or the returned
|
||||||
* {@link ScheduledFuture} gets cancelled.
|
* {@link ScheduledFuture} gets cancelled.
|
||||||
* @param task the Runnable to execute whenever the trigger fires
|
* @param task the Runnable to execute whenever the trigger fires
|
||||||
* @param delay the interval between successive executions of the task (in milliseconds)
|
* @param delay the interval between successive executions of the task (in milliseconds)
|
||||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||||
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
* @throws org.springframework.core.task.TaskRejectedException if the given task was not accepted
|
||||||
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
* for internal reasons (e.g. a pool overload handling policy or a pool shutdown in progress)
|
||||||
*/
|
*/
|
||||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1,41 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling;
|
package org.springframework.scheduling;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common interface for trigger objects that determine the next execution time
|
* Common interface for trigger objects that determine the next execution time
|
||||||
* of a task that they get associated with.
|
* of a task that they get associated with.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see TaskScheduler#schedule(Runnable, Trigger)
|
* @see TaskScheduler#schedule(Runnable, Trigger)
|
||||||
* @see org.springframework.scheduling.support.CronTrigger
|
* @see org.springframework.scheduling.support.CronTrigger
|
||||||
*/
|
*/
|
||||||
public interface Trigger {
|
public interface Trigger {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the next execution time according to the given trigger context.
|
* Determine the next execution time according to the given trigger context.
|
||||||
* @param triggerContext context object encapsulating last execution times
|
* @param triggerContext context object encapsulating last execution times
|
||||||
* and last completion time
|
* and last completion time
|
||||||
* @return the next execution time as defined by the trigger,
|
* @return the next execution time as defined by the trigger,
|
||||||
* or <code>null</code> if the trigger won't fire anymore
|
* or <code>null</code> if the trigger won't fire anymore
|
||||||
*/
|
*/
|
||||||
Date nextExecutionTime(TriggerContext triggerContext);
|
Date nextExecutionTime(TriggerContext triggerContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling;
|
package org.springframework.scheduling;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context object encapsulating last execution times and last completion time
|
* Context object encapsulating last execution times and last completion time
|
||||||
* of a given task.
|
* of a given task.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public interface TriggerContext {
|
public interface TriggerContext {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last <i>scheduled</i> execution time of the task,
|
* Return the last <i>scheduled</i> execution time of the task,
|
||||||
* or <code>null</code> if not scheduled before.
|
* or <code>null</code> if not scheduled before.
|
||||||
*/
|
*/
|
||||||
Date lastScheduledExecutionTime();
|
Date lastScheduledExecutionTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last <i>actual</i> execution time of the task,
|
* Return the last <i>actual</i> execution time of the task,
|
||||||
* or <code>null</code> if not scheduled before.
|
* or <code>null</code> if not scheduled before.
|
||||||
*/
|
*/
|
||||||
Date lastActualExecutionTime();
|
Date lastActualExecutionTime();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the last completion time of the task,
|
* Return the last completion time of the task,
|
||||||
* or <code>null</code> if not scheduled before.
|
* or <code>null</code> if not scheduled before.
|
||||||
*/
|
*/
|
||||||
Date lastCompletionTime();
|
Date lastCompletionTime();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.annotation;
|
package org.springframework.scheduling.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation that marks a method as a candidate for <i>asynchronous</i> execution.
|
* Annotation that marks a method as a candidate for <i>asynchronous</i> execution.
|
||||||
* Can also be used at the type level, in which case all of the type's methods are
|
* Can also be used at the type level, in which case all of the type's methods are
|
||||||
* considered as asynchronous.
|
* considered as asynchronous.
|
||||||
*
|
*
|
||||||
* <p>In terms of target method signatures, any parameter types are supported.
|
* <p>In terms of target method signatures, any parameter types are supported.
|
||||||
* However, the return type is constrained to either <code>void</code> or
|
* However, the return type is constrained to either <code>void</code> or
|
||||||
* <code>java.util.concurrent.Future</code>. In the latter case, the Future handle
|
* <code>java.util.concurrent.Future</code>. In the latter case, the Future handle
|
||||||
* returned from the proxy will be an actual asynchronous Future that can be used
|
* returned from the proxy will be an actual asynchronous Future that can be used
|
||||||
* to track the result of the asynchronous method execution. However, since the
|
* to track the result of the asynchronous method execution. However, since the
|
||||||
* target method needs to implement the same signature, it will have to return
|
* target method needs to implement the same signature, it will have to return
|
||||||
* a temporary Future handle that just passes the return value through: e.g.
|
* a temporary Future handle that just passes the return value through: e.g.
|
||||||
* Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>.
|
* Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.aop.interceptor.AsyncExecutionInterceptor
|
* @see org.springframework.aop.interceptor.AsyncExecutionInterceptor
|
||||||
* @see AsyncAnnotationAdvisor
|
* @see AsyncAnnotationAdvisor
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface Async {
|
public @interface Async {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,63 +1,63 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.annotation;
|
package org.springframework.scheduling.annotation;
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A pass-through <code>Future</code> handle that can be used for method signatures
|
* A pass-through <code>Future</code> handle that can be used for method signatures
|
||||||
* which are declared with a Future return type for asynchronous execution.
|
* which are declared with a Future return type for asynchronous execution.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see org.springframework.scheduling.annotation.Async
|
* @see org.springframework.scheduling.annotation.Async
|
||||||
*/
|
*/
|
||||||
public class AsyncResult<V> implements Future<V> {
|
public class AsyncResult<V> implements Future<V> {
|
||||||
|
|
||||||
private final V value;
|
private final V value;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new AsyncResult holder.
|
* Create a new AsyncResult holder.
|
||||||
* @param value the value to pass through
|
* @param value the value to pass through
|
||||||
*/
|
*/
|
||||||
public AsyncResult(V value) {
|
public AsyncResult(V value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public V get() {
|
public V get() {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public V get(long timeout, TimeUnit unit) {
|
public V get(long timeout, TimeUnit unit) {
|
||||||
return this.value;
|
return this.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.annotation;
|
package org.springframework.scheduling.annotation;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Annotation that marks a method to be scheduled. Exactly one of the
|
* Annotation that marks a method to be scheduled. Exactly one of the
|
||||||
* <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code>
|
* <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code>
|
||||||
* attributes must be provided.
|
* attributes must be provided.
|
||||||
*
|
*
|
||||||
* <p>The annotated method must expect no arguments and have a
|
* <p>The annotated method must expect no arguments and have a
|
||||||
* <code>void</code> return type.
|
* <code>void</code> return type.
|
||||||
*
|
*
|
||||||
* <p>Processing of {@code @Scheduled} annotations is performed by
|
* <p>Processing of {@code @Scheduled} annotations is performed by
|
||||||
* registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
|
* registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
|
||||||
* done manually or, more conveniently, through the {@code <task:annotation-driven/>}
|
* done manually or, more conveniently, through the {@code <task:annotation-driven/>}
|
||||||
* element or @{@link EnableScheduling} annotation.
|
* element or @{@link EnableScheduling} annotation.
|
||||||
*
|
*
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see EnableScheduling
|
* @see EnableScheduling
|
||||||
* @see ScheduledAnnotationBeanPostProcessor
|
* @see ScheduledAnnotationBeanPostProcessor
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface Scheduled {
|
public @interface Scheduled {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cron-like expression, extending the usual UN*X definition to include
|
* A cron-like expression, extending the usual UN*X definition to include
|
||||||
* triggers on the second as well as minute, hour, day of month, month
|
* triggers on the second as well as minute, hour, day of month, month
|
||||||
* and day of week. e.g. <code>"0 * * * * MON-FRI"</code> means once
|
* and day of week. e.g. <code>"0 * * * * MON-FRI"</code> means once
|
||||||
* per minute on weekdays (at the top of the minute - the 0th second).
|
* per minute on weekdays (at the top of the minute - the 0th second).
|
||||||
* @return an expression that can be parsed to a cron schedule
|
* @return an expression that can be parsed to a cron schedule
|
||||||
*/
|
*/
|
||||||
String cron() default "";
|
String cron() default "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the annotated method with a fixed period between the end
|
* Execute the annotated method with a fixed period between the end
|
||||||
* of the last invocation and the start of the next.
|
* of the last invocation and the start of the next.
|
||||||
* @return the delay in milliseconds
|
* @return the delay in milliseconds
|
||||||
*/
|
*/
|
||||||
long fixedDelay() default -1;
|
long fixedDelay() default -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the annotated method with a fixed period between invocations.
|
* Execute the annotated method with a fixed period between invocations.
|
||||||
* @return the period in milliseconds
|
* @return the period in milliseconds
|
||||||
*/
|
*/
|
||||||
long fixedRate() default -1;
|
long fixedRate() default -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,187 +1,187 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.concurrent;
|
package org.springframework.scheduling.concurrent;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.RejectedExecutionException;
|
import java.util.concurrent.RejectedExecutionException;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.springframework.core.task.TaskRejectedException;
|
import org.springframework.core.task.TaskRejectedException;
|
||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.TaskUtils;
|
import org.springframework.scheduling.support.TaskUtils;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ErrorHandler;
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code>
|
* Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code>
|
||||||
* and exposes a Spring {@link org.springframework.scheduling.TaskScheduler} for it.
|
* and exposes a Spring {@link org.springframework.scheduling.TaskScheduler} for it.
|
||||||
* Extends {@link ConcurrentTaskExecutor} in order to implement the
|
* Extends {@link ConcurrentTaskExecutor} in order to implement the
|
||||||
* {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well.
|
* {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well.
|
||||||
*
|
*
|
||||||
* <p>Note that there is a pre-built {@link ThreadPoolTaskScheduler} that allows for
|
* <p>Note that there is a pre-built {@link ThreadPoolTaskScheduler} that allows for
|
||||||
* defining a JDK 1.5 {@link java.util.concurrent.ScheduledThreadPoolExecutor} in bean style,
|
* defining a JDK 1.5 {@link java.util.concurrent.ScheduledThreadPoolExecutor} in bean style,
|
||||||
* exposing it as a Spring {@link org.springframework.scheduling.TaskScheduler} directly.
|
* exposing it as a Spring {@link org.springframework.scheduling.TaskScheduler} directly.
|
||||||
* This is a convenient alternative to a raw ScheduledThreadPoolExecutor definition with
|
* This is a convenient alternative to a raw ScheduledThreadPoolExecutor definition with
|
||||||
* a separate definition of the present adapter class.
|
* a separate definition of the present adapter class.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see java.util.concurrent.ScheduledExecutorService
|
* @see java.util.concurrent.ScheduledExecutorService
|
||||||
* @see java.util.concurrent.ScheduledThreadPoolExecutor
|
* @see java.util.concurrent.ScheduledThreadPoolExecutor
|
||||||
* @see java.util.concurrent.Executors
|
* @see java.util.concurrent.Executors
|
||||||
* @see ThreadPoolTaskScheduler
|
* @see ThreadPoolTaskScheduler
|
||||||
*/
|
*/
|
||||||
public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler {
|
public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler {
|
||||||
|
|
||||||
private volatile ScheduledExecutorService scheduledExecutor;
|
private volatile ScheduledExecutorService scheduledExecutor;
|
||||||
|
|
||||||
private volatile ErrorHandler errorHandler;
|
private volatile ErrorHandler errorHandler;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ConcurrentTaskScheduler,
|
* Create a new ConcurrentTaskScheduler,
|
||||||
* using a single thread executor as default.
|
* using a single thread executor as default.
|
||||||
* @see java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
|
* @see java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
|
||||||
*/
|
*/
|
||||||
public ConcurrentTaskScheduler() {
|
public ConcurrentTaskScheduler() {
|
||||||
super();
|
super();
|
||||||
setScheduledExecutor(null);
|
setScheduledExecutor(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ConcurrentTaskScheduler,
|
* Create a new ConcurrentTaskScheduler,
|
||||||
* using the given JDK 1.5 executor as shared delegate.
|
* using the given JDK 1.5 executor as shared delegate.
|
||||||
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
||||||
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} as well
|
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} as well
|
||||||
* as {@link TaskScheduler} invocations
|
* as {@link TaskScheduler} invocations
|
||||||
*/
|
*/
|
||||||
public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) {
|
public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) {
|
||||||
super(scheduledExecutor);
|
super(scheduledExecutor);
|
||||||
setScheduledExecutor(scheduledExecutor);
|
setScheduledExecutor(scheduledExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new ConcurrentTaskScheduler,
|
* Create a new ConcurrentTaskScheduler,
|
||||||
* using the given JDK 1.5 executors as delegates.
|
* using the given JDK 1.5 executors as delegates.
|
||||||
* @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to
|
* @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to
|
||||||
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
||||||
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
||||||
* for {@link TaskScheduler} invocations
|
* for {@link TaskScheduler} invocations
|
||||||
*/
|
*/
|
||||||
public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) {
|
public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) {
|
||||||
super(concurrentExecutor);
|
super(concurrentExecutor);
|
||||||
setScheduledExecutor(scheduledExecutor);
|
setScheduledExecutor(scheduledExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the JDK 1.5 scheduled executor to delegate to.
|
* Specify the JDK 1.5 scheduled executor to delegate to.
|
||||||
* <p>Note: This will only apply to {@link TaskScheduler} invocations.
|
* <p>Note: This will only apply to {@link TaskScheduler} invocations.
|
||||||
* If you want the given executor to apply to
|
* If you want the given executor to apply to
|
||||||
* {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
* {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
||||||
* as well, pass the same executor reference to {@link #setConcurrentExecutor}.
|
* as well, pass the same executor reference to {@link #setConcurrentExecutor}.
|
||||||
* @see #setConcurrentExecutor
|
* @see #setConcurrentExecutor
|
||||||
*/
|
*/
|
||||||
public final void setScheduledExecutor(ScheduledExecutorService scheduledExecutor) {
|
public final void setScheduledExecutor(ScheduledExecutorService scheduledExecutor) {
|
||||||
this.scheduledExecutor =
|
this.scheduledExecutor =
|
||||||
(scheduledExecutor != null ? scheduledExecutor : Executors.newSingleThreadScheduledExecutor());
|
(scheduledExecutor != null ? scheduledExecutor : Executors.newSingleThreadScheduledExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide an {@link ErrorHandler} strategy.
|
* Provide an {@link ErrorHandler} strategy.
|
||||||
*/
|
*/
|
||||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||||
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
||||||
this.errorHandler = errorHandler;
|
this.errorHandler = errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||||
try {
|
try {
|
||||||
ErrorHandler errorHandler =
|
ErrorHandler errorHandler =
|
||||||
(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
|
(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
|
||||||
return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule();
|
return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule();
|
||||||
}
|
}
|
||||||
catch (RejectedExecutionException ex) {
|
catch (RejectedExecutionException ex) {
|
||||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
return this.scheduledExecutor.schedule(
|
return this.scheduledExecutor.schedule(
|
||||||
errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS);
|
errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
catch (RejectedExecutionException ex) {
|
catch (RejectedExecutionException ex) {
|
||||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
return this.scheduledExecutor.scheduleAtFixedRate(
|
return this.scheduledExecutor.scheduleAtFixedRate(
|
||||||
errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS);
|
errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
catch (RejectedExecutionException ex) {
|
catch (RejectedExecutionException ex) {
|
||||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||||
try {
|
try {
|
||||||
return this.scheduledExecutor.scheduleAtFixedRate(
|
return this.scheduledExecutor.scheduleAtFixedRate(
|
||||||
errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS);
|
errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
catch (RejectedExecutionException ex) {
|
catch (RejectedExecutionException ex) {
|
||||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||||
try {
|
try {
|
||||||
return this.scheduledExecutor.scheduleWithFixedDelay(
|
return this.scheduledExecutor.scheduleWithFixedDelay(
|
||||||
errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS);
|
errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
catch (RejectedExecutionException ex) {
|
catch (RejectedExecutionException ex) {
|
||||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||||
try {
|
try {
|
||||||
return this.scheduledExecutor.scheduleWithFixedDelay(
|
return this.scheduledExecutor.scheduleWithFixedDelay(
|
||||||
errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS);
|
errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
catch (RejectedExecutionException ex) {
|
catch (RejectedExecutionException ex) {
|
||||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
||||||
return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask);
|
return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,160 +1,160 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.concurrent;
|
package org.springframework.scheduling.concurrent;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.RejectedExecutionHandler;
|
import java.util.concurrent.RejectedExecutionHandler;
|
||||||
import java.util.concurrent.ThreadFactory;
|
import java.util.concurrent.ThreadFactory;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanNameAware;
|
import org.springframework.beans.factory.BeanNameAware;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for classes that are setting up a
|
* Base class for classes that are setting up a
|
||||||
* <code>java.util.concurrent.ExecutorService</code>
|
* <code>java.util.concurrent.ExecutorService</code>
|
||||||
* (typically a {@link java.util.concurrent.ThreadPoolExecutor}).
|
* (typically a {@link java.util.concurrent.ThreadPoolExecutor}).
|
||||||
* Defines common configuration settings and common lifecycle handling.
|
* Defines common configuration settings and common lifecycle handling.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
* @see java.util.concurrent.ExecutorService
|
* @see java.util.concurrent.ExecutorService
|
||||||
* @see java.util.concurrent.Executors
|
* @see java.util.concurrent.Executors
|
||||||
* @see java.util.concurrent.ThreadPoolExecutor
|
* @see java.util.concurrent.ThreadPoolExecutor
|
||||||
*/
|
*/
|
||||||
public abstract class ExecutorConfigurationSupport extends CustomizableThreadFactory
|
public abstract class ExecutorConfigurationSupport extends CustomizableThreadFactory
|
||||||
implements BeanNameAware, InitializingBean, DisposableBean {
|
implements BeanNameAware, InitializingBean, DisposableBean {
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private ThreadFactory threadFactory = this;
|
private ThreadFactory threadFactory = this;
|
||||||
|
|
||||||
private boolean threadNamePrefixSet = false;
|
private boolean threadNamePrefixSet = false;
|
||||||
|
|
||||||
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
|
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
|
||||||
|
|
||||||
private boolean waitForTasksToCompleteOnShutdown = false;
|
private boolean waitForTasksToCompleteOnShutdown = false;
|
||||||
|
|
||||||
private String beanName;
|
private String beanName;
|
||||||
|
|
||||||
private ExecutorService executor;
|
private ExecutorService executor;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool.
|
* Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool.
|
||||||
* Default is the ThreadPoolExecutor's default thread factory.
|
* Default is the ThreadPoolExecutor's default thread factory.
|
||||||
* @see java.util.concurrent.Executors#defaultThreadFactory()
|
* @see java.util.concurrent.Executors#defaultThreadFactory()
|
||||||
*/
|
*/
|
||||||
public void setThreadFactory(ThreadFactory threadFactory) {
|
public void setThreadFactory(ThreadFactory threadFactory) {
|
||||||
this.threadFactory = (threadFactory != null ? threadFactory : this);
|
this.threadFactory = (threadFactory != null ? threadFactory : this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setThreadNamePrefix(String threadNamePrefix) {
|
public void setThreadNamePrefix(String threadNamePrefix) {
|
||||||
super.setThreadNamePrefix(threadNamePrefix);
|
super.setThreadNamePrefix(threadNamePrefix);
|
||||||
this.threadNamePrefixSet = true;
|
this.threadNamePrefixSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the RejectedExecutionHandler to use for the ThreadPoolExecutor.
|
* Set the RejectedExecutionHandler to use for the ThreadPoolExecutor.
|
||||||
* Default is the ThreadPoolExecutor's default abort policy.
|
* Default is the ThreadPoolExecutor's default abort policy.
|
||||||
* @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy
|
* @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy
|
||||||
*/
|
*/
|
||||||
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
|
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
|
||||||
this.rejectedExecutionHandler =
|
this.rejectedExecutionHandler =
|
||||||
(rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy());
|
(rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether to wait for scheduled tasks to complete on shutdown.
|
* Set whether to wait for scheduled tasks to complete on shutdown.
|
||||||
* <p>Default is "false". Switch this to "true" if you prefer
|
* <p>Default is "false". Switch this to "true" if you prefer
|
||||||
* fully completed tasks at the expense of a longer shutdown phase.
|
* fully completed tasks at the expense of a longer shutdown phase.
|
||||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
* @see java.util.concurrent.ExecutorService#shutdown()
|
||||||
* @see java.util.concurrent.ExecutorService#shutdownNow()
|
* @see java.util.concurrent.ExecutorService#shutdownNow()
|
||||||
*/
|
*/
|
||||||
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
|
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
|
||||||
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
|
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBeanName(String name) {
|
public void setBeanName(String name) {
|
||||||
this.beanName = name;
|
this.beanName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls <code>initialize()</code> after the container applied all property values.
|
* Calls <code>initialize()</code> after the container applied all property values.
|
||||||
* @see #initialize()
|
* @see #initialize()
|
||||||
*/
|
*/
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up the ExecutorService.
|
* Set up the ExecutorService.
|
||||||
*/
|
*/
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info("Initializing ExecutorService " + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
logger.info("Initializing ExecutorService " + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
||||||
}
|
}
|
||||||
if (!this.threadNamePrefixSet && this.beanName != null) {
|
if (!this.threadNamePrefixSet && this.beanName != null) {
|
||||||
setThreadNamePrefix(this.beanName + "-");
|
setThreadNamePrefix(this.beanName + "-");
|
||||||
}
|
}
|
||||||
this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
|
this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the target {@link java.util.concurrent.ExecutorService} instance.
|
* Create the target {@link java.util.concurrent.ExecutorService} instance.
|
||||||
* Called by <code>afterPropertiesSet</code>.
|
* Called by <code>afterPropertiesSet</code>.
|
||||||
* @param threadFactory the ThreadFactory to use
|
* @param threadFactory the ThreadFactory to use
|
||||||
* @param rejectedExecutionHandler the RejectedExecutionHandler to use
|
* @param rejectedExecutionHandler the RejectedExecutionHandler to use
|
||||||
* @return a new ExecutorService instance
|
* @return a new ExecutorService instance
|
||||||
* @see #afterPropertiesSet()
|
* @see #afterPropertiesSet()
|
||||||
*/
|
*/
|
||||||
protected abstract ExecutorService initializeExecutor(
|
protected abstract ExecutorService initializeExecutor(
|
||||||
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler);
|
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls <code>shutdown</code> when the BeanFactory destroys
|
* Calls <code>shutdown</code> when the BeanFactory destroys
|
||||||
* the task executor instance.
|
* the task executor instance.
|
||||||
* @see #shutdown()
|
* @see #shutdown()
|
||||||
*/
|
*/
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a shutdown on the ThreadPoolExecutor.
|
* Perform a shutdown on the ThreadPoolExecutor.
|
||||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
* @see java.util.concurrent.ExecutorService#shutdown()
|
||||||
*/
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
if (logger.isInfoEnabled()) {
|
if (logger.isInfoEnabled()) {
|
||||||
logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
||||||
}
|
}
|
||||||
if (this.waitForTasksToCompleteOnShutdown) {
|
if (this.waitForTasksToCompleteOnShutdown) {
|
||||||
this.executor.shutdown();
|
this.executor.shutdown();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.executor.shutdownNow();
|
this.executor.shutdownNow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +1,124 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2009 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.concurrent;
|
package org.springframework.scheduling.concurrent;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.Delayed;
|
import java.util.concurrent.Delayed;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
||||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||||
import org.springframework.util.ErrorHandler;
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal adapter that reschedules an underlying {@link Runnable} according
|
* Internal adapter that reschedules an underlying {@link Runnable} according
|
||||||
* to the next execution time suggested by a given {@link Trigger}.
|
* to the next execution time suggested by a given {@link Trigger}.
|
||||||
*
|
*
|
||||||
* <p>Necessary because a native {@link ScheduledExecutorService} supports
|
* <p>Necessary because a native {@link ScheduledExecutorService} supports
|
||||||
* delay-driven execution only. The flexibility of the {@link Trigger} interface
|
* delay-driven execution only. The flexibility of the {@link Trigger} interface
|
||||||
* will be translated onto a delay for the next execution time (repeatedly).
|
* will be translated onto a delay for the next execution time (repeatedly).
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> {
|
class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> {
|
||||||
|
|
||||||
private final Trigger trigger;
|
private final Trigger trigger;
|
||||||
|
|
||||||
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||||
|
|
||||||
private final ScheduledExecutorService executor;
|
private final ScheduledExecutorService executor;
|
||||||
|
|
||||||
private volatile ScheduledFuture currentFuture;
|
private volatile ScheduledFuture currentFuture;
|
||||||
|
|
||||||
private volatile Date scheduledExecutionTime;
|
private volatile Date scheduledExecutionTime;
|
||||||
|
|
||||||
private final Object triggerContextMonitor = new Object();
|
private final Object triggerContextMonitor = new Object();
|
||||||
|
|
||||||
|
|
||||||
public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) {
|
public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) {
|
||||||
super(delegate, errorHandler);
|
super(delegate, errorHandler);
|
||||||
this.trigger = trigger;
|
this.trigger = trigger;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ScheduledFuture schedule() {
|
public ScheduledFuture schedule() {
|
||||||
synchronized (this.triggerContextMonitor) {
|
synchronized (this.triggerContextMonitor) {
|
||||||
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
||||||
if (this.scheduledExecutionTime == null) {
|
if (this.scheduledExecutionTime == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
|
long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
|
||||||
this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
|
this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Date actualExecutionTime = new Date();
|
Date actualExecutionTime = new Date();
|
||||||
super.run();
|
super.run();
|
||||||
Date completionTime = new Date();
|
Date completionTime = new Date();
|
||||||
synchronized (this.triggerContextMonitor) {
|
synchronized (this.triggerContextMonitor) {
|
||||||
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
||||||
}
|
}
|
||||||
if (!this.currentFuture.isCancelled()) {
|
if (!this.currentFuture.isCancelled()) {
|
||||||
schedule();
|
schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||||
return this.currentFuture.cancel(mayInterruptIfRunning);
|
return this.currentFuture.cancel(mayInterruptIfRunning);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return this.currentFuture.isCancelled();
|
return this.currentFuture.isCancelled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDone() {
|
public boolean isDone() {
|
||||||
return this.currentFuture.isDone();
|
return this.currentFuture.isDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get() throws InterruptedException, ExecutionException {
|
public Object get() throws InterruptedException, ExecutionException {
|
||||||
return this.currentFuture.get();
|
return this.currentFuture.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
return this.currentFuture.get(timeout, unit);
|
return this.currentFuture.get(timeout, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getDelay(TimeUnit unit) {
|
public long getDelay(TimeUnit unit) {
|
||||||
return this.currentFuture.getDelay(unit);
|
return this.currentFuture.getDelay(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(Delayed other) {
|
public int compareTo(Delayed other) {
|
||||||
if (this == other) {
|
if (this == other) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
||||||
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user