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
|
||||
aspectj.version=1.6.8.RELEASE
|
||||
junit.version=4.9.0
|
||||
testng.version=5.12.1
|
||||
# common dependency versions
|
||||
aspectj.version=1.6.8.RELEASE
|
||||
junit.version=4.9.0
|
||||
testng.version=5.12.1
|
||||
|
||||
@@ -1,103 +1,103 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.interceptor;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* AOP Alliance <code>MethodInterceptor</code> that processes method invocations
|
||||
* asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}.
|
||||
* Typically used with the {@link org.springframework.context.task.Async} annotation.
|
||||
*
|
||||
* <p>In terms of target method signatures, any parameter types are supported.
|
||||
* 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
|
||||
* 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
|
||||
* target method needs to implement the same signature, it will have to return
|
||||
* a temporary Future handle that just passes the return value through
|
||||
* (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult}
|
||||
* or EJB 3.1's <code>javax.ejb.AsyncResult</code>).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.scheduling.annotation.Async
|
||||
* @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor
|
||||
*/
|
||||
public class AsyncExecutionInterceptor implements MethodInterceptor, Ordered {
|
||||
|
||||
private final AsyncTaskExecutor asyncExecutor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AsyncExecutionInterceptor.
|
||||
* @param asyncExecutor the Spring AsyncTaskExecutor to delegate to
|
||||
*/
|
||||
public AsyncExecutionInterceptor(AsyncTaskExecutor asyncExecutor) {
|
||||
Assert.notNull(asyncExecutor, "TaskExecutor must not be null");
|
||||
this.asyncExecutor = asyncExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AsyncExecutionInterceptor.
|
||||
* @param asyncExecutor the <code>java.util.concurrent</code> Executor
|
||||
* to delegate to (typically a {@link java.util.concurrent.ExecutorService}
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor asyncExecutor) {
|
||||
this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor);
|
||||
}
|
||||
|
||||
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
Future result = this.asyncExecutor.submit(new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
try {
|
||||
Object result = invocation.proceed();
|
||||
if (result instanceof Future) {
|
||||
return ((Future) result).get();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
ReflectionUtils.rethrowException(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.interceptor;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* AOP Alliance <code>MethodInterceptor</code> that processes method invocations
|
||||
* asynchronously, using a given {@link org.springframework.core.task.AsyncTaskExecutor}.
|
||||
* Typically used with the {@link org.springframework.context.task.Async} annotation.
|
||||
*
|
||||
* <p>In terms of target method signatures, any parameter types are supported.
|
||||
* 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
|
||||
* 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
|
||||
* target method needs to implement the same signature, it will have to return
|
||||
* a temporary Future handle that just passes the return value through
|
||||
* (like Spring's {@link org.springframework.scheduling.annotation.AsyncResult}
|
||||
* or EJB 3.1's <code>javax.ejb.AsyncResult</code>).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.scheduling.annotation.Async
|
||||
* @see org.springframework.scheduling.annotation.AsyncAnnotationAdvisor
|
||||
*/
|
||||
public class AsyncExecutionInterceptor implements MethodInterceptor, Ordered {
|
||||
|
||||
private final AsyncTaskExecutor asyncExecutor;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AsyncExecutionInterceptor.
|
||||
* @param asyncExecutor the Spring AsyncTaskExecutor to delegate to
|
||||
*/
|
||||
public AsyncExecutionInterceptor(AsyncTaskExecutor asyncExecutor) {
|
||||
Assert.notNull(asyncExecutor, "TaskExecutor must not be null");
|
||||
this.asyncExecutor = asyncExecutor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AsyncExecutionInterceptor.
|
||||
* @param asyncExecutor the <code>java.util.concurrent</code> Executor
|
||||
* to delegate to (typically a {@link java.util.concurrent.ExecutorService}
|
||||
*/
|
||||
public AsyncExecutionInterceptor(Executor asyncExecutor) {
|
||||
this.asyncExecutor = new TaskExecutorAdapter(asyncExecutor);
|
||||
}
|
||||
|
||||
|
||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||
Future result = this.asyncExecutor.submit(new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
try {
|
||||
Object result = invocation.proceed();
|
||||
if (result instanceof Future) {
|
||||
return ((Future) result).get();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
ReflectionUtils.rethrowException(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,174 +1,174 @@
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.aop.ThrowsAdvice;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class TrickyAspectJPointcutExpressionTests {
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithUnconditionalPointcut() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "TestServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithStaticPointcut() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithDynamicPointcut() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithDynamicPointcutAndProxyTargetClass() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithStaticPointcutAndTwoClassLoaders() throws Exception {
|
||||
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
||||
|
||||
// Test with default class loader first...
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, new TestServiceImpl(), "TestServiceImpl");
|
||||
|
||||
// Then try again with a different class loader on the target...
|
||||
SimpleThrowawayClassLoader loader = new SimpleThrowawayClassLoader(new TestServiceImpl().getClass().getClassLoader());
|
||||
// Make sure the interface is loaded from the parent class loader
|
||||
loader.excludeClass(TestService.class.getName());
|
||||
loader.excludeClass(TestException.class.getName());
|
||||
TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance();
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl");
|
||||
|
||||
}
|
||||
|
||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message)
|
||||
throws Exception {
|
||||
testAdvice(advisor, logAdvice, target, message, false);
|
||||
}
|
||||
|
||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message,
|
||||
boolean proxyTargetClass) throws Exception {
|
||||
|
||||
logAdvice.reset();
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(target);
|
||||
factory.setProxyTargetClass(proxyTargetClass);
|
||||
factory.addAdvisor(advisor);
|
||||
TestService bean = (TestService) factory.getProxy();
|
||||
|
||||
assertEquals(0, logAdvice.getCountThrows());
|
||||
try {
|
||||
bean.sayHello();
|
||||
fail("Expected exception");
|
||||
} catch (TestException e) {
|
||||
assertEquals(message, e.getMessage());
|
||||
}
|
||||
assertEquals(1, logAdvice.getCountThrows());
|
||||
}
|
||||
|
||||
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
|
||||
|
||||
/**
|
||||
* Create a new SimpleThrowawayClassLoader for the given class loader.
|
||||
* @param parent the ClassLoader to build a throwaway ClassLoader for
|
||||
*/
|
||||
public SimpleThrowawayClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestException extends RuntimeException {
|
||||
|
||||
public TestException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public static @interface Log {
|
||||
}
|
||||
|
||||
public static interface TestService {
|
||||
public String sayHello();
|
||||
}
|
||||
|
||||
@Log
|
||||
public static class TestServiceImpl implements TestService{
|
||||
public String sayHello() {
|
||||
throw new TestException("TestServiceImpl");
|
||||
}
|
||||
}
|
||||
|
||||
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
|
||||
|
||||
private int countBefore = 0;
|
||||
|
||||
private int countThrows = 0;
|
||||
|
||||
public void before(Method method, Object[] objects, Object o) throws Throwable {
|
||||
countBefore++;
|
||||
}
|
||||
|
||||
public void afterThrowing(Exception e) throws Throwable {
|
||||
countThrows++;
|
||||
throw e;
|
||||
}
|
||||
|
||||
public int getCountBefore() {
|
||||
return countBefore;
|
||||
}
|
||||
|
||||
public int getCountThrows() {
|
||||
return countThrows;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
countThrows = 0;
|
||||
countBefore = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
package org.springframework.aop.aspectj;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.MethodBeforeAdvice;
|
||||
import org.springframework.aop.ThrowsAdvice;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.core.OverridingClassLoader;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class TrickyAspectJPointcutExpressionTests {
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithUnconditionalPointcut() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
testAdvice(new DefaultPointcutAdvisor(logAdvice), logAdvice, target, "TestServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithStaticPointcut() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithDynamicPointcut() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithDynamicPointcutAndProxyTargetClass() throws Exception {
|
||||
TestService target = new TestServiceImpl();
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("@within(%s.Log)", getClass().getName()));
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, target, "TestServiceImpl", true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManualProxyJavaWithStaticPointcutAndTwoClassLoaders() throws Exception {
|
||||
|
||||
LogUserAdvice logAdvice = new LogUserAdvice();
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression(String.format("execution(* %s.TestService.*(..))", getClass().getName()));
|
||||
|
||||
// Test with default class loader first...
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, new TestServiceImpl(), "TestServiceImpl");
|
||||
|
||||
// Then try again with a different class loader on the target...
|
||||
SimpleThrowawayClassLoader loader = new SimpleThrowawayClassLoader(new TestServiceImpl().getClass().getClassLoader());
|
||||
// Make sure the interface is loaded from the parent class loader
|
||||
loader.excludeClass(TestService.class.getName());
|
||||
loader.excludeClass(TestException.class.getName());
|
||||
TestService other = (TestService) loader.loadClass(TestServiceImpl.class.getName()).newInstance();
|
||||
testAdvice(new DefaultPointcutAdvisor(pointcut, logAdvice), logAdvice, other, "TestServiceImpl");
|
||||
|
||||
}
|
||||
|
||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message)
|
||||
throws Exception {
|
||||
testAdvice(advisor, logAdvice, target, message, false);
|
||||
}
|
||||
|
||||
private void testAdvice(Advisor advisor, LogUserAdvice logAdvice, TestService target, String message,
|
||||
boolean proxyTargetClass) throws Exception {
|
||||
|
||||
logAdvice.reset();
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(target);
|
||||
factory.setProxyTargetClass(proxyTargetClass);
|
||||
factory.addAdvisor(advisor);
|
||||
TestService bean = (TestService) factory.getProxy();
|
||||
|
||||
assertEquals(0, logAdvice.getCountThrows());
|
||||
try {
|
||||
bean.sayHello();
|
||||
fail("Expected exception");
|
||||
} catch (TestException e) {
|
||||
assertEquals(message, e.getMessage());
|
||||
}
|
||||
assertEquals(1, logAdvice.getCountThrows());
|
||||
}
|
||||
|
||||
public static class SimpleThrowawayClassLoader extends OverridingClassLoader {
|
||||
|
||||
/**
|
||||
* Create a new SimpleThrowawayClassLoader for the given class loader.
|
||||
* @param parent the ClassLoader to build a throwaway ClassLoader for
|
||||
*/
|
||||
public SimpleThrowawayClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TestException extends RuntimeException {
|
||||
|
||||
public TestException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public static @interface Log {
|
||||
}
|
||||
|
||||
public static interface TestService {
|
||||
public String sayHello();
|
||||
}
|
||||
|
||||
@Log
|
||||
public static class TestServiceImpl implements TestService{
|
||||
public String sayHello() {
|
||||
throw new TestException("TestServiceImpl");
|
||||
}
|
||||
}
|
||||
|
||||
public class LogUserAdvice implements MethodBeforeAdvice, ThrowsAdvice {
|
||||
|
||||
private int countBefore = 0;
|
||||
|
||||
private int countThrows = 0;
|
||||
|
||||
public void before(Method method, Object[] objects, Object o) throws Throwable {
|
||||
countBefore++;
|
||||
}
|
||||
|
||||
public void afterThrowing(Exception e) throws Throwable {
|
||||
countThrows++;
|
||||
throw e;
|
||||
}
|
||||
|
||||
public int getCountBefore() {
|
||||
return countBefore;
|
||||
}
|
||||
|
||||
public int getCountThrows() {
|
||||
return countThrows;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
countThrows = 0;
|
||||
countBefore = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import test.beans.TestBean;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Colin Sampaleanu
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
*/
|
||||
public class ClassUtilsTests extends TestCase {
|
||||
|
||||
public void testGetShortNameForCglibClass() {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTarget(tb);
|
||||
pf.setProxyTargetClass(true);
|
||||
TestBean proxy = (TestBean) pf.getProxy();
|
||||
String className = ClassUtils.getShortName(proxy.getClass());
|
||||
assertEquals("Class name did not match", "TestBean", className);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.aop.support;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import test.beans.TestBean;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Colin Sampaleanu
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Rick Evans
|
||||
*/
|
||||
public class ClassUtilsTests extends TestCase {
|
||||
|
||||
public void testGetShortNameForCglibClass() {
|
||||
TestBean tb = new TestBean();
|
||||
ProxyFactory pf = new ProxyFactory();
|
||||
pf.setTarget(tb);
|
||||
pf.setProxyTargetClass(true);
|
||||
TestBean proxy = (TestBean) pf.getProxy();
|
||||
String className = ClassUtils.getShortName(proxy.getClass());
|
||||
assertEquals("Class name did not match", "TestBean", className);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
/**
|
||||
* Generic-based dependency injection aspect.
|
||||
* <p>
|
||||
* This aspect allows users to implement efficient, type-safe dependency injection without
|
||||
* the use of the @Configurable annotation.
|
||||
*
|
||||
* 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.
|
||||
* <pre>
|
||||
* aspect PricingStrategyDependencyInjectionAspect
|
||||
* extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> {
|
||||
* private PricingStrategy pricingStrategy;
|
||||
*
|
||||
* public void configure(PricingStrategyClient bean) {
|
||||
* bean.setPricingStrategy(pricingStrategy);
|
||||
* }
|
||||
*
|
||||
* public void setPricingStrategy(PricingStrategy pricingStrategy) {
|
||||
* this.pricingStrategy = pricingStrategy;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* @author Ramnivas Laddad
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect {
|
||||
declare parents: I implements ConfigurableObject;
|
||||
|
||||
public pointcut inConfigurableBean() : within(I+);
|
||||
|
||||
public final void configureBean(Object bean) {
|
||||
configure((I)bean);
|
||||
}
|
||||
|
||||
// Unfortunately, erasure used with generics won't allow to use the same named method
|
||||
protected abstract void configure(I bean);
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
/**
|
||||
* Generic-based dependency injection aspect.
|
||||
* <p>
|
||||
* This aspect allows users to implement efficient, type-safe dependency injection without
|
||||
* the use of the @Configurable annotation.
|
||||
*
|
||||
* 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.
|
||||
* <pre>
|
||||
* aspect PricingStrategyDependencyInjectionAspect
|
||||
* extends GenericInterfaceDrivenDependencyInjectionAspect<PricingStrategyClient> {
|
||||
* private PricingStrategy pricingStrategy;
|
||||
*
|
||||
* public void configure(PricingStrategyClient bean) {
|
||||
* bean.setPricingStrategy(pricingStrategy);
|
||||
* }
|
||||
*
|
||||
* public void setPricingStrategy(PricingStrategy pricingStrategy) {
|
||||
* this.pricingStrategy = pricingStrategy;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* @author Ramnivas Laddad
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public abstract aspect GenericInterfaceDrivenDependencyInjectionAspect<I> extends AbstractInterfaceDrivenDependencyInjectionAspect {
|
||||
declare parents: I implements ConfigurableObject;
|
||||
|
||||
public pointcut inConfigurableBean() : within(I+);
|
||||
|
||||
public final void configureBean(Object bean) {
|
||||
configure((I)bean);
|
||||
}
|
||||
|
||||
// Unfortunately, erasure used with generics won't allow to use the same named method
|
||||
protected abstract void configure(I bean);
|
||||
}
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.cache.interceptor.CacheAspectSupport;
|
||||
import org.springframework.cache.interceptor.CacheOperationSource;
|
||||
|
||||
/**
|
||||
* Abstract superaspect for AspectJ cache aspects. Concrete subaspects will implement the
|
||||
* {@link #cacheMethodExecution} pointcut using a strategy such as Java 5 annotations.
|
||||
*
|
||||
* <p>Suitable for use inside or outside the Spring IoC container. Set the
|
||||
* {@link #setCacheManager cacheManager} property appropriately, allowing use of any cache
|
||||
* implementation supported by Spring.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
public abstract aspect AbstractCacheAspect extends CacheAspectSupport {
|
||||
|
||||
protected AbstractCacheAspect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct object using the given caching metadata retrieval strategy.
|
||||
* @param cos {@link CacheOperationSource} implementation, retrieving Spring cache
|
||||
* metadata for each joinpoint.
|
||||
*/
|
||||
protected AbstractCacheAspect(CacheOperationSource... cos) {
|
||||
setCacheOperationSources(cos);
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
|
||||
Invoker aspectJInvoker = new Invoker() {
|
||||
public Object invoke() {
|
||||
return proceed(cachedObject);
|
||||
}
|
||||
};
|
||||
|
||||
return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete subaspects must implement this pointcut, to identify cached methods.
|
||||
*/
|
||||
protected abstract pointcut cacheMethodExecution(Object cachedObject);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.cache.interceptor.CacheAspectSupport;
|
||||
import org.springframework.cache.interceptor.CacheOperationSource;
|
||||
|
||||
/**
|
||||
* Abstract superaspect for AspectJ cache aspects. Concrete subaspects will implement the
|
||||
* {@link #cacheMethodExecution} pointcut using a strategy such as Java 5 annotations.
|
||||
*
|
||||
* <p>Suitable for use inside or outside the Spring IoC container. Set the
|
||||
* {@link #setCacheManager cacheManager} property appropriately, allowing use of any cache
|
||||
* implementation supported by Spring.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
public abstract aspect AbstractCacheAspect extends CacheAspectSupport {
|
||||
|
||||
protected AbstractCacheAspect() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct object using the given caching metadata retrieval strategy.
|
||||
* @param cos {@link CacheOperationSource} implementation, retrieving Spring cache
|
||||
* metadata for each joinpoint.
|
||||
*/
|
||||
protected AbstractCacheAspect(CacheOperationSource... cos) {
|
||||
setCacheOperationSources(cos);
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
Object around(final Object cachedObject) : cacheMethodExecution(cachedObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
|
||||
Invoker aspectJInvoker = new Invoker() {
|
||||
public Object invoke() {
|
||||
return proceed(cachedObject);
|
||||
}
|
||||
};
|
||||
|
||||
return execute(aspectJInvoker, thisJoinPoint.getTarget(), method, thisJoinPoint.getArgs());
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete subaspects must implement this pointcut, to identify cached methods.
|
||||
*/
|
||||
protected abstract pointcut cacheMethodExecution(Object cachedObject);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,116 +1,116 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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>
|
||||
* inherited.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* <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
|
||||
* annotated (regardless of visibility). Annotating non-public methods directly is the
|
||||
* only way to get caching demarcation for the execution of such operations.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
||||
|
||||
public AnnotationCacheAspect() {
|
||||
super(new AnnotationCacheOperationSource(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCacheableType() :
|
||||
execution(public * ((@Cacheable *)+).*(..)) && within(@Cacheable *);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
|
||||
execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCachePutType() :
|
||||
execution(public * ((@CachePut *)+).*(..)) && within(@CachePut *);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCachingType() :
|
||||
execution(public * ((@Caching *)+).*(..)) && within(@Caching *);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link Cacheable} annotation.
|
||||
*/
|
||||
private pointcut executionOfCacheableMethod() :
|
||||
execution(@Cacheable * *(..));
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link CacheEvict} annotation.
|
||||
*/
|
||||
private pointcut executionOfCacheEvictMethod() :
|
||||
execution(@CacheEvict * *(..));
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link CachePut} annotation.
|
||||
*/
|
||||
private pointcut executionOfCachePutMethod() :
|
||||
execution(@CachePut * *(..));
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link Caching} annotation.
|
||||
*/
|
||||
private pointcut executionOfCachingMethod() :
|
||||
execution(@Caching * *(..));
|
||||
|
||||
/**
|
||||
* Definition of pointcut from super aspect - matched join points will have Spring
|
||||
* cache management applied.
|
||||
*/
|
||||
protected pointcut cacheMethodExecution(Object cachedObject) :
|
||||
(executionOfAnyPublicMethodInAtCacheableType()
|
||||
|| executionOfAnyPublicMethodInAtCacheEvictType()
|
||||
|| executionOfAnyPublicMethodInAtCachePutType()
|
||||
|| executionOfAnyPublicMethodInAtCachingType()
|
||||
|| executionOfCacheableMethod()
|
||||
|| executionOfCacheEvictMethod()
|
||||
|| executionOfCachePutMethod()
|
||||
|| executionOfCachingMethod())
|
||||
&& this(cachedObject);
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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>
|
||||
* inherited.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* <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
|
||||
* annotated (regardless of visibility). Annotating non-public methods directly is the
|
||||
* only way to get caching demarcation for the execution of such operations.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
public aspect AnnotationCacheAspect extends AbstractCacheAspect {
|
||||
|
||||
public AnnotationCacheAspect() {
|
||||
super(new AnnotationCacheOperationSource(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCacheableType() :
|
||||
execution(public * ((@Cacheable *)+).*(..)) && within(@Cacheable *);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCacheEvictType() :
|
||||
execution(public * ((@CacheEvict *)+).*(..)) && within(@CacheEvict *);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCachePutType() :
|
||||
execution(public * ((@CachePut *)+).*(..)) && within(@CachePut *);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtCachingType() :
|
||||
execution(public * ((@Caching *)+).*(..)) && within(@Caching *);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link Cacheable} annotation.
|
||||
*/
|
||||
private pointcut executionOfCacheableMethod() :
|
||||
execution(@Cacheable * *(..));
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link CacheEvict} annotation.
|
||||
*/
|
||||
private pointcut executionOfCacheEvictMethod() :
|
||||
execution(@CacheEvict * *(..));
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link CachePut} annotation.
|
||||
*/
|
||||
private pointcut executionOfCachePutMethod() :
|
||||
execution(@CachePut * *(..));
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the @{@link Caching} annotation.
|
||||
*/
|
||||
private pointcut executionOfCachingMethod() :
|
||||
execution(@Caching * *(..));
|
||||
|
||||
/**
|
||||
* Definition of pointcut from super aspect - matched join points will have Spring
|
||||
* cache management applied.
|
||||
*/
|
||||
protected pointcut cacheMethodExecution(Object cachedObject) :
|
||||
(executionOfAnyPublicMethodInAtCacheableType()
|
||||
|| executionOfAnyPublicMethodInAtCacheEvictType()
|
||||
|| executionOfAnyPublicMethodInAtCachePutType()
|
||||
|| executionOfAnyPublicMethodInAtCachingType()
|
||||
|| executionOfCacheableMethod()
|
||||
|| executionOfCacheEvictMethod()
|
||||
|| executionOfCachePutMethod()
|
||||
|| executionOfCachingMethod())
|
||||
&& this(cachedObject);
|
||||
}
|
||||
@@ -1,197 +1,197 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract aspect to enable mocking of methods picked out by a pointcut.
|
||||
* Sub-aspects must define the mockStaticsTestMethod() pointcut to
|
||||
* indicate call stacks when mocking should be triggered, and the
|
||||
* methodToMock() pointcut to pick out a method invocations to mock.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
|
||||
|
||||
protected abstract pointcut mockStaticsTestMethod();
|
||||
|
||||
protected abstract pointcut methodToMock();
|
||||
|
||||
private boolean recording = true;
|
||||
|
||||
static enum CallResponse { nothing, return_, throw_ };
|
||||
|
||||
// Represents a list of expected calls to static entity methods
|
||||
// Public to allow inserted code to access: is this normal??
|
||||
public class Expectations {
|
||||
|
||||
// Represents an expected call to a static entity method
|
||||
private class Call {
|
||||
private final String signature;
|
||||
private final Object[] args;
|
||||
|
||||
private Object responseObject; // return value or throwable
|
||||
private CallResponse responseType = CallResponse.nothing;
|
||||
|
||||
public Call(String name, Object[] args) {
|
||||
this.signature = name;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public boolean hasResponseSpecified() {
|
||||
return responseType != CallResponse.nothing;
|
||||
}
|
||||
|
||||
public void setReturnVal(Object retVal) {
|
||||
this.responseObject = retVal;
|
||||
responseType = CallResponse.return_;
|
||||
}
|
||||
|
||||
public void setThrow(Throwable throwable) {
|
||||
this.responseObject = throwable;
|
||||
responseType = CallResponse.throw_;
|
||||
}
|
||||
|
||||
public Object returnValue(String lastSig, Object[] args) {
|
||||
checkSignature(lastSig, args);
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
public Object throwException(String lastSig, Object[] args) {
|
||||
checkSignature(lastSig, args);
|
||||
throw (RuntimeException)responseObject;
|
||||
}
|
||||
|
||||
private void checkSignature(String lastSig, Object[] args) {
|
||||
if (!signature.equals(lastSig)) {
|
||||
throw new IllegalArgumentException("Signature doesn't match");
|
||||
}
|
||||
if (!Arrays.equals(this.args, args)) {
|
||||
throw new IllegalArgumentException("Arguments don't match");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Call> calls = new LinkedList<Call>();
|
||||
|
||||
// Calls already verified
|
||||
private int verified;
|
||||
|
||||
public void verify() {
|
||||
if (verified != calls.size()) {
|
||||
throw new IllegalStateException("Expected " + calls.size()
|
||||
+ " calls, received " + verified);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the call and provide the expected return value
|
||||
* @param lastSig
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
public Object respond(String lastSig, Object[] args) {
|
||||
Call call = nextCall();
|
||||
CallResponse responseType = call.responseType;
|
||||
if (responseType == CallResponse.return_) {
|
||||
return call.returnValue(lastSig, args);
|
||||
} else if(responseType == CallResponse.throw_) {
|
||||
return (RuntimeException)call.throwException(lastSig, args);
|
||||
} else if(responseType == CallResponse.nothing) {
|
||||
// do nothing
|
||||
}
|
||||
throw new IllegalStateException("Behavior of " + call + " not specified");
|
||||
}
|
||||
|
||||
private Call nextCall() {
|
||||
if (verified > calls.size() - 1) {
|
||||
throw new IllegalStateException("Expected " + calls.size()
|
||||
+ " calls, received " + verified);
|
||||
}
|
||||
return calls.get(verified++);
|
||||
}
|
||||
|
||||
public void expectCall(String lastSig, Object lastArgs[]) {
|
||||
Call call = new Call(lastSig, lastArgs);
|
||||
calls.add(call);
|
||||
}
|
||||
|
||||
public boolean hasCalls() {
|
||||
return !calls.isEmpty();
|
||||
}
|
||||
|
||||
public void expectReturn(Object retVal) {
|
||||
Call call = calls.get(calls.size() - 1);
|
||||
if (call.hasResponseSpecified()) {
|
||||
throw new IllegalStateException("No static method invoked before setting return value");
|
||||
}
|
||||
call.setReturnVal(retVal);
|
||||
}
|
||||
|
||||
public void expectThrow(Throwable throwable) {
|
||||
Call call = calls.get(calls.size() - 1);
|
||||
if (call.hasResponseSpecified()) {
|
||||
throw new IllegalStateException("No static method invoked before setting throwable");
|
||||
}
|
||||
call.setThrow(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
private Expectations expectations = new Expectations();
|
||||
|
||||
after() returning : mockStaticsTestMethod() {
|
||||
if (recording && (expectations.hasCalls())) {
|
||||
throw new IllegalStateException(
|
||||
"Calls recorded, yet playback state never reached: Create expectations then call "
|
||||
+ this.getClass().getSimpleName() + ".playback()");
|
||||
}
|
||||
expectations.verify();
|
||||
}
|
||||
|
||||
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
|
||||
if (recording) {
|
||||
expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||
// Return value doesn't matter
|
||||
return null;
|
||||
} else {
|
||||
return expectations.respond(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public void expectReturnInternal(Object retVal) {
|
||||
if (!recording) {
|
||||
throw new IllegalStateException("Not recording: Cannot set return value");
|
||||
}
|
||||
expectations.expectReturn(retVal);
|
||||
}
|
||||
|
||||
public void expectThrowInternal(Throwable throwable) {
|
||||
if (!recording) {
|
||||
throw new IllegalStateException("Not recording: Cannot set throwable value");
|
||||
}
|
||||
expectations.expectThrow(throwable);
|
||||
}
|
||||
|
||||
public void playbackInternal() {
|
||||
recording = false;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract aspect to enable mocking of methods picked out by a pointcut.
|
||||
* Sub-aspects must define the mockStaticsTestMethod() pointcut to
|
||||
* indicate call stacks when mocking should be triggered, and the
|
||||
* methodToMock() pointcut to pick out a method invocations to mock.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public abstract aspect AbstractMethodMockingControl percflow(mockStaticsTestMethod()) {
|
||||
|
||||
protected abstract pointcut mockStaticsTestMethod();
|
||||
|
||||
protected abstract pointcut methodToMock();
|
||||
|
||||
private boolean recording = true;
|
||||
|
||||
static enum CallResponse { nothing, return_, throw_ };
|
||||
|
||||
// Represents a list of expected calls to static entity methods
|
||||
// Public to allow inserted code to access: is this normal??
|
||||
public class Expectations {
|
||||
|
||||
// Represents an expected call to a static entity method
|
||||
private class Call {
|
||||
private final String signature;
|
||||
private final Object[] args;
|
||||
|
||||
private Object responseObject; // return value or throwable
|
||||
private CallResponse responseType = CallResponse.nothing;
|
||||
|
||||
public Call(String name, Object[] args) {
|
||||
this.signature = name;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public boolean hasResponseSpecified() {
|
||||
return responseType != CallResponse.nothing;
|
||||
}
|
||||
|
||||
public void setReturnVal(Object retVal) {
|
||||
this.responseObject = retVal;
|
||||
responseType = CallResponse.return_;
|
||||
}
|
||||
|
||||
public void setThrow(Throwable throwable) {
|
||||
this.responseObject = throwable;
|
||||
responseType = CallResponse.throw_;
|
||||
}
|
||||
|
||||
public Object returnValue(String lastSig, Object[] args) {
|
||||
checkSignature(lastSig, args);
|
||||
return responseObject;
|
||||
}
|
||||
|
||||
public Object throwException(String lastSig, Object[] args) {
|
||||
checkSignature(lastSig, args);
|
||||
throw (RuntimeException)responseObject;
|
||||
}
|
||||
|
||||
private void checkSignature(String lastSig, Object[] args) {
|
||||
if (!signature.equals(lastSig)) {
|
||||
throw new IllegalArgumentException("Signature doesn't match");
|
||||
}
|
||||
if (!Arrays.equals(this.args, args)) {
|
||||
throw new IllegalArgumentException("Arguments don't match");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Call> calls = new LinkedList<Call>();
|
||||
|
||||
// Calls already verified
|
||||
private int verified;
|
||||
|
||||
public void verify() {
|
||||
if (verified != calls.size()) {
|
||||
throw new IllegalStateException("Expected " + calls.size()
|
||||
+ " calls, received " + verified);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the call and provide the expected return value
|
||||
* @param lastSig
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
public Object respond(String lastSig, Object[] args) {
|
||||
Call call = nextCall();
|
||||
CallResponse responseType = call.responseType;
|
||||
if (responseType == CallResponse.return_) {
|
||||
return call.returnValue(lastSig, args);
|
||||
} else if(responseType == CallResponse.throw_) {
|
||||
return (RuntimeException)call.throwException(lastSig, args);
|
||||
} else if(responseType == CallResponse.nothing) {
|
||||
// do nothing
|
||||
}
|
||||
throw new IllegalStateException("Behavior of " + call + " not specified");
|
||||
}
|
||||
|
||||
private Call nextCall() {
|
||||
if (verified > calls.size() - 1) {
|
||||
throw new IllegalStateException("Expected " + calls.size()
|
||||
+ " calls, received " + verified);
|
||||
}
|
||||
return calls.get(verified++);
|
||||
}
|
||||
|
||||
public void expectCall(String lastSig, Object lastArgs[]) {
|
||||
Call call = new Call(lastSig, lastArgs);
|
||||
calls.add(call);
|
||||
}
|
||||
|
||||
public boolean hasCalls() {
|
||||
return !calls.isEmpty();
|
||||
}
|
||||
|
||||
public void expectReturn(Object retVal) {
|
||||
Call call = calls.get(calls.size() - 1);
|
||||
if (call.hasResponseSpecified()) {
|
||||
throw new IllegalStateException("No static method invoked before setting return value");
|
||||
}
|
||||
call.setReturnVal(retVal);
|
||||
}
|
||||
|
||||
public void expectThrow(Throwable throwable) {
|
||||
Call call = calls.get(calls.size() - 1);
|
||||
if (call.hasResponseSpecified()) {
|
||||
throw new IllegalStateException("No static method invoked before setting throwable");
|
||||
}
|
||||
call.setThrow(throwable);
|
||||
}
|
||||
}
|
||||
|
||||
private Expectations expectations = new Expectations();
|
||||
|
||||
after() returning : mockStaticsTestMethod() {
|
||||
if (recording && (expectations.hasCalls())) {
|
||||
throw new IllegalStateException(
|
||||
"Calls recorded, yet playback state never reached: Create expectations then call "
|
||||
+ this.getClass().getSimpleName() + ".playback()");
|
||||
}
|
||||
expectations.verify();
|
||||
}
|
||||
|
||||
Object around() : methodToMock() && cflowbelow(mockStaticsTestMethod()) {
|
||||
if (recording) {
|
||||
expectations.expectCall(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||
// Return value doesn't matter
|
||||
return null;
|
||||
} else {
|
||||
return expectations.respond(thisJoinPointStaticPart.toLongString(), thisJoinPoint.getArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public void expectReturnInternal(Object retVal) {
|
||||
if (!recording) {
|
||||
throw new IllegalStateException("Not recording: Cannot set return value");
|
||||
}
|
||||
expectations.expectReturn(retVal);
|
||||
}
|
||||
|
||||
public void expectThrowInternal(Throwable throwable) {
|
||||
if (!recording) {
|
||||
throw new IllegalStateException("Not recording: Cannot set throwable value");
|
||||
}
|
||||
expectations.expectThrow(throwable);
|
||||
}
|
||||
|
||||
public void playbackInternal() {
|
||||
recording = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* <p>Also provides static methods to simplify the programming model for
|
||||
* entering playback mode and setting expected return values.
|
||||
*
|
||||
* <p>Usage:
|
||||
* <ol>
|
||||
* <li>Annotate a test class with @MockStaticEntityMethods.
|
||||
* <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode.
|
||||
* Invoke static methods on Entity classes, with each recording-mode invocation
|
||||
* being followed by an invocation to the static expectReturn() or expectThrow()
|
||||
* method on AnnotationDrivenStaticEntityMockingControl.
|
||||
* <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method.
|
||||
* <li>Call the code you wish to test that uses the static methods. Verification will
|
||||
* occur automatically.
|
||||
* </ol>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @see MockStaticEntityMethods
|
||||
*/
|
||||
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
|
||||
|
||||
/**
|
||||
* Stop recording mock calls and enter playback state
|
||||
*/
|
||||
public static void playback() {
|
||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
|
||||
}
|
||||
|
||||
public static void expectReturn(Object retVal) {
|
||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
|
||||
}
|
||||
|
||||
public static void expectThrow(Throwable throwable) {
|
||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
|
||||
}
|
||||
|
||||
// Only matches directly annotated @Test methods, to allow methods in
|
||||
// @MockStatics classes to invoke each other without resetting the mocking environment
|
||||
protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));
|
||||
|
||||
protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <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.
|
||||
*
|
||||
* <p>Also provides static methods to simplify the programming model for
|
||||
* entering playback mode and setting expected return values.
|
||||
*
|
||||
* <p>Usage:
|
||||
* <ol>
|
||||
* <li>Annotate a test class with @MockStaticEntityMethods.
|
||||
* <li>In each test method, AnnotationDrivenStaticEntityMockingControl will begin in recording mode.
|
||||
* Invoke static methods on Entity classes, with each recording-mode invocation
|
||||
* being followed by an invocation to the static expectReturn() or expectThrow()
|
||||
* method on AnnotationDrivenStaticEntityMockingControl.
|
||||
* <li>Invoke the static AnnotationDrivenStaticEntityMockingControl() method.
|
||||
* <li>Call the code you wish to test that uses the static methods. Verification will
|
||||
* occur automatically.
|
||||
* </ol>
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @see MockStaticEntityMethods
|
||||
*/
|
||||
public aspect AnnotationDrivenStaticEntityMockingControl extends AbstractMethodMockingControl {
|
||||
|
||||
/**
|
||||
* Stop recording mock calls and enter playback state
|
||||
*/
|
||||
public static void playback() {
|
||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().playbackInternal();
|
||||
}
|
||||
|
||||
public static void expectReturn(Object retVal) {
|
||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectReturnInternal(retVal);
|
||||
}
|
||||
|
||||
public static void expectThrow(Throwable throwable) {
|
||||
AnnotationDrivenStaticEntityMockingControl.aspectOf().expectThrowInternal(throwable);
|
||||
}
|
||||
|
||||
// Only matches directly annotated @Test methods, to allow methods in
|
||||
// @MockStatics classes to invoke each other without resetting the mocking environment
|
||||
protected pointcut mockStaticsTestMethod() : execution(public * (@MockStaticEntityMethods *).*(..));
|
||||
|
||||
protected pointcut methodToMock() : execution(public static * (@javax.persistence.Entity *).*(..));
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation to indicate a test class for whose @Test methods
|
||||
* static methods on Entity classes should be mocked.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see AbstractMethodMockingControl
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface MockStaticEntityMethods {
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation to indicate a test class for whose @Test methods
|
||||
* static methods on Entity classes should be mocked.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @see AbstractMethodMockingControl
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface MockStaticEntityMethods {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||
|
||||
/**
|
||||
* Abstract aspect that routes selected methods asynchronously.
|
||||
*
|
||||
* <p>This aspect needs to be injected with an implementation of
|
||||
* {@link Executor} to activate it for a specific thread pool.
|
||||
* Otherwise it will simply delegate all calls synchronously.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public abstract aspect AbstractAsyncExecutionAspect {
|
||||
|
||||
private AsyncTaskExecutor asyncExecutor;
|
||||
|
||||
public void setExecutor(Executor executor) {
|
||||
if (executor instanceof AsyncTaskExecutor) {
|
||||
this.asyncExecutor = (AsyncTaskExecutor) executor;
|
||||
}
|
||||
else {
|
||||
this.asyncExecutor = new TaskExecutorAdapter(executor);
|
||||
}
|
||||
}
|
||||
|
||||
Object around() : asyncMethod() {
|
||||
if (this.asyncExecutor == null) {
|
||||
return proceed();
|
||||
}
|
||||
Callable<Object> callable = new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
Object result = proceed();
|
||||
if (result instanceof Future) {
|
||||
return ((Future<?>) result).get();
|
||||
}
|
||||
return null;
|
||||
}};
|
||||
Future<?> result = this.asyncExecutor.submit(callable);
|
||||
if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract pointcut asyncMethod();
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.core.task.AsyncTaskExecutor;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.support.TaskExecutorAdapter;
|
||||
|
||||
/**
|
||||
* Abstract aspect that routes selected methods asynchronously.
|
||||
*
|
||||
* <p>This aspect needs to be injected with an implementation of
|
||||
* {@link Executor} to activate it for a specific thread pool.
|
||||
* Otherwise it will simply delegate all calls synchronously.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public abstract aspect AbstractAsyncExecutionAspect {
|
||||
|
||||
private AsyncTaskExecutor asyncExecutor;
|
||||
|
||||
public void setExecutor(Executor executor) {
|
||||
if (executor instanceof AsyncTaskExecutor) {
|
||||
this.asyncExecutor = (AsyncTaskExecutor) executor;
|
||||
}
|
||||
else {
|
||||
this.asyncExecutor = new TaskExecutorAdapter(executor);
|
||||
}
|
||||
}
|
||||
|
||||
Object around() : asyncMethod() {
|
||||
if (this.asyncExecutor == null) {
|
||||
return proceed();
|
||||
}
|
||||
Callable<Object> callable = new Callable<Object>() {
|
||||
public Object call() throws Exception {
|
||||
Object result = proceed();
|
||||
if (result instanceof Future) {
|
||||
return ((Future<?>) result).get();
|
||||
}
|
||||
return null;
|
||||
}};
|
||||
Future<?> result = this.asyncExecutor.submit(callable);
|
||||
if (Future.class.isAssignableFrom(((MethodSignature) thisJoinPointStaticPart.getSignature()).getReturnType())) {
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract pointcut asyncMethod();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
/**
|
||||
* Aspect to route methods based on 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
|
||||
* to be routed asynchronously must return either void, {@link Future},
|
||||
* 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.
|
||||
* If, however, a class marked with <code>@Async</code> contains a method that
|
||||
* violates this constraint, it produces only a warning.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect {
|
||||
|
||||
private pointcut asyncMarkedMethod()
|
||||
: execution(@Async (void || Future+) *(..));
|
||||
|
||||
private pointcut asyncTypeMarkedMethod()
|
||||
: execution((void || Future+) (@Async *).*(..));
|
||||
|
||||
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod();
|
||||
|
||||
declare error:
|
||||
execution(@Async !(void||Future) *(..)):
|
||||
"Only methods that return void or Future may have an @Async annotation";
|
||||
|
||||
declare warning:
|
||||
execution(!(void||Future) (@Async *).*(..)):
|
||||
"Methods in a class marked with @Async that do not return void or Future will be routed synchronously";
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
|
||||
/**
|
||||
* Aspect to route methods based on 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
|
||||
* to be routed asynchronously must return either void, {@link Future},
|
||||
* 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.
|
||||
* If, however, a class marked with <code>@Async</code> contains a method that
|
||||
* violates this constraint, it produces only a warning.
|
||||
*
|
||||
* @author Ramnivas Laddad
|
||||
* @since 3.0.5
|
||||
*/
|
||||
public aspect AnnotationAsyncExecutionAspect extends AbstractAsyncExecutionAspect {
|
||||
|
||||
private pointcut asyncMarkedMethod()
|
||||
: execution(@Async (void || Future+) *(..));
|
||||
|
||||
private pointcut asyncTypeMarkedMethod()
|
||||
: execution((void || Future+) (@Async *).*(..));
|
||||
|
||||
public pointcut asyncMethod() : asyncMarkedMethod() || asyncTypeMarkedMethod();
|
||||
|
||||
declare error:
|
||||
execution(@Async !(void||Future) *(..)):
|
||||
"Only methods that return void or Future may have an @Async annotation";
|
||||
|
||||
declare warning:
|
||||
execution(!(void||Future) (@Async *).*(..)):
|
||||
"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.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
|
||||
/**
|
||||
* Abstract superaspect for AspectJ transaction aspects. Concrete
|
||||
* subaspects will implement the <code>transactionalMethodExecution()</code>
|
||||
* pointcut using a strategy such as Java 5 annotations.
|
||||
*
|
||||
* <p>Suitable for use inside or outside the Spring IoC container.
|
||||
* Set the "transactionManager" property appropriately, allowing
|
||||
* use of any transaction implementation supported by Spring.
|
||||
*
|
||||
* <p><b>NB:</b> If a method implements an interface that is itself
|
||||
* transactionally annotated, the relevant Spring transaction attribute
|
||||
* 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
|
||||
* transaction annotations should be added to classes, rather than business
|
||||
* interfaces, as they are an implementation detail rather than a contract
|
||||
* specification validation.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {
|
||||
|
||||
/**
|
||||
* Construct object using the given transaction metadata retrieval strategy.
|
||||
* @param tas TransactionAttributeSource implementation, retrieving Spring
|
||||
* transaction metadata for each joinpoint. Write the subclass to pass in null
|
||||
* if it's intended to be configured by Setter Injection.
|
||||
*/
|
||||
protected AbstractTransactionAspect(TransactionAttributeSource tas) {
|
||||
setTransactionAttributeSource(tas);
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
before(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
|
||||
try {
|
||||
completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
|
||||
}
|
||||
catch (Throwable t2) {
|
||||
logger.error("Failed to close transaction after throwing in a transactional method", t2);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) returning() : transactionalMethodExecution(txObject) {
|
||||
commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete subaspects must implement this pointcut, to identify
|
||||
* transactional methods. For each selected joinpoint, TransactionMetadata
|
||||
* will be retrieved using Spring's TransactionAttributeSource interface.
|
||||
*/
|
||||
protected abstract pointcut transactionalMethodExecution(Object txObject);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.aspectj.lang.annotation.SuppressAjWarnings;
|
||||
import org.aspectj.lang.reflect.MethodSignature;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttributeSource;
|
||||
|
||||
/**
|
||||
* Abstract superaspect for AspectJ transaction aspects. Concrete
|
||||
* subaspects will implement the <code>transactionalMethodExecution()</code>
|
||||
* pointcut using a strategy such as Java 5 annotations.
|
||||
*
|
||||
* <p>Suitable for use inside or outside the Spring IoC container.
|
||||
* Set the "transactionManager" property appropriately, allowing
|
||||
* use of any transaction implementation supported by Spring.
|
||||
*
|
||||
* <p><b>NB:</b> If a method implements an interface that is itself
|
||||
* transactionally annotated, the relevant Spring transaction attribute
|
||||
* 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
|
||||
* transaction annotations should be added to classes, rather than business
|
||||
* interfaces, as they are an implementation detail rather than a contract
|
||||
* specification validation.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract aspect AbstractTransactionAspect extends TransactionAspectSupport {
|
||||
|
||||
/**
|
||||
* Construct object using the given transaction metadata retrieval strategy.
|
||||
* @param tas TransactionAttributeSource implementation, retrieving Spring
|
||||
* transaction metadata for each joinpoint. Write the subclass to pass in null
|
||||
* if it's intended to be configured by Setter Injection.
|
||||
*/
|
||||
protected AbstractTransactionAspect(TransactionAttributeSource tas) {
|
||||
setTransactionAttributeSource(tas);
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
before(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
|
||||
Method method = methodSignature.getMethod();
|
||||
TransactionInfo txInfo = createTransactionIfNecessary(method, txObject.getClass());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) throwing(Throwable t) : transactionalMethodExecution(txObject) {
|
||||
try {
|
||||
completeTransactionAfterThrowing(TransactionAspectSupport.currentTransactionInfo(), t);
|
||||
}
|
||||
catch (Throwable t2) {
|
||||
logger.error("Failed to close transaction after throwing in a transactional method", t2);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) returning() : transactionalMethodExecution(txObject) {
|
||||
commitTransactionAfterReturning(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
@SuppressAjWarnings("adviceDidNotMatch")
|
||||
after(Object txObject) : transactionalMethodExecution(txObject) {
|
||||
cleanupTransactionInfo(TransactionAspectSupport.currentTransactionInfo());
|
||||
}
|
||||
|
||||
/**
|
||||
* Concrete subaspects must implement this pointcut, to identify
|
||||
* transactional methods. For each selected joinpoint, TransactionMetadata
|
||||
* will be retrieved using Spring's TransactionAttributeSource interface.
|
||||
*/
|
||||
protected abstract pointcut transactionalMethodExecution(Object txObject);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
|
||||
*
|
||||
* <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 implements. AspectJ follows Java's rule that annotations on
|
||||
* interfaces are <i>not</i> inherited.
|
||||
*
|
||||
* <p>An @Transactional annotation on a class specifies the default transaction
|
||||
* 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
|
||||
* default transaction semantics given by the class annotation (if present).
|
||||
* Any method may be annotated (regardless of visibility).
|
||||
* Annotating non-public methods directly is the only way
|
||||
* to get transaction demarcation for the execution of such operations.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
* @see org.springframework.transaction.annotation.Transactional
|
||||
*/
|
||||
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
||||
|
||||
public AnnotationTransactionAspect() {
|
||||
super(new AnnotationTransactionAttributeSource(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the execution of any public method in a type with the
|
||||
* Transactional annotation, or any subtype of a type with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
|
||||
execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfTransactionalMethod() :
|
||||
execution(@Transactional * *(..));
|
||||
|
||||
/**
|
||||
* Definition of pointcut from super aspect - matched join points
|
||||
* will have Spring transaction management applied.
|
||||
*/
|
||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||
|| executionOfTransactionalMethod() )
|
||||
&& this(txObject);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Concrete AspectJ transaction aspect using Spring's @Transactional annotation.
|
||||
*
|
||||
* <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 implements. AspectJ follows Java's rule that annotations on
|
||||
* interfaces are <i>not</i> inherited.
|
||||
*
|
||||
* <p>An @Transactional annotation on a class specifies the default transaction
|
||||
* 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
|
||||
* default transaction semantics given by the class annotation (if present).
|
||||
* Any method may be annotated (regardless of visibility).
|
||||
* Annotating non-public methods directly is the only way
|
||||
* to get transaction demarcation for the execution of such operations.
|
||||
*
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
* @see org.springframework.transaction.annotation.Transactional
|
||||
*/
|
||||
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect {
|
||||
|
||||
public AnnotationTransactionAspect() {
|
||||
super(new AnnotationTransactionAttributeSource(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the execution of any public method in a type with the
|
||||
* Transactional annotation, or any subtype of a type with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfAnyPublicMethodInAtTransactionalType() :
|
||||
execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *);
|
||||
|
||||
/**
|
||||
* Matches the execution of any method with the
|
||||
* Transactional annotation.
|
||||
*/
|
||||
private pointcut executionOfTransactionalMethod() :
|
||||
execution(@Transactional * *(..));
|
||||
|
||||
/**
|
||||
* Definition of pointcut from super aspect - matched join points
|
||||
* will have Spring transaction management applied.
|
||||
*/
|
||||
protected pointcut transactionalMethodExecution(Object txObject) :
|
||||
(executionOfAnyPublicMethodInAtTransactionalType()
|
||||
|| executionOfTransactionalMethod() )
|
||||
&& this(txObject);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
public class AutoProxyWithCodeStyleAspectsTests extends TestCase {
|
||||
|
||||
public void testNoAutoproxyingOfAjcCompiledAspects() {
|
||||
new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml");
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
public class AutoProxyWithCodeStyleAspectsTests extends TestCase {
|
||||
|
||||
public void testNoAutoproxyingOfAjcCompiledAspects() {
|
||||
new ClassPathXmlApplicationContext("org/springframework/aop/aspectj/autoproxy/ajcAutoproxyTests.xml");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
public aspect CodeStyleAspect {
|
||||
|
||||
private String foo;
|
||||
|
||||
pointcut somePC() : call(* someMethod());
|
||||
|
||||
before() : somePC() {
|
||||
System.out.println("match");
|
||||
}
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.aop.aspectj.autoproxy;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
*/
|
||||
public aspect CodeStyleAspect {
|
||||
|
||||
private String foo;
|
||||
|
||||
pointcut somePC() : call(* someMethod());
|
||||
|
||||
before() : somePC() {
|
||||
System.out.println("match");
|
||||
}
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SpringConfiguredWithAutoProxyingTests extends TestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
||||
}
|
||||
|
||||
public void testSpringConfiguredAndAutoProxyUsedTogether() {
|
||||
; // set up is sufficient to trigger failure if this is going to fail...
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.aspectj;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SpringConfiguredWithAutoProxyingTests extends TestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
new ClassPathXmlApplicationContext("org/springframework/beans/factory/aspectj/springConfigured.xml");
|
||||
}
|
||||
|
||||
public void testSpringConfiguredAndAutoProxyUsedTogether() {
|
||||
; // 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.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class AspectJAnnotationTest extends AbstractAnnotationTest {
|
||||
|
||||
|
||||
@Override
|
||||
protected ApplicationContext getApplicationContext() {
|
||||
return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.aspectj;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class AspectJAnnotationTest extends AbstractAnnotationTest {
|
||||
|
||||
|
||||
@Override
|
||||
protected ApplicationContext getApplicationContext() {
|
||||
return new GenericXmlApplicationContext("/org/springframework/cache/config/annotation-cache-aspectj.xml");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,138 +1,138 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
@Cacheable("default")
|
||||
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
public static final AtomicLong nullInvocations = new AtomicLong();
|
||||
|
||||
public Object cache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
public Object conditional(int field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void invalidate(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void evictWithException(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", allEntries = true)
|
||||
public void evictAll(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", beforeInvocation = true)
|
||||
public void evictEarly(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0")
|
||||
public void evict(Object arg1, Object arg2) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||
public void invalidateEarly(Object arg1, Object arg2) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#p0")
|
||||
public Object key(Object arg1, Object arg2) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name")
|
||||
public Object name(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||
public Object rootVars(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut("default")
|
||||
public Object update(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||
public Object conditionalUpdate(Object arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Object nullValue(Object arg1) {
|
||||
nullInvocations.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Number nullInvocations() {
|
||||
return nullInvocations.get();
|
||||
}
|
||||
|
||||
public Long throwChecked(Object arg1) throws Exception {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
public Long throwUnchecked(Object arg1) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||
public Object multiCache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||
public Object multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||
public Object multiUpdate(Object arg1) {
|
||||
return arg1;
|
||||
}
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
@Cacheable("default")
|
||||
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
public static final AtomicLong nullInvocations = new AtomicLong();
|
||||
|
||||
public Object cache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
public Object conditional(int field) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void invalidate(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void evictWithException(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", allEntries = true)
|
||||
public void evictAll(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", beforeInvocation = true)
|
||||
public void evictEarly(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0")
|
||||
public void evict(Object arg1, Object arg2) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||
public void invalidateEarly(Object arg1, Object arg2) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#p0")
|
||||
public Object key(Object arg1, Object arg2) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.caches[0].name")
|
||||
public Object name(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||
public Object rootVars(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut("default")
|
||||
public Object update(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||
public Object conditionalUpdate(Object arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Object nullValue(Object arg1) {
|
||||
nullInvocations.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Number nullInvocations() {
|
||||
return nullInvocations.get();
|
||||
}
|
||||
|
||||
public Long throwChecked(Object arg1) throws Exception {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
public Long throwUnchecked(Object arg1) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||
public Object multiCache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||
public Object multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Object multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||
public Object multiUpdate(Object arg1) {
|
||||
return arg1;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
/**
|
||||
* Basic service interface.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public interface CacheableService<T> {
|
||||
|
||||
T cache(Object arg1);
|
||||
|
||||
void invalidate(Object arg1);
|
||||
|
||||
void evictEarly(Object arg1);
|
||||
|
||||
void evictAll(Object arg1);
|
||||
|
||||
void evictWithException(Object arg1);
|
||||
|
||||
void evict(Object arg1, Object arg2);
|
||||
|
||||
void invalidateEarly(Object arg1, Object arg2);
|
||||
|
||||
T conditional(int field);
|
||||
|
||||
T key(Object arg1, Object arg2);
|
||||
|
||||
T name(Object arg1);
|
||||
|
||||
T nullValue(Object arg1);
|
||||
|
||||
T update(Object arg1);
|
||||
|
||||
T conditionalUpdate(Object arg2);
|
||||
|
||||
Number nullInvocations();
|
||||
|
||||
T rootVars(Object arg1);
|
||||
|
||||
T throwChecked(Object arg1) throws Exception;
|
||||
|
||||
T throwUnchecked(Object arg1);
|
||||
|
||||
// multi annotations
|
||||
T multiCache(Object arg1);
|
||||
|
||||
T multiEvict(Object arg1);
|
||||
|
||||
T multiCacheAndEvict(Object arg1);
|
||||
|
||||
T multiConditionalCacheAndEvict(Object arg1);
|
||||
|
||||
T multiUpdate(Object arg1);
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
/**
|
||||
* Basic service interface.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public interface CacheableService<T> {
|
||||
|
||||
T cache(Object arg1);
|
||||
|
||||
void invalidate(Object arg1);
|
||||
|
||||
void evictEarly(Object arg1);
|
||||
|
||||
void evictAll(Object arg1);
|
||||
|
||||
void evictWithException(Object arg1);
|
||||
|
||||
void evict(Object arg1, Object arg2);
|
||||
|
||||
void invalidateEarly(Object arg1, Object arg2);
|
||||
|
||||
T conditional(int field);
|
||||
|
||||
T key(Object arg1, Object arg2);
|
||||
|
||||
T name(Object arg1);
|
||||
|
||||
T nullValue(Object arg1);
|
||||
|
||||
T update(Object arg1);
|
||||
|
||||
T conditionalUpdate(Object arg2);
|
||||
|
||||
Number nullInvocations();
|
||||
|
||||
T rootVars(Object arg1);
|
||||
|
||||
T throwChecked(Object arg1) throws Exception;
|
||||
|
||||
T throwUnchecked(Object arg1);
|
||||
|
||||
// multi annotations
|
||||
T multiCache(Object arg1);
|
||||
|
||||
T multiEvict(Object arg1);
|
||||
|
||||
T multiCacheAndEvict(Object arg1);
|
||||
|
||||
T multiConditionalCacheAndEvict(Object arg1);
|
||||
|
||||
T multiUpdate(Object arg1);
|
||||
}
|
||||
@@ -1,144 +1,144 @@
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* Simple cacheable service
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DefaultCacheableService implements CacheableService<Long> {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
private final AtomicLong nullInvocations = new AtomicLong();
|
||||
|
||||
@Cacheable("default")
|
||||
public Long cache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void invalidate(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void evictWithException(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", allEntries = true)
|
||||
public void evictAll(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", beforeInvocation = true)
|
||||
public void evictEarly(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0")
|
||||
public void evict(Object arg1, Object arg2) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||
public void invalidateEarly(Object arg1, Object arg2) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", condition = "#classField == 3")
|
||||
public Long conditional(int classField) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#p0")
|
||||
public Long key(Object arg1, Object arg2) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName")
|
||||
public Long name(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||
public Long rootVars(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut("default")
|
||||
public Long update(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||
public Long conditionalUpdate(Object arg) {
|
||||
return Long.valueOf(arg.toString());
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long nullValue(Object arg1) {
|
||||
nullInvocations.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Number nullInvocations() {
|
||||
return nullInvocations.get();
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long throwChecked(Object arg1) throws Exception {
|
||||
throw new Exception(arg1.toString());
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long throwUnchecked(Object arg1) {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||
public Long multiCache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||
public Long multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||
public Long multiCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Long multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||
public Long multiUpdate(Object arg1) {
|
||||
return Long.valueOf(arg1.toString());
|
||||
}
|
||||
/*
|
||||
* Copyright 2010-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.CachePut;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.cache.annotation.Caching;
|
||||
|
||||
/**
|
||||
* Simple cacheable service
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DefaultCacheableService implements CacheableService<Long> {
|
||||
|
||||
private final AtomicLong counter = new AtomicLong();
|
||||
private final AtomicLong nullInvocations = new AtomicLong();
|
||||
|
||||
@Cacheable("default")
|
||||
public Long cache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void invalidate(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict("default")
|
||||
public void evictWithException(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should NOT occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", allEntries = true)
|
||||
public void evictAll(Object arg1) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", beforeInvocation = true)
|
||||
public void evictEarly(Object arg1) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0")
|
||||
public void evict(Object arg1, Object arg2) {
|
||||
}
|
||||
|
||||
@CacheEvict(value = "default", key = "#p0", beforeInvocation = true)
|
||||
public void invalidateEarly(Object arg1, Object arg2) {
|
||||
throw new RuntimeException("exception thrown - evict should still occur");
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", condition = "#classField == 3")
|
||||
public Long conditional(int classField) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#p0")
|
||||
public Long key(Object arg1, Object arg2) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName")
|
||||
public Long name(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Cacheable(value = "default", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
|
||||
public Long rootVars(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut("default")
|
||||
public Long update(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@CachePut(value = "default", condition = "#arg.equals(3)")
|
||||
public Long conditionalUpdate(Object arg) {
|
||||
return Long.valueOf(arg.toString());
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long nullValue(Object arg1) {
|
||||
nullInvocations.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
|
||||
public Number nullInvocations() {
|
||||
return nullInvocations.get();
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long throwChecked(Object arg1) throws Exception {
|
||||
throw new Exception(arg1.toString());
|
||||
}
|
||||
|
||||
@Cacheable("default")
|
||||
public Long throwUnchecked(Object arg1) {
|
||||
throw new UnsupportedOperationException(arg1.toString());
|
||||
}
|
||||
|
||||
// multi annotations
|
||||
|
||||
@Caching(cacheable = { @Cacheable("primary"), @Cacheable("secondary") })
|
||||
public Long multiCache(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
|
||||
public Long multiEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
|
||||
public Long multiCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
|
||||
public Long multiConditionalCacheAndEvict(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Caching(put = { @CachePut("primary"), @CachePut("secondary") })
|
||||
public Long multiUpdate(Object arg1) {
|
||||
return Long.valueOf(arg1.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,146 +1,146 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test for static entity mocking framework.
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
@MockStaticEntityMethods
|
||||
@RunWith(JUnit4.class)
|
||||
public class AnnotationDrivenStaticEntityMockingControlTest {
|
||||
|
||||
@Test
|
||||
public void testNoArgIntReturn() {
|
||||
int expectedCount = 13;
|
||||
Person.countPeople();
|
||||
expectReturn(expectedCount);
|
||||
playback();
|
||||
Assert.assertEquals(expectedCount, Person.countPeople());
|
||||
}
|
||||
|
||||
@Test(expected=PersistenceException.class)
|
||||
public void testNoArgThrows() {
|
||||
Person.countPeople();
|
||||
expectThrow(new PersistenceException());
|
||||
playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodMatches() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLongSeriesOfCalls() {
|
||||
long id1 = 13;
|
||||
long id2 = 24;
|
||||
Person found1 = new Person();
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person found2 = new Person();
|
||||
Person.findPerson(id2);
|
||||
expectReturn(found2);
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person.countPeople();
|
||||
expectReturn(0);
|
||||
playback();
|
||||
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(found2, Person.findPerson(id2));
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(0, Person.countPeople());
|
||||
}
|
||||
|
||||
// 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
|
||||
// this method returns, failing the test case
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
try {
|
||||
new Delegate().testArgMethodNoMatchExpectReturn();
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
new Delegate().testArgMethodNoMatchExpectThrow();
|
||||
}
|
||||
|
||||
private void called(Person found, long id) {
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentrant() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
called(found, id);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testRejectUnexpectedCall() {
|
||||
new Delegate().rejectUnexpectedCall();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testFailTooFewCalls() {
|
||||
new Delegate().failTooFewCalls();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
// Test that verification check doesn't blow up if no replay() call happened
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverReplay() {
|
||||
new Delegate().doesntEverReplay();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverSetReturn() {
|
||||
new Delegate().doesntEverSetReturn();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import static org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test for static entity mocking framework.
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*
|
||||
*/
|
||||
@MockStaticEntityMethods
|
||||
@RunWith(JUnit4.class)
|
||||
public class AnnotationDrivenStaticEntityMockingControlTest {
|
||||
|
||||
@Test
|
||||
public void testNoArgIntReturn() {
|
||||
int expectedCount = 13;
|
||||
Person.countPeople();
|
||||
expectReturn(expectedCount);
|
||||
playback();
|
||||
Assert.assertEquals(expectedCount, Person.countPeople());
|
||||
}
|
||||
|
||||
@Test(expected=PersistenceException.class)
|
||||
public void testNoArgThrows() {
|
||||
Person.countPeople();
|
||||
expectThrow(new PersistenceException());
|
||||
playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodMatches() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLongSeriesOfCalls() {
|
||||
long id1 = 13;
|
||||
long id2 = 24;
|
||||
Person found1 = new Person();
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person found2 = new Person();
|
||||
Person.findPerson(id2);
|
||||
expectReturn(found2);
|
||||
Person.findPerson(id1);
|
||||
expectReturn(found1);
|
||||
Person.countPeople();
|
||||
expectReturn(0);
|
||||
playback();
|
||||
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(found2, Person.findPerson(id2));
|
||||
Assert.assertEquals(found1, Person.findPerson(id1));
|
||||
Assert.assertEquals(0, Person.countPeople());
|
||||
}
|
||||
|
||||
// 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
|
||||
// this method returns, failing the test case
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
try {
|
||||
new Delegate().testArgMethodNoMatchExpectReturn();
|
||||
Assert.fail();
|
||||
} catch (IllegalArgumentException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
new Delegate().testArgMethodNoMatchExpectThrow();
|
||||
}
|
||||
|
||||
private void called(Person found, long id) {
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReentrant() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
expectReturn(found);
|
||||
playback();
|
||||
called(found, id);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testRejectUnexpectedCall() {
|
||||
new Delegate().rejectUnexpectedCall();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testFailTooFewCalls() {
|
||||
new Delegate().failTooFewCalls();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmpty() {
|
||||
// Test that verification check doesn't blow up if no replay() call happened
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverReplay() {
|
||||
new Delegate().doesntEverReplay();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalStateException.class)
|
||||
public void testDoesntEverSetReturn() {
|
||||
new Delegate().doesntEverSetReturn();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,92 +1,92 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
||||
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
||||
|
||||
//Used because verification failures occur after method returns,
|
||||
//so we can't test for them in the test case itself
|
||||
@MockStaticEntityMethods
|
||||
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
||||
public class Delegate {
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failTooFewCalls() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverReplay() {
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverSetReturn() {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectUnexpectedCall() {
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test(expected=RemoteException.class)
|
||||
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
// No calls to allow verification failure
|
||||
throw new RemoteException();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.staticmock.AnnotationDrivenStaticEntityMockingControl;
|
||||
import org.springframework.mock.staticmock.MockStaticEntityMethods;
|
||||
|
||||
//Used because verification failures occur after method returns,
|
||||
//so we can't test for them in the test case itself
|
||||
@MockStaticEntityMethods
|
||||
@Ignore // This isn't meant for direct testing; rather it is driven from AnnotationDrivenStaticEntityMockingControl
|
||||
public class Delegate {
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectReturn() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArgMethodNoMatchExpectThrow() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectThrow(new PersistenceException());
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failTooFewCalls() {
|
||||
long id = 13;
|
||||
Person found = new Person();
|
||||
Person.findPerson(id);
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(found);
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.expectReturn(25);
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Assert.assertEquals(found, Person.findPerson(id));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverReplay() {
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doesntEverSetReturn() {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rejectUnexpectedCall() {
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
Person.countPeople();
|
||||
}
|
||||
|
||||
@Test(expected=RemoteException.class)
|
||||
public void testVerificationFailsEvenWhenTestFailsInExpectedManner() throws RemoteException {
|
||||
Person.countPeople();
|
||||
AnnotationDrivenStaticEntityMockingControl.playback();
|
||||
// No calls to allow verification failure
|
||||
throw new RemoteException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
}
|
||||
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
privileged aspect Person_Roo_Entity {
|
||||
|
||||
@javax.persistence.PersistenceContext
|
||||
transient javax.persistence.EntityManager Person.entityManager;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
||||
@javax.persistence.Column(name = "id")
|
||||
private java.lang.Long Person.id;
|
||||
|
||||
@javax.persistence.Version
|
||||
@javax.persistence.Column(name = "version")
|
||||
private java.lang.Integer Person.version;
|
||||
|
||||
public java.lang.Long Person.getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void Person.setId(java.lang.Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public java.lang.Integer Person.getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void Person.setVersion(java.lang.Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
this.entityManager.persist(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
this.entityManager.remove(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
this.entityManager.flush();
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
Person merged = this.entityManager.merge(this);
|
||||
this.entityManager.flush();
|
||||
this.id = merged.getId();
|
||||
}
|
||||
|
||||
public static long Person.countPeople() {
|
||||
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?)");
|
||||
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findAllPeople() {
|
||||
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?)");
|
||||
return em.createQuery("select o from Person o").getResultList();
|
||||
}
|
||||
|
||||
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");
|
||||
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?)");
|
||||
return em.find(Person.class, id);
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
||||
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?)");
|
||||
return em.createQuery("select o from Person o").setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.mock.staticmock;
|
||||
|
||||
privileged aspect Person_Roo_Entity {
|
||||
|
||||
@javax.persistence.PersistenceContext
|
||||
transient javax.persistence.EntityManager Person.entityManager;
|
||||
|
||||
@javax.persistence.Id
|
||||
@javax.persistence.GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
|
||||
@javax.persistence.Column(name = "id")
|
||||
private java.lang.Long Person.id;
|
||||
|
||||
@javax.persistence.Version
|
||||
@javax.persistence.Column(name = "version")
|
||||
private java.lang.Integer Person.version;
|
||||
|
||||
public java.lang.Long Person.getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void Person.setId(java.lang.Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public java.lang.Integer Person.getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void Person.setVersion(java.lang.Integer version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
this.entityManager.persist(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
this.entityManager.remove(this);
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
this.entityManager.flush();
|
||||
}
|
||||
|
||||
@org.springframework.transaction.annotation.Transactional
|
||||
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?)");
|
||||
Person merged = this.entityManager.merge(this);
|
||||
this.entityManager.flush();
|
||||
this.id = merged.getId();
|
||||
}
|
||||
|
||||
public static long Person.countPeople() {
|
||||
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?)");
|
||||
return (Long) em.createQuery("select count(o) from Person o").getSingleResult();
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findAllPeople() {
|
||||
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?)");
|
||||
return em.createQuery("select o from Person o").getResultList();
|
||||
}
|
||||
|
||||
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");
|
||||
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?)");
|
||||
return em.find(Person.class, id);
|
||||
}
|
||||
|
||||
public static java.util.List<Person> Person.findPersonEntries(int firstResult, int maxResults) {
|
||||
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?)");
|
||||
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.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class AnnotationAsyncExecutionAspectTests {
|
||||
|
||||
private static final long WAIT_TIME = 1000; //milli seconds
|
||||
|
||||
private CountingExecutor executor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executor = new CountingExecutor();
|
||||
AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodGetsRoutedAsynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.incrementAsync();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
// No need to executor.waitForCompletion() as future.get() will have the same effect
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void syncMethodGetsRoutedSynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.increment();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void voidMethodInAsyncClassGetsRoutedAsynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
obj.increment();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
int returnValue = obj.return5();
|
||||
assertEquals(5, returnValue);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class CountingExecutor extends SimpleAsyncTaskExecutor {
|
||||
int submitStartCounter;
|
||||
int submitCompleteCounter;
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
submitStartCounter++;
|
||||
Future<T> future = super.submit(task);
|
||||
submitCompleteCounter++;
|
||||
synchronized (this) {
|
||||
notifyAll();
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
public synchronized void waitForCompletion() {
|
||||
try {
|
||||
wait(WAIT_TIME);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ClassWithoutAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
@Async public void incrementAsync() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
@Async public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
|
||||
// It should be an error to attach @Async to a method that returns a non-void
|
||||
// or non-Future.
|
||||
// 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
|
||||
// produces an error message due to the 'declare error' statement
|
||||
// in AnnotationAsyncExecutionAspect
|
||||
// @Async public int getInt() {
|
||||
// return 0;
|
||||
// }
|
||||
}
|
||||
|
||||
@Async
|
||||
static class ClassWithAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
// Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect
|
||||
public int return5() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.aspectj;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import static junit.framework.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.AsyncResult;
|
||||
|
||||
/**
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class AnnotationAsyncExecutionAspectTests {
|
||||
|
||||
private static final long WAIT_TIME = 1000; //milli seconds
|
||||
|
||||
private CountingExecutor executor;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
executor = new CountingExecutor();
|
||||
AnnotationAsyncExecutionAspect.aspectOf().setExecutor(executor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodGetsRoutedAsynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.incrementAsync();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void asyncMethodReturningFutureGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
// No need to executor.waitForCompletion() as future.get() will have the same effect
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void syncMethodGetsRoutedSynchronously() {
|
||||
ClassWithoutAsyncAnnotation obj = new ClassWithoutAsyncAnnotation();
|
||||
obj.increment();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void voidMethodInAsyncClassGetsRoutedAsynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
obj.increment();
|
||||
executor.waitForCompletion();
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningFutureInAsyncClassGetsRoutedAsynchronouslyAndReturnsAFuture() throws InterruptedException, ExecutionException {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
Future<Integer> future = obj.incrementReturningAFuture();
|
||||
assertEquals(5, future.get().intValue());
|
||||
assertEquals(1, obj.counter);
|
||||
assertEquals(1, executor.submitStartCounter);
|
||||
assertEquals(1, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodReturningNonVoidNonFutureInAsyncClassGetsRoutedSynchronously() {
|
||||
ClassWithAsyncAnnotation obj = new ClassWithAsyncAnnotation();
|
||||
int returnValue = obj.return5();
|
||||
assertEquals(5, returnValue);
|
||||
assertEquals(0, executor.submitStartCounter);
|
||||
assertEquals(0, executor.submitCompleteCounter);
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class CountingExecutor extends SimpleAsyncTaskExecutor {
|
||||
int submitStartCounter;
|
||||
int submitCompleteCounter;
|
||||
|
||||
@Override
|
||||
public <T> Future<T> submit(Callable<T> task) {
|
||||
submitStartCounter++;
|
||||
Future<T> future = super.submit(task);
|
||||
submitCompleteCounter++;
|
||||
synchronized (this) {
|
||||
notifyAll();
|
||||
}
|
||||
return future;
|
||||
}
|
||||
|
||||
public synchronized void waitForCompletion() {
|
||||
try {
|
||||
wait(WAIT_TIME);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail("Didn't finish the async job in " + WAIT_TIME + " milliseconds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class ClassWithoutAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
@Async public void incrementAsync() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
@Async public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
|
||||
// It should be an error to attach @Async to a method that returns a non-void
|
||||
// or non-Future.
|
||||
// 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
|
||||
// produces an error message due to the 'declare error' statement
|
||||
// in AnnotationAsyncExecutionAspect
|
||||
// @Async public int getInt() {
|
||||
// return 0;
|
||||
// }
|
||||
}
|
||||
|
||||
@Async
|
||||
static class ClassWithAsyncAnnotation {
|
||||
int counter;
|
||||
|
||||
public void increment() {
|
||||
counter++;
|
||||
}
|
||||
|
||||
// Manually check that there is a warning from the 'declare warning' statement in AnnotationAsynchExecutionAspect
|
||||
public int return5() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public Future<Integer> incrementReturningAFuture() {
|
||||
counter++;
|
||||
return new AsyncResult<Integer>(5);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Created on 11 Sep 2006 by Adrian Colyer
|
||||
*/
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClassWithPrivateAnnotatedMember {
|
||||
|
||||
public void doSomething() {
|
||||
doInTransaction();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void doInTransaction() {}
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Created on 11 Sep 2006 by Adrian Colyer
|
||||
*/
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClassWithPrivateAnnotatedMember {
|
||||
|
||||
public void doSomething() {
|
||||
doInTransaction();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void doInTransaction() {}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Created on 11 Sep 2006 by Adrian Colyer
|
||||
*/
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClassWithProtectedAnnotatedMember {
|
||||
|
||||
public void doSomething() {
|
||||
doInTransaction();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected void doInTransaction() {}
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2006 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Created on 11 Sep 2006 by Adrian Colyer
|
||||
*/
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Adrian Colyer
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ClassWithProtectedAnnotatedMember {
|
||||
|
||||
public void doSomething() {
|
||||
doInTransaction();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
protected void doInTransaction() {}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Transactional
|
||||
public interface ITransactional {
|
||||
|
||||
Object echo(Throwable t) throws Throwable;
|
||||
|
||||
}
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Transactional
|
||||
public interface ITransactional {
|
||||
|
||||
Object echo(Throwable t) throws Throwable;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class MethodAnnotationOnClassWithNoInterface {
|
||||
|
||||
@Transactional(rollbackFor=InterruptedException.class)
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void noTransactionAttribute() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class MethodAnnotationOnClassWithNoInterface {
|
||||
|
||||
@Transactional(rollbackFor=InterruptedException.class)
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void noTransactionAttribute() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,261 +1,261 @@
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.springframework.transaction.CallCountingTransactionManager;
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttribute;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private TransactionAspectSupport transactionAspect;
|
||||
|
||||
private CallCountingTransactionManager txManager;
|
||||
|
||||
private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
|
||||
|
||||
private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
|
||||
|
||||
private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
|
||||
|
||||
private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
|
||||
|
||||
|
||||
public void setAnnotationOnlyOnClassWithNoInterface(
|
||||
TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
|
||||
this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
|
||||
}
|
||||
|
||||
public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
|
||||
this.beanWithAnnotatedProtectedMethod = aBean;
|
||||
}
|
||||
|
||||
public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
|
||||
this.beanWithAnnotatedPrivateMethod = aBean;
|
||||
}
|
||||
|
||||
public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
|
||||
this.transactionAspect = transactionAspect;
|
||||
this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
|
||||
}
|
||||
|
||||
public TransactionAspectSupport getTransactionAspect() {
|
||||
return this.transactionAspect;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getConfigPath() {
|
||||
return "TransactionAspectTests-context.xml";
|
||||
}
|
||||
|
||||
|
||||
public void testCommitOnAnnotatedClass() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
annotationOnlyOnClassWithNoInterface.echo(null);
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
beanWithAnnotatedProtectedMethod.doInTransaction();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
beanWithAnnotatedPrivateMethod.doSomething();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0,txManager.begun);
|
||||
annotationOnlyOnClassWithNoInterface.nonTransactionalMethod();
|
||||
assertEquals(0,txManager.begun);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
methodAnnotationOnly.echo(null);
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
|
||||
public static class NotTransactional {
|
||||
public void noop() {
|
||||
}
|
||||
}
|
||||
|
||||
public void testNotTransactional() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
new NotTransactional().noop();
|
||||
assertEquals(0, txManager.begun);
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultCommitOnAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return annotationOnlyOnClassWithNoInterface.echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException());
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
||||
public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public static class ImplementsAnnotatedInterface implements ITransactional {
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
// testRollback(new TransactionOperationCallback() {
|
||||
// public Object performTransactionalOperation() throws Throwable {
|
||||
// return new ImplementsAnnotatedInterface().echo(new Exception());
|
||||
// }
|
||||
// }, false);
|
||||
|
||||
final Exception ex = new Exception();
|
||||
testNotTransactional(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new ImplementsAnnotatedInterface().echo(ex);
|
||||
}
|
||||
}, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: resolution does not occur. Thus we can't make a class transactional if
|
||||
* it implements a transactionally annotated interface. This behaviour could only
|
||||
* be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
|
||||
* @throws SecurityException
|
||||
* @throws NoSuchMethodException
|
||||
*/
|
||||
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException {
|
||||
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
|
||||
Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
|
||||
TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
|
||||
assertNull(ta);
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
// testRollback(new TransactionOperationCallback() {
|
||||
// public Object performTransactionalOperation() throws Throwable {
|
||||
// return new ImplementsAnnotatedInterface().echo(new RuntimeException());
|
||||
// }
|
||||
// }, true);
|
||||
|
||||
final Exception rollbackProvokingException = new RuntimeException();
|
||||
testNotTransactional(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new ImplementsAnnotatedInterface().echo(rollbackProvokingException);
|
||||
}
|
||||
}, rollbackProvokingException);
|
||||
}
|
||||
|
||||
|
||||
protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
try {
|
||||
toc.performTransactionalOperation();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
catch (Throwable caught) {
|
||||
if (caught instanceof AssertionFailedError) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rollback) {
|
||||
assertEquals(1, txManager.rollbacks);
|
||||
}
|
||||
assertEquals(1, txManager.begun);
|
||||
}
|
||||
|
||||
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
try {
|
||||
toc.performTransactionalOperation();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (expected == null) {
|
||||
fail("Expected " + expected);
|
||||
}
|
||||
assertSame(expected, t);
|
||||
}
|
||||
finally {
|
||||
assertEquals(0, txManager.begun);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private interface TransactionOperationCallback {
|
||||
|
||||
Object performTransactionalOperation() throws Throwable;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import junit.framework.AssertionFailedError;
|
||||
|
||||
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
|
||||
import org.springframework.transaction.CallCountingTransactionManager;
|
||||
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
import org.springframework.transaction.interceptor.TransactionAttribute;
|
||||
|
||||
/**
|
||||
* @author Rod Johnson
|
||||
* @author Ramnivas Laddad
|
||||
*/
|
||||
public class TransactionAspectTests extends AbstractDependencyInjectionSpringContextTests {
|
||||
|
||||
private TransactionAspectSupport transactionAspect;
|
||||
|
||||
private CallCountingTransactionManager txManager;
|
||||
|
||||
private TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface;
|
||||
|
||||
private ClassWithProtectedAnnotatedMember beanWithAnnotatedProtectedMethod;
|
||||
|
||||
private ClassWithPrivateAnnotatedMember beanWithAnnotatedPrivateMethod;
|
||||
|
||||
private MethodAnnotationOnClassWithNoInterface methodAnnotationOnly = new MethodAnnotationOnClassWithNoInterface();
|
||||
|
||||
|
||||
public void setAnnotationOnlyOnClassWithNoInterface(
|
||||
TransactionalAnnotationOnlyOnClassWithNoInterface annotationOnlyOnClassWithNoInterface) {
|
||||
this.annotationOnlyOnClassWithNoInterface = annotationOnlyOnClassWithNoInterface;
|
||||
}
|
||||
|
||||
public void setClassWithAnnotatedProtectedMethod(ClassWithProtectedAnnotatedMember aBean) {
|
||||
this.beanWithAnnotatedProtectedMethod = aBean;
|
||||
}
|
||||
|
||||
public void setClassWithAnnotatedPrivateMethod(ClassWithPrivateAnnotatedMember aBean) {
|
||||
this.beanWithAnnotatedPrivateMethod = aBean;
|
||||
}
|
||||
|
||||
public void setTransactionAspect(TransactionAspectSupport transactionAspect) {
|
||||
this.transactionAspect = transactionAspect;
|
||||
this.txManager = (CallCountingTransactionManager) transactionAspect.getTransactionManager();
|
||||
}
|
||||
|
||||
public TransactionAspectSupport getTransactionAspect() {
|
||||
return this.transactionAspect;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getConfigPath() {
|
||||
return "TransactionAspectTests-context.xml";
|
||||
}
|
||||
|
||||
|
||||
public void testCommitOnAnnotatedClass() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
annotationOnlyOnClassWithNoInterface.echo(null);
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedProtectedMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
beanWithAnnotatedProtectedMethod.doInTransaction();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedPrivateMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
beanWithAnnotatedPrivateMethod.doSomething();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
public void testNoCommitOnNonAnnotatedNonPublicMethodInTransactionalType() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0,txManager.begun);
|
||||
annotationOnlyOnClassWithNoInterface.nonTransactionalMethod();
|
||||
assertEquals(0,txManager.begun);
|
||||
}
|
||||
|
||||
public void testCommitOnAnnotatedMethod() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
methodAnnotationOnly.echo(null);
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
|
||||
|
||||
public static class NotTransactional {
|
||||
public void noop() {
|
||||
}
|
||||
}
|
||||
|
||||
public void testNotTransactional() throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
new NotTransactional().noop();
|
||||
assertEquals(0, txManager.begun);
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultCommitOnAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return annotationOnlyOnClassWithNoInterface.echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public void testDefaultRollbackOnAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return annotationOnlyOnClassWithNoInterface.echo(new RuntimeException());
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
||||
public static class SubclassOfClassWithTransactionalAnnotation extends TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnSubclassOfAnnotatedClass() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new SubclassOfClassWithTransactionalAnnotation().echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public static class SubclassOfClassWithTransactionalMethodAnnotation extends MethodAnnotationOnClassWithNoInterface {
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnSubclassOfClassWithTransactionalMethodAnnotated() throws Throwable {
|
||||
testRollback(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new SubclassOfClassWithTransactionalMethodAnnotation().echo(new Exception());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
public static class ImplementsAnnotatedInterface implements ITransactional {
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
public void testDefaultCommitOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
// testRollback(new TransactionOperationCallback() {
|
||||
// public Object performTransactionalOperation() throws Throwable {
|
||||
// return new ImplementsAnnotatedInterface().echo(new Exception());
|
||||
// }
|
||||
// }, false);
|
||||
|
||||
final Exception ex = new Exception();
|
||||
testNotTransactional(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new ImplementsAnnotatedInterface().echo(ex);
|
||||
}
|
||||
}, ex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: resolution does not occur. Thus we can't make a class transactional if
|
||||
* it implements a transactionally annotated interface. This behaviour could only
|
||||
* be changed in AbstractFallbackTransactionAttributeSource in Spring proper.
|
||||
* @throws SecurityException
|
||||
* @throws NoSuchMethodException
|
||||
*/
|
||||
public void testDoesNotResolveTxAnnotationOnMethodFromClassImplementingAnnotatedInterface() throws SecurityException, NoSuchMethodException {
|
||||
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
|
||||
Method m = ImplementsAnnotatedInterface.class.getMethod("echo", Throwable.class);
|
||||
TransactionAttribute ta = atas.getTransactionAttribute(m, ImplementsAnnotatedInterface.class);
|
||||
assertNull(ta);
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultRollbackOnImplementationOfAnnotatedInterface() throws Throwable {
|
||||
// testRollback(new TransactionOperationCallback() {
|
||||
// public Object performTransactionalOperation() throws Throwable {
|
||||
// return new ImplementsAnnotatedInterface().echo(new RuntimeException());
|
||||
// }
|
||||
// }, true);
|
||||
|
||||
final Exception rollbackProvokingException = new RuntimeException();
|
||||
testNotTransactional(new TransactionOperationCallback() {
|
||||
public Object performTransactionalOperation() throws Throwable {
|
||||
return new ImplementsAnnotatedInterface().echo(rollbackProvokingException);
|
||||
}
|
||||
}, rollbackProvokingException);
|
||||
}
|
||||
|
||||
|
||||
protected void testRollback(TransactionOperationCallback toc, boolean rollback) throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
try {
|
||||
toc.performTransactionalOperation();
|
||||
assertEquals(1, txManager.commits);
|
||||
}
|
||||
catch (Throwable caught) {
|
||||
if (caught instanceof AssertionFailedError) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rollback) {
|
||||
assertEquals(1, txManager.rollbacks);
|
||||
}
|
||||
assertEquals(1, txManager.begun);
|
||||
}
|
||||
|
||||
protected void testNotTransactional(TransactionOperationCallback toc, Throwable expected) throws Throwable {
|
||||
txManager.clear();
|
||||
assertEquals(0, txManager.begun);
|
||||
try {
|
||||
toc.performTransactionalOperation();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (expected == null) {
|
||||
fail("Expected " + expected);
|
||||
}
|
||||
assertSame(expected, t);
|
||||
}
|
||||
finally {
|
||||
assertEquals(0, txManager.begun);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private interface TransactionOperationCallback {
|
||||
|
||||
Object performTransactionalOperation() throws Throwable;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Transactional
|
||||
public class TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void nonTransactionalMethod() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package org.springframework.transaction.aspectj;
|
||||
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Transactional
|
||||
public class TransactionalAnnotationOnlyOnClassWithNoInterface {
|
||||
|
||||
public Object echo(Throwable t) throws Throwable {
|
||||
if (t != null) {
|
||||
throw t;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void nonTransactionalMethod() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
Bundle-SymbolicName: org.springframework.aspects
|
||||
Bundle-Name: Spring Aspects
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
javax.persistence;version="[1.0.0,3.0.0)";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
||||
org.springframework.context.*;version=${spring.osgi.range},
|
||||
org.springframework.beans.*;version=${spring.osgi.range},
|
||||
org.springframework.cache.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.springframework.core.*;version=${spring.osgi.range},
|
||||
org.springframework.dao.*;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.transaction.*;version=${spring.osgi.range};resolution:=optional
|
||||
Ignored-Existing-Headers:
|
||||
Bnd-LastModified,
|
||||
Import-Package,
|
||||
Tool
|
||||
Bundle-SymbolicName: org.springframework.aspects
|
||||
Bundle-Name: Spring Aspects
|
||||
Bundle-Vendor: SpringSource
|
||||
Bundle-ManifestVersion: 2
|
||||
Import-Template:
|
||||
javax.persistence;version="[1.0.0,3.0.0)";resolution:=optional,
|
||||
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
|
||||
org.aspectj.*;version=${aj.osgi.range};resolution:=optional,
|
||||
org.springframework.context.*;version=${spring.osgi.range},
|
||||
org.springframework.beans.*;version=${spring.osgi.range},
|
||||
org.springframework.cache.*;version=${spring.osgi.range};resolution:=optional,
|
||||
org.springframework.core.*;version=${spring.osgi.range},
|
||||
org.springframework.dao.*;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.transaction.*;version=${spring.osgi.range};resolution:=optional
|
||||
Ignored-Existing-Headers:
|
||||
Bnd-LastModified,
|
||||
Import-Package,
|
||||
Tool
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation at the field or method/constructor parameter level
|
||||
* that indicates a default value expression for the affected argument.
|
||||
*
|
||||
* <p>Typically used for expression-driven dependency injection. Also supported
|
||||
* for dynamic resolution of handler method parameters, e.g. in Spring MVC.
|
||||
*
|
||||
* <p>A common use case is to assign default field values using
|
||||
* "#{systemProperties.myProp}" style expressions.
|
||||
*
|
||||
* <p>Note that actual processing of the {@code @Value} annotation is performed
|
||||
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||
* BeanPostProcessor} which in turn means that you <em>cannot</em> use
|
||||
* {@code @Value} within
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||
* BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please
|
||||
* consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
|
||||
* class (which, by default, checks for the presence of this annotation).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see AutowiredAnnotationBeanPostProcessor
|
||||
* @see Autowired
|
||||
* @see org.springframework.beans.factory.config.BeanExpressionResolver
|
||||
* @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Value {
|
||||
|
||||
/**
|
||||
* The actual value expression: e.g. "#{systemProperties.myProp}".
|
||||
*/
|
||||
String value();
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation at the field or method/constructor parameter level
|
||||
* that indicates a default value expression for the affected argument.
|
||||
*
|
||||
* <p>Typically used for expression-driven dependency injection. Also supported
|
||||
* for dynamic resolution of handler method parameters, e.g. in Spring MVC.
|
||||
*
|
||||
* <p>A common use case is to assign default field values using
|
||||
* "#{systemProperties.myProp}" style expressions.
|
||||
*
|
||||
* <p>Note that actual processing of the {@code @Value} annotation is performed
|
||||
* by a {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||
* BeanPostProcessor} which in turn means that you <em>cannot</em> use
|
||||
* {@code @Value} within
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor
|
||||
* BeanPostProcessor} or {@link BeanFactoryPostProcessor} types. Please
|
||||
* consult the javadoc for the {@link AutowiredAnnotationBeanPostProcessor}
|
||||
* class (which, by default, checks for the presence of this annotation).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see AutowiredAnnotationBeanPostProcessor
|
||||
* @see Autowired
|
||||
* @see org.springframework.beans.factory.config.BeanExpressionResolver
|
||||
* @see org.springframework.beans.factory.support.AutowireCandidateResolver#getSuggestedValue
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Value {
|
||||
|
||||
/**
|
||||
* The actual value expression: e.g. "#{systemProperties.myProp}".
|
||||
*/
|
||||
String value();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Context object for evaluating an expression within a bean definition.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BeanExpressionContext {
|
||||
|
||||
private final ConfigurableBeanFactory beanFactory;
|
||||
|
||||
private final Scope scope;
|
||||
|
||||
|
||||
public BeanExpressionContext(ConfigurableBeanFactory beanFactory, Scope scope) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public final ConfigurableBeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
public final Scope getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
|
||||
public boolean containsObject(String key) {
|
||||
return (this.beanFactory.containsBean(key) ||
|
||||
(this.scope != null && this.scope.resolveContextualObject(key) != null));
|
||||
}
|
||||
|
||||
public Object getObject(String key) {
|
||||
if (this.beanFactory.containsBean(key)) {
|
||||
return this.beanFactory.getBean(key);
|
||||
}
|
||||
else if (this.scope != null){
|
||||
return this.scope.resolveContextualObject(key);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof BeanExpressionContext)) {
|
||||
return false;
|
||||
}
|
||||
BeanExpressionContext otherContext = (BeanExpressionContext) other;
|
||||
return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.beanFactory.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Context object for evaluating an expression within a bean definition.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BeanExpressionContext {
|
||||
|
||||
private final ConfigurableBeanFactory beanFactory;
|
||||
|
||||
private final Scope scope;
|
||||
|
||||
|
||||
public BeanExpressionContext(ConfigurableBeanFactory beanFactory, Scope scope) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public final ConfigurableBeanFactory getBeanFactory() {
|
||||
return this.beanFactory;
|
||||
}
|
||||
|
||||
public final Scope getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
|
||||
public boolean containsObject(String key) {
|
||||
return (this.beanFactory.containsBean(key) ||
|
||||
(this.scope != null && this.scope.resolveContextualObject(key) != null));
|
||||
}
|
||||
|
||||
public Object getObject(String key) {
|
||||
if (this.beanFactory.containsBean(key)) {
|
||||
return this.beanFactory.getBean(key);
|
||||
}
|
||||
else if (this.scope != null){
|
||||
return this.scope.resolveContextualObject(key);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof BeanExpressionContext)) {
|
||||
return false;
|
||||
}
|
||||
BeanExpressionContext otherContext = (BeanExpressionContext) other;
|
||||
return (this.beanFactory == otherContext.beanFactory && this.scope == otherContext.scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.beanFactory.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
/**
|
||||
* Strategy interface for resolving a value through evaluating it
|
||||
* as an expression, if applicable.
|
||||
*
|
||||
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
||||
* contain a default implementation of this strategy. However,
|
||||
* {@link org.springframework.context.ApplicationContext} implementations
|
||||
* will provide expression support out of the box.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface BeanExpressionResolver {
|
||||
|
||||
/**
|
||||
* Evaluate the given value as an expression, if applicable;
|
||||
* return the value as-is otherwise.
|
||||
* @param value the value to check
|
||||
* @param evalContext the evaluation context
|
||||
* @return the resolved value (potentially the given value as-is)
|
||||
* @throws BeansException if evaluation failed
|
||||
*/
|
||||
Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException;
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
/**
|
||||
* Strategy interface for resolving a value through evaluating it
|
||||
* as an expression, if applicable.
|
||||
*
|
||||
* <p>A raw {@link org.springframework.beans.factory.BeanFactory} does not
|
||||
* contain a default implementation of this strategy. However,
|
||||
* {@link org.springframework.context.ApplicationContext} implementations
|
||||
* will provide expression support out of the box.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface BeanExpressionResolver {
|
||||
|
||||
/**
|
||||
* Evaluate the given value as an expression, if applicable;
|
||||
* return the value as-is otherwise.
|
||||
* @param value the value to check
|
||||
* @param evalContext the evaluation context
|
||||
* @return the resolved value (potentially the given value as-is)
|
||||
* @throws BeansException if evaluation failed
|
||||
*/
|
||||
Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,95 +1,95 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* 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 bean sourced from a {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* <p>This is basically a JSR-330 compliant variant of Spring's good old
|
||||
* {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional
|
||||
* external dependency injection configuration that targets a property or
|
||||
* constructor argument of type <code>javax.inject.Provider</code>, as an
|
||||
* alternative to JSR-330's <code>@Inject</code> annotation-driven approach.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.2
|
||||
* @see javax.inject.Provider
|
||||
* @see ObjectFactoryCreatingFactoryBean
|
||||
*/
|
||||
public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> {
|
||||
|
||||
private String targetBeanName;
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the target bean.
|
||||
* <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
|
||||
* 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).
|
||||
*/
|
||||
public void setTargetBeanName(String targetBeanName) {
|
||||
this.targetBeanName = targetBeanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
|
||||
super.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class getObjectType() {
|
||||
return Provider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Provider createInstance() {
|
||||
return new TargetBeanProvider(getBeanFactory(), this.targetBeanName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Independent inner class - for serialization purposes.
|
||||
*/
|
||||
private static class TargetBeanProvider implements Provider, Serializable {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
private final String targetBeanName;
|
||||
|
||||
public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.targetBeanName = targetBeanName;
|
||||
}
|
||||
|
||||
public Object get() throws BeansException {
|
||||
return this.beanFactory.getBean(this.targetBeanName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* 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 bean sourced from a {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* <p>This is basically a JSR-330 compliant variant of Spring's good old
|
||||
* {@link ObjectFactoryCreatingFactoryBean}. It can be used for traditional
|
||||
* external dependency injection configuration that targets a property or
|
||||
* constructor argument of type <code>javax.inject.Provider</code>, as an
|
||||
* alternative to JSR-330's <code>@Inject</code> annotation-driven approach.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.2
|
||||
* @see javax.inject.Provider
|
||||
* @see ObjectFactoryCreatingFactoryBean
|
||||
*/
|
||||
public class ProviderCreatingFactoryBean extends AbstractFactoryBean<Provider> {
|
||||
|
||||
private String targetBeanName;
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the target bean.
|
||||
* <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
|
||||
* 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).
|
||||
*/
|
||||
public void setTargetBeanName(String targetBeanName) {
|
||||
this.targetBeanName = targetBeanName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasText(this.targetBeanName, "Property 'targetBeanName' is required");
|
||||
super.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class getObjectType() {
|
||||
return Provider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Provider createInstance() {
|
||||
return new TargetBeanProvider(getBeanFactory(), this.targetBeanName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Independent inner class - for serialization purposes.
|
||||
*/
|
||||
private static class TargetBeanProvider implements Provider, Serializable {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
private final String targetBeanName;
|
||||
|
||||
public TargetBeanProvider(BeanFactory beanFactory, String targetBeanName) {
|
||||
this.beanFactory = beanFactory;
|
||||
this.targetBeanName = targetBeanName;
|
||||
}
|
||||
|
||||
public Object get() throws BeansException {
|
||||
return this.beanFactory.getBean(this.targetBeanName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Tag collection class used to hold managed array elements, which may
|
||||
* include runtime bean references (to be resolved into bean objects).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ManagedArray extends ManagedList<Object> {
|
||||
|
||||
/** Resolved element type for runtime creation of the target array */
|
||||
volatile Class resolvedElementType;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new managed array placeholder.
|
||||
* @param elementTypeName the target element type as a class name
|
||||
* @param size the size of the array
|
||||
*/
|
||||
public ManagedArray(String elementTypeName, int size) {
|
||||
super(size);
|
||||
Assert.notNull(elementTypeName, "elementTypeName must not be null");
|
||||
setElementTypeName(elementTypeName);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Tag collection class used to hold managed array elements, which may
|
||||
* include runtime bean references (to be resolved into bean objects).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class ManagedArray extends ManagedList<Object> {
|
||||
|
||||
/** Resolved element type for runtime creation of the target array */
|
||||
volatile Class resolvedElementType;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new managed array placeholder.
|
||||
* @param elementTypeName the target element type as a class name
|
||||
* @param size the size of the array
|
||||
*/
|
||||
public ManagedArray(String elementTypeName, int size) {
|
||||
super(size);
|
||||
Assert.notNull(elementTypeName, "elementTypeName must not be null");
|
||||
setElementTypeName(elementTypeName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
/**
|
||||
* Provider of the security context of the code running inside the bean factory.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface SecurityContextProvider {
|
||||
|
||||
/**
|
||||
* Provides a security access control context relevant to a bean factory.
|
||||
* @return bean factory security control context
|
||||
*/
|
||||
AccessControlContext getAccessControlContext();
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
|
||||
/**
|
||||
* Provider of the security context of the code running inside the bean factory.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface SecurityContextProvider {
|
||||
|
||||
/**
|
||||
* Provides a security access control context relevant to a bean factory.
|
||||
* @return bean factory security control context
|
||||
*/
|
||||
AccessControlContext getAccessControlContext();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,58 +1,58 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* Simple {@link SecurityContextProvider} implementation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SimpleSecurityContextProvider implements SecurityContextProvider {
|
||||
|
||||
private final AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
||||
* <p>The security context will be retrieved on each call from the current
|
||||
* thread.
|
||||
*/
|
||||
public SimpleSecurityContextProvider() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
||||
* <p>If the given control context is null, the security context will be
|
||||
* retrieved on each call from the current thread.
|
||||
* @param acc access control context (can be <code>null</code>)
|
||||
* @see AccessController#getContext()
|
||||
*/
|
||||
public SimpleSecurityContextProvider(AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return (this.acc != null ? acc : AccessController.getContext());
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
|
||||
/**
|
||||
* Simple {@link SecurityContextProvider} implementation.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SimpleSecurityContextProvider implements SecurityContextProvider {
|
||||
|
||||
private final AccessControlContext acc;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
||||
* <p>The security context will be retrieved on each call from the current
|
||||
* thread.
|
||||
*/
|
||||
public SimpleSecurityContextProvider() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new <code>SimpleSecurityContextProvider</code> instance.
|
||||
* <p>If the given control context is null, the security context will be
|
||||
* retrieved on each call from the current thread.
|
||||
* @param acc access control context (can be <code>null</code>)
|
||||
* @see AccessController#getContext()
|
||||
*/
|
||||
public SimpleSecurityContextProvider(AccessControlContext acc) {
|
||||
this.acc = acc;
|
||||
}
|
||||
|
||||
|
||||
public AccessControlContext getAccessControlContext() {
|
||||
return (this.acc != null ? acc : AccessController.getContext());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,151 +1,151 @@
|
||||
/*
|
||||
* Copyright 2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.xml;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Simple <code>NamespaceHandler</code> implementation that maps custom
|
||||
* attributes directly through to bean properties. An important point to note is
|
||||
* that this <code>NamespaceHandler</code> does not have a corresponding schema
|
||||
* since there is no way to know in advance all possible attribute names.
|
||||
*
|
||||
* <p>
|
||||
* An example of the usage of this <code>NamespaceHandler</code> is shown below:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/>
|
||||
* </pre>
|
||||
*
|
||||
* Here the '<code>c:name</code>' corresponds directly to the '<code>name</code>
|
||||
* ' argument declared on the constructor of class '<code>TestBean</code>'. The
|
||||
* '<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
|
||||
* the bean that will be considered as a parameter.
|
||||
*
|
||||
* <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
|
||||
* the container which, by default, does type introspection.
|
||||
*
|
||||
* @see SimplePropertyNamespaceHandler
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
|
||||
private static final String REF_SUFFIX = "-ref";
|
||||
private static final String DELIMITER_PREFIX = "_";
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Class [" + getClass().getName() + "] does not support custom elements.", element);
|
||||
return null;
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
||||
if (node instanceof Attr) {
|
||||
Attr attr = (Attr) node;
|
||||
String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
|
||||
String argValue = StringUtils.trimWhitespace(attr.getValue());
|
||||
|
||||
ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
|
||||
boolean ref = false;
|
||||
|
||||
// handle -ref arguments
|
||||
if (argName.endsWith(REF_SUFFIX)) {
|
||||
ref = true;
|
||||
argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
|
||||
}
|
||||
|
||||
ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
|
||||
valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));
|
||||
|
||||
// handle "escaped"/"_" arguments
|
||||
if (argName.startsWith(DELIMITER_PREFIX)) {
|
||||
String arg = argName.substring(1).trim();
|
||||
|
||||
// fast default check
|
||||
if (!StringUtils.hasText(arg)) {
|
||||
cvs.addGenericArgumentValue(valueHolder);
|
||||
}
|
||||
// assume an index otherwise
|
||||
else {
|
||||
int index = -1;
|
||||
try {
|
||||
index = Integer.parseInt(arg);
|
||||
} catch (NumberFormatException ex) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' specifies an invalid integer", attr);
|
||||
}
|
||||
if (index < 0) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' specifies a negative index", attr);
|
||||
}
|
||||
|
||||
if (cvs.hasIndexedArgumentValue(index)){
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." +
|
||||
" Only one approach may be used per argument.", attr);
|
||||
}
|
||||
|
||||
cvs.addIndexedArgumentValue(index, valueHolder);
|
||||
}
|
||||
}
|
||||
// no escaping -> ctr name
|
||||
else {
|
||||
String name = Conventions.attributeNameToPropertyName(argName);
|
||||
if (containsArgWithName(name, cvs)){
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' already defined using <constructor-arg>." +
|
||||
" Only one approach may be used per argument.", attr);
|
||||
}
|
||||
valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
|
||||
cvs.addGenericArgumentValue(valueHolder);
|
||||
}
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
||||
private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) {
|
||||
if (!checkName(name, cvs.getGenericArgumentValues())) {
|
||||
return checkName(name, cvs.getIndexedArgumentValues().values());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkName(String name, Collection<ValueHolder> values) {
|
||||
for (ValueHolder holder : values) {
|
||||
if (name.equals(holder.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* Copyright 2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.xml;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
|
||||
import org.springframework.core.Conventions;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Simple <code>NamespaceHandler</code> implementation that maps custom
|
||||
* attributes directly through to bean properties. An important point to note is
|
||||
* that this <code>NamespaceHandler</code> does not have a corresponding schema
|
||||
* since there is no way to know in advance all possible attribute names.
|
||||
*
|
||||
* <p>
|
||||
* An example of the usage of this <code>NamespaceHandler</code> is shown below:
|
||||
*
|
||||
* <pre class="code">
|
||||
* <bean id="author" class="..TestBean" c:name="Enescu" c:work-ref="compositions"/>
|
||||
* </pre>
|
||||
*
|
||||
* Here the '<code>c:name</code>' corresponds directly to the '<code>name</code>
|
||||
* ' argument declared on the constructor of class '<code>TestBean</code>'. The
|
||||
* '<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
|
||||
* the bean that will be considered as a parameter.
|
||||
*
|
||||
* <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
|
||||
* the container which, by default, does type introspection.
|
||||
*
|
||||
* @see SimplePropertyNamespaceHandler
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class SimpleConstructorNamespaceHandler implements NamespaceHandler {
|
||||
|
||||
private static final String REF_SUFFIX = "-ref";
|
||||
private static final String DELIMITER_PREFIX = "_";
|
||||
|
||||
public void init() {
|
||||
}
|
||||
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Class [" + getClass().getName() + "] does not support custom elements.", element);
|
||||
return null;
|
||||
}
|
||||
|
||||
public BeanDefinitionHolder decorate(Node node, BeanDefinitionHolder definition, ParserContext parserContext) {
|
||||
if (node instanceof Attr) {
|
||||
Attr attr = (Attr) node;
|
||||
String argName = StringUtils.trimWhitespace(parserContext.getDelegate().getLocalName(attr));
|
||||
String argValue = StringUtils.trimWhitespace(attr.getValue());
|
||||
|
||||
ConstructorArgumentValues cvs = definition.getBeanDefinition().getConstructorArgumentValues();
|
||||
boolean ref = false;
|
||||
|
||||
// handle -ref arguments
|
||||
if (argName.endsWith(REF_SUFFIX)) {
|
||||
ref = true;
|
||||
argName = argName.substring(0, argName.length() - REF_SUFFIX.length());
|
||||
}
|
||||
|
||||
ValueHolder valueHolder = new ValueHolder(ref ? new RuntimeBeanReference(argValue) : argValue);
|
||||
valueHolder.setSource(parserContext.getReaderContext().extractSource(attr));
|
||||
|
||||
// handle "escaped"/"_" arguments
|
||||
if (argName.startsWith(DELIMITER_PREFIX)) {
|
||||
String arg = argName.substring(1).trim();
|
||||
|
||||
// fast default check
|
||||
if (!StringUtils.hasText(arg)) {
|
||||
cvs.addGenericArgumentValue(valueHolder);
|
||||
}
|
||||
// assume an index otherwise
|
||||
else {
|
||||
int index = -1;
|
||||
try {
|
||||
index = Integer.parseInt(arg);
|
||||
} catch (NumberFormatException ex) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' specifies an invalid integer", attr);
|
||||
}
|
||||
if (index < 0) {
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' specifies a negative index", attr);
|
||||
}
|
||||
|
||||
if (cvs.hasIndexedArgumentValue(index)){
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' with index "+ index+" already defined using <constructor-arg>." +
|
||||
" Only one approach may be used per argument.", attr);
|
||||
}
|
||||
|
||||
cvs.addIndexedArgumentValue(index, valueHolder);
|
||||
}
|
||||
}
|
||||
// no escaping -> ctr name
|
||||
else {
|
||||
String name = Conventions.attributeNameToPropertyName(argName);
|
||||
if (containsArgWithName(name, cvs)){
|
||||
parserContext.getReaderContext().error(
|
||||
"Constructor argument '" + argName + "' already defined using <constructor-arg>." +
|
||||
" Only one approach may be used per argument.", attr);
|
||||
}
|
||||
valueHolder.setName(Conventions.attributeNameToPropertyName(argName));
|
||||
cvs.addGenericArgumentValue(valueHolder);
|
||||
}
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
||||
private boolean containsArgWithName(String name, ConstructorArgumentValues cvs) {
|
||||
if (!checkName(name, cvs.getGenericArgumentValues())) {
|
||||
return checkName(name, cvs.getIndexedArgumentValues().values());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkName(String name, Collection<ValueHolder> values) {
|
||||
for (ValueHolder holder : values) {
|
||||
if (name.equals(holder.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,43 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.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.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.util.Currency
|
||||
*/
|
||||
public class CurrencyEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
setValue(Currency.getInstance(text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
Currency value = (Currency) getValue();
|
||||
return (value != null ? value.getCurrencyCode() : "");
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.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.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.util.Currency
|
||||
*/
|
||||
public class CurrencyEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
setValue(Currency.getInstance(text));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
Currency value = (Currency) getValue();
|
||||
return (value != null ? value.getCurrencyCode() : "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Editor for <code>java.util.TimeZone</code>, translating timezone IDs into
|
||||
* TimeZone objects. Does not expose a text representation for TimeZone objects.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.util.TimeZone
|
||||
*/
|
||||
public class TimeZoneEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
setValue(TimeZone.getTimeZone(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation returns <code>null</code> to indicate that
|
||||
* there is no appropriate text representation.
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* Editor for <code>java.util.TimeZone</code>, translating timezone IDs into
|
||||
* TimeZone objects. Does not expose a text representation for TimeZone objects.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.util.TimeZone
|
||||
*/
|
||||
public class TimeZoneEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
setValue(TimeZone.getTimeZone(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation returns <code>null</code> to indicate that
|
||||
* there is no appropriate text representation.
|
||||
*/
|
||||
@Override
|
||||
public String getAsText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Editor for <code>java.util.UUID</code>, translating UUID
|
||||
* String representations into UUID objects and back.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.1
|
||||
* @see java.util.UUID
|
||||
*/
|
||||
public class UUIDEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
if (StringUtils.hasText(text)) {
|
||||
setValue(UUID.fromString(text));
|
||||
}
|
||||
else {
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
UUID value = (UUID) getValue();
|
||||
return (value != null ? value.toString() : "");
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.propertyeditors;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Editor for <code>java.util.UUID</code>, translating UUID
|
||||
* String representations into UUID objects and back.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.1
|
||||
* @see java.util.UUID
|
||||
*/
|
||||
public class UUIDEditor extends PropertyEditorSupport {
|
||||
|
||||
@Override
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
if (StringUtils.hasText(text)) {
|
||||
setValue(UUID.fromString(text));
|
||||
}
|
||||
else {
|
||||
setValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsText() {
|
||||
UUID value = (UUID) getValue();
|
||||
return (value != null ? value.toString() : "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
package com.foo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Component {
|
||||
private String name;
|
||||
private List<Component> components = new ArrayList<Component>();
|
||||
|
||||
// mmm, there is no setter method for the 'components'
|
||||
public void addComponent(Component component) {
|
||||
this.components.add(component);
|
||||
}
|
||||
|
||||
public List<Component> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
package com.foo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Component {
|
||||
private String name;
|
||||
private List<Component> components = new ArrayList<Component>();
|
||||
|
||||
// mmm, there is no setter method for the 'components'
|
||||
public void addComponent(Component component) {
|
||||
this.components.add(component);
|
||||
}
|
||||
|
||||
public List<Component> getComponents() {
|
||||
return components;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
package com.foo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
protected AbstractBeanDefinition parseInternal(Element element,
|
||||
ParserContext parserContext) {
|
||||
return parseComponentElement(element);
|
||||
}
|
||||
|
||||
private static AbstractBeanDefinition parseComponentElement(Element element) {
|
||||
BeanDefinitionBuilder factory = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(ComponentFactoryBean.class);
|
||||
|
||||
factory.addPropertyValue("parent", parseComponent(element));
|
||||
|
||||
List<Element> childElements = DomUtils.getChildElementsByTagName(
|
||||
element, "component");
|
||||
if (childElements != null && childElements.size() > 0) {
|
||||
parseChildComponents(childElements, factory);
|
||||
}
|
||||
|
||||
return factory.getBeanDefinition();
|
||||
}
|
||||
|
||||
private static BeanDefinition parseComponent(Element element) {
|
||||
BeanDefinitionBuilder component = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(Component.class);
|
||||
component.addPropertyValue("name", element.getAttribute("name"));
|
||||
return component.getBeanDefinition();
|
||||
}
|
||||
|
||||
private static void parseChildComponents(List<Element> childElements,
|
||||
BeanDefinitionBuilder factory) {
|
||||
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>(
|
||||
childElements.size());
|
||||
for (Element element : childElements) {
|
||||
children.add(parseComponentElement(element));
|
||||
}
|
||||
factory.addPropertyValue("children", children);
|
||||
}
|
||||
}
|
||||
package com.foo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public class ComponentBeanDefinitionParser extends AbstractBeanDefinitionParser {
|
||||
|
||||
protected AbstractBeanDefinition parseInternal(Element element,
|
||||
ParserContext parserContext) {
|
||||
return parseComponentElement(element);
|
||||
}
|
||||
|
||||
private static AbstractBeanDefinition parseComponentElement(Element element) {
|
||||
BeanDefinitionBuilder factory = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(ComponentFactoryBean.class);
|
||||
|
||||
factory.addPropertyValue("parent", parseComponent(element));
|
||||
|
||||
List<Element> childElements = DomUtils.getChildElementsByTagName(
|
||||
element, "component");
|
||||
if (childElements != null && childElements.size() > 0) {
|
||||
parseChildComponents(childElements, factory);
|
||||
}
|
||||
|
||||
return factory.getBeanDefinition();
|
||||
}
|
||||
|
||||
private static BeanDefinition parseComponent(Element element) {
|
||||
BeanDefinitionBuilder component = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(Component.class);
|
||||
component.addPropertyValue("name", element.getAttribute("name"));
|
||||
return component.getBeanDefinition();
|
||||
}
|
||||
|
||||
private static void parseChildComponents(List<Element> childElements,
|
||||
BeanDefinitionBuilder factory) {
|
||||
ManagedList<BeanDefinition> children = new ManagedList<BeanDefinition>(
|
||||
childElements.size());
|
||||
for (Element element : childElements) {
|
||||
children.add(parseComponentElement(element));
|
||||
}
|
||||
factory.addPropertyValue("children", children);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +1,74 @@
|
||||
/*
|
||||
* Copyright 2006-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.foo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class ComponentBeanDefinitionParserTest {
|
||||
|
||||
private static XmlBeanFactory bf;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
bf = new XmlBeanFactory(new ClassPathResource(
|
||||
"com/foo/component-config.xml"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
bf.destroySingletons();
|
||||
}
|
||||
|
||||
private Component getBionicFamily() {
|
||||
return bf.getBean("bionic-family", Component.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBionicBasic() throws Exception {
|
||||
Component cp = getBionicFamily();
|
||||
assertThat("Bionic-1", equalTo(cp.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBionicFirstLevelChildren() throws Exception {
|
||||
Component cp = getBionicFamily();
|
||||
List<Component> components = cp.getComponents();
|
||||
assertThat(2, equalTo(components.size()));
|
||||
assertThat("Mother-1", equalTo(components.get(0).getName()));
|
||||
assertThat("Rock-1", equalTo(components.get(1).getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBionicSecondLevenChildren() throws Exception {
|
||||
Component cp = getBionicFamily();
|
||||
List<Component> components = cp.getComponents().get(0).getComponents();
|
||||
assertThat(2, equalTo(components.size()));
|
||||
assertThat("Karate-1", equalTo(components.get(0).getName()));
|
||||
assertThat("Sport-1", equalTo(components.get(1).getName()));
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.foo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.xml.XmlBeanFactory;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class ComponentBeanDefinitionParserTest {
|
||||
|
||||
private static XmlBeanFactory bf;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpBeforeClass() throws Exception {
|
||||
bf = new XmlBeanFactory(new ClassPathResource(
|
||||
"com/foo/component-config.xml"));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownAfterClass() throws Exception {
|
||||
bf.destroySingletons();
|
||||
}
|
||||
|
||||
private Component getBionicFamily() {
|
||||
return bf.getBean("bionic-family", Component.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBionicBasic() throws Exception {
|
||||
Component cp = getBionicFamily();
|
||||
assertThat("Bionic-1", equalTo(cp.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBionicFirstLevelChildren() throws Exception {
|
||||
Component cp = getBionicFamily();
|
||||
List<Component> components = cp.getComponents();
|
||||
assertThat(2, equalTo(components.size()));
|
||||
assertThat("Mother-1", equalTo(components.get(0).getName()));
|
||||
assertThat("Rock-1", equalTo(components.get(1).getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBionicSecondLevenChildren() throws Exception {
|
||||
Component cp = getBionicFamily();
|
||||
List<Component> components = cp.getComponents().get(0).getComponents();
|
||||
assertThat(2, equalTo(components.size()));
|
||||
assertThat("Karate-1", equalTo(components.get(0).getName()));
|
||||
assertThat("Sport-1", equalTo(components.get(1).getName()));
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,35 @@
|
||||
package com.foo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
public class ComponentFactoryBean implements FactoryBean<Component> {
|
||||
private Component parent;
|
||||
private List<Component> children;
|
||||
|
||||
public void setParent(Component parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setChildren(List<Component> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public Component getObject() throws Exception {
|
||||
if (this.children != null && this.children.size() > 0) {
|
||||
for (Component child : children) {
|
||||
this.parent.addComponent(child);
|
||||
}
|
||||
}
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public Class<Component> getObjectType() {
|
||||
return Component.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package com.foo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
public class ComponentFactoryBean implements FactoryBean<Component> {
|
||||
private Component parent;
|
||||
private List<Component> children;
|
||||
|
||||
public void setParent(Component parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setChildren(List<Component> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public Component getObject() throws Exception {
|
||||
if (this.children != null && this.children.size() > 0) {
|
||||
for (Component child : children) {
|
||||
this.parent.addComponent(child);
|
||||
}
|
||||
}
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public Class<Component> getObjectType() {
|
||||
return Component.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.foo;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
public class ComponentNamespaceHandler extends NamespaceHandlerSupport {
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("component",
|
||||
new ComponentBeanDefinitionParser());
|
||||
}
|
||||
}
|
||||
package com.foo;
|
||||
|
||||
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
|
||||
public class ComponentNamespaceHandler extends NamespaceHandlerSupport {
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("component",
|
||||
new ComponentBeanDefinitionParser());
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
||||
grant {
|
||||
permission java.security.AllPermission;
|
||||
grant {
|
||||
permission java.security.AllPermission;
|
||||
};
|
||||
@@ -1,30 +1,30 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class ConstructorBean {
|
||||
|
||||
public ConstructorBean() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public ConstructorBean(Object obj) {
|
||||
System.out.println("Received object " + obj);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class ConstructorBean {
|
||||
|
||||
public ConstructorBean() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public ConstructorBean(Object obj) {
|
||||
System.out.println("Received object " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomCallbackBean {
|
||||
|
||||
public void init() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomCallbackBean {
|
||||
|
||||
public void init() {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
public Class getObjectType() {
|
||||
System.setProperty("factory.object.type", "true");
|
||||
return Properties.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class CustomFactoryBean implements FactoryBean<Object> {
|
||||
|
||||
public Object getObject() throws Exception {
|
||||
return System.getProperties();
|
||||
}
|
||||
|
||||
public Class getObjectType() {
|
||||
System.setProperty("factory.object.type", "true");
|
||||
return Properties.class;
|
||||
}
|
||||
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DestroyBean implements DisposableBean {
|
||||
|
||||
public void destroy() throws Exception {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DestroyBean implements DisposableBean {
|
||||
|
||||
public void destroy() throws Exception {
|
||||
System.setProperty("security.destroy", "true");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class FactoryBean {
|
||||
|
||||
public static Object makeStaticInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
|
||||
protected static Object protectedStaticInstance() {
|
||||
return "protectedStaticInstance";
|
||||
}
|
||||
|
||||
public Object makeInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class FactoryBean {
|
||||
|
||||
public static Object makeStaticInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
|
||||
protected static Object protectedStaticInstance() {
|
||||
return "protectedStaticInstance";
|
||||
}
|
||||
|
||||
public Object makeInstance() {
|
||||
System.getProperties();
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class InitBean implements InitializingBean {
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
System.getProperties();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class InitBean implements InitializingBean {
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
System.getProperties();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class PropertyBean {
|
||||
|
||||
public void setSecurityProperty(Object property) {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void setProperty(Object property) {
|
||||
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.beans.factory.support.security.support;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class PropertyBean {
|
||||
|
||||
public void setSecurityProperty(Object property) {
|
||||
System.getProperties();
|
||||
}
|
||||
|
||||
public void setProperty(Object property) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package test.beans;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DummyBean {
|
||||
|
||||
private Object value;
|
||||
private String name;
|
||||
private int age;
|
||||
private TestBean spouse;
|
||||
|
||||
public DummyBean(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public DummyBean(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public DummyBean(int ageRef, String nameRef) {
|
||||
this.name = nameRef;
|
||||
this.age = ageRef;
|
||||
}
|
||||
|
||||
public DummyBean(String name, TestBean spouse) {
|
||||
this.name = name;
|
||||
this.spouse = spouse;
|
||||
}
|
||||
|
||||
public DummyBean(String name, Object value, int age) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public TestBean getSpouse() {
|
||||
return spouse;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package test.beans;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
*/
|
||||
public class DummyBean {
|
||||
|
||||
private Object value;
|
||||
private String name;
|
||||
private int age;
|
||||
private TestBean spouse;
|
||||
|
||||
public DummyBean(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public DummyBean(String name, int age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public DummyBean(int ageRef, String nameRef) {
|
||||
this.name = nameRef;
|
||||
this.age = ageRef;
|
||||
}
|
||||
|
||||
public DummyBean(String name, TestBean spouse) {
|
||||
this.name = name;
|
||||
this.spouse = spouse;
|
||||
}
|
||||
|
||||
public DummyBean(String name, Object value, int age) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public TestBean getSpouse() {
|
||||
return spouse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#Wed Mar 31 18:40:01 EEST 2010
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_Spring
|
||||
formatter_settings_version=11
|
||||
#Wed Mar 31 18:40:01 EEST 2010
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_Spring
|
||||
formatter_settings_version=11
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.commonj;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import commonj.timers.TimerManager;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.jndi.JndiLocatorSupport;
|
||||
|
||||
/**
|
||||
* Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager}
|
||||
* Defines common configuration settings and common lifecycle handling.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see commonj.timers.TimerManager
|
||||
*/
|
||||
public abstract class TimerManagerAccessor extends JndiLocatorSupport
|
||||
implements InitializingBean, DisposableBean, Lifecycle {
|
||||
|
||||
private TimerManager timerManager;
|
||||
|
||||
private String timerManagerName;
|
||||
|
||||
private boolean shared = false;
|
||||
|
||||
|
||||
/**
|
||||
* Specify the CommonJ TimerManager to delegate to.
|
||||
* <p>Note that the given TimerManager's lifecycle will be managed
|
||||
* by this FactoryBean.
|
||||
* <p>Alternatively (and typically), you can specify the JNDI name
|
||||
* of the target TimerManager.
|
||||
* @see #setTimerManagerName
|
||||
*/
|
||||
public void setTimerManager(TimerManager timerManager) {
|
||||
this.timerManager = timerManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JNDI name of the CommonJ TimerManager.
|
||||
* <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".
|
||||
* @see #setTimerManager
|
||||
* @see #setResourceRef
|
||||
*/
|
||||
public void setTimerManagerName(String timerManagerName) {
|
||||
this.timerManagerName = timerManagerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the TimerManager obtained by this FactoryBean
|
||||
* is a shared instance ("true") or an independent instance ("false").
|
||||
* 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.
|
||||
* <p>Default is "false", i.e. managing an independent TimerManager instance.
|
||||
* This is what the CommonJ specification suggests that application servers
|
||||
* are supposed to offer via JNDI lookups, typically declared as a
|
||||
* <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'.
|
||||
* <p>Switch this flag to "true" if you are obtaining a shared TimerManager,
|
||||
* typically through specifying the JNDI location of a TimerManager that
|
||||
* has been explicitly declared as 'Shareable'. Note that WebLogic's
|
||||
* cluster-aware Job Scheduler is a shared TimerManager too.
|
||||
* <p>The sole difference between this FactoryBean being in shared or
|
||||
* non-shared mode is that it will only attempt to suspend / resume / stop
|
||||
* the underlying TimerManager in case of an independent (non-shared) instance.
|
||||
* This only affects the {@link org.springframework.context.Lifecycle} support
|
||||
* as well as application context shutdown.
|
||||
* @see #stop()
|
||||
* @see #start()
|
||||
* @see #destroy()
|
||||
* @see commonj.timers.TimerManager
|
||||
*/
|
||||
public void setShared(boolean shared) {
|
||||
this.shared = shared;
|
||||
}
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws NamingException {
|
||||
if (this.timerManager == null) {
|
||||
if (this.timerManagerName == null) {
|
||||
throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified");
|
||||
}
|
||||
this.timerManager = lookup(this.timerManagerName, TimerManager.class);
|
||||
}
|
||||
}
|
||||
|
||||
protected final TimerManager getTimerManager() {
|
||||
return this.timerManager;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of Lifecycle interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resumes the underlying TimerManager (if not shared).
|
||||
* @see commonj.timers.TimerManager#resume()
|
||||
*/
|
||||
public void start() {
|
||||
if (!this.shared) {
|
||||
this.timerManager.resume();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspends the underlying TimerManager (if not shared).
|
||||
* @see commonj.timers.TimerManager#suspend()
|
||||
*/
|
||||
public void stop() {
|
||||
if (!this.shared) {
|
||||
this.timerManager.suspend();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Considers the underlying TimerManager as running if it is
|
||||
* neither suspending nor stopping.
|
||||
* @see commonj.timers.TimerManager#isSuspending()
|
||||
* @see commonj.timers.TimerManager#isStopping()
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return (!this.timerManager.isSuspending() && !this.timerManager.isStopping());
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of DisposableBean interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Stops the underlying TimerManager (if not shared).
|
||||
* @see commonj.timers.TimerManager#stop()
|
||||
*/
|
||||
public void destroy() {
|
||||
// Stop the entire TimerManager, if necessary.
|
||||
if (!this.shared) {
|
||||
// May return early, but at least we already cancelled all known Timers.
|
||||
this.timerManager.stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.commonj;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
|
||||
import commonj.timers.TimerManager;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.jndi.JndiLocatorSupport;
|
||||
|
||||
/**
|
||||
* Base class for classes that are accessing a CommonJ {@link commonj.timers.TimerManager}
|
||||
* Defines common configuration settings and common lifecycle handling.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see commonj.timers.TimerManager
|
||||
*/
|
||||
public abstract class TimerManagerAccessor extends JndiLocatorSupport
|
||||
implements InitializingBean, DisposableBean, Lifecycle {
|
||||
|
||||
private TimerManager timerManager;
|
||||
|
||||
private String timerManagerName;
|
||||
|
||||
private boolean shared = false;
|
||||
|
||||
|
||||
/**
|
||||
* Specify the CommonJ TimerManager to delegate to.
|
||||
* <p>Note that the given TimerManager's lifecycle will be managed
|
||||
* by this FactoryBean.
|
||||
* <p>Alternatively (and typically), you can specify the JNDI name
|
||||
* of the target TimerManager.
|
||||
* @see #setTimerManagerName
|
||||
*/
|
||||
public void setTimerManager(TimerManager timerManager) {
|
||||
this.timerManager = timerManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the JNDI name of the CommonJ TimerManager.
|
||||
* <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".
|
||||
* @see #setTimerManager
|
||||
* @see #setResourceRef
|
||||
*/
|
||||
public void setTimerManagerName(String timerManagerName) {
|
||||
this.timerManagerName = timerManagerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether the TimerManager obtained by this FactoryBean
|
||||
* is a shared instance ("true") or an independent instance ("false").
|
||||
* 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.
|
||||
* <p>Default is "false", i.e. managing an independent TimerManager instance.
|
||||
* This is what the CommonJ specification suggests that application servers
|
||||
* are supposed to offer via JNDI lookups, typically declared as a
|
||||
* <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'.
|
||||
* <p>Switch this flag to "true" if you are obtaining a shared TimerManager,
|
||||
* typically through specifying the JNDI location of a TimerManager that
|
||||
* has been explicitly declared as 'Shareable'. Note that WebLogic's
|
||||
* cluster-aware Job Scheduler is a shared TimerManager too.
|
||||
* <p>The sole difference between this FactoryBean being in shared or
|
||||
* non-shared mode is that it will only attempt to suspend / resume / stop
|
||||
* the underlying TimerManager in case of an independent (non-shared) instance.
|
||||
* This only affects the {@link org.springframework.context.Lifecycle} support
|
||||
* as well as application context shutdown.
|
||||
* @see #stop()
|
||||
* @see #start()
|
||||
* @see #destroy()
|
||||
* @see commonj.timers.TimerManager
|
||||
*/
|
||||
public void setShared(boolean shared) {
|
||||
this.shared = shared;
|
||||
}
|
||||
|
||||
|
||||
public void afterPropertiesSet() throws NamingException {
|
||||
if (this.timerManager == null) {
|
||||
if (this.timerManagerName == null) {
|
||||
throw new IllegalArgumentException("Either 'timerManager' or 'timerManagerName' must be specified");
|
||||
}
|
||||
this.timerManager = lookup(this.timerManagerName, TimerManager.class);
|
||||
}
|
||||
}
|
||||
|
||||
protected final TimerManager getTimerManager() {
|
||||
return this.timerManager;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of Lifecycle interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Resumes the underlying TimerManager (if not shared).
|
||||
* @see commonj.timers.TimerManager#resume()
|
||||
*/
|
||||
public void start() {
|
||||
if (!this.shared) {
|
||||
this.timerManager.resume();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspends the underlying TimerManager (if not shared).
|
||||
* @see commonj.timers.TimerManager#suspend()
|
||||
*/
|
||||
public void stop() {
|
||||
if (!this.shared) {
|
||||
this.timerManager.suspend();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Considers the underlying TimerManager as running if it is
|
||||
* neither suspending nor stopping.
|
||||
* @see commonj.timers.TimerManager#isSuspending()
|
||||
* @see commonj.timers.TimerManager#isStopping()
|
||||
*/
|
||||
public boolean isRunning() {
|
||||
return (!this.timerManager.isSuspending() && !this.timerManager.isStopping());
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of DisposableBean interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Stops the underlying TimerManager (if not shared).
|
||||
* @see commonj.timers.TimerManager#stop()
|
||||
*/
|
||||
public void destroy() {
|
||||
// Stop the entire TimerManager, if necessary.
|
||||
if (!this.shared) {
|
||||
// May return early, but at least we already cancelled all known Timers.
|
||||
this.timerManager.stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,174 +1,174 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.commonj;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import commonj.timers.Timer;
|
||||
import commonj.timers.TimerListener;
|
||||
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||
import org.springframework.scheduling.support.TaskUtils;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
||||
* a CommonJ {@link commonj.timers.TimerManager}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
*/
|
||||
public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler {
|
||||
|
||||
private volatile ErrorHandler errorHandler;
|
||||
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||
return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule();
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false));
|
||||
Timer timer = getTimerManager().schedule(futureTask, startTime);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().schedule(futureTask, startTime, delay);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().schedule(futureTask, 0, delay);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) {
|
||||
return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ScheduledFuture adapter that wraps a CommonJ Timer.
|
||||
*/
|
||||
private static class TimerScheduledFuture extends FutureTask<Object> implements TimerListener, ScheduledFuture<Object> {
|
||||
|
||||
protected transient Timer timer;
|
||||
|
||||
protected transient boolean cancelled = false;
|
||||
|
||||
public TimerScheduledFuture(Runnable runnable) {
|
||||
super(runnable, null);
|
||||
}
|
||||
|
||||
public void setTimer(Timer timer) {
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
public void timerExpired(Timer timer) {
|
||||
runAndReset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
boolean result = super.cancel(mayInterruptIfRunning);
|
||||
this.timer.cancel();
|
||||
this.cancelled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public int compareTo(Delayed other) {
|
||||
if (this == other) {
|
||||
return 0;
|
||||
}
|
||||
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
||||
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ScheduledFuture adapter for trigger-based rescheduling.
|
||||
*/
|
||||
private class ReschedulingTimerListener extends TimerScheduledFuture {
|
||||
|
||||
private final Trigger trigger;
|
||||
|
||||
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||
|
||||
private volatile Date scheduledExecutionTime;
|
||||
|
||||
public ReschedulingTimerListener(Runnable runnable, Trigger trigger) {
|
||||
super(runnable);
|
||||
this.trigger = trigger;
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule() {
|
||||
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
||||
if (this.scheduledExecutionTime == null) {
|
||||
return null;
|
||||
}
|
||||
setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timerExpired(Timer timer) {
|
||||
Date actualExecutionTime = new Date();
|
||||
super.timerExpired(timer);
|
||||
Date completionTime = new Date();
|
||||
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
||||
if (!this.cancelled) {
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.commonj;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import commonj.timers.Timer;
|
||||
import commonj.timers.TimerListener;
|
||||
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||
import org.springframework.scheduling.support.TaskUtils;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
||||
* a CommonJ {@link commonj.timers.TimerManager}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
*/
|
||||
public class TimerManagerTaskScheduler extends TimerManagerAccessor implements TaskScheduler {
|
||||
|
||||
private volatile ErrorHandler errorHandler;
|
||||
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||
return new ReschedulingTimerListener(errorHandlingTask(task, true), trigger).schedule();
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, false));
|
||||
Timer timer = getTimerManager().schedule(futureTask, startTime);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, startTime, period);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().scheduleAtFixedRate(futureTask, 0, period);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().schedule(futureTask, startTime, delay);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||
TimerScheduledFuture futureTask = new TimerScheduledFuture(errorHandlingTask(task, true));
|
||||
Timer timer = getTimerManager().schedule(futureTask, 0, delay);
|
||||
futureTask.setTimer(timer);
|
||||
return futureTask;
|
||||
}
|
||||
|
||||
private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) {
|
||||
return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ScheduledFuture adapter that wraps a CommonJ Timer.
|
||||
*/
|
||||
private static class TimerScheduledFuture extends FutureTask<Object> implements TimerListener, ScheduledFuture<Object> {
|
||||
|
||||
protected transient Timer timer;
|
||||
|
||||
protected transient boolean cancelled = false;
|
||||
|
||||
public TimerScheduledFuture(Runnable runnable) {
|
||||
super(runnable, null);
|
||||
}
|
||||
|
||||
public void setTimer(Timer timer) {
|
||||
this.timer = timer;
|
||||
}
|
||||
|
||||
public void timerExpired(Timer timer) {
|
||||
runAndReset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
boolean result = super.cancel(mayInterruptIfRunning);
|
||||
this.timer.cancel();
|
||||
this.cancelled = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return unit.convert(System.currentTimeMillis() - this.timer.getScheduledExecutionTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public int compareTo(Delayed other) {
|
||||
if (this == other) {
|
||||
return 0;
|
||||
}
|
||||
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
||||
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ScheduledFuture adapter for trigger-based rescheduling.
|
||||
*/
|
||||
private class ReschedulingTimerListener extends TimerScheduledFuture {
|
||||
|
||||
private final Trigger trigger;
|
||||
|
||||
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||
|
||||
private volatile Date scheduledExecutionTime;
|
||||
|
||||
public ReschedulingTimerListener(Runnable runnable, Trigger trigger) {
|
||||
super(runnable);
|
||||
this.trigger = trigger;
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule() {
|
||||
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
||||
if (this.scheduledExecutionTime == null) {
|
||||
return null;
|
||||
}
|
||||
setTimer(getTimerManager().schedule(this, this.scheduledExecutionTime));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timerExpired(Timer timer) {
|
||||
Date actualExecutionTime = new Date();
|
||||
super.timerExpired(timer);
|
||||
Date completionTime = new Date();
|
||||
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
||||
if (!this.cancelled) {
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context;
|
||||
|
||||
import org.springframework.beans.factory.Aware;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
|
||||
* ApplicationContextAware/BeanFactoryAware interfaces.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 3.0.3
|
||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
|
||||
*/
|
||||
public interface EmbeddedValueResolverAware extends Aware {
|
||||
|
||||
/**
|
||||
* Set the StringValueResolver to use for resolving embedded definition values.
|
||||
*/
|
||||
void setEmbeddedValueResolver(StringValueResolver resolver);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context;
|
||||
|
||||
import org.springframework.beans.factory.Aware;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* <p>This is an alternative to a full ConfigurableBeanFactory dependency via the
|
||||
* ApplicationContextAware/BeanFactoryAware interfaces.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 3.0.3
|
||||
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#resolveEmbeddedValue
|
||||
*/
|
||||
public interface EmbeddedValueResolverAware extends Aware {
|
||||
|
||||
/**
|
||||
* Set the StringValueResolver to use for resolving embedded definition values.
|
||||
*/
|
||||
void setEmbeddedValueResolver(StringValueResolver resolver);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,177 +1,177 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.EnvironmentCapable;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenient adapter for programmatic registration of annotated bean classes.
|
||||
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
|
||||
* the same resolution of annotations but for explicitly registered classes only.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see AnnotationConfigApplicationContext#register
|
||||
*/
|
||||
public class AnnotatedBeanDefinitionReader {
|
||||
|
||||
private final BeanDefinitionRegistry registry;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
|
||||
|
||||
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
|
||||
|
||||
/**
|
||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
|
||||
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
|
||||
* the {@link Environment} will be inherited, otherwise a new
|
||||
* {@link StandardEnvironment} will be created and used.
|
||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||
* in the form of a {@code BeanDefinitionRegistry}
|
||||
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
|
||||
* @see #setEnvironment(Environment)
|
||||
*/
|
||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||||
this(registry, getOrCreateEnvironment(registry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
|
||||
* the given {@link Environment}.
|
||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||
* in the form of a {@code BeanDefinitionRegistry}
|
||||
* @param environment the {@code Environment} to use when evaluating bean definition
|
||||
* profiles.
|
||||
* @since 3.1
|
||||
*/
|
||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
Assert.notNull(environment, "Environment must not be null");
|
||||
|
||||
this.registry = registry;
|
||||
this.environment = environment;
|
||||
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BeanDefinitionRegistry that this scanner operates on.
|
||||
*/
|
||||
public final BeanDefinitionRegistry getRegistry() {
|
||||
return this.registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Environment to use when evaluating whether
|
||||
* {@link Profile @Profile}-annotated component classes should be registered.
|
||||
* <p>The default is a {@link StandardEnvironment}.
|
||||
* @see #registerBean(Class, String, Class...)
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BeanNameGenerator to use for detected bean classes.
|
||||
* <p>The default is a {@link AnnotationBeanNameGenerator}.
|
||||
*/
|
||||
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
||||
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ScopeMetadataResolver to use for detected bean classes.
|
||||
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
|
||||
*/
|
||||
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
|
||||
this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver
|
||||
: new AnnotationScopeMetadataResolver());
|
||||
}
|
||||
|
||||
public void register(Class<?>... annotatedClasses) {
|
||||
for (Class<?> annotatedClass : annotatedClasses) {
|
||||
registerBean(annotatedClass);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass) {
|
||||
registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
|
||||
registerBean(annotatedClass, null, qualifiers);
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
|
||||
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
|
||||
AnnotationMetadata metadata = abd.getMetadata();
|
||||
|
||||
if (ProfileHelper.isProfileAnnotationPresent(metadata)) {
|
||||
if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
|
||||
abd.setScope(scopeMetadata.getScopeName());
|
||||
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
|
||||
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
|
||||
if (qualifiers != null) {
|
||||
for (Class<? extends Annotation> qualifier : qualifiers) {
|
||||
if (Primary.class.equals(qualifier)) {
|
||||
abd.setPrimary(true);
|
||||
} else if (Lazy.class.equals(qualifier)) {
|
||||
abd.setLazyInit(true);
|
||||
} else {
|
||||
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
|
||||
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Environment from the given registry if possible, otherwise return a new
|
||||
* StandardEnvironment.
|
||||
*/
|
||||
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
if (registry instanceof EnvironmentCapable) {
|
||||
return ((EnvironmentCapable) registry).getEnvironment();
|
||||
}
|
||||
return new StandardEnvironment();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.EnvironmentCapable;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenient adapter for programmatic registration of annotated bean classes.
|
||||
* This is an alternative to {@link ClassPathBeanDefinitionScanner}, applying
|
||||
* the same resolution of annotations but for explicitly registered classes only.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @author Sam Brannen
|
||||
* @since 3.0
|
||||
* @see AnnotationConfigApplicationContext#register
|
||||
*/
|
||||
public class AnnotatedBeanDefinitionReader {
|
||||
|
||||
private final BeanDefinitionRegistry registry;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
|
||||
|
||||
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
|
||||
|
||||
/**
|
||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
|
||||
* If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
|
||||
* the {@link Environment} will be inherited, otherwise a new
|
||||
* {@link StandardEnvironment} will be created and used.
|
||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||
* in the form of a {@code BeanDefinitionRegistry}
|
||||
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
|
||||
* @see #setEnvironment(Environment)
|
||||
*/
|
||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||||
this(registry, getOrCreateEnvironment(registry));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
|
||||
* the given {@link Environment}.
|
||||
* @param registry the {@code BeanFactory} to load bean definitions into,
|
||||
* in the form of a {@code BeanDefinitionRegistry}
|
||||
* @param environment the {@code Environment} to use when evaluating bean definition
|
||||
* profiles.
|
||||
* @since 3.1
|
||||
*/
|
||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
Assert.notNull(environment, "Environment must not be null");
|
||||
|
||||
this.registry = registry;
|
||||
this.environment = environment;
|
||||
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the BeanDefinitionRegistry that this scanner operates on.
|
||||
*/
|
||||
public final BeanDefinitionRegistry getRegistry() {
|
||||
return this.registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Environment to use when evaluating whether
|
||||
* {@link Profile @Profile}-annotated component classes should be registered.
|
||||
* <p>The default is a {@link StandardEnvironment}.
|
||||
* @see #registerBean(Class, String, Class...)
|
||||
*/
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BeanNameGenerator to use for detected bean classes.
|
||||
* <p>The default is a {@link AnnotationBeanNameGenerator}.
|
||||
*/
|
||||
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
||||
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ScopeMetadataResolver to use for detected bean classes.
|
||||
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
|
||||
*/
|
||||
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
|
||||
this.scopeMetadataResolver = (scopeMetadataResolver != null ? scopeMetadataResolver
|
||||
: new AnnotationScopeMetadataResolver());
|
||||
}
|
||||
|
||||
public void register(Class<?>... annotatedClasses) {
|
||||
for (Class<?> annotatedClass : annotatedClasses) {
|
||||
registerBean(annotatedClass);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass) {
|
||||
registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
|
||||
registerBean(annotatedClass, null, qualifiers);
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
|
||||
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
|
||||
AnnotationMetadata metadata = abd.getMetadata();
|
||||
|
||||
if (ProfileHelper.isProfileAnnotationPresent(metadata)) {
|
||||
if (!this.environment.acceptsProfiles(ProfileHelper.getCandidateProfiles(metadata))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
|
||||
abd.setScope(scopeMetadata.getScopeName());
|
||||
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
|
||||
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
|
||||
if (qualifiers != null) {
|
||||
for (Class<? extends Annotation> qualifier : qualifiers) {
|
||||
if (Primary.class.equals(qualifier)) {
|
||||
abd.setPrimary(true);
|
||||
} else if (Lazy.class.equals(qualifier)) {
|
||||
abd.setLazyInit(true);
|
||||
} else {
|
||||
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
|
||||
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the Environment from the given registry if possible, otherwise return a new
|
||||
* StandardEnvironment.
|
||||
*/
|
||||
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
|
||||
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
|
||||
if (registry instanceof EnvironmentCapable) {
|
||||
return ((EnvironmentCapable) registry).getEnvironment();
|
||||
}
|
||||
return new StandardEnvironment();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,54 +1,54 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* does not explicitly depend on another through properties or constructor arguments,
|
||||
* but rather depends on the side effects of another bean's initialization.
|
||||
* <p>Note: This attribute will not be inherited by child bean definitions,
|
||||
* hence it needs to be specified per concrete bean definition.
|
||||
*
|
||||
* <p>May be used on any class directly or indirectly annotated with
|
||||
* {@link org.springframework.stereotype.Component} or on methods annotated
|
||||
* with {@link Bean}.
|
||||
*
|
||||
* <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,
|
||||
* {@link DependsOn} annotation metadata is ignored, and
|
||||
* {@code <bean depends-on="..."/>} is respected instead.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface DependsOn {
|
||||
|
||||
String[] value() default {};
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Documented;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* does not explicitly depend on another through properties or constructor arguments,
|
||||
* but rather depends on the side effects of another bean's initialization.
|
||||
* <p>Note: This attribute will not be inherited by child bean definitions,
|
||||
* hence it needs to be specified per concrete bean definition.
|
||||
*
|
||||
* <p>May be used on any class directly or indirectly annotated with
|
||||
* {@link org.springframework.stereotype.Component} or on methods annotated
|
||||
* with {@link Bean}.
|
||||
*
|
||||
* <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,
|
||||
* {@link DependsOn} annotation metadata is ignored, and
|
||||
* {@code <bean depends-on="..."/>} is respected instead.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
@Documented
|
||||
public @interface DependsOn {
|
||||
|
||||
String[] value() default {};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,111 +1,111 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
||||
/**
|
||||
* Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules:
|
||||
* defaulting to prototype scope unless {@link javax.inject.Singleton} is present.
|
||||
*
|
||||
* <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and
|
||||
* {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However,
|
||||
* 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.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see #registerScope
|
||||
* @see #resolveScopeName
|
||||
* @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
|
||||
* @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
|
||||
*/
|
||||
public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
|
||||
|
||||
private final Map<String, String> scopeMap = new HashMap<String, String>();
|
||||
|
||||
|
||||
public Jsr330ScopeMetadataResolver() {
|
||||
registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register an extended JSR-330 scope annotation, mapping it onto a
|
||||
* specific Spring scope by name.
|
||||
* @param annotationType the JSR-330 annotation type as a Class
|
||||
* @param scopeName the Spring scope name
|
||||
*/
|
||||
public final void registerScope(Class annotationType, String scopeName) {
|
||||
this.scopeMap.put(annotationType.getName(), scopeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an extended JSR-330 scope annotation, mapping it onto a
|
||||
* specific Spring scope by name.
|
||||
* @param annotationType the JSR-330 annotation type by name
|
||||
* @param scopeName the Spring scope name
|
||||
*/
|
||||
public final void registerScope(String annotationType, String scopeName) {
|
||||
this.scopeMap.put(annotationType, scopeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given annotation type into a named Spring scope.
|
||||
* <p>The default implementation simply checks against registered scopes.
|
||||
* Can be overridden for custom mapping rules, e.g. naming conventions.
|
||||
* @param annotationType the JSR-330 annotation type
|
||||
* @return the Spring scope name
|
||||
*/
|
||||
protected String resolveScopeName(String annotationType) {
|
||||
return this.scopeMap.get(annotationType);
|
||||
}
|
||||
|
||||
|
||||
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
|
||||
ScopeMetadata metadata = new ScopeMetadata();
|
||||
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
if (definition instanceof AnnotatedBeanDefinition) {
|
||||
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
||||
Set<String> annTypes = annDef.getMetadata().getAnnotationTypes();
|
||||
String found = null;
|
||||
for (String annType : annTypes) {
|
||||
Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType);
|
||||
if (metaAnns.contains("javax.inject.Scope")) {
|
||||
if (found != null) {
|
||||
throw new IllegalStateException("Found ambiguous scope annotations on bean class [" +
|
||||
definition.getBeanClassName() + "]: " + found + ", " + annType);
|
||||
}
|
||||
found = annType;
|
||||
String scopeName = resolveScopeName(annType);
|
||||
if (scopeName == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unsupported scope annotation - not mapped onto Spring scope name: " + annType);
|
||||
}
|
||||
metadata.setScopeName(scopeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
|
||||
/**
|
||||
* Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules:
|
||||
* defaulting to prototype scope unless {@link javax.inject.Singleton} is present.
|
||||
*
|
||||
* <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and
|
||||
* {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However,
|
||||
* 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.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see #registerScope
|
||||
* @see #resolveScopeName
|
||||
* @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
|
||||
* @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
|
||||
*/
|
||||
public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
|
||||
|
||||
private final Map<String, String> scopeMap = new HashMap<String, String>();
|
||||
|
||||
|
||||
public Jsr330ScopeMetadataResolver() {
|
||||
registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register an extended JSR-330 scope annotation, mapping it onto a
|
||||
* specific Spring scope by name.
|
||||
* @param annotationType the JSR-330 annotation type as a Class
|
||||
* @param scopeName the Spring scope name
|
||||
*/
|
||||
public final void registerScope(Class annotationType, String scopeName) {
|
||||
this.scopeMap.put(annotationType.getName(), scopeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an extended JSR-330 scope annotation, mapping it onto a
|
||||
* specific Spring scope by name.
|
||||
* @param annotationType the JSR-330 annotation type by name
|
||||
* @param scopeName the Spring scope name
|
||||
*/
|
||||
public final void registerScope(String annotationType, String scopeName) {
|
||||
this.scopeMap.put(annotationType, scopeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the given annotation type into a named Spring scope.
|
||||
* <p>The default implementation simply checks against registered scopes.
|
||||
* Can be overridden for custom mapping rules, e.g. naming conventions.
|
||||
* @param annotationType the JSR-330 annotation type
|
||||
* @return the Spring scope name
|
||||
*/
|
||||
protected String resolveScopeName(String annotationType) {
|
||||
return this.scopeMap.get(annotationType);
|
||||
}
|
||||
|
||||
|
||||
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
|
||||
ScopeMetadata metadata = new ScopeMetadata();
|
||||
metadata.setScopeName(BeanDefinition.SCOPE_PROTOTYPE);
|
||||
if (definition instanceof AnnotatedBeanDefinition) {
|
||||
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
||||
Set<String> annTypes = annDef.getMetadata().getAnnotationTypes();
|
||||
String found = null;
|
||||
for (String annType : annTypes) {
|
||||
Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType);
|
||||
if (metaAnns.contains("javax.inject.Scope")) {
|
||||
if (found != null) {
|
||||
throw new IllegalStateException("Found ambiguous scope annotations on bean class [" +
|
||||
definition.getBeanClassName() + "]: " + found + ", " + annType);
|
||||
}
|
||||
found = annType;
|
||||
String scopeName = resolveScopeName(annType);
|
||||
if (scopeName == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unsupported scope annotation - not mapped onto Spring scope name: " + annType);
|
||||
}
|
||||
metadata.setScopeName(scopeName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.springframework.aop.scope.ScopedProxyUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
|
||||
/**
|
||||
* Delegate factory class used to just introduce an AOP framework dependency
|
||||
* when actually creating a scoped proxy.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy
|
||||
*/
|
||||
class ScopedProxyCreator {
|
||||
|
||||
public static BeanDefinitionHolder createScopedProxy(
|
||||
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
|
||||
|
||||
return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
|
||||
}
|
||||
|
||||
public static String getTargetBeanName(String originalBeanName) {
|
||||
return ScopedProxyUtils.getTargetBeanName(originalBeanName);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import org.springframework.aop.scope.ScopedProxyUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
|
||||
/**
|
||||
* Delegate factory class used to just introduce an AOP framework dependency
|
||||
* when actually creating a scoped proxy.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy
|
||||
*/
|
||||
class ScopedProxyCreator {
|
||||
|
||||
public static BeanDefinitionHolder createScopedProxy(
|
||||
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
|
||||
|
||||
return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
|
||||
}
|
||||
|
||||
public static String getTargetBeanName(String originalBeanName) {
|
||||
return ScopedProxyUtils.getTargetBeanName(originalBeanName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.event;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link SmartApplicationListener} adapter that determines supported event types
|
||||
* through introspecting the generically declared type of the target listener.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent
|
||||
*/
|
||||
public class GenericApplicationListenerAdapter implements SmartApplicationListener {
|
||||
|
||||
private final ApplicationListener delegate;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new GenericApplicationListener for the given delegate.
|
||||
* @param delegate the delegate listener to be invoked
|
||||
*/
|
||||
public GenericApplicationListenerAdapter(ApplicationListener delegate) {
|
||||
Assert.notNull(delegate, "Delegate listener must not be null");
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
this.delegate.onApplicationEvent(event);
|
||||
}
|
||||
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class);
|
||||
if (typeArg == null || typeArg.equals(ApplicationEvent.class)) {
|
||||
Class targetClass = AopUtils.getTargetClass(this.delegate);
|
||||
if (targetClass != this.delegate.getClass()) {
|
||||
typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class);
|
||||
}
|
||||
}
|
||||
return (typeArg == null || typeArg.isAssignableFrom(eventType));
|
||||
}
|
||||
|
||||
public boolean supportsSourceType(Class<?> sourceType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.event;
|
||||
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link SmartApplicationListener} adapter that determines supported event types
|
||||
* through introspecting the generically declared type of the target listener.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent
|
||||
*/
|
||||
public class GenericApplicationListenerAdapter implements SmartApplicationListener {
|
||||
|
||||
private final ApplicationListener delegate;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new GenericApplicationListener for the given delegate.
|
||||
* @param delegate the delegate listener to be invoked
|
||||
*/
|
||||
public GenericApplicationListenerAdapter(ApplicationListener delegate) {
|
||||
Assert.notNull(delegate, "Delegate listener must not be null");
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
this.delegate.onApplicationEvent(event);
|
||||
}
|
||||
|
||||
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
|
||||
Class typeArg = GenericTypeResolver.resolveTypeArgument(this.delegate.getClass(), ApplicationListener.class);
|
||||
if (typeArg == null || typeArg.equals(ApplicationEvent.class)) {
|
||||
Class targetClass = AopUtils.getTargetClass(this.delegate);
|
||||
if (targetClass != this.delegate.getClass()) {
|
||||
typeArg = GenericTypeResolver.resolveTypeArgument(targetClass, ApplicationListener.class);
|
||||
}
|
||||
}
|
||||
return (typeArg == null || typeArg.isAssignableFrom(eventType));
|
||||
}
|
||||
|
||||
public boolean supportsSourceType(Class<?> sourceType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getOrder() {
|
||||
return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +1,42 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* Extended variant of the standard {@link ApplicationListener} interface,
|
||||
* exposing further metadata such as the supported event type.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
|
||||
|
||||
/**
|
||||
* Determine whether this listener actually supports the given event type.
|
||||
*/
|
||||
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
|
||||
|
||||
/**
|
||||
* Determine whether this listener actually supports the given source type.
|
||||
*/
|
||||
boolean supportsSourceType(Class<?> sourceType);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* Extended variant of the standard {@link ApplicationListener} interface,
|
||||
* exposing further metadata such as the supported event type.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {
|
||||
|
||||
/**
|
||||
* Determine whether this listener actually supports the given event type.
|
||||
*/
|
||||
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);
|
||||
|
||||
/**
|
||||
* Determine whether this listener actually supports the given source type.
|
||||
*/
|
||||
boolean supportsSourceType(Class<?> sourceType);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the beans and contextual objects
|
||||
* of a Spring {@link org.springframework.beans.factory.config.BeanExpressionContext}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BeanExpressionContextAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return ((BeanExpressionContext) target).containsObject(name);
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(((BeanExpressionContext) target).getObject(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
throw new AccessException("Beans in a BeanFactory are read-only");
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return new Class[] {BeanExpressionContext.class};
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the beans and contextual objects
|
||||
* of a Spring {@link org.springframework.beans.factory.config.BeanExpressionContext}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BeanExpressionContextAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return ((BeanExpressionContext) target).containsObject(name);
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(((BeanExpressionContext) target).getObject(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
throw new AccessException("Beans in a BeanFactory are read-only");
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return new Class[] {BeanExpressionContext.class};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,55 +1,55 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the beans of a
|
||||
* Spring {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BeanFactoryAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return (((BeanFactory) target).containsBean(name));
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(((BeanFactory) target).getBean(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
throw new AccessException("Beans in a BeanFactory are read-only");
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return new Class[] {BeanFactory.class};
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the beans of a
|
||||
* Spring {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BeanFactoryAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return (((BeanFactory) target).containsBean(name));
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return new TypedValue(((BeanFactory) target).getBean(name));
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
throw new AccessException("Beans in a BeanFactory are read-only");
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return new Class[] {BeanFactory.class};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,51 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* EL bean resolver that operates against a Spring
|
||||
* {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.4
|
||||
*/
|
||||
public class BeanFactoryResolver implements BeanResolver {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
public BeanFactoryResolver(BeanFactory beanFactory) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
|
||||
try {
|
||||
return this.beanFactory.getBean(beanName);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
throw new AccessException("Could not resolve bean reference against BeanFactory", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* EL bean resolver that operates against a Spring
|
||||
* {@link org.springframework.beans.factory.BeanFactory}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.4
|
||||
*/
|
||||
public class BeanFactoryResolver implements BeanResolver {
|
||||
|
||||
private final BeanFactory beanFactory;
|
||||
|
||||
public BeanFactoryResolver(BeanFactory beanFactory) {
|
||||
Assert.notNull(beanFactory, "BeanFactory must not be null");
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
public Object resolve(EvaluationContext context, String beanName) throws AccessException {
|
||||
try {
|
||||
return this.beanFactory.getBean(beanName);
|
||||
}
|
||||
catch (BeansException ex) {
|
||||
throw new AccessException("Could not resolve bean reference against BeanFactory", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,84 +1,84 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the keys
|
||||
* of a standard {@link java.util.Map}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class MapAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
Map map = (Map) target;
|
||||
return map.containsKey(name);
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
Map map = (Map) target;
|
||||
Object value = map.get(name);
|
||||
if (value == null && !map.containsKey(name)) {
|
||||
throw new MapAccessException(name);
|
||||
}
|
||||
return new TypedValue(value);
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
Map map = (Map) target;
|
||||
map.put(name, newValue);
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return new Class[] {Map.class};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exception thrown from <code>read</code> in order to reset a cached
|
||||
* PropertyAccessor, allowing other accessors to have a try.
|
||||
*/
|
||||
private static class MapAccessException extends AccessException {
|
||||
|
||||
private final String key;
|
||||
|
||||
public MapAccessException(String key) {
|
||||
super(null);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Map does not contain a value for key '" + this.key + "'";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
* EL property accessor that knows how to traverse the keys
|
||||
* of a standard {@link java.util.Map}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
* @since 3.0
|
||||
*/
|
||||
public class MapAccessor implements PropertyAccessor {
|
||||
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
Map map = (Map) target;
|
||||
return map.containsKey(name);
|
||||
}
|
||||
|
||||
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
Map map = (Map) target;
|
||||
Object value = map.get(name);
|
||||
if (value == null && !map.containsKey(name)) {
|
||||
throw new MapAccessException(name);
|
||||
}
|
||||
return new TypedValue(value);
|
||||
}
|
||||
|
||||
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
|
||||
Map map = (Map) target;
|
||||
map.put(name, newValue);
|
||||
}
|
||||
|
||||
public Class[] getSpecificTargetClasses() {
|
||||
return new Class[] {Map.class};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exception thrown from <code>read</code> in order to reset a cached
|
||||
* PropertyAccessor, allowing other accessors to have a try.
|
||||
*/
|
||||
private static class MapAccessException extends AccessException {
|
||||
|
||||
private final String key;
|
||||
|
||||
public MapAccessException(String key) {
|
||||
super(null);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "Map does not contain a value for key '" + this.key + "'";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +1,153 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanExpressionException;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Standard implementation of the
|
||||
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
|
||||
* interface, parsing and evaluating Spring EL using Spring's expression module.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.expression.ExpressionParser
|
||||
* @see org.springframework.expression.spel.standard.SpelExpressionParser
|
||||
* @see org.springframework.expression.spel.support.StandardEvaluationContext
|
||||
*/
|
||||
public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
|
||||
/** Default expression prefix: "#{" */
|
||||
public static final String DEFAULT_EXPRESSION_PREFIX = "#{";
|
||||
|
||||
/** Default expression suffix: "}" */
|
||||
public static final String DEFAULT_EXPRESSION_SUFFIX = "}";
|
||||
|
||||
|
||||
private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;
|
||||
|
||||
private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;
|
||||
|
||||
private ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();
|
||||
|
||||
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
||||
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>();
|
||||
|
||||
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
||||
public boolean isTemplate() {
|
||||
return true;
|
||||
}
|
||||
public String getExpressionPrefix() {
|
||||
return expressionPrefix;
|
||||
}
|
||||
public String getExpressionSuffix() {
|
||||
return expressionSuffix;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the prefix that an expression string starts with.
|
||||
* The default is "#{".
|
||||
* @see #DEFAULT_EXPRESSION_PREFIX
|
||||
*/
|
||||
public void setExpressionPrefix(String expressionPrefix) {
|
||||
Assert.hasText(expressionPrefix, "Expression prefix must not be empty");
|
||||
this.expressionPrefix = expressionPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the suffix that an expression string ends with.
|
||||
* The default is "}".
|
||||
* @see #DEFAULT_EXPRESSION_SUFFIX
|
||||
*/
|
||||
public void setExpressionSuffix(String expressionSuffix) {
|
||||
Assert.hasText(expressionSuffix, "Expression suffix must not be empty");
|
||||
this.expressionSuffix = expressionSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the EL parser to use for expression parsing.
|
||||
* <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser},
|
||||
* compatible with standard Unified EL style expression syntax.
|
||||
*/
|
||||
public void setExpressionParser(ExpressionParser expressionParser) {
|
||||
Assert.notNull(expressionParser, "ExpressionParser must not be null");
|
||||
this.expressionParser = expressionParser;
|
||||
}
|
||||
|
||||
|
||||
public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException {
|
||||
if (!StringUtils.hasLength(value)) {
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
Expression expr = this.expressionCache.get(value);
|
||||
if (expr == null) {
|
||||
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
|
||||
this.expressionCache.put(value, expr);
|
||||
}
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
||||
if (sec == null) {
|
||||
sec = new StandardEvaluationContext();
|
||||
sec.setRootObject(evalContext);
|
||||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
sec.addPropertyAccessor(new EnvironmentAccessor());
|
||||
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
|
||||
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
||||
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
|
||||
if (conversionService != null) {
|
||||
sec.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||
}
|
||||
customizeEvaluationContext(sec);
|
||||
this.evaluationCache.put(evalContext, sec);
|
||||
}
|
||||
return expr.getValue(sec);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanExpressionException("Expression parsing failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method for customizing the expression evaluation context.
|
||||
* <p>The default implementation is empty.
|
||||
*/
|
||||
protected void customizeEvaluationContext(StandardEvaluationContext evalContext) {
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.expression;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanExpressionException;
|
||||
import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Standard implementation of the
|
||||
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
|
||||
* interface, parsing and evaluating Spring EL using Spring's expression module.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.expression.ExpressionParser
|
||||
* @see org.springframework.expression.spel.standard.SpelExpressionParser
|
||||
* @see org.springframework.expression.spel.support.StandardEvaluationContext
|
||||
*/
|
||||
public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||
|
||||
/** Default expression prefix: "#{" */
|
||||
public static final String DEFAULT_EXPRESSION_PREFIX = "#{";
|
||||
|
||||
/** Default expression suffix: "}" */
|
||||
public static final String DEFAULT_EXPRESSION_SUFFIX = "}";
|
||||
|
||||
|
||||
private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;
|
||||
|
||||
private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;
|
||||
|
||||
private ExpressionParser expressionParser = new SpelExpressionParser();
|
||||
|
||||
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();
|
||||
|
||||
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
||||
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>();
|
||||
|
||||
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
||||
public boolean isTemplate() {
|
||||
return true;
|
||||
}
|
||||
public String getExpressionPrefix() {
|
||||
return expressionPrefix;
|
||||
}
|
||||
public String getExpressionSuffix() {
|
||||
return expressionSuffix;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the prefix that an expression string starts with.
|
||||
* The default is "#{".
|
||||
* @see #DEFAULT_EXPRESSION_PREFIX
|
||||
*/
|
||||
public void setExpressionPrefix(String expressionPrefix) {
|
||||
Assert.hasText(expressionPrefix, "Expression prefix must not be empty");
|
||||
this.expressionPrefix = expressionPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the suffix that an expression string ends with.
|
||||
* The default is "}".
|
||||
* @see #DEFAULT_EXPRESSION_SUFFIX
|
||||
*/
|
||||
public void setExpressionSuffix(String expressionSuffix) {
|
||||
Assert.hasText(expressionSuffix, "Expression suffix must not be empty");
|
||||
this.expressionSuffix = expressionSuffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the EL parser to use for expression parsing.
|
||||
* <p>Default is a {@link org.springframework.expression.spel.standard.SpelExpressionParser},
|
||||
* compatible with standard Unified EL style expression syntax.
|
||||
*/
|
||||
public void setExpressionParser(ExpressionParser expressionParser) {
|
||||
Assert.notNull(expressionParser, "ExpressionParser must not be null");
|
||||
this.expressionParser = expressionParser;
|
||||
}
|
||||
|
||||
|
||||
public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException {
|
||||
if (!StringUtils.hasLength(value)) {
|
||||
return value;
|
||||
}
|
||||
try {
|
||||
Expression expr = this.expressionCache.get(value);
|
||||
if (expr == null) {
|
||||
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext);
|
||||
this.expressionCache.put(value, expr);
|
||||
}
|
||||
StandardEvaluationContext sec = this.evaluationCache.get(evalContext);
|
||||
if (sec == null) {
|
||||
sec = new StandardEvaluationContext();
|
||||
sec.setRootObject(evalContext);
|
||||
sec.addPropertyAccessor(new BeanExpressionContextAccessor());
|
||||
sec.addPropertyAccessor(new BeanFactoryAccessor());
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
sec.addPropertyAccessor(new EnvironmentAccessor());
|
||||
sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory()));
|
||||
sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader()));
|
||||
ConversionService conversionService = evalContext.getBeanFactory().getConversionService();
|
||||
if (conversionService != null) {
|
||||
sec.setTypeConverter(new StandardTypeConverter(conversionService));
|
||||
}
|
||||
customizeEvaluationContext(sec);
|
||||
this.evaluationCache.put(evalContext, sec);
|
||||
}
|
||||
return expr.getValue(sec);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanExpressionException("Expression parsing failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method for customizing the expression evaluation context.
|
||||
* <p>The default implementation is empty.
|
||||
*/
|
||||
protected void customizeEvaluationContext(StandardEvaluationContext evalContext) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,134 +1,134 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.support;
|
||||
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Convenient application context with built-in XML support.
|
||||
* This is a flexible alternative to {@link ClassPathXmlApplicationContext}
|
||||
* and {@link FileSystemXmlApplicationContext}, to be configured via setters,
|
||||
* with an eventual {@link #refresh()} call activating the context.
|
||||
*
|
||||
* <p>In case of multiple configuration files, bean definitions in later files
|
||||
* will override those defined in earlier files. This can be leveraged to
|
||||
* deliberately override certain bean definitions via an extra configuration file.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
* @see #load
|
||||
* @see XmlBeanDefinitionReader
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
*/
|
||||
public class GenericXmlApplicationContext extends GenericApplicationContext {
|
||||
|
||||
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext that needs to be
|
||||
* {@linkplain #load loaded} and then manually {@link #refresh refreshed}.
|
||||
*/
|
||||
public GenericXmlApplicationContext() {
|
||||
reader.setEnvironment(this.getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||
* from the given resources and automatically refreshing the context.
|
||||
* @param resources the resources to load from
|
||||
*/
|
||||
public GenericXmlApplicationContext(Resource... resources) {
|
||||
load(resources);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||
* from the given resource locations and automatically refreshing the context.
|
||||
* @param resourceLocations the resources to load from
|
||||
*/
|
||||
public GenericXmlApplicationContext(String... resourceLocations) {
|
||||
load(resourceLocations);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||
* from the given resource locations and automatically refreshing the context.
|
||||
* @param relativeClass class whose package will be used as a prefix when
|
||||
* loading each specified resource name
|
||||
* @param resourceNames relatively-qualified names of resources to load
|
||||
*/
|
||||
public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) {
|
||||
load(relativeClass, resourceNames);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to use XML validation. Default is <code>true</code>.
|
||||
*/
|
||||
public void setValidating(boolean validating) {
|
||||
this.reader.setValidating(validating);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}.
|
||||
* Should be called before any call to {@link #load}.
|
||||
*/
|
||||
@Override
|
||||
public void setEnvironment(ConfigurableEnvironment environment) {
|
||||
super.setEnvironment(environment);
|
||||
this.reader.setEnvironment(this.getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load bean definitions from the given XML resources.
|
||||
* @param resources one or more resources to load from
|
||||
*/
|
||||
public void load(Resource... resources) {
|
||||
this.reader.loadBeanDefinitions(resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load bean definitions from the given XML resources.
|
||||
* @param resourceLocations one or more resource locations to load from
|
||||
*/
|
||||
public void load(String... resourceLocations) {
|
||||
this.reader.loadBeanDefinitions(resourceLocations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load bean definitions from the given XML resources.
|
||||
* @param relativeClass class whose package will be used as a prefix when
|
||||
* loading each specified resource name
|
||||
* @param resourceNames relatively-qualified names of resources to load
|
||||
*/
|
||||
public void load(Class<?> relativeClass, String... resourceNames) {
|
||||
Resource[] resources = new Resource[resourceNames.length];
|
||||
for (int i = 0; i < resourceNames.length; i++) {
|
||||
resources[i] = new ClassPathResource(resourceNames[i], relativeClass);
|
||||
}
|
||||
this.load(resources);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.support;
|
||||
|
||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
/**
|
||||
* Convenient application context with built-in XML support.
|
||||
* This is a flexible alternative to {@link ClassPathXmlApplicationContext}
|
||||
* and {@link FileSystemXmlApplicationContext}, to be configured via setters,
|
||||
* with an eventual {@link #refresh()} call activating the context.
|
||||
*
|
||||
* <p>In case of multiple configuration files, bean definitions in later files
|
||||
* will override those defined in earlier files. This can be leveraged to
|
||||
* deliberately override certain bean definitions via an extra configuration file.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Chris Beams
|
||||
* @since 3.0
|
||||
* @see #load
|
||||
* @see XmlBeanDefinitionReader
|
||||
* @see org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
*/
|
||||
public class GenericXmlApplicationContext extends GenericApplicationContext {
|
||||
|
||||
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext that needs to be
|
||||
* {@linkplain #load loaded} and then manually {@link #refresh refreshed}.
|
||||
*/
|
||||
public GenericXmlApplicationContext() {
|
||||
reader.setEnvironment(this.getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||
* from the given resources and automatically refreshing the context.
|
||||
* @param resources the resources to load from
|
||||
*/
|
||||
public GenericXmlApplicationContext(Resource... resources) {
|
||||
load(resources);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||
* from the given resource locations and automatically refreshing the context.
|
||||
* @param resourceLocations the resources to load from
|
||||
*/
|
||||
public GenericXmlApplicationContext(String... resourceLocations) {
|
||||
load(resourceLocations);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new GenericXmlApplicationContext, loading bean definitions
|
||||
* from the given resource locations and automatically refreshing the context.
|
||||
* @param relativeClass class whose package will be used as a prefix when
|
||||
* loading each specified resource name
|
||||
* @param resourceNames relatively-qualified names of resources to load
|
||||
*/
|
||||
public GenericXmlApplicationContext(Class<?> relativeClass, String... resourceNames) {
|
||||
load(relativeClass, resourceNames);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to use XML validation. Default is <code>true</code>.
|
||||
*/
|
||||
public void setValidating(boolean validating) {
|
||||
this.reader.setValidating(validating);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Delegates the given environment to underlying {@link XmlBeanDefinitionReader}.
|
||||
* Should be called before any call to {@link #load}.
|
||||
*/
|
||||
@Override
|
||||
public void setEnvironment(ConfigurableEnvironment environment) {
|
||||
super.setEnvironment(environment);
|
||||
this.reader.setEnvironment(this.getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Load bean definitions from the given XML resources.
|
||||
* @param resources one or more resources to load from
|
||||
*/
|
||||
public void load(Resource... resources) {
|
||||
this.reader.loadBeanDefinitions(resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load bean definitions from the given XML resources.
|
||||
* @param resourceLocations one or more resource locations to load from
|
||||
*/
|
||||
public void load(String... resourceLocations) {
|
||||
this.reader.loadBeanDefinitions(resourceLocations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load bean definitions from the given XML resources.
|
||||
* @param relativeClass class whose package will be used as a prefix when
|
||||
* loading each specified resource name
|
||||
* @param resourceNames relatively-qualified names of resources to load
|
||||
*/
|
||||
public void load(Class<?> relativeClass, String... resourceNames) {
|
||||
Resource[] resources = new Resource[resourceNames.length];
|
||||
for (int i = 0; i < resourceNames.length; i++) {
|
||||
resources[i] = new ClassPathResource(resourceNames[i], relativeClass);
|
||||
}
|
||||
this.load(resources);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,74 +1,74 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.format.number;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.format.Formatter;
|
||||
|
||||
/**
|
||||
* Abstract formatter for Numbers,
|
||||
* providing a {@link #getNumberFormat(java.util.Locale)} template method.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class AbstractNumberFormatter implements Formatter<Number> {
|
||||
|
||||
private boolean lenient = 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.
|
||||
* With strict parsing, inputs must match the format exactly.
|
||||
*/
|
||||
public void setLenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
public String print(Number number, Locale locale) {
|
||||
return getNumberFormat(locale).format(number);
|
||||
}
|
||||
|
||||
public Number parse(String text, Locale locale) throws ParseException {
|
||||
NumberFormat format = getNumberFormat(locale);
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
Number number = format.parse(text, position);
|
||||
if (position.getErrorIndex() != -1) {
|
||||
throw new ParseException(text, position.getIndex());
|
||||
}
|
||||
if (!this.lenient) {
|
||||
if (text.length() != position.getIndex()) {
|
||||
// indicates a part of the string that was not parsed
|
||||
throw new ParseException(text, position.getIndex());
|
||||
}
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a concrete NumberFormat for the specified locale.
|
||||
* @param locale the current locale
|
||||
* @return the NumberFormat instance (never <code>null</code>)
|
||||
*/
|
||||
protected abstract NumberFormat getNumberFormat(Locale locale);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.format.number;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.springframework.format.Formatter;
|
||||
|
||||
/**
|
||||
* Abstract formatter for Numbers,
|
||||
* providing a {@link #getNumberFormat(java.util.Locale)} template method.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Keith Donald
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class AbstractNumberFormatter implements Formatter<Number> {
|
||||
|
||||
private boolean lenient = 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.
|
||||
* With strict parsing, inputs must match the format exactly.
|
||||
*/
|
||||
public void setLenient(boolean lenient) {
|
||||
this.lenient = lenient;
|
||||
}
|
||||
|
||||
public String print(Number number, Locale locale) {
|
||||
return getNumberFormat(locale).format(number);
|
||||
}
|
||||
|
||||
public Number parse(String text, Locale locale) throws ParseException {
|
||||
NumberFormat format = getNumberFormat(locale);
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
Number number = format.parse(text, position);
|
||||
if (position.getErrorIndex() != -1) {
|
||||
throw new ParseException(text, position.getIndex());
|
||||
}
|
||||
if (!this.lenient) {
|
||||
if (text.length() != position.getIndex()) {
|
||||
// indicates a part of the string that was not parsed
|
||||
throw new ParseException(text, position.getIndex());
|
||||
}
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain a concrete NumberFormat for the specified locale.
|
||||
* @param locale the current locale
|
||||
* @return the NumberFormat instance (never <code>null</code>)
|
||||
*/
|
||||
protected abstract NumberFormat getNumberFormat(Locale locale);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,128 +1,128 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.glassfish;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Reflective wrapper around the GlassFish class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* <p>Supports GlassFish V1, V2 and V3 (currently in beta).
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
class GlassFishClassLoaderAdapter {
|
||||
|
||||
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2 = "com.sun.enterprise.loader.InstrumentableClassLoader";
|
||||
|
||||
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3 = "org.glassfish.api.deployment.InstrumentableClassLoader";
|
||||
|
||||
private static final String CLASS_TRANSFORMER = "javax.persistence.spi.ClassTransformer";
|
||||
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private final Method addTransformer;
|
||||
|
||||
private final Method copy;
|
||||
|
||||
private final boolean glassFishV3;
|
||||
|
||||
|
||||
public GlassFishClassLoaderAdapter(ClassLoader classLoader) {
|
||||
Class<?> instrumentableLoaderClass;
|
||||
boolean glassV3 = false;
|
||||
try {
|
||||
// try the V1/V2 API first
|
||||
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// fall back to V3
|
||||
try {
|
||||
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3);
|
||||
glassV3 = true;
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalStateException("Could not initialize GlassFish LoadTimeWeaver because " +
|
||||
"GlassFish (V1, V2 or V3) API classes are not available", ex);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class<?> classTransformerClass =
|
||||
(glassV3 ? ClassFileTransformer.class : classLoader.loadClass(CLASS_TRANSFORMER));
|
||||
|
||||
this.addTransformer = instrumentableLoaderClass.getMethod("addTransformer", classTransformerClass);
|
||||
this.copy = instrumentableLoaderClass.getMethod("copy");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize GlassFish LoadTimeWeaver because GlassFish API classes are not available", ex);
|
||||
}
|
||||
|
||||
ClassLoader clazzLoader = null;
|
||||
// Detect transformation-aware ClassLoader by traversing the hierarchy
|
||||
// (as in GlassFish, Spring can be loaded by the WebappClassLoader).
|
||||
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
||||
if (instrumentableLoaderClass.isInstance(cl)) {
|
||||
clazzLoader = cl;
|
||||
}
|
||||
}
|
||||
|
||||
if (clazzLoader == null) {
|
||||
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" +
|
||||
instrumentableLoaderClass.getName() + "] implementation is required.");
|
||||
}
|
||||
|
||||
this.classLoader = clazzLoader;
|
||||
this.glassFishV3 = glassV3;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
try {
|
||||
this.addTransformer.invoke(this.classLoader,
|
||||
(this.glassFishV3 ? transformer : new ClassTransformerAdapter(transformer)));
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("GlassFish addTransformer method threw exception ", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke GlassFish addTransformer method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
return (ClassLoader) this.copy.invoke(this.classLoader);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("GlassFish copy method threw exception ", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke GlassFish copy method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.glassfish;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Reflective wrapper around the GlassFish class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* <p>Supports GlassFish V1, V2 and V3 (currently in beta).
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
class GlassFishClassLoaderAdapter {
|
||||
|
||||
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2 = "com.sun.enterprise.loader.InstrumentableClassLoader";
|
||||
|
||||
static final String INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3 = "org.glassfish.api.deployment.InstrumentableClassLoader";
|
||||
|
||||
private static final String CLASS_TRANSFORMER = "javax.persistence.spi.ClassTransformer";
|
||||
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private final Method addTransformer;
|
||||
|
||||
private final Method copy;
|
||||
|
||||
private final boolean glassFishV3;
|
||||
|
||||
|
||||
public GlassFishClassLoaderAdapter(ClassLoader classLoader) {
|
||||
Class<?> instrumentableLoaderClass;
|
||||
boolean glassV3 = false;
|
||||
try {
|
||||
// try the V1/V2 API first
|
||||
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V2);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
// fall back to V3
|
||||
try {
|
||||
instrumentableLoaderClass = classLoader.loadClass(INSTRUMENTABLE_CLASSLOADER_GLASSFISH_V3);
|
||||
glassV3 = true;
|
||||
}
|
||||
catch (ClassNotFoundException cnfe) {
|
||||
throw new IllegalStateException("Could not initialize GlassFish LoadTimeWeaver because " +
|
||||
"GlassFish (V1, V2 or V3) API classes are not available", ex);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class<?> classTransformerClass =
|
||||
(glassV3 ? ClassFileTransformer.class : classLoader.loadClass(CLASS_TRANSFORMER));
|
||||
|
||||
this.addTransformer = instrumentableLoaderClass.getMethod("addTransformer", classTransformerClass);
|
||||
this.copy = instrumentableLoaderClass.getMethod("copy");
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize GlassFish LoadTimeWeaver because GlassFish API classes are not available", ex);
|
||||
}
|
||||
|
||||
ClassLoader clazzLoader = null;
|
||||
// Detect transformation-aware ClassLoader by traversing the hierarchy
|
||||
// (as in GlassFish, Spring can be loaded by the WebappClassLoader).
|
||||
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
||||
if (instrumentableLoaderClass.isInstance(cl)) {
|
||||
clazzLoader = cl;
|
||||
}
|
||||
}
|
||||
|
||||
if (clazzLoader == null) {
|
||||
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: A [" +
|
||||
instrumentableLoaderClass.getName() + "] implementation is required.");
|
||||
}
|
||||
|
||||
this.classLoader = clazzLoader;
|
||||
this.glassFishV3 = glassV3;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
try {
|
||||
this.addTransformer.invoke(this.classLoader,
|
||||
(this.glassFishV3 ? transformer : new ClassTransformerAdapter(transformer)));
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("GlassFish addTransformer method threw exception ", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke GlassFish addTransformer method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
return (ClassLoader) this.copy.invoke(this.classLoader);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("GlassFish copy method threw exception ", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke GlassFish copy method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
/**
|
||||
* Simple interface used for handling the different JBoss class loader adapters.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
interface JBossClassLoaderAdapter {
|
||||
|
||||
void addTransformer(ClassFileTransformer transformer);
|
||||
|
||||
ClassLoader getInstrumentableClassLoader();
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
/**
|
||||
* Simple interface used for handling the different JBoss class loader adapters.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
interface JBossClassLoaderAdapter {
|
||||
|
||||
void addTransformer(ClassFileTransformer transformer);
|
||||
|
||||
ClassLoader getInstrumentableClassLoader();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,91 +1,91 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.instrument.classloading.SimpleThrowawayClassLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader.
|
||||
* Autodetects the specific JBoss version at runtime: currently supports
|
||||
* 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
|
||||
* application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt>
|
||||
* file to the application archive - with the following content:
|
||||
* <pre><scanning xmlns="urn:jboss:scanning:1.0"/></pre>
|
||||
*
|
||||
* <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
private final JBossClassLoaderAdapter adapter;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
||||
* the default {@link ClassLoader class loader}.
|
||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||
*/
|
||||
public JBossLoadTimeWeaver() {
|
||||
this(ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
||||
* the supplied {@link ClassLoader}.
|
||||
* @param classLoader the <code>ClassLoader</code> to delegate to for
|
||||
* weaving (must not be <code>null</code>)
|
||||
*/
|
||||
public JBossLoadTimeWeaver(ClassLoader classLoader) {
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||
String loaderClassName = classLoader.getClass().getName();
|
||||
|
||||
if (loaderClassName.startsWith("org.jboss.classloader")) {
|
||||
// JBoss AS 5 or JBoss AS 6
|
||||
this.adapter = new JBossMCAdapter(classLoader);
|
||||
}
|
||||
else if (loaderClassName.startsWith("org.jboss.modules")) {
|
||||
// JBoss AS 7
|
||||
this.adapter = new JBossModulesAdapter(classLoader);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unexpected ClassLoader type: " + loaderClassName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
this.adapter.addTransformer(transformer);
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return this.adapter.getInstrumentableClassLoader();
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
return new SimpleThrowawayClassLoader(getInstrumentableClassLoader());
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.instrument.classloading.SimpleThrowawayClassLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link LoadTimeWeaver} implementation for JBoss's instrumentable ClassLoader.
|
||||
* Autodetects the specific JBoss version at runtime: currently supports
|
||||
* 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
|
||||
* application actually starts, one needs to add a <tt>WEB-INF/jboss-scanning.xml</tt>
|
||||
* file to the application archive - with the following content:
|
||||
* <pre><scanning xmlns="urn:jboss:scanning:1.0"/></pre>
|
||||
*
|
||||
* <p>Thanks to Ales Justin and Marius Bogoevici for the initial prototype.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.0
|
||||
*/
|
||||
public class JBossLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
private final JBossClassLoaderAdapter adapter;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
||||
* the default {@link ClassLoader class loader}.
|
||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||
*/
|
||||
public JBossLoadTimeWeaver() {
|
||||
this(ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link JBossLoadTimeWeaver} class using
|
||||
* the supplied {@link ClassLoader}.
|
||||
* @param classLoader the <code>ClassLoader</code> to delegate to for
|
||||
* weaving (must not be <code>null</code>)
|
||||
*/
|
||||
public JBossLoadTimeWeaver(ClassLoader classLoader) {
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||
String loaderClassName = classLoader.getClass().getName();
|
||||
|
||||
if (loaderClassName.startsWith("org.jboss.classloader")) {
|
||||
// JBoss AS 5 or JBoss AS 6
|
||||
this.adapter = new JBossMCAdapter(classLoader);
|
||||
}
|
||||
else if (loaderClassName.startsWith("org.jboss.modules")) {
|
||||
// JBoss AS 7
|
||||
this.adapter = new JBossModulesAdapter(classLoader);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unexpected ClassLoader type: " + loaderClassName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
this.adapter.addTransformer(transformer);
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return this.adapter.getInstrumentableClassLoader();
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
return new SimpleThrowawayClassLoader(getInstrumentableClassLoader());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,145 +1,145 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Reflective wrapper around a JBoss 5 and 6 class loader methods (discovered and called
|
||||
* through reflection) for load time weaving.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class JBossMCAdapter implements JBossClassLoaderAdapter {
|
||||
|
||||
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 DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain";
|
||||
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 GET_POLICY = "getPolicy";
|
||||
private static final String GET_DOMAIN = "getClassLoaderDomain";
|
||||
private static final String GET_SYSTEM = "getClassLoaderSystem";
|
||||
|
||||
// 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";
|
||||
// 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 final ClassLoader classLoader;
|
||||
private final Class<?> translatorClass;
|
||||
|
||||
private final Method addTranslator;
|
||||
private final Object target;
|
||||
|
||||
JBossMCAdapter(ClassLoader classLoader) {
|
||||
Class<?> clazzLoaderType = null;
|
||||
try {
|
||||
// resolve BaseClassLoader.class
|
||||
clazzLoaderType = classLoader.loadClass(LOADER_NAME);
|
||||
|
||||
ClassLoader clazzLoader = null;
|
||||
// walk the hierarchy to detect the instrumentation aware classloader
|
||||
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
||||
if (clazzLoaderType.isInstance(cl)) {
|
||||
clazzLoader = cl;
|
||||
}
|
||||
}
|
||||
|
||||
if (clazzLoader == null) {
|
||||
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: "
|
||||
+ "A [" + LOADER_NAME + "] implementation is required.");
|
||||
}
|
||||
|
||||
this.classLoader = clazzLoader;
|
||||
// use the classloader that loaded the classloader to load
|
||||
// the types for reflection purposes
|
||||
classLoader = clazzLoader.getClass().getClassLoader();
|
||||
|
||||
// BaseClassLoader#getPolicy
|
||||
Method method = clazzLoaderType.getDeclaredMethod(GET_POLICY);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
Object policy = method.invoke(this.classLoader);
|
||||
|
||||
Object addTarget = null;
|
||||
Method addMethod = null;
|
||||
|
||||
// try the 5.1.x hooks
|
||||
// check existence of BaseClassLoaderPolicy#addTranslator(Translator)
|
||||
this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME);
|
||||
Class<?> clazz = classLoader.loadClass(POLICY_NAME);
|
||||
try {
|
||||
addMethod = clazz.getDeclaredMethod(ADD_TRANSLATOR_NAME, translatorClass);
|
||||
addTarget = policy;
|
||||
} catch (NoSuchMethodException ex) {
|
||||
}
|
||||
|
||||
// fall back to 5.0.x method
|
||||
if (addMethod == null) {
|
||||
|
||||
// BaseClassLoaderPolicy#getClassLoaderDomain
|
||||
method = clazz.getDeclaredMethod(GET_DOMAIN);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
Object domain = method.invoke(policy);
|
||||
|
||||
// BaseClassLoaderDomain#getClassLoaderSystem
|
||||
clazz = classLoader.loadClass(DOMAIN_NAME);
|
||||
method = clazz.getDeclaredMethod(GET_SYSTEM);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
Object system = method.invoke(domain);
|
||||
|
||||
// resolve ClassLoaderSystem
|
||||
clazz = classLoader.loadClass(DEDICATED_SYSTEM);
|
||||
Assert.isInstanceOf(clazz, system, "JBoss LoadTimeWeaver requires JBoss loader system of type "
|
||||
+ clazz.getName() + " on JBoss 5.0.x");
|
||||
|
||||
// ClassLoaderSystem#setTranslator
|
||||
addMethod = clazz.getDeclaredMethod(SET_TRANSLATOR_NAME, translatorClass);
|
||||
addTarget = system;
|
||||
}
|
||||
|
||||
this.addTranslator = addMethod;
|
||||
this.target = addTarget;
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(),
|
||||
new Class[] { this.translatorClass }, adapter);
|
||||
|
||||
try {
|
||||
addTranslator.invoke(target, adapterInstance);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not add transformer on JBoss 5/6 classloader " + classLoader, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Reflective wrapper around a JBoss 5 and 6 class loader methods (discovered and called
|
||||
* through reflection) for load time weaving.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class JBossMCAdapter implements JBossClassLoaderAdapter {
|
||||
|
||||
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 DOMAIN_NAME = "org.jboss.classloader.spi.base.BaseClassLoaderDomain";
|
||||
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 GET_POLICY = "getPolicy";
|
||||
private static final String GET_DOMAIN = "getClassLoaderDomain";
|
||||
private static final String GET_SYSTEM = "getClassLoaderSystem";
|
||||
|
||||
// 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";
|
||||
// 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 final ClassLoader classLoader;
|
||||
private final Class<?> translatorClass;
|
||||
|
||||
private final Method addTranslator;
|
||||
private final Object target;
|
||||
|
||||
JBossMCAdapter(ClassLoader classLoader) {
|
||||
Class<?> clazzLoaderType = null;
|
||||
try {
|
||||
// resolve BaseClassLoader.class
|
||||
clazzLoaderType = classLoader.loadClass(LOADER_NAME);
|
||||
|
||||
ClassLoader clazzLoader = null;
|
||||
// walk the hierarchy to detect the instrumentation aware classloader
|
||||
for (ClassLoader cl = classLoader; cl != null && clazzLoader == null; cl = cl.getParent()) {
|
||||
if (clazzLoaderType.isInstance(cl)) {
|
||||
clazzLoader = cl;
|
||||
}
|
||||
}
|
||||
|
||||
if (clazzLoader == null) {
|
||||
throw new IllegalArgumentException(classLoader + " and its parents are not suitable ClassLoaders: "
|
||||
+ "A [" + LOADER_NAME + "] implementation is required.");
|
||||
}
|
||||
|
||||
this.classLoader = clazzLoader;
|
||||
// use the classloader that loaded the classloader to load
|
||||
// the types for reflection purposes
|
||||
classLoader = clazzLoader.getClass().getClassLoader();
|
||||
|
||||
// BaseClassLoader#getPolicy
|
||||
Method method = clazzLoaderType.getDeclaredMethod(GET_POLICY);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
Object policy = method.invoke(this.classLoader);
|
||||
|
||||
Object addTarget = null;
|
||||
Method addMethod = null;
|
||||
|
||||
// try the 5.1.x hooks
|
||||
// check existence of BaseClassLoaderPolicy#addTranslator(Translator)
|
||||
this.translatorClass = classLoader.loadClass(TRANSLATOR_NAME);
|
||||
Class<?> clazz = classLoader.loadClass(POLICY_NAME);
|
||||
try {
|
||||
addMethod = clazz.getDeclaredMethod(ADD_TRANSLATOR_NAME, translatorClass);
|
||||
addTarget = policy;
|
||||
} catch (NoSuchMethodException ex) {
|
||||
}
|
||||
|
||||
// fall back to 5.0.x method
|
||||
if (addMethod == null) {
|
||||
|
||||
// BaseClassLoaderPolicy#getClassLoaderDomain
|
||||
method = clazz.getDeclaredMethod(GET_DOMAIN);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
Object domain = method.invoke(policy);
|
||||
|
||||
// BaseClassLoaderDomain#getClassLoaderSystem
|
||||
clazz = classLoader.loadClass(DOMAIN_NAME);
|
||||
method = clazz.getDeclaredMethod(GET_SYSTEM);
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
Object system = method.invoke(domain);
|
||||
|
||||
// resolve ClassLoaderSystem
|
||||
clazz = classLoader.loadClass(DEDICATED_SYSTEM);
|
||||
Assert.isInstanceOf(clazz, system, "JBoss LoadTimeWeaver requires JBoss loader system of type "
|
||||
+ clazz.getName() + " on JBoss 5.0.x");
|
||||
|
||||
// ClassLoaderSystem#setTranslator
|
||||
addMethod = clazz.getDeclaredMethod(SET_TRANSLATOR_NAME, translatorClass);
|
||||
addTarget = system;
|
||||
}
|
||||
|
||||
this.addTranslator = addMethod;
|
||||
this.target = addTarget;
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize JBoss LoadTimeWeaver because the JBoss 5 API classes are not available", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
InvocationHandler adapter = new JBossMCTranslatorAdapter(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.translatorClass.getClassLoader(),
|
||||
new Class[] { this.translatorClass }, adapter);
|
||||
|
||||
try {
|
||||
addTranslator.invoke(target, adapterInstance);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not add transformer on JBoss 5/6 classloader " + classLoader, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
}
|
||||
@@ -1,82 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* Adapter that implements JBoss Translator interface, delegating to a
|
||||
* standard JDK {@link ClassFileTransformer} underneath.
|
||||
*
|
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||
* being used.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class JBossMCTranslatorAdapter implements InvocationHandler {
|
||||
|
||||
private final ClassFileTransformer transformer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JBossMCTranslatorAdapter}.
|
||||
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
||||
* not be <code>null</code>)
|
||||
*/
|
||||
public JBossMCTranslatorAdapter(ClassFileTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String name = method.getName();
|
||||
|
||||
if ("equals".equals(name)) {
|
||||
return (Boolean.valueOf(proxy == args[0]));
|
||||
} else if ("hashCode".equals(name)) {
|
||||
return hashCode();
|
||||
} else if ("toString".equals(name)) {
|
||||
return toString();
|
||||
} else if ("transform".equals(name)) {
|
||||
return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3],
|
||||
(byte[]) args[4]);
|
||||
} else if ("unregisterClassLoader".equals(name)) {
|
||||
unregisterClassLoader((ClassLoader) args[0]);
|
||||
return null;
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception {
|
||||
return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
|
||||
}
|
||||
|
||||
public void unregisterClassLoader(ClassLoader loader) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||
builder.append(" for transformer: ");
|
||||
builder.append(this.transformer);
|
||||
return builder.toString();
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* Adapter that implements JBoss Translator interface, delegating to a
|
||||
* standard JDK {@link ClassFileTransformer} underneath.
|
||||
*
|
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||
* being used.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class JBossMCTranslatorAdapter implements InvocationHandler {
|
||||
|
||||
private final ClassFileTransformer transformer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JBossMCTranslatorAdapter}.
|
||||
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
||||
* not be <code>null</code>)
|
||||
*/
|
||||
public JBossMCTranslatorAdapter(ClassFileTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String name = method.getName();
|
||||
|
||||
if ("equals".equals(name)) {
|
||||
return (Boolean.valueOf(proxy == args[0]));
|
||||
} else if ("hashCode".equals(name)) {
|
||||
return hashCode();
|
||||
} else if ("toString".equals(name)) {
|
||||
return toString();
|
||||
} else if ("transform".equals(name)) {
|
||||
return transform((ClassLoader) args[0], (String) args[1], (Class<?>) args[2], (ProtectionDomain) args[3],
|
||||
(byte[]) args[4]);
|
||||
} else if ("unregisterClassLoader".equals(name)) {
|
||||
unregisterClassLoader((ClassLoader) args[0]);
|
||||
return null;
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws Exception {
|
||||
return transformer.transform(loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
|
||||
}
|
||||
|
||||
public void unregisterClassLoader(ClassLoader loader) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||
builder.append(" for transformer: ");
|
||||
builder.append(this.transformer);
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,71 +1,71 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* JBoss 7 adapter.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class JBossModulesAdapter implements JBossClassLoaderAdapter {
|
||||
|
||||
private static final String TRANSFORMER_FIELD_NAME = "transformer";
|
||||
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 final ClassLoader classLoader;
|
||||
private final Method addTransformer;
|
||||
private final Object delegatingTransformer;
|
||||
|
||||
public JBossModulesAdapter(ClassLoader loader) {
|
||||
this.classLoader = loader;
|
||||
|
||||
try {
|
||||
Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME);
|
||||
transformers.setAccessible(true);
|
||||
|
||||
delegatingTransformer = transformers.get(classLoader);
|
||||
|
||||
Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME),
|
||||
"Transformer not of the expected type: " + delegatingTransformer.getClass().getName());
|
||||
addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME,
|
||||
ClassFileTransformer.class);
|
||||
addTransformer.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
try {
|
||||
addTransformer.invoke(delegatingTransformer, transformer);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* JBoss 7 adapter.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class JBossModulesAdapter implements JBossClassLoaderAdapter {
|
||||
|
||||
private static final String TRANSFORMER_FIELD_NAME = "transformer";
|
||||
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 final ClassLoader classLoader;
|
||||
private final Method addTransformer;
|
||||
private final Object delegatingTransformer;
|
||||
|
||||
public JBossModulesAdapter(ClassLoader loader) {
|
||||
this.classLoader = loader;
|
||||
|
||||
try {
|
||||
Field transformers = ReflectionUtils.findField(classLoader.getClass(), TRANSFORMER_FIELD_NAME);
|
||||
transformers.setAccessible(true);
|
||||
|
||||
delegatingTransformer = transformers.get(classLoader);
|
||||
|
||||
Assert.state(delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME),
|
||||
"Transformer not of the expected type: " + delegatingTransformer.getClass().getName());
|
||||
addTransformer = ReflectionUtils.findMethod(delegatingTransformer.getClass(), TRANSFORMER_ADD_METHOD_NAME,
|
||||
ClassFileTransformer.class);
|
||||
addTransformer.setAccessible(true);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not initialize JBoss 7 LoadTimeWeaver", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
try {
|
||||
addTransformer.invoke(delegatingTransformer, transformer);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not add transformer on JBoss 7 classloader " + classLoader, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x.
|
||||
*
|
||||
*/
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for class instrumentation on JBoss AS 5.x / JBoss MC 2.0.x.
|
||||
*
|
||||
*/
|
||||
package org.springframework.instrument.classloading.jboss;
|
||||
|
||||
|
||||
@@ -1,88 +1,88 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.oc4j;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Reflective wrapper around a OC4J class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
class OC4JClassLoaderAdapter {
|
||||
|
||||
private static final String CL_UTILS = "oracle.classloader.util.ClassLoaderUtilities";
|
||||
private static final String PREPROCESS_UTILS = "oracle.classloader.util.ClassPreprocessor";
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
private final Class<?> processorClass;
|
||||
private final Method addTransformer;
|
||||
private final Method copy;
|
||||
|
||||
public OC4JClassLoaderAdapter(ClassLoader classLoader) {
|
||||
try {
|
||||
// Since OC4J 10.1.3's PolicyClassLoader is going to be removed,
|
||||
// we rely on the ClassLoaderUtilities API instead.
|
||||
Class<?> utilClass = classLoader.loadClass(CL_UTILS);
|
||||
this.processorClass = classLoader.loadClass(PREPROCESS_UTILS);
|
||||
|
||||
this.addTransformer = utilClass.getMethod("addPreprocessor", new Class[] { ClassLoader.class,
|
||||
this.processorClass });
|
||||
this.copy = utilClass.getMethod("copy", new Class[] { ClassLoader.class });
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize OC4J LoadTimeWeaver because OC4J API classes are not available", ex);
|
||||
}
|
||||
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
||||
try {
|
||||
OC4JClassPreprocessorAdapter adapter = new OC4JClassPreprocessorAdapter(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.processorClass.getClassLoader(),
|
||||
new Class[] { this.processorClass }, adapter);
|
||||
this.addTransformer.invoke(null, new Object[] { this.classLoader, adapterInstance });
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("OC4J addPreprocessor method threw exception", ex.getCause());
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke OC4J addPreprocessor method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
return (ClassLoader) this.copy.invoke(null, new Object[] { this.classLoader });
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("OC4J copy method failed", ex.getCause());
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not copy OC4J classloader", ex);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.oc4j;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Reflective wrapper around a OC4J class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
class OC4JClassLoaderAdapter {
|
||||
|
||||
private static final String CL_UTILS = "oracle.classloader.util.ClassLoaderUtilities";
|
||||
private static final String PREPROCESS_UTILS = "oracle.classloader.util.ClassPreprocessor";
|
||||
|
||||
private final ClassLoader classLoader;
|
||||
private final Class<?> processorClass;
|
||||
private final Method addTransformer;
|
||||
private final Method copy;
|
||||
|
||||
public OC4JClassLoaderAdapter(ClassLoader classLoader) {
|
||||
try {
|
||||
// Since OC4J 10.1.3's PolicyClassLoader is going to be removed,
|
||||
// we rely on the ClassLoaderUtilities API instead.
|
||||
Class<?> utilClass = classLoader.loadClass(CL_UTILS);
|
||||
this.processorClass = classLoader.loadClass(PREPROCESS_UTILS);
|
||||
|
||||
this.addTransformer = utilClass.getMethod("addPreprocessor", new Class[] { ClassLoader.class,
|
||||
this.processorClass });
|
||||
this.copy = utilClass.getMethod("copy", new Class[] { ClassLoader.class });
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize OC4J LoadTimeWeaver because OC4J API classes are not available", ex);
|
||||
}
|
||||
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
||||
try {
|
||||
OC4JClassPreprocessorAdapter adapter = new OC4JClassPreprocessorAdapter(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.processorClass.getClassLoader(),
|
||||
new Class[] { this.processorClass }, adapter);
|
||||
this.addTransformer.invoke(null, new Object[] { this.classLoader, adapterInstance });
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("OC4J addPreprocessor method threw exception", ex.getCause());
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke OC4J addPreprocessor method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
return (ClassLoader) this.copy.invoke(null, new Object[] { this.classLoader });
|
||||
} catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("OC4J copy method failed", ex.getCause());
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not copy OC4J classloader", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,95 +1,95 @@
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.oc4j;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.IllegalClassFormatException;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* Adapter that implements OC4J ClassPreProcessor interface, delegating to a
|
||||
* standard JDK {@link ClassFileTransformer} underneath.
|
||||
*
|
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||
* being used.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
class OC4JClassPreprocessorAdapter implements InvocationHandler {
|
||||
|
||||
private final ClassFileTransformer transformer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link OC4JClassPreprocessorAdapter}.
|
||||
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
||||
* not be <code>null</code>)
|
||||
*/
|
||||
public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String name = method.getName();
|
||||
|
||||
if ("equals".equals(name)) {
|
||||
return (Boolean.valueOf(proxy == args[0]));
|
||||
} else if ("hashCode".equals(name)) {
|
||||
return hashCode();
|
||||
} else if ("toString".equals(name)) {
|
||||
return toString();
|
||||
} else if ("initialize".equals(name)) {
|
||||
initialize(proxy, (ClassLoader) args[0]);
|
||||
return null;
|
||||
} else if ("processClass".equals(name)) {
|
||||
return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3],
|
||||
(ProtectionDomain) args[4], (ClassLoader) args[5]);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
// maps to oracle.classloader.util.ClassPreprocessor#initialize
|
||||
// the proxy is passed since it implements the Oracle interface which
|
||||
// is asked as a return type
|
||||
public Object initialize(Object proxy, ClassLoader loader) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd,
|
||||
ClassLoader loader) {
|
||||
try {
|
||||
byte[] tempArray = new byte[length];
|
||||
System.arraycopy(origClassBytes, offset, tempArray, 0, length);
|
||||
|
||||
// NB: OC4J passes className as "." without class while the
|
||||
// transformer expects a VM, "/" format
|
||||
byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray);
|
||||
return (result != null ? result : origClassBytes);
|
||||
} catch (IllegalClassFormatException ex) {
|
||||
throw new IllegalStateException("Cannot transform because of illegal class format", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||
builder.append(" for transformer: ");
|
||||
builder.append(this.transformer);
|
||||
return builder.toString();
|
||||
}
|
||||
/*
|
||||
* Copyright 2006-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.oc4j;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.instrument.IllegalClassFormatException;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
* Adapter that implements OC4J ClassPreProcessor interface, delegating to a
|
||||
* standard JDK {@link ClassFileTransformer} underneath.
|
||||
*
|
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||
* being used.
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
class OC4JClassPreprocessorAdapter implements InvocationHandler {
|
||||
|
||||
private final ClassFileTransformer transformer;
|
||||
|
||||
/**
|
||||
* Creates a new {@link OC4JClassPreprocessorAdapter}.
|
||||
* @param transformer the {@link ClassFileTransformer} to be adapted (must
|
||||
* not be <code>null</code>)
|
||||
*/
|
||||
public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
}
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String name = method.getName();
|
||||
|
||||
if ("equals".equals(name)) {
|
||||
return (Boolean.valueOf(proxy == args[0]));
|
||||
} else if ("hashCode".equals(name)) {
|
||||
return hashCode();
|
||||
} else if ("toString".equals(name)) {
|
||||
return toString();
|
||||
} else if ("initialize".equals(name)) {
|
||||
initialize(proxy, (ClassLoader) args[0]);
|
||||
return null;
|
||||
} else if ("processClass".equals(name)) {
|
||||
return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3],
|
||||
(ProtectionDomain) args[4], (ClassLoader) args[5]);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
// maps to oracle.classloader.util.ClassPreprocessor#initialize
|
||||
// the proxy is passed since it implements the Oracle interface which
|
||||
// is asked as a return type
|
||||
public Object initialize(Object proxy, ClassLoader loader) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd,
|
||||
ClassLoader loader) {
|
||||
try {
|
||||
byte[] tempArray = new byte[length];
|
||||
System.arraycopy(origClassBytes, offset, tempArray, 0, length);
|
||||
|
||||
// NB: OC4J passes className as "." without class while the
|
||||
// transformer expects a VM, "/" format
|
||||
byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray);
|
||||
return (result != null ? result : origClassBytes);
|
||||
} catch (IllegalClassFormatException ex) {
|
||||
throw new IllegalStateException("Cannot transform because of illegal class format", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||
builder.append(" for transformer: ");
|
||||
builder.append(this.transformer);
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,111 +1,111 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Reflective wrapper around a WebSphere 7 class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class WebSphereClassLoaderAdapter {
|
||||
|
||||
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 PLUGINS_FIELD = "preDefinePlugins";
|
||||
|
||||
private ClassLoader classLoader;
|
||||
private Class<?> wsPreProcessorClass;
|
||||
private Method addPreDefinePlugin;
|
||||
private Constructor<? extends ClassLoader> cloneConstructor;
|
||||
private Field transformerList;
|
||||
|
||||
public WebSphereClassLoaderAdapter(ClassLoader classLoader) {
|
||||
Class<?> wsCompoundClassLoaderClass = null;
|
||||
try {
|
||||
wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME);
|
||||
cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
|
||||
cloneConstructor.setAccessible(true);
|
||||
|
||||
wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
|
||||
addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass);
|
||||
transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
|
||||
transformerList.setAccessible(true);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available",
|
||||
ex);
|
||||
}
|
||||
Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader,
|
||||
"ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]");
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
||||
try {
|
||||
InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(),
|
||||
new Class[] { this.wsPreProcessorClass }, adapter);
|
||||
this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance);
|
||||
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
ClassLoader loader = (ClassLoader) cloneConstructor.newInstance(getClassLoader());
|
||||
// clear out the transformers (copied as well)
|
||||
List list = (List) transformerList.get(loader);
|
||||
list.clear();
|
||||
return loader;
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Reflective wrapper around a WebSphere 7 class loader. Used to
|
||||
* encapsulate the classloader-specific methods (discovered and
|
||||
* called through reflection) from the load-time weaver.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class WebSphereClassLoaderAdapter {
|
||||
|
||||
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 PLUGINS_FIELD = "preDefinePlugins";
|
||||
|
||||
private ClassLoader classLoader;
|
||||
private Class<?> wsPreProcessorClass;
|
||||
private Method addPreDefinePlugin;
|
||||
private Constructor<? extends ClassLoader> cloneConstructor;
|
||||
private Field transformerList;
|
||||
|
||||
public WebSphereClassLoaderAdapter(ClassLoader classLoader) {
|
||||
Class<?> wsCompoundClassLoaderClass = null;
|
||||
try {
|
||||
wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME);
|
||||
cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
|
||||
cloneConstructor.setAccessible(true);
|
||||
|
||||
wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
|
||||
addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", wsPreProcessorClass);
|
||||
transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
|
||||
transformerList.setAccessible(true);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(
|
||||
"Could not initialize WebSphere LoadTimeWeaver because WebSphere 7 API classes are not available",
|
||||
ex);
|
||||
}
|
||||
Assert.isInstanceOf(wsCompoundClassLoaderClass, classLoader,
|
||||
"ClassLoader must be instance of [" + COMPOUND_CLASS_LOADER_NAME + "]");
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return this.classLoader;
|
||||
}
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
Assert.notNull(transformer, "ClassFileTransformer must not be null");
|
||||
try {
|
||||
InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);
|
||||
Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(),
|
||||
new Class[] { this.wsPreProcessorClass }, adapter);
|
||||
this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance);
|
||||
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
try {
|
||||
ClassLoader loader = (ClassLoader) cloneConstructor.newInstance(getClassLoader());
|
||||
// clear out the transformers (copied as well)
|
||||
List list = (List) transformerList.get(loader);
|
||||
list.clear();
|
||||
return loader;
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,100 +1,100 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.CodeSource;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface,
|
||||
* delegating to a standard JDK {@link ClassFileTransformer} underneath.
|
||||
*
|
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||
* being used.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class WebSphereClassPreDefinePlugin implements InvocationHandler {
|
||||
|
||||
private final ClassFileTransformer transformer;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link WebSphereClassPreDefinePlugin}.
|
||||
* @param transformer the {@link ClassFileTransformer} to be adapted
|
||||
* (must not be <code>null</code>)
|
||||
*/
|
||||
public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
ClassLoader classLoader = transformer.getClass().getClassLoader();
|
||||
|
||||
// first force the full class loading of the weaver by invoking transformation on a dummy class
|
||||
try {
|
||||
String dummyClass = Dummy.class.getName().replace('.', '/');
|
||||
byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));
|
||||
transformer.transform(classLoader, dummyClass, null, null, bytes);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalArgumentException("Cannot load transformer", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String name = method.getName();
|
||||
if ("equals".equals(name)) {
|
||||
return (proxy == args[0]);
|
||||
}
|
||||
else if ("hashCode".equals(name)) {
|
||||
return hashCode();
|
||||
}
|
||||
else if ("toString".equals(name)) {
|
||||
return toString();
|
||||
}
|
||||
else if ("transformClass".equals(name)) {
|
||||
return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader)
|
||||
throws Exception {
|
||||
|
||||
// NB: WebSphere passes className as "." without class while the transformer expects a VM, "/" format
|
||||
byte[] result = transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer);
|
||||
return (result != null ? result : classfileBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||
builder.append(" for transformer: ");
|
||||
builder.append(this.transformer);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static class Dummy {
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.CodeSource;
|
||||
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface,
|
||||
* delegating to a standard JDK {@link ClassFileTransformer} underneath.
|
||||
*
|
||||
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
|
||||
* being used.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
class WebSphereClassPreDefinePlugin implements InvocationHandler {
|
||||
|
||||
private final ClassFileTransformer transformer;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link WebSphereClassPreDefinePlugin}.
|
||||
* @param transformer the {@link ClassFileTransformer} to be adapted
|
||||
* (must not be <code>null</code>)
|
||||
*/
|
||||
public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) {
|
||||
this.transformer = transformer;
|
||||
ClassLoader classLoader = transformer.getClass().getClassLoader();
|
||||
|
||||
// first force the full class loading of the weaver by invoking transformation on a dummy class
|
||||
try {
|
||||
String dummyClass = Dummy.class.getName().replace('.', '/');
|
||||
byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));
|
||||
transformer.transform(classLoader, dummyClass, null, null, bytes);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new IllegalArgumentException("Cannot load transformer", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
String name = method.getName();
|
||||
if ("equals".equals(name)) {
|
||||
return (proxy == args[0]);
|
||||
}
|
||||
else if ("hashCode".equals(name)) {
|
||||
return hashCode();
|
||||
}
|
||||
else if ("toString".equals(name)) {
|
||||
return toString();
|
||||
}
|
||||
else if ("transformClass".equals(name)) {
|
||||
return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Unknown method: " + method);
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader)
|
||||
throws Exception {
|
||||
|
||||
// NB: WebSphere passes className as "." without class while the transformer expects a VM, "/" format
|
||||
byte[] result = transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer);
|
||||
return (result != null ? result : classfileBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder(getClass().getName());
|
||||
builder.append(" for transformer: ");
|
||||
builder.append(this.transformer);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
||||
private static class Dummy {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader.
|
||||
* Compatible with WebSphere 7 as well as 8.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
public class WebSphereLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
private final WebSphereClassLoaderAdapter classLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
||||
* the default {@link ClassLoader class loader}.
|
||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||
*/
|
||||
public WebSphereLoadTimeWeaver() {
|
||||
this(ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
||||
* the supplied {@link ClassLoader}.
|
||||
* @param classLoader the <code>ClassLoader</code> to delegate to for weaving
|
||||
* (must not be <code>null</code>)
|
||||
*/
|
||||
public WebSphereLoadTimeWeaver(ClassLoader classLoader) {
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||
this.classLoader = new WebSphereClassLoaderAdapter(classLoader);
|
||||
}
|
||||
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
this.classLoader.addTransformer(transformer);
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return this.classLoader.getClassLoader();
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
return this.classLoader.getThrowawayClassLoader();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
import java.lang.instrument.ClassFileTransformer;
|
||||
|
||||
import org.springframework.instrument.classloading.LoadTimeWeaver;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader.
|
||||
* Compatible with WebSphere 7 as well as 8.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @since 3.1
|
||||
*/
|
||||
public class WebSphereLoadTimeWeaver implements LoadTimeWeaver {
|
||||
|
||||
private final WebSphereClassLoaderAdapter classLoader;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
||||
* the default {@link ClassLoader class loader}.
|
||||
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
|
||||
*/
|
||||
public WebSphereLoadTimeWeaver() {
|
||||
this(ClassUtils.getDefaultClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
|
||||
* the supplied {@link ClassLoader}.
|
||||
* @param classLoader the <code>ClassLoader</code> to delegate to for weaving
|
||||
* (must not be <code>null</code>)
|
||||
*/
|
||||
public WebSphereLoadTimeWeaver(ClassLoader classLoader) {
|
||||
Assert.notNull(classLoader, "ClassLoader must not be null");
|
||||
this.classLoader = new WebSphereClassLoaderAdapter(classLoader);
|
||||
}
|
||||
|
||||
|
||||
public void addTransformer(ClassFileTransformer transformer) {
|
||||
this.classLoader.addTransformer(transformer);
|
||||
}
|
||||
|
||||
public ClassLoader getInstrumentableClassLoader() {
|
||||
return this.classLoader.getClassLoader();
|
||||
}
|
||||
|
||||
public ClassLoader getThrowawayClassLoader() {
|
||||
return this.classLoader.getThrowawayClassLoader();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for class instrumentation on IBM WebSphere Application Server 7.
|
||||
*
|
||||
*/
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Support for class instrumentation on IBM WebSphere Application Server 7.
|
||||
*
|
||||
*/
|
||||
package org.springframework.instrument.classloading.websphere;
|
||||
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jndi;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* {@link JndiLocatorSupport} subclass with public lookup methods,
|
||||
* for convenient use as a delegate.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public class JndiLocatorDelegate extends JndiLocatorSupport {
|
||||
|
||||
@Override
|
||||
public Object lookup(String jndiName) throws NamingException {
|
||||
return super.lookup(jndiName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException {
|
||||
return super.lookup(jndiName, requiredType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure a {@code JndiLocatorDelegate} with its "resourceRef" property set to
|
||||
* <code>true</code>, meaning that all names will be prefixed with "java:comp/env/".
|
||||
* @see #setResourceRef
|
||||
*/
|
||||
public static JndiLocatorDelegate createDefaultResourceRefLocator() {
|
||||
JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
|
||||
jndiLocator.setResourceRef(true);
|
||||
return jndiLocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a default JNDI environment, as in a J2EE environment,
|
||||
* is available on this JVM.
|
||||
* @return <code>true</code> if a default InitialContext can be used,
|
||||
* <code>false</code> if not
|
||||
*/
|
||||
public static boolean isDefaultJndiEnvironmentAvailable() {
|
||||
try {
|
||||
new InitialContext();
|
||||
return true;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.jndi;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* {@link JndiLocatorSupport} subclass with public lookup methods,
|
||||
* for convenient use as a delegate.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.1
|
||||
*/
|
||||
public class JndiLocatorDelegate extends JndiLocatorSupport {
|
||||
|
||||
@Override
|
||||
public Object lookup(String jndiName) throws NamingException {
|
||||
return super.lookup(jndiName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException {
|
||||
return super.lookup(jndiName, requiredType);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure a {@code JndiLocatorDelegate} with its "resourceRef" property set to
|
||||
* <code>true</code>, meaning that all names will be prefixed with "java:comp/env/".
|
||||
* @see #setResourceRef
|
||||
*/
|
||||
public static JndiLocatorDelegate createDefaultResourceRefLocator() {
|
||||
JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
|
||||
jndiLocator.setResourceRef(true);
|
||||
return jndiLocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a default JNDI environment, as in a J2EE environment,
|
||||
* is available on this JVM.
|
||||
* @return <code>true</code> if a default InitialContext can be used,
|
||||
* <code>false</code> if not
|
||||
*/
|
||||
public static boolean isDefaultJndiEnvironmentAvailable() {
|
||||
try {
|
||||
new InitialContext();
|
||||
return true;
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,139 +1,139 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* Task scheduler interface that abstracts the scheduling of
|
||||
* {@link Runnable Runnables} based on different kinds of triggers.
|
||||
*
|
||||
* <p>This interface is separate from {@link SchedulingTaskExecutor} since it
|
||||
* usually represents for a different kind of backend, i.e. a thread pool with
|
||||
* different characteristics and capabilities. Implementations may implement
|
||||
* both interfaces if they can handle both kinds of execution characteristics.
|
||||
*
|
||||
* <p>The 'default' implementation is
|
||||
* {@link org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler},
|
||||
* wrapping a native {@link java.util.concurrent.ScheduledExecutorService}
|
||||
* and adding extended trigger capabilities.
|
||||
*
|
||||
* <p>This interface is roughly equivalent to a JSR-236
|
||||
* <code>ManagedScheduledExecutorService</code> as supported in Java EE 6
|
||||
* environments. However, at the time of the Spring 3.0 release, the
|
||||
* JSR-236 interfaces have not been released in official form yet.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.core.task.TaskExecutor
|
||||
* @see java.util.concurrent.ScheduledExecutorService
|
||||
* @see org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
|
||||
*/
|
||||
public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, invoking it whenever the trigger
|
||||
* indicates a next execution time.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @param trigger an implementation of the {@link Trigger} interface,
|
||||
* e.g. a {@link org.springframework.scheduling.support.CronTrigger} object
|
||||
* wrapping a cron expression
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task,
|
||||
* or <code>null</code> if the given Trigger object never fires (i.e. returns
|
||||
* <code>null</code> from {@link Trigger#nextExecutionTime})
|
||||
* @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)
|
||||
* @see org.springframework.scheduling.support.CronTrigger
|
||||
*/
|
||||
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @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)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture schedule(Runnable task, Date startTime);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time
|
||||
* and subsequently with the given period.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @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)
|
||||
* @param period the interval between successive executions of the task (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, starting as soon as possible and
|
||||
* invoking it with the given period.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @param period the interval between successive executions of the task (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
|
||||
|
||||
/**
|
||||
* 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 the start of the next.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @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)
|
||||
* @param delay the delay between the completion of one execution and the start
|
||||
* of the next (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, starting as soon as possible and
|
||||
* invoking it with the given delay between the completion of one execution
|
||||
* and the start of the next.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @param delay the interval between successive executions of the task (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
/**
|
||||
* Task scheduler interface that abstracts the scheduling of
|
||||
* {@link Runnable Runnables} based on different kinds of triggers.
|
||||
*
|
||||
* <p>This interface is separate from {@link SchedulingTaskExecutor} since it
|
||||
* usually represents for a different kind of backend, i.e. a thread pool with
|
||||
* different characteristics and capabilities. Implementations may implement
|
||||
* both interfaces if they can handle both kinds of execution characteristics.
|
||||
*
|
||||
* <p>The 'default' implementation is
|
||||
* {@link org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler},
|
||||
* wrapping a native {@link java.util.concurrent.ScheduledExecutorService}
|
||||
* and adding extended trigger capabilities.
|
||||
*
|
||||
* <p>This interface is roughly equivalent to a JSR-236
|
||||
* <code>ManagedScheduledExecutorService</code> as supported in Java EE 6
|
||||
* environments. However, at the time of the Spring 3.0 release, the
|
||||
* JSR-236 interfaces have not been released in official form yet.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.core.task.TaskExecutor
|
||||
* @see java.util.concurrent.ScheduledExecutorService
|
||||
* @see org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
|
||||
*/
|
||||
public interface TaskScheduler {
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, invoking it whenever the trigger
|
||||
* indicates a next execution time.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @param trigger an implementation of the {@link Trigger} interface,
|
||||
* e.g. a {@link org.springframework.scheduling.support.CronTrigger} object
|
||||
* wrapping a cron expression
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task,
|
||||
* or <code>null</code> if the given Trigger object never fires (i.e. returns
|
||||
* <code>null</code> from {@link Trigger#nextExecutionTime})
|
||||
* @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)
|
||||
* @see org.springframework.scheduling.support.CronTrigger
|
||||
*/
|
||||
ScheduledFuture schedule(Runnable task, Trigger trigger);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @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)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture schedule(Runnable task, Date startTime);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, invoking it at the specified execution time
|
||||
* and subsequently with the given period.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @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)
|
||||
* @param period the interval between successive executions of the task (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, starting as soon as possible and
|
||||
* invoking it with the given period.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @param period the interval between successive executions of the task (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);
|
||||
|
||||
/**
|
||||
* 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 the start of the next.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @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)
|
||||
* @param delay the delay between the completion of one execution and the start
|
||||
* of the next (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
|
||||
|
||||
/**
|
||||
* Schedule the given {@link Runnable}, starting as soon as possible and
|
||||
* invoking it with the given delay between the completion of one execution
|
||||
* and the start of the next.
|
||||
* <p>Execution will end once the scheduler shuts down or the returned
|
||||
* {@link ScheduledFuture} gets cancelled.
|
||||
* @param task the Runnable to execute whenever the trigger fires
|
||||
* @param delay the interval between successive executions of the task (in milliseconds)
|
||||
* @return a {@link ScheduledFuture} representing pending completion of the task
|
||||
* @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)
|
||||
*/
|
||||
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Common interface for trigger objects that determine the next execution time
|
||||
* of a task that they get associated with.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see TaskScheduler#schedule(Runnable, Trigger)
|
||||
* @see org.springframework.scheduling.support.CronTrigger
|
||||
*/
|
||||
public interface Trigger {
|
||||
|
||||
/**
|
||||
* Determine the next execution time according to the given trigger context.
|
||||
* @param triggerContext context object encapsulating last execution times
|
||||
* and last completion time
|
||||
* @return the next execution time as defined by the trigger,
|
||||
* or <code>null</code> if the trigger won't fire anymore
|
||||
*/
|
||||
Date nextExecutionTime(TriggerContext triggerContext);
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Common interface for trigger objects that determine the next execution time
|
||||
* of a task that they get associated with.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see TaskScheduler#schedule(Runnable, Trigger)
|
||||
* @see org.springframework.scheduling.support.CronTrigger
|
||||
*/
|
||||
public interface Trigger {
|
||||
|
||||
/**
|
||||
* Determine the next execution time according to the given trigger context.
|
||||
* @param triggerContext context object encapsulating last execution times
|
||||
* and last completion time
|
||||
* @return the next execution time as defined by the trigger,
|
||||
* or <code>null</code> if the trigger won't fire anymore
|
||||
*/
|
||||
Date nextExecutionTime(TriggerContext triggerContext);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Context object encapsulating last execution times and last completion time
|
||||
* of a given task.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface TriggerContext {
|
||||
|
||||
/**
|
||||
* Return the last <i>scheduled</i> execution time of the task,
|
||||
* or <code>null</code> if not scheduled before.
|
||||
*/
|
||||
Date lastScheduledExecutionTime();
|
||||
|
||||
/**
|
||||
* Return the last <i>actual</i> execution time of the task,
|
||||
* or <code>null</code> if not scheduled before.
|
||||
*/
|
||||
Date lastActualExecutionTime();
|
||||
|
||||
/**
|
||||
* Return the last completion time of the task,
|
||||
* or <code>null</code> if not scheduled before.
|
||||
*/
|
||||
Date lastCompletionTime();
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Context object encapsulating last execution times and last completion time
|
||||
* of a given task.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface TriggerContext {
|
||||
|
||||
/**
|
||||
* Return the last <i>scheduled</i> execution time of the task,
|
||||
* or <code>null</code> if not scheduled before.
|
||||
*/
|
||||
Date lastScheduledExecutionTime();
|
||||
|
||||
/**
|
||||
* Return the last <i>actual</i> execution time of the task,
|
||||
* or <code>null</code> if not scheduled before.
|
||||
*/
|
||||
Date lastActualExecutionTime();
|
||||
|
||||
/**
|
||||
* Return the last completion time of the task,
|
||||
* or <code>null</code> if not scheduled before.
|
||||
*/
|
||||
Date lastCompletionTime();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* considered as asynchronous.
|
||||
*
|
||||
* <p>In terms of target method signatures, any parameter types are supported.
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
* Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.aop.interceptor.AsyncExecutionInterceptor
|
||||
* @see AsyncAnnotationAdvisor
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Async {
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* considered as asynchronous.
|
||||
*
|
||||
* <p>In terms of target method signatures, any parameter types are supported.
|
||||
* 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
|
||||
* 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
|
||||
* 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.
|
||||
* Spring's {@link AsyncResult} or EJB 3.1's <code>javax.ejb.AsyncResult</code>.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.aop.interceptor.AsyncExecutionInterceptor
|
||||
* @see AsyncAnnotationAdvisor
|
||||
*/
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Async {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.scheduling.annotation.Async
|
||||
*/
|
||||
public class AsyncResult<V> implements Future<V> {
|
||||
|
||||
private final V value;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AsyncResult holder.
|
||||
* @param value the value to pass through
|
||||
*/
|
||||
public AsyncResult(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public V get() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public V get(long timeout, TimeUnit unit) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see org.springframework.scheduling.annotation.Async
|
||||
*/
|
||||
public class AsyncResult<V> implements Future<V> {
|
||||
|
||||
private final V value;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new AsyncResult holder.
|
||||
* @param value the value to pass through
|
||||
*/
|
||||
public AsyncResult(V value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public V get() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public V get(long timeout, TimeUnit unit) {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,71 +1,71 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation that marks a method to be scheduled. Exactly one of the
|
||||
* <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code>
|
||||
* attributes must be provided.
|
||||
*
|
||||
* <p>The annotated method must expect no arguments and have a
|
||||
* <code>void</code> return type.
|
||||
*
|
||||
* <p>Processing of {@code @Scheduled} annotations is performed by
|
||||
* registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
|
||||
* done manually or, more conveniently, through the {@code <task:annotation-driven/>}
|
||||
* element or @{@link EnableScheduling} annotation.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Dave Syer
|
||||
* @since 3.0
|
||||
* @see EnableScheduling
|
||||
* @see ScheduledAnnotationBeanPostProcessor
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Scheduled {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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).
|
||||
* @return an expression that can be parsed to a cron schedule
|
||||
*/
|
||||
String cron() default "";
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period between the end
|
||||
* of the last invocation and the start of the next.
|
||||
* @return the delay in milliseconds
|
||||
*/
|
||||
long fixedDelay() default -1;
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period between invocations.
|
||||
* @return the period in milliseconds
|
||||
*/
|
||||
long fixedRate() default -1;
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation that marks a method to be scheduled. Exactly one of the
|
||||
* <code>cron</code>, <code>fixedDelay</code>, or <code>fixedRate</code>
|
||||
* attributes must be provided.
|
||||
*
|
||||
* <p>The annotated method must expect no arguments and have a
|
||||
* <code>void</code> return type.
|
||||
*
|
||||
* <p>Processing of {@code @Scheduled} annotations is performed by
|
||||
* registering a {@link ScheduledAnnotationBeanPostProcessor}. This can be
|
||||
* done manually or, more conveniently, through the {@code <task:annotation-driven/>}
|
||||
* element or @{@link EnableScheduling} annotation.
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Dave Syer
|
||||
* @since 3.0
|
||||
* @see EnableScheduling
|
||||
* @see ScheduledAnnotationBeanPostProcessor
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Scheduled {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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).
|
||||
* @return an expression that can be parsed to a cron schedule
|
||||
*/
|
||||
String cron() default "";
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period between the end
|
||||
* of the last invocation and the start of the next.
|
||||
* @return the delay in milliseconds
|
||||
*/
|
||||
long fixedDelay() default -1;
|
||||
|
||||
/**
|
||||
* Execute the annotated method with a fixed period between invocations.
|
||||
* @return the period in milliseconds
|
||||
*/
|
||||
long fixedRate() default -1;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,187 +1,187 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.concurrent;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.core.task.TaskRejectedException;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.TaskUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code>
|
||||
* and exposes a Spring {@link org.springframework.scheduling.TaskScheduler} for it.
|
||||
* Extends {@link ConcurrentTaskExecutor} in order to implement the
|
||||
* {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well.
|
||||
*
|
||||
* <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,
|
||||
* exposing it as a Spring {@link org.springframework.scheduling.TaskScheduler} directly.
|
||||
* This is a convenient alternative to a raw ScheduledThreadPoolExecutor definition with
|
||||
* a separate definition of the present adapter class.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
* @see java.util.concurrent.ScheduledExecutorService
|
||||
* @see java.util.concurrent.ScheduledThreadPoolExecutor
|
||||
* @see java.util.concurrent.Executors
|
||||
* @see ThreadPoolTaskScheduler
|
||||
*/
|
||||
public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler {
|
||||
|
||||
private volatile ScheduledExecutorService scheduledExecutor;
|
||||
|
||||
private volatile ErrorHandler errorHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentTaskScheduler,
|
||||
* using a single thread executor as default.
|
||||
* @see java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
|
||||
*/
|
||||
public ConcurrentTaskScheduler() {
|
||||
super();
|
||||
setScheduledExecutor(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentTaskScheduler,
|
||||
* using the given JDK 1.5 executor as shared delegate.
|
||||
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
||||
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} as well
|
||||
* as {@link TaskScheduler} invocations
|
||||
*/
|
||||
public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) {
|
||||
super(scheduledExecutor);
|
||||
setScheduledExecutor(scheduledExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentTaskScheduler,
|
||||
* using the given JDK 1.5 executors as delegates.
|
||||
* @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to
|
||||
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
||||
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
||||
* for {@link TaskScheduler} invocations
|
||||
*/
|
||||
public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) {
|
||||
super(concurrentExecutor);
|
||||
setScheduledExecutor(scheduledExecutor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the JDK 1.5 scheduled executor to delegate to.
|
||||
* <p>Note: This will only apply to {@link TaskScheduler} invocations.
|
||||
* If you want the given executor to apply to
|
||||
* {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
||||
* as well, pass the same executor reference to {@link #setConcurrentExecutor}.
|
||||
* @see #setConcurrentExecutor
|
||||
*/
|
||||
public final void setScheduledExecutor(ScheduledExecutorService scheduledExecutor) {
|
||||
this.scheduledExecutor =
|
||||
(scheduledExecutor != null ? scheduledExecutor : Executors.newSingleThreadScheduledExecutor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an {@link ErrorHandler} strategy.
|
||||
*/
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||
try {
|
||||
ErrorHandler errorHandler =
|
||||
(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
|
||||
return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule();
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||
try {
|
||||
return this.scheduledExecutor.schedule(
|
||||
errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleAtFixedRate(
|
||||
errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleAtFixedRate(
|
||||
errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleWithFixedDelay(
|
||||
errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleWithFixedDelay(
|
||||
errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
||||
return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.concurrent;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.core.task.TaskRejectedException;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.TaskUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code>
|
||||
* and exposes a Spring {@link org.springframework.scheduling.TaskScheduler} for it.
|
||||
* Extends {@link ConcurrentTaskExecutor} in order to implement the
|
||||
* {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well.
|
||||
*
|
||||
* <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,
|
||||
* exposing it as a Spring {@link org.springframework.scheduling.TaskScheduler} directly.
|
||||
* This is a convenient alternative to a raw ScheduledThreadPoolExecutor definition with
|
||||
* a separate definition of the present adapter class.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
* @see java.util.concurrent.ScheduledExecutorService
|
||||
* @see java.util.concurrent.ScheduledThreadPoolExecutor
|
||||
* @see java.util.concurrent.Executors
|
||||
* @see ThreadPoolTaskScheduler
|
||||
*/
|
||||
public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler {
|
||||
|
||||
private volatile ScheduledExecutorService scheduledExecutor;
|
||||
|
||||
private volatile ErrorHandler errorHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentTaskScheduler,
|
||||
* using a single thread executor as default.
|
||||
* @see java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
|
||||
*/
|
||||
public ConcurrentTaskScheduler() {
|
||||
super();
|
||||
setScheduledExecutor(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentTaskScheduler,
|
||||
* using the given JDK 1.5 executor as shared delegate.
|
||||
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
||||
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} as well
|
||||
* as {@link TaskScheduler} invocations
|
||||
*/
|
||||
public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) {
|
||||
super(scheduledExecutor);
|
||||
setScheduledExecutor(scheduledExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConcurrentTaskScheduler,
|
||||
* using the given JDK 1.5 executors as delegates.
|
||||
* @param concurrentExecutor the JDK 1.5 concurrent executor to delegate to
|
||||
* for {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
||||
* @param scheduledExecutor the JDK 1.5 scheduled executor to delegate to
|
||||
* for {@link TaskScheduler} invocations
|
||||
*/
|
||||
public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) {
|
||||
super(concurrentExecutor);
|
||||
setScheduledExecutor(scheduledExecutor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the JDK 1.5 scheduled executor to delegate to.
|
||||
* <p>Note: This will only apply to {@link TaskScheduler} invocations.
|
||||
* If you want the given executor to apply to
|
||||
* {@link org.springframework.scheduling.SchedulingTaskExecutor} invocations
|
||||
* as well, pass the same executor reference to {@link #setConcurrentExecutor}.
|
||||
* @see #setConcurrentExecutor
|
||||
*/
|
||||
public final void setScheduledExecutor(ScheduledExecutorService scheduledExecutor) {
|
||||
this.scheduledExecutor =
|
||||
(scheduledExecutor != null ? scheduledExecutor : Executors.newSingleThreadScheduledExecutor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide an {@link ErrorHandler} strategy.
|
||||
*/
|
||||
public void setErrorHandler(ErrorHandler errorHandler) {
|
||||
Assert.notNull(errorHandler, "'errorHandler' must not be null");
|
||||
this.errorHandler = errorHandler;
|
||||
}
|
||||
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||
try {
|
||||
ErrorHandler errorHandler =
|
||||
(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
|
||||
return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule();
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||
try {
|
||||
return this.scheduledExecutor.schedule(
|
||||
errorHandlingTask(task, false), initialDelay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleAtFixedRate(
|
||||
errorHandlingTask(task, true), initialDelay, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleAtFixedRate(
|
||||
errorHandlingTask(task, true), 0, period, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||
long initialDelay = startTime.getTime() - System.currentTimeMillis();
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleWithFixedDelay(
|
||||
errorHandlingTask(task, true), initialDelay, delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||
try {
|
||||
return this.scheduledExecutor.scheduleWithFixedDelay(
|
||||
errorHandlingTask(task, true), 0, delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
catch (RejectedExecutionException ex) {
|
||||
throw new TaskRejectedException("Executor [" + this.scheduledExecutor + "] did not accept task: " + task, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
||||
return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,160 +1,160 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.concurrent;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Base class for classes that are setting up a
|
||||
* <code>java.util.concurrent.ExecutorService</code>
|
||||
* (typically a {@link java.util.concurrent.ThreadPoolExecutor}).
|
||||
* Defines common configuration settings and common lifecycle handling.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.util.concurrent.ExecutorService
|
||||
* @see java.util.concurrent.Executors
|
||||
* @see java.util.concurrent.ThreadPoolExecutor
|
||||
*/
|
||||
public abstract class ExecutorConfigurationSupport extends CustomizableThreadFactory
|
||||
implements BeanNameAware, InitializingBean, DisposableBean {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private ThreadFactory threadFactory = this;
|
||||
|
||||
private boolean threadNamePrefixSet = false;
|
||||
|
||||
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
|
||||
|
||||
private boolean waitForTasksToCompleteOnShutdown = false;
|
||||
|
||||
private String beanName;
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
|
||||
/**
|
||||
* Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool.
|
||||
* Default is the ThreadPoolExecutor's default thread factory.
|
||||
* @see java.util.concurrent.Executors#defaultThreadFactory()
|
||||
*/
|
||||
public void setThreadFactory(ThreadFactory threadFactory) {
|
||||
this.threadFactory = (threadFactory != null ? threadFactory : this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThreadNamePrefix(String threadNamePrefix) {
|
||||
super.setThreadNamePrefix(threadNamePrefix);
|
||||
this.threadNamePrefixSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the RejectedExecutionHandler to use for the ThreadPoolExecutor.
|
||||
* Default is the ThreadPoolExecutor's default abort policy.
|
||||
* @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy
|
||||
*/
|
||||
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
|
||||
this.rejectedExecutionHandler =
|
||||
(rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to wait for scheduled tasks to complete on shutdown.
|
||||
* <p>Default is "false". Switch this to "true" if you prefer
|
||||
* fully completed tasks at the expense of a longer shutdown phase.
|
||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
||||
* @see java.util.concurrent.ExecutorService#shutdownNow()
|
||||
*/
|
||||
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
|
||||
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
|
||||
}
|
||||
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls <code>initialize()</code> after the container applied all property values.
|
||||
* @see #initialize()
|
||||
*/
|
||||
public void afterPropertiesSet() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the ExecutorService.
|
||||
*/
|
||||
public void initialize() {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Initializing ExecutorService " + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
||||
}
|
||||
if (!this.threadNamePrefixSet && this.beanName != null) {
|
||||
setThreadNamePrefix(this.beanName + "-");
|
||||
}
|
||||
this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the target {@link java.util.concurrent.ExecutorService} instance.
|
||||
* Called by <code>afterPropertiesSet</code>.
|
||||
* @param threadFactory the ThreadFactory to use
|
||||
* @param rejectedExecutionHandler the RejectedExecutionHandler to use
|
||||
* @return a new ExecutorService instance
|
||||
* @see #afterPropertiesSet()
|
||||
*/
|
||||
protected abstract ExecutorService initializeExecutor(
|
||||
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler);
|
||||
|
||||
|
||||
/**
|
||||
* Calls <code>shutdown</code> when the BeanFactory destroys
|
||||
* the task executor instance.
|
||||
* @see #shutdown()
|
||||
*/
|
||||
public void destroy() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a shutdown on the ThreadPoolExecutor.
|
||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
||||
}
|
||||
if (this.waitForTasksToCompleteOnShutdown) {
|
||||
this.executor.shutdown();
|
||||
}
|
||||
else {
|
||||
this.executor.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.concurrent;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.RejectedExecutionHandler;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* Base class for classes that are setting up a
|
||||
* <code>java.util.concurrent.ExecutorService</code>
|
||||
* (typically a {@link java.util.concurrent.ThreadPoolExecutor}).
|
||||
* Defines common configuration settings and common lifecycle handling.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see java.util.concurrent.ExecutorService
|
||||
* @see java.util.concurrent.Executors
|
||||
* @see java.util.concurrent.ThreadPoolExecutor
|
||||
*/
|
||||
public abstract class ExecutorConfigurationSupport extends CustomizableThreadFactory
|
||||
implements BeanNameAware, InitializingBean, DisposableBean {
|
||||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private ThreadFactory threadFactory = this;
|
||||
|
||||
private boolean threadNamePrefixSet = false;
|
||||
|
||||
private RejectedExecutionHandler rejectedExecutionHandler = new ThreadPoolExecutor.AbortPolicy();
|
||||
|
||||
private boolean waitForTasksToCompleteOnShutdown = false;
|
||||
|
||||
private String beanName;
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
|
||||
/**
|
||||
* Set the ThreadFactory to use for the ThreadPoolExecutor's thread pool.
|
||||
* Default is the ThreadPoolExecutor's default thread factory.
|
||||
* @see java.util.concurrent.Executors#defaultThreadFactory()
|
||||
*/
|
||||
public void setThreadFactory(ThreadFactory threadFactory) {
|
||||
this.threadFactory = (threadFactory != null ? threadFactory : this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setThreadNamePrefix(String threadNamePrefix) {
|
||||
super.setThreadNamePrefix(threadNamePrefix);
|
||||
this.threadNamePrefixSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the RejectedExecutionHandler to use for the ThreadPoolExecutor.
|
||||
* Default is the ThreadPoolExecutor's default abort policy.
|
||||
* @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy
|
||||
*/
|
||||
public void setRejectedExecutionHandler(RejectedExecutionHandler rejectedExecutionHandler) {
|
||||
this.rejectedExecutionHandler =
|
||||
(rejectedExecutionHandler != null ? rejectedExecutionHandler : new ThreadPoolExecutor.AbortPolicy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to wait for scheduled tasks to complete on shutdown.
|
||||
* <p>Default is "false". Switch this to "true" if you prefer
|
||||
* fully completed tasks at the expense of a longer shutdown phase.
|
||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
||||
* @see java.util.concurrent.ExecutorService#shutdownNow()
|
||||
*/
|
||||
public void setWaitForTasksToCompleteOnShutdown(boolean waitForJobsToCompleteOnShutdown) {
|
||||
this.waitForTasksToCompleteOnShutdown = waitForJobsToCompleteOnShutdown;
|
||||
}
|
||||
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls <code>initialize()</code> after the container applied all property values.
|
||||
* @see #initialize()
|
||||
*/
|
||||
public void afterPropertiesSet() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the ExecutorService.
|
||||
*/
|
||||
public void initialize() {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Initializing ExecutorService " + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
||||
}
|
||||
if (!this.threadNamePrefixSet && this.beanName != null) {
|
||||
setThreadNamePrefix(this.beanName + "-");
|
||||
}
|
||||
this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the target {@link java.util.concurrent.ExecutorService} instance.
|
||||
* Called by <code>afterPropertiesSet</code>.
|
||||
* @param threadFactory the ThreadFactory to use
|
||||
* @param rejectedExecutionHandler the RejectedExecutionHandler to use
|
||||
* @return a new ExecutorService instance
|
||||
* @see #afterPropertiesSet()
|
||||
*/
|
||||
protected abstract ExecutorService initializeExecutor(
|
||||
ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler);
|
||||
|
||||
|
||||
/**
|
||||
* Calls <code>shutdown</code> when the BeanFactory destroys
|
||||
* the task executor instance.
|
||||
* @see #shutdown()
|
||||
*/
|
||||
public void destroy() {
|
||||
shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a shutdown on the ThreadPoolExecutor.
|
||||
* @see java.util.concurrent.ExecutorService#shutdown()
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Shutting down ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
|
||||
}
|
||||
if (this.waitForTasksToCompleteOnShutdown) {
|
||||
this.executor.shutdown();
|
||||
}
|
||||
else {
|
||||
this.executor.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.concurrent;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* Internal adapter that reschedules an underlying {@link Runnable} according
|
||||
* to the next execution time suggested by a given {@link Trigger}.
|
||||
*
|
||||
* <p>Necessary because a native {@link ScheduledExecutorService} supports
|
||||
* delay-driven execution only. The flexibility of the {@link Trigger} interface
|
||||
* will be translated onto a delay for the next execution time (repeatedly).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
*/
|
||||
class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> {
|
||||
|
||||
private final Trigger trigger;
|
||||
|
||||
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
private volatile ScheduledFuture currentFuture;
|
||||
|
||||
private volatile Date scheduledExecutionTime;
|
||||
|
||||
private final Object triggerContextMonitor = new Object();
|
||||
|
||||
|
||||
public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) {
|
||||
super(delegate, errorHandler);
|
||||
this.trigger = trigger;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
|
||||
public ScheduledFuture schedule() {
|
||||
synchronized (this.triggerContextMonitor) {
|
||||
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
||||
if (this.scheduledExecutionTime == null) {
|
||||
return null;
|
||||
}
|
||||
long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
|
||||
this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Date actualExecutionTime = new Date();
|
||||
super.run();
|
||||
Date completionTime = new Date();
|
||||
synchronized (this.triggerContextMonitor) {
|
||||
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
||||
}
|
||||
if (!this.currentFuture.isCancelled()) {
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return this.currentFuture.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return this.currentFuture.isCancelled();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return this.currentFuture.isDone();
|
||||
}
|
||||
|
||||
public Object get() throws InterruptedException, ExecutionException {
|
||||
return this.currentFuture.get();
|
||||
}
|
||||
|
||||
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return this.currentFuture.get(timeout, unit);
|
||||
}
|
||||
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return this.currentFuture.getDelay(unit);
|
||||
}
|
||||
|
||||
public int compareTo(Delayed other) {
|
||||
if (this == other) {
|
||||
return 0;
|
||||
}
|
||||
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
||||
return (diff == 0 ? 0 : ((diff < 0)? -1 : 1));
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.scheduling.concurrent;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.Delayed;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* Internal adapter that reschedules an underlying {@link Runnable} according
|
||||
* to the next execution time suggested by a given {@link Trigger}.
|
||||
*
|
||||
* <p>Necessary because a native {@link ScheduledExecutorService} supports
|
||||
* delay-driven execution only. The flexibility of the {@link Trigger} interface
|
||||
* will be translated onto a delay for the next execution time (repeatedly).
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Mark Fisher
|
||||
* @since 3.0
|
||||
*/
|
||||
class ReschedulingRunnable extends DelegatingErrorHandlingRunnable implements ScheduledFuture<Object> {
|
||||
|
||||
private final Trigger trigger;
|
||||
|
||||
private final SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||
|
||||
private final ScheduledExecutorService executor;
|
||||
|
||||
private volatile ScheduledFuture currentFuture;
|
||||
|
||||
private volatile Date scheduledExecutionTime;
|
||||
|
||||
private final Object triggerContextMonitor = new Object();
|
||||
|
||||
|
||||
public ReschedulingRunnable(Runnable delegate, Trigger trigger, ScheduledExecutorService executor, ErrorHandler errorHandler) {
|
||||
super(delegate, errorHandler);
|
||||
this.trigger = trigger;
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
|
||||
public ScheduledFuture schedule() {
|
||||
synchronized (this.triggerContextMonitor) {
|
||||
this.scheduledExecutionTime = this.trigger.nextExecutionTime(this.triggerContext);
|
||||
if (this.scheduledExecutionTime == null) {
|
||||
return null;
|
||||
}
|
||||
long initialDelay = this.scheduledExecutionTime.getTime() - System.currentTimeMillis();
|
||||
this.currentFuture = this.executor.schedule(this, initialDelay, TimeUnit.MILLISECONDS);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Date actualExecutionTime = new Date();
|
||||
super.run();
|
||||
Date completionTime = new Date();
|
||||
synchronized (this.triggerContextMonitor) {
|
||||
this.triggerContext.update(this.scheduledExecutionTime, actualExecutionTime, completionTime);
|
||||
}
|
||||
if (!this.currentFuture.isCancelled()) {
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return this.currentFuture.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return this.currentFuture.isCancelled();
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return this.currentFuture.isDone();
|
||||
}
|
||||
|
||||
public Object get() throws InterruptedException, ExecutionException {
|
||||
return this.currentFuture.get();
|
||||
}
|
||||
|
||||
public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return this.currentFuture.get(timeout, unit);
|
||||
}
|
||||
|
||||
public long getDelay(TimeUnit unit) {
|
||||
return this.currentFuture.getDelay(unit);
|
||||
}
|
||||
|
||||
public int compareTo(Delayed other) {
|
||||
if (this == other) {
|
||||
return 0;
|
||||
}
|
||||
long diff = getDelay(TimeUnit.MILLISECONDS) - other.getDelay(TimeUnit.MILLISECONDS);
|
||||
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