├── .gitignore ├── .springjavaformatconfig ├── README.md ├── outline.png ├── pom.xml └── src ├── main ├── java │ └── net │ │ └── jrouter │ │ ├── AbstractProxy.java │ │ ├── ActionFactory.java │ │ ├── ActionFactoryAware.java │ │ ├── ActionFilter.java │ │ ├── ActionInvocation.java │ │ ├── ActionProxy.java │ │ ├── ConverterFactory.java │ │ ├── Invoker.java │ │ ├── JRouterException.java │ │ ├── MethodInvokerFactory.java │ │ ├── NotFoundException.java │ │ ├── ObjectFactory.java │ │ ├── ParameterConverter.java │ │ ├── PathGenerator.java │ │ ├── annotation │ │ ├── Action.java │ │ ├── Dynamic.java │ │ ├── Ignore.java │ │ ├── Interceptor.java │ │ ├── InterceptorStack.java │ │ ├── Namespace.java │ │ ├── Parameter.java │ │ ├── Result.java │ │ ├── ResultType.java │ │ ├── Scope.java │ │ └── package-info.java │ │ ├── bytecode │ │ ├── javassist │ │ │ ├── JavassistInvoker.java │ │ │ ├── JavassistMethodChecker.java │ │ │ ├── JavassistMethodInvokerFactory.java │ │ │ ├── JavassistProxyObjectFactory.java │ │ │ └── package-info.java │ │ └── package-info.java │ │ ├── config │ │ ├── AopAction.java │ │ ├── Configuration.java │ │ ├── ConfigurationException.java │ │ └── package-info.java │ │ ├── impl │ │ ├── AbstractActionFactory.java │ │ ├── DefaultActionFactory.java │ │ ├── DefaultProxy.java │ │ ├── Injector.java │ │ ├── InterceptorProxy.java │ │ ├── InterceptorStackProxy.java │ │ ├── InvocationProxyException.java │ │ ├── MultiParameterConverterFactory.java │ │ ├── PathActionFactory.java │ │ ├── PathActionInvocation.java │ │ ├── PathActionProxy.java │ │ ├── PathTree.java │ │ ├── ResultProxy.java │ │ ├── ResultTypeProxy.java │ │ └── package-info.java │ │ ├── interceptor │ │ ├── DefaultInterceptorStack.java │ │ ├── SampleInterceptor.java │ │ └── package-info.java │ │ ├── package-info.java │ │ ├── result │ │ ├── DefaultResult.java │ │ └── package-info.java │ │ ├── spring │ │ ├── AopActionBean.java │ │ ├── DefaultActionFactoryBean.java │ │ ├── SpringObjectFactory.java │ │ └── package-info.java │ │ ├── support │ │ ├── ActionInvocationDelegate.java │ │ └── package-info.java │ │ └── util │ │ ├── AntPathMatcher.java │ │ ├── ClassScanner.java │ │ ├── ClassUtil.java │ │ ├── CollectionUtil.java │ │ ├── LRUMap.java │ │ ├── MethodUtil.java │ │ ├── StringUtil.java │ │ └── package-info.java └── resources │ ├── LICENSE.txt │ ├── changelog.txt │ ├── jrouter-1.6.xsd │ ├── jrouter-internal.properties │ ├── jrouter-spring.xml │ ├── jrouter.properties │ └── jrouter.xml └── test ├── java └── net │ └── jrouter │ ├── InterceptorTestAction.java │ ├── PathTestAction.java │ ├── PathTestAction2.java │ ├── SimpleAction.java │ ├── TestDuplicate.java │ ├── URLTestAction.java │ ├── URLTestAction2.java │ ├── bytecode │ └── javassist │ │ └── JavassistMethodCheckerTest.java │ ├── config │ ├── Configuration2Test.java │ ├── ConfigurationAopTest.java │ ├── ConfigurationScanComponentTest.java │ └── ConfigurationTest.java │ ├── impl │ ├── ActionFactory2Test.java │ ├── ActionFactory3Test.java │ ├── ActionFactory4Test.java │ ├── ActionFactoryTest.java │ ├── ConverterParameterActionFactory.java │ ├── ConverterParameterActionFactoryTest.java │ ├── MultiParameterConverterTest.java │ ├── PathActionFactory1Test.java │ ├── PathActionFactory2Test.java │ ├── PathActionFactoryTest.java │ └── PathTreeTest.java │ ├── interceptor │ ├── DemoInterceptor.java │ ├── DemoInterceptorStack.java │ └── DemoThreadActionContextInterceptor.java │ ├── result │ └── DemoResult.java │ ├── spring │ ├── DefaultActionFactoryBeanAopTest.java │ ├── DefaultActionFactoryBeanScanComponentTest.java │ ├── DefaultActionFactoryBeanTest.java │ ├── RequestMappingActionFilter.java │ └── SpringObjectFactoryTest.java │ └── util │ ├── AntPathMatcherTest.java │ ├── ClassScannerTest.java │ ├── ClassUtilTest.java │ ├── CollectionUtilTest.java │ └── StringUtilTest.java └── resources ├── jrouter-spring_aop.xml ├── jrouter-spring_autoscan.xml ├── jrouter-spring_test.xml ├── jrouter_aop.xml ├── jrouter_autoscan.xml ├── jrouter_error.xml ├── jrouter_test.xml ├── logback.xml └── test ├── include1.xml └── include2.xml /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### STS ### 7 | .apt_generated 8 | .classpath 9 | .factorypath 10 | .project 11 | .settings 12 | .springBeans 13 | .sts4-cache 14 | 15 | ### IntelliJ IDEA ### 16 | .idea 17 | *.iws 18 | *.iml 19 | *.ipr 20 | 21 | ### NetBeans ### 22 | nb-configuration.xml 23 | /nbproject/ 24 | /nbproject/private/ 25 | /nbbuild/ 26 | /dist/ 27 | /nbdist/ 28 | /.nb-gradle/ 29 | build/ 30 | !**/src/main/**/build/ 31 | !**/src/test/**/build/ 32 | 33 | ### VS Code ### 34 | .vscode/ 35 | -------------------------------------------------------------------------------- /.springjavaformatconfig: -------------------------------------------------------------------------------- 1 | java-baseline=8 2 | indentation-style=spaces -------------------------------------------------------------------------------- /outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tripluo/jrouter/5a382c1ec14017ca74e1ce7fda2fc9345afb5702/outline.png -------------------------------------------------------------------------------- /src/main/java/net/jrouter/AbstractProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * 提供方法代理的一个抽象类,包括了{@link Method}对象、调用{@code Method}的对象。 24 | */ 25 | public abstract class AbstractProxy { 26 | 27 | /** 28 | * 方法对象 29 | */ 30 | @lombok.Getter 31 | protected Method method; 32 | 33 | /** 34 | * 方法所在的对象 35 | */ 36 | @lombok.Getter 37 | protected Object object; 38 | 39 | /** 40 | * 指定方法及其对象的构造方法。 41 | * @param method 指定的方法。 42 | * @param object 指定的对象。 43 | */ 44 | public AbstractProxy(Method method, Object object) { 45 | this.method = method; 46 | this.object = object; 47 | } 48 | 49 | /** 50 | * 调用所代理的方法。 51 | * @param params 用于方法调用的参数。 52 | * @return 方法调用后的结果。 53 | * @throws JRouterException 如果发生方法调用错误。 54 | * @see Method#invoke(java.lang.Object, java.lang.Object[]) 55 | */ 56 | public abstract Object invoke(Object... params) throws JRouterException; 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ActionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | 22 | import java.util.Map; 23 | 24 | /** 25 | * ActionFactory接口。 26 | * 27 | * @param

调用{@link Action}的标识。 28 | */ 29 | public interface ActionFactory

{ 30 | 31 | /** 32 | * 返回Action过滤器。 33 | * @return Action过滤器。 34 | */ 35 | ActionFilter getActionFilter(); 36 | 37 | /** 38 | * 返回创建对象的工厂对象。 39 | * @return 创建对象的工厂对象。 40 | */ 41 | ObjectFactory getObjectFactory(); 42 | 43 | /** 44 | * 返回创建方法调用对象的工厂对象。 45 | * @return 创建方法调用对象的工厂对象。 46 | */ 47 | MethodInvokerFactory getMethodInvokerFactory(); 48 | 49 | /** 50 | * 返回路径生成器。 51 | * @return 路径生成器。 52 | */ 53 | PathGenerator

getPathGenerator(); 54 | 55 | /** 56 | * 返回创建方法转换器的工厂对象。 57 | * @return 创建方法转换器的工厂对象。 58 | */ 59 | ConverterFactory getConverterFactory(); 60 | 61 | /** 62 | * 通过路径调用相应的Action,可以传递Action代理方法相应的参数。 63 | * @param 调用Action的结果类型。 64 | * @param path Action的映射标识。 65 | * @param params 用于Action的调用参数。 66 | * @return 调用后的结果。 67 | * @throws JRouterException 如果发生调用错误。 68 | */ 69 | T invokeAction(P path, Object... params) throws JRouterException; 70 | 71 | /** 72 | * 移除ActionFactory中所有关联关系。 73 | * @throws JRouterException 如果发生错误。 74 | */ 75 | void clear() throws JRouterException; 76 | 77 | /** 78 | * 返回Action集合。 79 | * @return Action集合。 80 | */ 81 | Map getActions(); 82 | 83 | /** 84 | * 返回拦截器集合。 85 | * @return 拦截器集合。 86 | */ 87 | Map getInterceptors(); 88 | 89 | /** 90 | * 返回拦截栈集合。 91 | * @return 拦截栈集合。 92 | */ 93 | Map getInterceptorStacks(); 94 | 95 | /** 96 | * 返回结果类型集合。 97 | * @return 结果类型集合。 98 | */ 99 | Map getResultTypes(); 100 | 101 | /** 102 | * 返回结果对象集合。 103 | * @return 结果对象集合。 104 | */ 105 | Map getResults(); 106 | 107 | /** 108 | * 返回默认拦截栈名称。 109 | * @return 默认拦截栈名称。 110 | */ 111 | String getDefaultInterceptorStack(); 112 | 113 | /** 114 | * 设置默认视图类型。 115 | * @return 默认视图类型。 116 | */ 117 | String getDefaultResultType(); 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ActionFactoryAware.java: -------------------------------------------------------------------------------- 1 | package net.jrouter; 2 | 3 | /** 4 | * 提供设置{@link ActionFactory}的接口。 5 | */ 6 | public interface ActionFactoryAware { 7 | 8 | /** 9 | * Set {@link ActionFactory}. 10 | * @param actionFactory ActionFactory object. 11 | */ 12 | void setActionFactory(ActionFactory actionFactory); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ActionFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Namespace; 22 | 23 | import java.lang.reflect.Method; 24 | 25 | /** 26 | * ActionFilter接口。提供过滤{@code Method}和转换自定义注解类至{@link Action}。 27 | * 28 | * @since 1.7.4 29 | */ 30 | public interface ActionFilter { 31 | 32 | /** 33 | * 是否接受指定的方法。 34 | * @param obj 调用方法的对象。 35 | * @param method 指定的方法。 36 | * @return 是否接受指定的方法。 37 | */ 38 | boolean accept(Object obj, Method method); 39 | 40 | /** 41 | * 根据指定的方法获取{@code Action}对象。 42 | * @param obj 调用方法的对象。 43 | * @param method 指定的方法。 44 | * @return {@code Action}对象。 45 | */ 46 | Action getAction(Object obj, Method method); 47 | 48 | /** 49 | * 根据指定的方法获取{@code Namespace}对象。 50 | * @param obj 调用方法的对象。 51 | * @param method 指定的方法。 52 | * @return {@code Namespace}对象。 53 | */ 54 | Namespace getNamespace(Object obj, Method method); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ActionInvocation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Dynamic; 22 | import net.jrouter.annotation.Result; 23 | 24 | import java.util.Map; 25 | 26 | /** 27 | * {@link Action}运行时上下文的代理接口。在{@link Action}调用时记录并返回其状态、调用参数、结果对象、ActionFactory等信息。 28 | * 29 | * @param

Action Path type. 30 | */ 31 | @Dynamic 32 | public interface ActionInvocation

{ 33 | 34 | /** 35 | * 返回ActionFactory。 36 | * @return ActionFactory。 37 | */ 38 | ActionFactory

getActionFactory(); 39 | 40 | /** 41 | * 返回ActionInvocation持有的ActionProxy。 42 | * @return ActionInvocation持有的ActionProxy。 43 | */ 44 | ActionProxy

getActionProxy(); 45 | 46 | /** 47 | * 返回Aciton调用的路径参数。 48 | * @return Aciton调用的真实路径参数。 49 | */ 50 | P getActionPath(); 51 | 52 | /** 53 | * 返回Action是否已调用。 54 | * @return Action是否已调用。 55 | */ 56 | boolean isExecuted(); 57 | 58 | /** 59 | * 返回Action的调用参数。 60 | * @return Action的调用参数。 61 | */ 62 | Object[] getParameters(); 63 | 64 | /** 65 | * 由指定参数调用Action,并激发下一步操作(通常指拦截器调用)。 66 | * @param Action调用结果的类型。 67 | * @param params 调用参数。 68 | * @return 调用后的结果。 69 | * @throws JRouterException 如果发生调用错误。 70 | */ 71 | T invoke(Object... params) throws JRouterException; 72 | 73 | /** 74 | * 由指定参数调用Action(通常不触发拦截器调用)。 75 | * @param Action调用结果的类型。 76 | * @param params 调用参数。 77 | * @return 调用后的结果。 78 | * @throws JRouterException 如果发生调用错误。 79 | */ 80 | T invokeActionOnly(Object... params) throws JRouterException; 81 | 82 | /** 83 | * 返回Action调用的结果,如果Action尚未被调用或者尚未设置指定的值则返回null。 84 | * @return Action调用的结果,如果Action尚未被调用则返回null。 85 | */ 86 | Object getInvokeResult(); 87 | 88 | /** 89 | * 设置Action调用的结果,可在Action调用期间记录结果对象。 90 | * @param result Action调用的结果对象。 91 | */ 92 | void setInvokeResult(Object result); 93 | 94 | /** 95 | * 返回Action调用完成后将执行的结果对象,若Action尚未调用则返回null。 96 | * @return 结果对象。 97 | */ 98 | Result getResult(); 99 | 100 | /** 101 | * 设置Action调用完成后将执行的结果对象。 102 | * @param result 指定的结果对象。 103 | */ 104 | void setResult(Result result); 105 | 106 | /** 107 | * 返回当前Action运行时上下文中的方法参数转换器。 108 | * @return 方法参数转换器。 109 | */ 110 | ParameterConverter getParameterConverter(); 111 | 112 | /** 113 | * 设置Action运行时上下文中的方法参数转换器。 114 | * @param parameterConverter 方法参数转换器。 115 | */ 116 | void setParameterConverter(ParameterConverter parameterConverter); 117 | 118 | /** 119 | * 返回提供给参数转换器的参数,转换参数可不同于原调用参数。 120 | * @return 提供给参数转换器的参数。 121 | */ 122 | Object[] getConvertParameters(); 123 | 124 | /** 125 | * 设置提供给参数转换器的参数,转换参数可不同于原调用参数。 126 | * @param params 提供给参数转换器的参数。 127 | */ 128 | void setConvertParameters(Object... params); 129 | 130 | /** 131 | * 返回Action路径匹配的键值映射,不包含任何匹配的键值则返回空映射。 132 | * @return Action路径匹配的键值映射。 133 | */ 134 | Map getPathParameters(); 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ActionProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Interceptor; 22 | import net.jrouter.annotation.Result; 23 | 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | /** 28 | * {@link Action}代理类接口。 29 | * 30 | * @param

Path type. 31 | */ 32 | public interface ActionProxy

{ 33 | 34 | /** 35 | * 返回所代理的Action对象。 36 | * @return 代理的Action对象。 37 | */ 38 | Action getAction(); 39 | 40 | /** 41 | * 返回Action所映射的全路径(可能为带参数的动态路径,而非真实调用路径)。 42 | * @return Action所对应的全路径(可能为带参数的动态路径,而非真实调用路径)。 43 | */ 44 | P getPath(); 45 | 46 | /** 47 | * 返回Action的命名空间。 48 | * @return Action的命名空间。 49 | */ 50 | String getNamespace(); 51 | 52 | /** 53 | * 返回Action初始化参数键/值(多值)映射,不包含任何参数映射则返回长度为 0 的映射。 54 | * @return Action初始化参数键/值(多值)映射。 55 | * @see Action#parameters() 56 | */ 57 | Map getActionParameters(); 58 | 59 | /** 60 | * 由指定名称返回Action初始化参数中字符串形式的值。 61 | *

62 | * 如果值不存在则返回 null; 如果为多值,请使用{@link #getActionParameterValues}。 如果为多值,请使用返回多值数组中的第一个。 63 | *

64 | * @param name 指定的名称。 65 | * @return Action初始化参数中字符串形式的值。 66 | * @see #getActionParameterValues(java.lang.String) 67 | */ 68 | String getActionParameter(String name); 69 | 70 | /** 71 | * 由指定名称返回Action初始化参数中多值字符串数组。 72 | *

73 | * 如果值不存在,则返回 null。如果值为空,则返回长宽为 0 的数组。 74 | *

75 | * @param name 指定的名称。 76 | * @return Action初始化参数中多值字符串数组。 77 | * @see #getActionParameter(java.lang.String) 78 | */ 79 | String[] getActionParameterValues(String name); 80 | 81 | /** 82 | * 返回Action所配置的拦截器集合,不包含任何拦截器则返回长度为 0 的集合。 83 | * @return Action所配置的拦截器集合。 84 | * @see Action#interceptors() 85 | */ 86 | List getInterceptors(); 87 | 88 | /** 89 | * 返回Action的结果对象集合,不包含任何结果对象则返回长度为 0 的集合。 90 | * @return Action的结果对象集合。 91 | * @see Action#results() 92 | * @deprecated 93 | */ 94 | @Deprecated 95 | Map getResults(); 96 | 97 | /** 98 | * 返回调用的底层方法。 99 | * @return 调用的底层方法。 100 | */ 101 | java.lang.reflect.Method getMethod(); 102 | 103 | /** 104 | * 返回调用方法的描述信息。 105 | * @return 调用方法的描述信息。 106 | * @deprecated 107 | */ 108 | @Deprecated 109 | String getMethodInfo(); 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ConverterFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | /** 21 | * ConverterFactory接口。负责创建转换对象。 22 | */ 23 | public interface ConverterFactory { 24 | 25 | /** 26 | * 根据参数创建或返回参数转换对象。 27 | * @return 参数转换对象。 28 | */ 29 | ParameterConverter getParameterConverter(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/Invoker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * 调用底层方法的接口。 24 | */ 25 | public interface Invoker { 26 | 27 | /** 28 | * 由指定对象和参数调用方法。 29 | * @param 方法调用结果的类型。 30 | * @param method {@code Method}对象。 31 | * @param obj 调用方法的对象。 32 | * @param params 用于方法调用的参数。 33 | * @return 方法调用后的结果。 34 | * @throws JRouterException 如果发生调用异常。 35 | */ 36 | T invoke(Method method, Object obj, Object... params) throws JRouterException; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/JRouterException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | /** 21 | * jrouter用此异常或其子异常来标识jrouter特定的异常信息。 22 | */ 23 | public class JRouterException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | /** 28 | * 构造一个包含指定详细消息的JRouterException。 29 | * @param message 详细消息。 30 | */ 31 | public JRouterException(String message) { 32 | super(message); 33 | } 34 | 35 | /** 36 | * 构造一个包含指定原因的的JRouterException。 37 | * @param cause 异常原因。 38 | */ 39 | public JRouterException(Throwable cause) { 40 | super(cause); 41 | } 42 | 43 | /** 44 | * 构造一个包含指定详细消息和原因的JRouterException。 45 | * @param message 详细消息。 46 | * @param cause 异常原因。 47 | */ 48 | public JRouterException(String message, Throwable cause) { 49 | super(message, cause); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/MethodInvokerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * 根据底层方法生成调用对象的工厂接口。 24 | */ 25 | public interface MethodInvokerFactory { 26 | 27 | /** 28 | * 由指定的底层方法及所表示的 {@code Class} 对象生成调用对象。 29 | * @param targetClass 底层方法所表示的 {@code Class} 对象。 30 | * @param method 底层方法。 31 | * @return Invoker调用对象。 32 | */ 33 | Invoker newInstance(Class targetClass, Method method); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/NotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | /** 21 | * 标识指定资源不存在时抛出的异常。 22 | */ 23 | public class NotFoundException extends JRouterException { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | /** 28 | * 构造一个包含指定详细消息的NotFoundException。 29 | * @param message 详细消息。 30 | */ 31 | public NotFoundException(String message) { 32 | super(message); 33 | } 34 | 35 | /** 36 | * 构造一个包含指定原因的的NotFoundException。 37 | * @param cause 异常原因。 38 | */ 39 | public NotFoundException(Throwable cause) { 40 | super(cause); 41 | } 42 | 43 | /** 44 | * 构造一个包含指定详细消息和原因的NotFoundException。 45 | * @param message 详细消息。 46 | * @param cause 异常原因。 47 | */ 48 | public NotFoundException(String message, Throwable cause) { 49 | super(message, cause); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ObjectFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | /** 21 | * ObjectFactory接口。负责创建新的对象实例。 22 | */ 23 | public interface ObjectFactory { 24 | 25 | /** 26 | * 根据指定的{@code Class}对象所表示的类生成一个新的对象实例。 27 | * @param 生成对象实例的类型。 28 | * @param clazz 指定的{@code Class}对象。 29 | * @return 新的对象实例。 30 | */ 31 | T newInstance(Class clazz); 32 | 33 | /** 34 | * 根据指定的{@code Object}对象(或代理)获取其所属的{@code Class}类型。 35 | * @param obj {@code Object}对象。 36 | * @return 指定{@code Object}对象所属的{@code Class}类型。 37 | */ 38 | Class getClass(Object obj); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/ParameterConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Dynamic; 21 | 22 | import java.lang.reflect.Method; 23 | 24 | /** 25 | * 提供方法参数转换器。 26 | */ 27 | @Dynamic 28 | public interface ParameterConverter { 29 | 30 | /** 31 | * 传递底层方法、调用对象及原有的参数,返回转换处理后的调用参数。 原调用参数由ActionFactory的invokeAction方法指定传递。 32 | * @param method {@code Method}对象。 33 | * @param obj 调用方法的对象。 34 | * @param originalParams 传递于方法调用的原参数。 35 | * @param convertParams 提供给转换器的参数。 36 | * @return 转换处理后的调用参数。 37 | * @throws JRouterException 如果发生转换异常。 38 | * @see ActionFactory#invokeAction(java.lang.Object, java.lang.Object...) 39 | */ 40 | Object[] convert(Method method, Object obj, Object[] originalParams, Object[] convertParams) 41 | throws JRouterException; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/PathGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | /** 23 | * Path generator. 24 | * 25 | * @param

path type. 26 | * @since 1.7.7 27 | */ 28 | // @FunctionalInterface 29 | public interface PathGenerator

{ 30 | 31 | /** 32 | * Generate the path(s). 33 | * @param targetClass 底层方法所表示的 {@code Class} 对象。 34 | * @param method 底层方法。 35 | * @return the generated Path(s). 36 | */ 37 | P[] generatePath(Class targetClass, Method method); 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Action.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * Action,定义于方法上的注解。 24 | *

25 | * Action上拦截器集合: 26 | *

27 | *

28 | * Action指定的拦截器集合 = 存在Action指定的拦截栈 ? 指定拦截栈的拦截器集合 + 指定的拦截器集合 : 指定的拦截器集合。 29 | *

30 | *

31 | * Action最终的拦截器集合 = Action指定拦截器集合 > 命名空间拦截器集合 > 路径匹配拦截栈(拦截器集合) > 全局默认拦截器集合。 32 | *

33 | * 34 | *

35 | * Action上拦截栈优先级: 36 | *

37 | *

38 | * Action指定拦截栈 > 命名空间拦截栈 > 路径匹配拦截栈 > 全局默认拦截栈。 39 | *

40 | *

41 | * 若需表明Action不包含任何拦截器,应该指定其拦截栈为空拦截栈;直接指定其拦截器集合为空集合不产生任何效果。 42 | * 43 | * @see net.jrouter.interceptor.DefaultInterceptorStack#EMPTY_INTERCEPTOR_STACK 44 | */ 45 | @Target(ElementType.METHOD) 46 | @Retention(RetentionPolicy.RUNTIME) 47 | @Documented 48 | public @interface Action { 49 | 50 | /** 51 | * Action名称,可多个路径映射同一个Action。 52 | * 等同于{@link #name()},name属性非空时优先选取name值,当仅需要name属性时提供便捷的注解方式。 53 | * @return Action名称。 54 | * @see #name() 55 | * @since 1.7.1 56 | */ 57 | String[] value() default {}; 58 | 59 | /** 60 | * Action名称,可多个路径映射同一个Aciton,需保证其最终生成路径的唯一性。 Action名称为空时,默认取其所在的方法名称(区分大小写)。 61 | * @return Action名称。 62 | * @see #value() 63 | */ 64 | String[] name() default {}; 65 | 66 | /** 67 | * Action指定的拦截栈名称。 68 | * @return Action指定的拦截栈名称。 69 | */ 70 | String interceptorStack() default ""; 71 | 72 | /** 73 | * Action指定的拦截器集合的名称集合,指定空集合无效。 74 | * @return Action指定的拦截器集合的名称集合。 75 | * @deprecated 1.8.1 76 | */ 77 | @Deprecated 78 | String[] interceptors() default {}; 79 | 80 | /** 81 | * 结果对象集合。 82 | * @return 结果对象集合。 83 | * @deprecated 84 | */ 85 | @Deprecated 86 | Result[] results() default {}; 87 | 88 | /** 89 | * 调用的范围,Action默认为单例。 90 | * @return Action单例或非单例。 91 | */ 92 | Scope scope() default Scope.SINGLETON; 93 | 94 | /** 95 | * Action初始化参数的键/值(多值)集合。 96 | * @return Action初始化参数的键/值(多值)集合。 97 | */ 98 | Parameter[] parameters() default {}; 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Dynamic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * 指示经常需要根据条件创建新对象的接口、类或成员变量(注解于成员变量上警示避免多线程安全问题)。 24 | */ 25 | @Target({ ElementType.TYPE, ElementType.FIELD }) 26 | @Retention(RetentionPolicy.SOURCE) 27 | @Documented 28 | public @interface Dynamic { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Ignore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * 表明略过所注解的方法不做处理。 24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Documented 28 | public @interface Ignore { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * 拦截器。 24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Documented 28 | public @interface Interceptor { 29 | 30 | /** 31 | * 拦截器名称。 32 | * @return 拦截器名称。 33 | */ 34 | String name(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/InterceptorStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * 拦截栈,定义于字符串{@code String}变量上的注解。 24 | */ 25 | @Target(ElementType.FIELD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Documented 28 | public @interface InterceptorStack { 29 | 30 | /** 31 | * 拦截栈名称,未指定则默认取字符串变量的值。 32 | * @return 拦截栈名称。 33 | */ 34 | String name() default ""; 35 | 36 | /** 37 | * TODO 父拦截栈名称。 38 | * @return 父拦截栈名称。 39 | */ 40 | // String parent() default ""; 41 | 42 | /** 43 | * 包含的拦截器集合。 44 | * @return 所包含的拦截器集合。 45 | */ 46 | Interceptor[] interceptors() default {}; 47 | 48 | /** 49 | * 匹配的路径集合(默认空不包含任何)。 50 | * @return 匹配的路径集合。 51 | * @since 1.8.1 52 | */ 53 | String[] include() default {}; 54 | 55 | /** 56 | * 不匹配的路径集合(默认空不排除任何)。 57 | * @return 不匹配的路径集合。 58 | * @since 1.8.1 59 | */ 60 | String[] exclude() default {}; 61 | 62 | /** 63 | * 排序值,默认0。多匹配后者覆盖前者。 64 | * @return 排序值。 65 | */ 66 | int order() default 0; 67 | 68 | /** 69 | * 包含于拦截栈的拦截器配置。 70 | */ 71 | @Target({}) 72 | @Retention(RetentionPolicy.RUNTIME) 73 | @Documented 74 | @interface Interceptor { 75 | 76 | /** 77 | * 拦截器名称。 78 | * @return 拦截器名称。 79 | */ 80 | String value(); 81 | 82 | /** 83 | * 不匹配的路径集合(默认空不排除任何)。 84 | * @return 不匹配的路径集合。 85 | * @since 1.8.1 86 | */ 87 | String[] exclude() default {}; 88 | 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Namespace.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * Namespace,定义于类{@code Class}上的注解。 24 | *

25 | * Namespace上拦截器集合: 26 | *

27 | *

28 | * Namespace的拦截器集合 = 存在Namespace指定的拦截栈 ? 指定拦截栈的拦截器集合 + 指定的拦截器集合 : 指定的拦截器集合。 29 | *

30 | *

31 | * 若需表明Namespace不包含任何拦截器,应该指定其拦截栈为空拦截栈;直接指定其拦截器集合为空集合不产生任何效果。 32 | * 33 | * @see net.jrouter.interceptor.DefaultInterceptorStack#EMPTY_INTERCEPTOR_STACK 34 | */ 35 | @Target(ElementType.TYPE) 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Documented 38 | public @interface Namespace { 39 | 40 | /** 41 | * 命名空间名称。 42 | * @return 命名空间名称。 43 | */ 44 | String name(); 45 | 46 | /** 47 | * 命名空间的拦截栈名称。 48 | * @return 命名空间的默认拦截栈名称。 49 | */ 50 | String interceptorStack() default ""; 51 | 52 | /** 53 | * 指定的拦截器集合的名称集合,指定空集合无效。 54 | * @return 指定拦截器集合的名称集合。 55 | * @see net.jrouter.interceptor.DefaultInterceptorStack#EMPTY_INTERCEPTOR_STACK 56 | * @deprecated 1.8.1 57 | */ 58 | @Deprecated 59 | String[] interceptors() default {}; 60 | 61 | /** 62 | * 是否自动加载定义类所有public/protected方法,默认不自动加载。 63 | * @return 是否自动加载所定义类的public/protected方法,默认不自动加载。 64 | */ 65 | boolean autoIncluded() default false; 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Parameter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * 参数。名称/值(多值)。 27 | * 28 | * @see Action#parameters() 29 | */ 30 | @Target({}) 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Documented 33 | public @interface Parameter { 34 | 35 | /** 36 | * 参数名称。 37 | * @return 参数名称。 38 | */ 39 | String name(); 40 | 41 | /** 42 | * 参数名称对应的值/多值。 43 | * @return 参数名称对应的值/多值。 44 | */ 45 | String[] value(); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Result.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | *

24 | * 当Result定义于注解Action中的子项时,表示Action特定的结果对象; 25 | *

26 | *

27 | * 当Result单独定义于方法上时,表示某种特定{@code String}类型全局的结果对象。 28 | * 当作为全局结果对象时,type值为空时直接调用后结束;type值不为空调用后再调用相应的{@link ResultType}。 29 | *

30 | */ 31 | @Target(ElementType.METHOD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | @Documented 34 | public @interface Result { 35 | 36 | /** 37 | * 结果对象的名称。 38 | * @return 结果对象的名称。 39 | */ 40 | String name(); 41 | 42 | /** 43 | * 结果对象的类型名称。 44 | * @return 结果对象的类型。 45 | */ 46 | String type() default ""; 47 | 48 | /** 49 | * 结果对象相关联的资源路径。 50 | * @return 资源路径。 51 | */ 52 | String location() default ""; 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/ResultType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | import java.lang.annotation.*; 21 | 22 | /** 23 | * 定义于方法上,表明同一类型结果处理。 24 | */ 25 | @Target(ElementType.METHOD) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Documented 28 | public @interface ResultType { 29 | 30 | /** 31 | * 结果类型的名称。 32 | * @return 结果类型的名称。 33 | */ 34 | String type(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/Scope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.annotation; 19 | 20 | /** 21 | * Scope表示了{@link Action}的调用范围。 Action调用可为单例(每次都调用同一对象的方法)或非单例(每次都调用新对象的方法)。 22 | * 23 | * @see Action#scope() 24 | */ 25 | public enum Scope { 26 | 27 | /** 28 | * 单例。 29 | */ 30 | SINGLETON, 31 | /** 32 | * 非单例。 33 | */ 34 | PROTOTYPE 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/annotation/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供 jrouter 的注解类。 19 | */ 20 | package net.jrouter.annotation; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/bytecode/javassist/JavassistInvoker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.bytecode.javassist; 19 | 20 | import net.jrouter.Invoker; 21 | 22 | import java.lang.reflect.Method; 23 | 24 | /** 25 | * Invoker接口的封装,本质未实现方法。 26 | * 27 | * @see JavassistMethodInvokerFactory#newInstance 28 | */ 29 | public class JavassistInvoker implements Invoker { 30 | 31 | @Override 32 | public T invoke(Method method, Object obj, Object... params) { 33 | throw new UnsupportedOperationException("Not implemented here."); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/bytecode/javassist/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供基于 javassist 的增强。 19 | */ 20 | package net.jrouter.bytecode.javassist; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/bytecode/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供字节码增强。 19 | */ 20 | package net.jrouter.bytecode; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/config/AopAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.config; 19 | 20 | import net.jrouter.annotation.Action; 21 | 22 | import java.io.Serializable; 23 | import java.util.List; 24 | 25 | /** 26 | * 针对相应路径的所有{@link Action},添加/修改其对应的拦截器集合。 27 | * 28 | * @deprecated 1.8.1 29 | */ 30 | @Deprecated 31 | public class AopAction implements Serializable { 32 | 33 | private static final long serialVersionUID = 1L; 34 | 35 | /** 36 | * Action的路径匹配。 37 | */ 38 | @lombok.Getter 39 | @lombok.Setter 40 | private String matches; 41 | 42 | /** 43 | * 依序指定的拦截栈集合。 44 | */ 45 | @lombok.Getter 46 | @lombok.Setter 47 | private List interceptorStacks; 48 | 49 | /** 50 | * 依序指定的拦截器集合。 51 | */ 52 | @lombok.Getter 53 | @lombok.Setter 54 | private List interceptors; 55 | 56 | /** 57 | * aop的类型。 58 | */ 59 | @lombok.Getter 60 | @lombok.Setter 61 | private Type type; 62 | 63 | @Override 64 | public String toString() { 65 | return "AopAction{" + "matches=" + matches + ", interceptorStacks=" + interceptorStacks + ", interceptors=" 66 | + interceptors + ", type=" + (type == null ? null : type.getCode()) + '}'; 67 | } 68 | 69 | /** 70 | * 修改Action拦截器集合的aop操作类型。 71 | */ 72 | public enum Type { 73 | 74 | /** 75 | * 添加于已有拦截器集合之前。 76 | */ 77 | ADD_BEFORE("add-before"), 78 | /** 79 | * 添加于已有拦截器集合之后。 80 | */ 81 | ADD_AFTER("add-after"), 82 | /** 83 | * 覆盖已有拦截器集合。 84 | */ 85 | OVERRIDE("override"); 86 | 87 | // aop类型所表征的字符串代码 88 | @lombok.Getter 89 | private final String code; 90 | 91 | /** 92 | * 构造指定代码的aop类型。 93 | * @param code 指定代码。 94 | */ 95 | Type(String code) { 96 | this.code = code; 97 | } 98 | 99 | /** 100 | * 由指定代码返回aop类型。 101 | * @param code op的类型代码。 102 | * @return aop类型。 103 | */ 104 | public static Type parseCode(String code) { 105 | if (ADD_BEFORE.getCode().equals(code)) { 106 | return ADD_BEFORE; 107 | } 108 | else if (ADD_AFTER.getCode().equals(code)) { 109 | return ADD_AFTER; 110 | } 111 | else if (OVERRIDE.getCode().equals(code)) { 112 | return OVERRIDE; 113 | } 114 | throw new IllegalArgumentException("No enum const " + Type.class + "." + code); 115 | } 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/config/ConfigurationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.config; 19 | 20 | /** 21 | * 标识jrouter解析配置发生错误时的异常。 22 | */ 23 | public class ConfigurationException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | /** 28 | * 构造一个包含指定原因的ConfigurationException。 29 | * @param cause 异常原因。 30 | */ 31 | public ConfigurationException(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | /** 36 | * 构造一个包含指定详细消息和原因的ConfigurationException。 37 | * @param message 详细消息。 38 | * @param cause 异常原因。 39 | */ 40 | public ConfigurationException(String message, Throwable cause) { 41 | super(message, cause); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/config/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供 jrouter 的配置解析。 19 | */ 20 | package net.jrouter.config; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/DefaultActionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import java.util.Map; 21 | 22 | /** 23 | * Use {@link PathActionFactory} instead. 24 | * 25 | * @see PathActionFactory 26 | * @deprecated 27 | */ 28 | @Deprecated 29 | public class DefaultActionFactory extends PathActionFactory { 30 | 31 | /** 32 | * Constructor. 33 | */ 34 | public DefaultActionFactory(Map properties) { 35 | super(properties); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/DefaultProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.AbstractProxy; 21 | import net.jrouter.ActionFactory; 22 | import net.jrouter.Invoker; 23 | import net.jrouter.util.MethodUtil; 24 | 25 | import java.lang.reflect.InvocationTargetException; 26 | import java.lang.reflect.Method; 27 | 28 | /** 29 | * 默认方法代理类实现,封装了调用代理方法时及异常的处理。 30 | */ 31 | public class DefaultProxy extends AbstractProxy { 32 | 33 | /** 34 | * 底层方法的调用对象 35 | */ 36 | private Invoker invoker; 37 | 38 | /** 39 | * 指定方法及其对象的构造方法。 40 | * @param method 指定的方法。 41 | * @param object 指定的对象。 42 | * @param actionFactory 指定的ActionFactory。 43 | */ 44 | public DefaultProxy(Method method, Object object, ActionFactory actionFactory) { 45 | super(method, object); 46 | if (actionFactory != null && actionFactory.getMethodInvokerFactory() != null) { 47 | Class targetClass = ((object == null || actionFactory.getObjectFactory() == null) 48 | ? method.getDeclaringClass() : actionFactory.getObjectFactory().getClass(object)); 49 | this.invoker = actionFactory.getMethodInvokerFactory().newInstance(targetClass, method); 50 | } 51 | } 52 | 53 | @Override 54 | public Object invoke(Object... params) { 55 | return invoke(method, object, params); 56 | } 57 | 58 | /** 59 | * 使用Java反射或调用对象调用底层方法。 60 | * @param method 底层方法。 61 | * @param obj 调用底层方法的对象。 62 | * @param params 用于方法调用的参数。 63 | * @return 方法调用后的结果。 64 | */ 65 | private Object invoke(Method method, Object obj, Object... params) { 66 | try { 67 | return invoker == null ? method.invoke(obj, params) : invoker.invoke(method, obj, params); 68 | } 69 | catch (IllegalAccessException e) { 70 | throw new InvocationProxyException(e, this); 71 | } 72 | catch (InvocationTargetException e) { 73 | throw new InvocationProxyException(e.getTargetException(), this);// NOPMD 74 | // PreserveStackTrace 75 | } // convert Exception to InvocationProxyException 76 | catch (Exception e) { // NOPMD IdenticalCatchBranches 77 | throw new InvocationProxyException(e, this); 78 | } 79 | } 80 | 81 | /** 82 | * 返回调用方法的描述信息。 83 | * @return 调用方法的描述信息。 84 | */ 85 | public String getMethodInfo() { 86 | return MethodUtil.getMethod(method); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/InterceptorProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import lombok.Getter; 21 | import net.jrouter.ActionFactory; 22 | import net.jrouter.annotation.Action; 23 | import net.jrouter.annotation.Interceptor; 24 | 25 | import java.lang.reflect.Method; 26 | 27 | /** 28 | * 拦截器的代理类,包括了拦截器的名称及在对{@link Action}做拦截调用时是否将{@link Action}的运行时状态作为参数传递等信息。 29 | */ 30 | @Getter 31 | public final class InterceptorProxy extends DefaultProxy { 32 | 33 | /** 34 | * 拦截器的名称。 35 | */ 36 | private final String name; 37 | 38 | /** 39 | * 拦截器。 40 | */ 41 | private final Interceptor interceptor; 42 | 43 | /** 44 | * 构造一个拦截器的代理类,包含指定的拦截器名称、拦截器调用参数的状态。 45 | * @param actionFactory 指定的ActionFactory。 46 | * @param interceptor 所代理的拦截器。 47 | * @param method 代理的方法。 48 | * @param object 代理的方法的对象。 49 | */ 50 | public InterceptorProxy(ActionFactory actionFactory, Interceptor interceptor, Method method, Object object) { 51 | super(method, object, actionFactory); 52 | this.interceptor = interceptor; 53 | this.name = interceptor.name().trim(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/InterceptorStackProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.annotation.InterceptorStack; 21 | import net.jrouter.util.CollectionUtil; 22 | 23 | import java.lang.reflect.Field; 24 | import java.util.*; 25 | 26 | /** 27 | * 拦截栈的代理类,包括了拦截栈的名称、字段来源及其所包含的拦截器集合。 28 | */ 29 | public final class InterceptorStackProxy { 30 | 31 | /** 32 | * 拦截栈名称 33 | */ 34 | @lombok.Getter 35 | private final String name; 36 | 37 | /** 38 | * 拦截栈取名字段 39 | */ 40 | private final Field field; 41 | 42 | /** 43 | * 拦截栈 44 | */ 45 | @lombok.Getter 46 | private final InterceptorStack interceptorStack; 47 | 48 | /** 49 | * 包含的拦截器集合 50 | */ 51 | @lombok.Getter(lombok.AccessLevel.PACKAGE) 52 | private final List interceptorDelegates; 53 | 54 | /** 55 | * 构造一个拦截栈的代理类,包含拦截栈的名称、字段来源及其所包含的拦截器集合。 56 | * @param name 拦截栈的名称。 57 | * @param field 拦截栈字段来源。 58 | * @param interceptorDelegates 包含的拦截器集合。 59 | */ 60 | public InterceptorStackProxy(String name, Field field, InterceptorStack interceptorStack, 61 | List interceptorDelegates) { 62 | this.name = name; 63 | this.field = field; 64 | this.interceptorStack = interceptorStack; 65 | this.interceptorDelegates = interceptorDelegates; 66 | } 67 | 68 | /** 69 | * 返回拦截栈所包含的拦截器的代理集合。 70 | * @return 拦截栈所包含的拦截器的代理集合。 71 | */ 72 | public List getInterceptors() { 73 | if (CollectionUtil.isNotEmpty(interceptorDelegates)) { 74 | List interceptors = new ArrayList<>(interceptorDelegates.size()); 75 | for (InterceptorDelegate delegate : interceptorDelegates) { 76 | interceptors.add(delegate.interceptorProxy); 77 | } 78 | return interceptors; 79 | } 80 | return Collections.emptyList(); 81 | } 82 | 83 | /** 84 | * 返回拦截栈取名字段的信息。 85 | * @return 拦截栈取名字段的信息。 86 | */ 87 | public String getFieldName() { 88 | return field.toString(); 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | StringBuilder msg = new StringBuilder(); 94 | msg.append('['); 95 | if (interceptorDelegates != null) { 96 | Iterator it = interceptorDelegates.iterator(); 97 | while (it.hasNext()) { 98 | msg.append(it.next().interceptorProxy.getName()); 99 | if (it.hasNext()) { 100 | msg.append(", "); 101 | } 102 | } 103 | } 104 | msg.append(']'); 105 | return msg.toString(); 106 | } 107 | 108 | /** 109 | * Extended InterceptorProxy. 110 | */ 111 | @lombok.Getter 112 | public final static class InterceptorDelegate { 113 | 114 | /** 115 | * InterceptorStack.Interceptor. 116 | */ 117 | private final InterceptorStack.Interceptor interceptor; 118 | 119 | /** 120 | * Interceptor Proxy. 121 | */ 122 | private final InterceptorProxy interceptorProxy; 123 | 124 | /** 125 | * Constructor. 126 | */ 127 | public InterceptorDelegate(InterceptorStack.Interceptor interceptor, InterceptorProxy interceptorProxy) { 128 | Objects.requireNonNull(interceptor); 129 | Objects.requireNonNull(interceptorProxy); 130 | this.interceptor = interceptor; 131 | this.interceptorProxy = interceptorProxy; 132 | } 133 | 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/InvocationProxyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package net.jrouter.impl; 18 | 19 | import lombok.Getter; 20 | import net.jrouter.JRouterException; 21 | 22 | /** 23 | * 标识代理的方法调用发生错误时的异常。 此异常类型限制外部构造生成,避免用户直接抛出此异常引发错误的异常吞噬。 24 | */ 25 | @Getter 26 | public class InvocationProxyException extends JRouterException { 27 | 28 | private static final long serialVersionUID = 1L; 29 | 30 | /** 31 | * 异常发生的对象。 32 | */ 33 | private final Object target; 34 | 35 | /** 36 | * 构造一个包含指定原因和异常发生对象的InvocationException。 37 | * @param cause 异常原因。 38 | * @param target 异常发生的对象。 39 | * @see #getSource() 40 | */ 41 | InvocationProxyException(Throwable cause, Object target) { 42 | super(cause); 43 | this.target = target; 44 | } 45 | 46 | /** 47 | * 构造一个包含指定详细消息、原因和异常发生对象的InvocationException。 48 | * @param cause 异常原因。 49 | * @param target 异常发生的对象。 50 | * @see #getSource() 51 | */ 52 | InvocationProxyException(String message, Throwable cause, Object target) { 53 | super(message, cause); 54 | this.target = target; 55 | } 56 | 57 | /** 58 | * 返回首个非InvocationException类型的cause。 59 | * @return 首个非InvocationException的cause,如果 cause 不存在或是未知的,则返回 null。 60 | */ 61 | public Throwable getSource() { 62 | Throwable cur = this.getCause(); 63 | while (cur instanceof InvocationProxyException && (cur = cur.getCause()) != null) { // NOPMD 64 | // for 65 | // EmptyControlStatement 66 | } 67 | return cur; 68 | } 69 | 70 | /** 71 | * 返回最初抛出的InvocationException。 72 | * @return 最初抛出的InvocationException。 73 | */ 74 | public InvocationProxyException getSourceInvocationException() { 75 | Throwable cur = this; 76 | Throwable cause; 77 | while ((cause = cur.getCause()) instanceof InvocationProxyException) { 78 | cur = cause; 79 | } 80 | return (InvocationProxyException) cur; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/MultiParameterConverterFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.ConverterFactory; 22 | import net.jrouter.JRouterException; 23 | import net.jrouter.ParameterConverter; 24 | import net.jrouter.util.CollectionUtil; 25 | import net.jrouter.util.MethodUtil; 26 | 27 | import java.lang.reflect.Method; 28 | import java.util.Map; 29 | import java.util.concurrent.ConcurrentHashMap; 30 | 31 | /** 32 | * 创建多参数自动映射转换器的工厂类。 33 | */ 34 | public class MultiParameterConverterFactory implements ConverterFactory { 35 | 36 | /** 37 | * 转换参数类型是否固定顺序,默认固定参数。 38 | * 39 | * @see ActionInvocation#getConvertParameters() 40 | */ 41 | @lombok.Getter 42 | private final boolean fixedOrder; 43 | 44 | /** 45 | * 多参数转换器,线程安全的单例对象。 46 | */ 47 | private final ParameterConverter parameterConverter; 48 | 49 | /** 50 | * 缓存转换参数匹配的位置 51 | */ 52 | private Map methodParametersCache; 53 | 54 | /** 55 | * 创建固定参数自动映射转换器的工厂类。 56 | */ 57 | public MultiParameterConverterFactory() { 58 | this(true); 59 | } 60 | 61 | /** 62 | * 创建多参数自动映射转换器的工厂类。 63 | * @param fixedOrder 参数类型是否固定顺序。 64 | */ 65 | public MultiParameterConverterFactory(boolean fixedOrder) { 66 | this.fixedOrder = fixedOrder; 67 | if (fixedOrder) { 68 | methodParametersCache = new ConcurrentHashMap<>(); 69 | } 70 | parameterConverter = new MultiParameterConverter(); 71 | } 72 | 73 | /** 74 | * 返回线程安全的多参数自动映射转换器。 此参数转换器可能需要ActionFactory支持,在创建ActionInvocation时区分处理原始参数和转换参数。 75 | */ 76 | @Override 77 | public ParameterConverter getParameterConverter() { 78 | return parameterConverter; 79 | } 80 | 81 | /** 82 | * 不缓存转换参数位置的工厂类。提供一个便捷的无参数构造类。 MultiParameterConverterFactory.NoFixedOrder()即 83 | * MultiParameterConverterFactory(false)。 84 | */ 85 | public static class NoFixedOrder extends MultiParameterConverterFactory { 86 | 87 | /** 88 | * 不缓存转换参数位置的工厂类。 89 | */ 90 | public NoFixedOrder() { 91 | super(false); 92 | } 93 | 94 | } 95 | 96 | /** 97 | * 提供多参数自动映射的转换器。不包含任何成员对象,线程安全。 注入并自动映射调用的参数(无类型匹配的参数映射为{@code null})。 98 | */ 99 | public class MultiParameterConverter implements ParameterConverter { 100 | 101 | @Override 102 | public Object[] convert(Method method, Object obj, Object[] originalParams, Object[] convertParams) 103 | throws JRouterException { 104 | int paramSize = method.getParameterTypes().length; 105 | // 无参数的方法 106 | if (paramSize == 0) { 107 | return CollectionUtil.EMPTY_OBJECT_ARRAY; 108 | } 109 | if (CollectionUtil.isEmpty(originalParams) && CollectionUtil.isEmpty(convertParams)) { 110 | return new Object[paramSize]; 111 | } 112 | Object[] allParams = CollectionUtil.append(originalParams, convertParams); 113 | int[] idx = match(method, allParams); 114 | Object[] newArgs = new Object[paramSize]; 115 | for (int i = 0; i < paramSize; i++) { 116 | newArgs[i] = (idx[i] == -1 ? null : allParams[idx[i]]); 117 | } 118 | return newArgs; 119 | } 120 | 121 | /** 122 | * 匹配追加注入的参数相对于方法参数类型中的映射; 匹配顺序不考虑父子优先级,追加的参数按顺序优先匹配;{@code null}不匹配任何参数类型。 123 | * 如果追加注入的参数类型固定,则会缓存记录。 124 | * @param method 指定的方法。 125 | * @param parameters 注入的参数。 126 | * @return 注入的参数相对于方法参数类型中的映射。 127 | * @see #methodParametersCache 128 | */ 129 | private int[] match(Method method, Object[] parameters) { 130 | int[] idx = null; 131 | if (fixedOrder) { 132 | // get from cache 133 | idx = methodParametersCache.get(method); 134 | if (idx != null) { 135 | return idx; 136 | } 137 | } 138 | idx = MethodUtil.match(method, parameters); 139 | if (fixedOrder) { 140 | // put in cache 141 | methodParametersCache.put(method, idx); 142 | } 143 | return idx; 144 | } 145 | 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/ResultProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.ActionFactory; 21 | import net.jrouter.annotation.Result; 22 | import net.jrouter.annotation.ResultType; 23 | 24 | import java.lang.reflect.Method; 25 | 26 | /** 27 | * 结果对象的代理类,包括了结果对象及调用参数的状态。 28 | * 29 | * @deprecated 30 | */ 31 | @Deprecated 32 | public final class ResultProxy extends DefaultProxy { 33 | 34 | /** 35 | * 结果对象 36 | */ 37 | @lombok.Getter 38 | private final Result result; 39 | 40 | /** 41 | * 结果对象相应的结果类型 未完成 42 | */ 43 | private ResultType resultType; 44 | 45 | /** 46 | * 构造一个结果对象的代理类,包含指定的结果对象及其调用参数的状态。 47 | * @param actionFactory 指定的ActionFactory。 48 | * @param result 代理的结果对象。 49 | * @param method 代理的方法。 50 | * @param object 代理的方法的对象。 51 | */ 52 | public ResultProxy(ActionFactory actionFactory, Result result, Method method, Object object) { 53 | super(method, object, actionFactory); 54 | this.result = result; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/ResultTypeProxy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import lombok.Getter; 21 | import net.jrouter.ActionFactory; 22 | import net.jrouter.annotation.Action; 23 | import net.jrouter.annotation.ResultType; 24 | 25 | import java.lang.reflect.Method; 26 | 27 | /** 28 | * 结果类型的代理类,包括了结果类型的名称及在对{@link Action}做结果调用时是否将{@link Action}的运行时状态作为参数传递。 29 | */ 30 | @Getter 31 | public final class ResultTypeProxy extends DefaultProxy { 32 | 33 | /** 34 | * 结果类型的名称 35 | */ 36 | private final String type; 37 | 38 | /** 39 | * 结果类型 40 | */ 41 | private final ResultType resultType; 42 | 43 | /** 44 | * 构造一个结果类型的代理类,包含指定的结果类型、代理的方法及方法的对象。 45 | * @param actionFactory 指定的ActionFactory。 46 | * @param resultType 所代理的结果类型。 47 | * @param method 代理的方法。 48 | * @param object 代理的方法的对象。 49 | */ 50 | public ResultTypeProxy(ActionFactory actionFactory, ResultType resultType, Method method, Object object) { 51 | super(method, object, actionFactory); 52 | this.resultType = resultType; 53 | this.type = resultType.type().trim(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/impl/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供 jrouter 的默认实现。 19 | */ 20 | package net.jrouter.impl; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/interceptor/DefaultInterceptorStack.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.interceptor; 19 | 20 | import net.jrouter.annotation.InterceptorStack; 21 | 22 | /** 23 | * 内置拦截栈。 24 | */ 25 | public class DefaultInterceptorStack { 26 | 27 | /** 28 | * 空拦截栈名称,不包含任何拦截器。 29 | */ 30 | @InterceptorStack(interceptors = {}) 31 | public static final String EMPTY_INTERCEPTOR_STACK = "empty"; 32 | 33 | /** 34 | * 示例拦截栈名称,包含日志拦截器和计时拦截器。 35 | * 36 | * @see SampleInterceptor#logging 37 | * @see SampleInterceptor#timer 38 | */ 39 | @InterceptorStack(interceptors = { @InterceptorStack.Interceptor(SampleInterceptor.LOGGING), 40 | @InterceptorStack.Interceptor(SampleInterceptor.TIMER) }) 41 | public static final String SAMPLE_INTERCEPTOR_STACK = "sample"; 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/interceptor/SampleInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.interceptor; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.annotation.Interceptor; 22 | import org.slf4j.Logger; 23 | import org.slf4j.LoggerFactory; 24 | 25 | import java.util.Date; 26 | 27 | /** 28 | * 示例拦截器。 29 | */ 30 | public class SampleInterceptor { 31 | 32 | /** 33 | * 计时拦截器 34 | */ 35 | public static final String TIMER = "timer"; 36 | 37 | /** 38 | * 日志拦截器 39 | */ 40 | public static final String LOGGING = "logging"; 41 | 42 | /** 43 | * LOG 44 | */ 45 | private static final Logger LOG = LoggerFactory.getLogger(SampleInterceptor.class); 46 | 47 | /** 48 | * 记录Action调用耗时。 49 | * @param invocation Action运行时上下文。 50 | * @return 拦截器处理后的Action调用结果。 51 | */ 52 | @Interceptor(name = TIMER) 53 | public static Object timer(ActionInvocation invocation) { 54 | long startTime = System.currentTimeMillis(); 55 | Object result = null; 56 | try { 57 | // invoke 58 | result = invocation.invoke(); 59 | } 60 | finally { 61 | if (LOG.isInfoEnabled()) { 62 | long executionTime = System.currentTimeMillis() - startTime; 63 | StringBuilder message = new StringBuilder(64); 64 | message.append("Executed action [").append(invocation.getActionPath()); 65 | message.append("] took ").append(executionTime).append(" ms."); 66 | LOG.info(message.toString()); 67 | } 68 | } 69 | return result; 70 | } 71 | 72 | /** 73 | * 记录Action起始结束时间。 74 | * @param invocation Action运行时上下文。 75 | * @return 拦截器处理后的Action调用结果。 76 | */ 77 | @Interceptor(name = LOGGING) 78 | public static Object logging(ActionInvocation invocation) { 79 | if (LOG.isInfoEnabled()) { 80 | LOG.info("Starting action [{}] at {}.", invocation.getActionPath(), new Date()); 81 | } 82 | // invoke 83 | Object result = invocation.invoke(); 84 | if (LOG.isInfoEnabled()) { 85 | LOG.info("Finishing action [{}] at {}.", invocation.getActionPath(), new Date()); 86 | } 87 | return result; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/interceptor/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供常用拦截栈和拦截器。 19 | */ 20 | package net.jrouter.interceptor; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供围绕对象方法基于责任链(拦截器)模式设计的开源轻量级Java容器。 19 | */ 20 | package net.jrouter; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/result/DefaultResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.result; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.NotFoundException; 22 | import net.jrouter.annotation.Result; 23 | import net.jrouter.annotation.ResultType; 24 | 25 | /** 26 | * 内置结果类型。 27 | */ 28 | public class DefaultResult { 29 | 30 | /** 31 | * 默认结果类型名称,不作任何处理 32 | */ 33 | public static final String EMPTY = "empty"; 34 | 35 | /** 36 | * actionForward结果类型名称 37 | */ 38 | public static final String FORWARD = "actionForward"; 39 | 40 | /** 41 | * result not found 42 | */ 43 | public static final String RESULT_NOT_FOUND = "resultNotFound"; 44 | 45 | /** 46 | * 默认结果类型,未作任何处理。 47 | * @param invocation Action运行时上下文。 48 | */ 49 | @ResultType(type = EMPTY) 50 | public static void result(ActionInvocation invocation) { 51 | // invocation.invoke(); 52 | } 53 | 54 | /** 55 | * Action结果直接调用映射的Action,类似forward结果类型。 actionForward可多次关联调用,需自行判断循环调用。 56 | * @param invocation Action运行时上下文。 57 | * @return 返回actionForward后的调用结果。 58 | */ 59 | @ResultType(type = FORWARD) 60 | public static Object actionForward(ActionInvocation invocation) { 61 | return invocation.getActionFactory() 62 | .invokeAction(invocation.getResult().location(), invocation.getParameters()); 63 | } 64 | 65 | /** 66 | * result not found 67 | * @param invocation Action运行时上下文。 68 | * @return 抛出NullPointerException。 69 | * @deprecated 70 | */ 71 | @Deprecated 72 | @Result(name = RESULT_NOT_FOUND) 73 | public static Object resultNotFound(ActionInvocation invocation) { 74 | throw new NotFoundException("Result not found : " + invocation.getResult().location()); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/result/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供默认的结果类型和结果对象。 19 | */ 20 | package net.jrouter.result; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/spring/AopActionBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.spring; 19 | 20 | import net.jrouter.config.AopAction; 21 | import net.jrouter.util.CollectionUtil; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | /** 27 | * Actions' aop for springframework's bean. 28 | */ 29 | public class AopActionBean extends AopAction { 30 | 31 | private static final long serialVersionUID = 1L; 32 | 33 | /** 34 | * 分隔符 35 | */ 36 | private final char[] sep = { ',', ';' }; 37 | 38 | /** 39 | * 设置指定的拦截栈集合。 40 | * @param interceptorNames 拦截栈集合的字符串名称,支持','或';'分隔。 41 | */ 42 | public void setInterceptorNames(String interceptorNames) { 43 | List list = new ArrayList<>(4); 44 | CollectionUtil.stringToCollection(interceptorNames, list, sep); 45 | setInterceptors(list); 46 | } 47 | 48 | /** 49 | * 设置指定的拦截栈集合。 50 | * @param interceptorStackNames 拦截栈集合,支持','或';'分隔。 51 | */ 52 | public void setInterceptorStackNames(String interceptorStackNames) { 53 | List list = new ArrayList<>(4); 54 | CollectionUtil.stringToCollection(interceptorStackNames, list, sep); 55 | setInterceptorStacks(list); 56 | } 57 | 58 | /** 59 | * 设置aop的类型。 60 | * @param typeName aop的类型名称。 61 | * @see Type 62 | */ 63 | public void setTypeName(String typeName) { 64 | setType(Type.parseCode(typeName)); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/spring/SpringObjectFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.spring; 19 | 20 | import net.jrouter.ObjectFactory; 21 | import org.springframework.aop.framework.AopProxyUtils; 22 | import org.springframework.beans.factory.config.AutowireCapableBeanFactory; 23 | import org.springframework.context.ApplicationContext; 24 | import org.springframework.context.ApplicationContextAware; 25 | import org.springframework.context.ConfigurableApplicationContext; 26 | 27 | /** 28 | * 借由 springframework 的工厂对象创建新的对象实例。 29 | */ 30 | public class SpringObjectFactory implements ObjectFactory, ApplicationContextAware { 31 | 32 | /** 33 | * {@link AutowireCapableBeanFactory}对象。 34 | */ 35 | protected AutowireCapableBeanFactory autowireCapableBeanFactory; 36 | 37 | /** 38 | * springframework 属性注入的策略;默认{@code byName}. 39 | * 40 | * @see AutowireCapableBeanFactory#AUTOWIRE_BY_NAME 41 | * @see AutowireCapableBeanFactory#AUTOWIRE_BY_TYPE 42 | * @see AutowireCapableBeanFactory#AUTOWIRE_CONSTRUCTOR 43 | * @see AutowireCapableBeanFactory#AUTOWIRE_NO 44 | */ 45 | @lombok.Getter 46 | @lombok.Setter 47 | private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; 48 | 49 | /** 50 | * Empty Constructor. 51 | */ 52 | public SpringObjectFactory() { 53 | super(); 54 | } 55 | 56 | /** 57 | * Constructor. 58 | * @param autowireCapableBeanFactory {@link AutowireCapableBeanFactory}。 59 | */ 60 | public SpringObjectFactory(AutowireCapableBeanFactory autowireCapableBeanFactory) { 61 | this.autowireCapableBeanFactory = autowireCapableBeanFactory; 62 | } 63 | 64 | /** 65 | * Constructor. 66 | * @param applicationContext ApplicationContext对象。 67 | */ 68 | public SpringObjectFactory(ApplicationContext applicationContext) { 69 | setApplicationContext(applicationContext); 70 | } 71 | 72 | @Override 73 | public T newInstance(Class clazz) { 74 | if (AutowireCapableBeanFactory.AUTOWIRE_NO == autowireMode) { 75 | return autowireCapableBeanFactory.createBean(clazz); 76 | } 77 | return (T) autowireCapableBeanFactory.createBean(clazz, autowireMode, false); 78 | } 79 | 80 | @Override 81 | public final void setApplicationContext(ApplicationContext applicationContext) { 82 | autowireCapableBeanFactory = findAutoWiringBeanFactory(applicationContext); 83 | } 84 | 85 | /** 86 | * If the given context is assignable to AutowireCapableBeanFactory or contains a 87 | * parent or a factory that is, then set the autoWiringFactory appropriately. 88 | * @param context the application context 89 | * @return the bean factory 90 | */ 91 | protected AutowireCapableBeanFactory findAutoWiringBeanFactory(ApplicationContext context) { 92 | if (context instanceof AutowireCapableBeanFactory) { 93 | // Check the context 94 | return (AutowireCapableBeanFactory) context; 95 | } 96 | else if (context instanceof ConfigurableApplicationContext) { 97 | // Try and grab the beanFactory 98 | return ((ConfigurableApplicationContext) context).getBeanFactory(); 99 | } 100 | else if (context.getParent() != null) { 101 | // And if all else fails, try again with the parent context 102 | return findAutoWiringBeanFactory(context.getParent()); 103 | } 104 | return null; 105 | } 106 | 107 | @Override 108 | public Class getClass(Object obj) { 109 | return AopProxyUtils.ultimateTargetClass(obj); 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/spring/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供与 springframework 集成的类。 19 | */ 20 | package net.jrouter.spring; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/support/ActionInvocationDelegate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.support; 19 | 20 | import net.jrouter.ActionInvocation; 21 | 22 | /** 23 | * ActionInvocation's Delegate. 24 | * 25 | * @param

Action Path type. 26 | */ 27 | public class ActionInvocationDelegate

implements ActionInvocation

{ 28 | 29 | /** 30 | * Delegated object. 31 | */ 32 | @lombok.experimental.Delegate 33 | protected ActionInvocation

delegate = null; 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/support/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 提供常用便捷的支持类。 19 | */ 20 | package net.jrouter.support; 21 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/util/ClassScanner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.util; 19 | 20 | import java.lang.reflect.Constructor; 21 | import java.lang.reflect.Modifier; 22 | import java.util.Collections; 23 | import java.util.Iterator; 24 | import java.util.Set; 25 | 26 | /** 27 | * 类扫描的工具。通过设置扫描的包名及包含的表达式、排除类的表达式(排除优先于包含),计算并返回扫描结果的类的集合。 默认排除接口、抽象类、非公共类及无公共无参数构造函数的类。 28 | * 29 | * @see #getClasses() 30 | */ 31 | public class ClassScanner { 32 | 33 | /** 34 | * Class路径匹配器。 35 | */ 36 | private final AntPathMatcher classMatcher = new AntPathMatcher("."); 37 | 38 | /** 39 | * 包含的包或类。 40 | */ 41 | @lombok.Setter 42 | private Set includePackages = Collections.emptySet(); 43 | 44 | /** 45 | * 包含匹配类的表达式。 46 | */ 47 | @lombok.Setter 48 | private Set includeExpressions; 49 | 50 | /** 51 | * 排除匹配类的表达式。 52 | */ 53 | @lombok.Setter 54 | private Set excludeExpressions; 55 | 56 | /** 57 | * 计算最终扫描结果的类集合,排除接口、抽象类、非公共类及无公共无参数构造函数的类。 58 | * @return 扫描结果的类集合。 59 | */ 60 | public Set> getClasses() { 61 | Set> includes = ClassUtil.getClasses(includePackages.toArray(new String[0])); 62 | // filter the scan classes 63 | Iterator> it = includes.iterator(); 64 | out: while (it.hasNext()) { 65 | Class cls = it.next(); 66 | // exclude interface, no public class and no default constructors 67 | if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers()) 68 | || !Modifier.isPublic(cls.getModifiers())) { 69 | it.remove(); 70 | continue out; 71 | } // 去除无默认public空构造方法的类 72 | else { 73 | // 获取对象的public构造方法 74 | Constructor[] cs = cls.getConstructors(); 75 | if (cs.length == 0) { 76 | it.remove(); 77 | continue out; 78 | } 79 | else { 80 | boolean hasEmptyConstructor = false; 81 | for (Constructor c : cs) { 82 | // 空构造方法 83 | if (c.getParameterTypes().length == 0) { 84 | hasEmptyConstructor = true; 85 | break; 86 | } 87 | } 88 | if (!hasEmptyConstructor) { 89 | it.remove(); 90 | continue out; 91 | } 92 | } 93 | } 94 | 95 | // class name 96 | String clsName = cls.getName(); 97 | 98 | // only include matched expression, it means to exclude the classes not match 99 | // the expression 100 | if (CollectionUtil.isNotEmpty(includeExpressions)) { 101 | boolean isInclude = false; 102 | for (String includeExpression : includeExpressions) { 103 | // the include expression must a pattern 104 | if (classMatcher.match(includeExpression, clsName)) { 105 | isInclude = true; 106 | break; 107 | } 108 | } 109 | // 不包含与include expressions中 110 | if (!isInclude) { 111 | it.remove(); 112 | continue out; 113 | } 114 | } 115 | 116 | // exclude matched expressions 117 | if (CollectionUtil.isNotEmpty(excludeExpressions)) { 118 | for (String excludeExpression : excludeExpressions) { 119 | if (classMatcher.match(excludeExpression, clsName)) { 120 | it.remove(); 121 | continue out; 122 | } 123 | } 124 | } 125 | } 126 | return includes; 127 | } 128 | 129 | @Override 130 | public String toString() { 131 | return "ClassScanner{" + "includePackages=" + includePackages + ", includeExpressions=" + includeExpressions 132 | + ", excludeExpressions=" + excludeExpressions + '}'; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/util/LRUMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.util; 19 | 20 | import java.util.LinkedHashMap; 21 | import java.util.Map; 22 | 23 | /** 24 | * A simple LRU cache that implements the{@code Map} interface. Instances are not 25 | * thread-safe and should be synchronized externally, for instance by using 26 | * {@link java.util.Collections#synchronizedMap}. 27 | * 28 | * @param the type of keys maintained by this map 29 | * @param the type of mapped values 30 | */ 31 | public class LRUMap extends LinkedHashMap { 32 | 33 | private static final long serialVersionUID = 1L; 34 | 35 | /** 36 | * The max number of key-value mappings contained in this map. 37 | */ 38 | private final int maxEntries; 39 | 40 | /** 41 | * 构造一个带指定最大条目数的空{@code LRUMap}实例。 42 | * @param maxEntries 最大条目数。 43 | */ 44 | public LRUMap(int maxEntries) { 45 | this(128, maxEntries); 46 | } 47 | 48 | /** 49 | * 构造一个带指定初始容量、最大条目数的空{@code LRUMap}实例。 50 | * @param initialEntries 初始容量。 51 | * @param maxEntries 最大条目数。 52 | */ 53 | public LRUMap(int initialEntries, int maxEntries) { 54 | super(initialEntries, .75f, true); 55 | this.maxEntries = maxEntries; 56 | } 57 | 58 | @Override 59 | protected boolean removeEldestEntry(Map.Entry eldest) { 60 | return size() > maxEntries; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.util; 19 | 20 | /** 21 | * 字符串工具类。 22 | */ 23 | public class StringUtil { 24 | 25 | /** 26 | * 判断CharSequence是否为空。 27 | * @param cs 待检测的CharSequence。 28 | * @return CharSequence为null或者为空则返回{@code true}。 29 | */ 30 | public static boolean isEmpty(CharSequence cs) { 31 | return cs == null || cs.length() == 0; 32 | } 33 | 34 | /** 35 | * 判断CharSequence是否不为空。 36 | * @param cs 待检测的CharSequence。 37 | * @return CharSequence不为null且不为空则返回{@code true}。 38 | */ 39 | public static boolean isNotEmpty(CharSequence cs) { 40 | return !(cs == null || cs.length() == 0); 41 | } 42 | 43 | /** 44 | * 判断CharSequence是否为空或空白。 45 | * @param cs 待检测的CharSequence。 46 | * @return CharSequence为null、空或者空白则返回{@code true}。 47 | */ 48 | public static boolean isBlank(CharSequence cs) { 49 | int strLen; 50 | if (cs == null || (strLen = cs.length()) == 0) { 51 | return true; 52 | } 53 | for (int i = 0; i < strLen; i++) { 54 | if ((Character.isWhitespace(cs.charAt(i)) == false)) { 55 | return false; 56 | } 57 | } 58 | return true; 59 | } 60 | 61 | /** 62 | * 判断CharSequence是否不为空或空白。 63 | * @param cs 待检测的CharSequence。 64 | * @return CharSequence为null、空或者空白则返回{@code true}。 65 | */ 66 | public static boolean isNotBlank(CharSequence cs) { 67 | return !StringUtil.isBlank(cs); 68 | } 69 | 70 | /** 71 | * 去除字符串首尾的空格和特定字符。 72 | * @param src 原字符串。 73 | * @param ch 指定字符。 74 | * @return 去除首尾空白和指定字符后的字符串。 75 | */ 76 | public static String trim(String src, char ch) { 77 | if (isEmpty(src)) { 78 | return src; 79 | } 80 | int begin = 0; 81 | int end = src.length() - 1; 82 | while (begin < end) { 83 | char c = src.charAt(begin); 84 | if (c == ch || Character.isWhitespace(c)) { 85 | begin++; 86 | } 87 | else { 88 | break; 89 | } 90 | } 91 | while (end >= begin) { 92 | char c = src.charAt(end); 93 | if (c == ch || Character.isWhitespace(c)) { 94 | end--; 95 | } 96 | else { 97 | break; 98 | } 99 | } 100 | return src.substring(begin, end + 1); 101 | } 102 | 103 | /** 104 | * 去除字符串首尾的空格和特定字符数组。 105 | * @param src 原字符串。 106 | * @param chs 指定字符数组。 107 | * @return 去除首尾空白和指定字符后的字符串。 108 | */ 109 | public static String trim(String src, char... chs) { 110 | if (isEmpty(src)) { 111 | return src; 112 | } 113 | int begin = 0; 114 | int end = src.length() - 1; 115 | while (begin < end) { 116 | char c = src.charAt(begin); 117 | if (CollectionUtil.contains(c, chs) || Character.isWhitespace(c)) { 118 | begin++; 119 | } 120 | else { 121 | break; 122 | } 123 | } 124 | while (end >= begin) { 125 | char c = src.charAt(end); 126 | if (CollectionUtil.contains(c, chs) || Character.isWhitespace(c)) { 127 | end--; 128 | } 129 | else { 130 | break; 131 | } 132 | } 133 | return src.substring(begin, end + 1); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/net/jrouter/util/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | /** 18 | * 实用工具包。 19 | */ 20 | package net.jrouter.util; 21 | -------------------------------------------------------------------------------- /src/main/resources/jrouter-internal.properties: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2111 sunjumper@163.com 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ############################################################################### 15 | ### JRouter's internal 16 | ### InterceptorStack 17 | ### see DefaultInterceptorStack.java 18 | empty= 19 | sample=logging, timer 20 | ### Interceptor 21 | ### see SampleInterceptor.java 22 | logging 23 | timer 24 | ### ResultType 25 | ### see DefaultResult.java 26 | empty 27 | actionForward 28 | ### Result 29 | ### see DefaultResult.java 30 | resultNotFound 31 | 32 | -------------------------------------------------------------------------------- /src/main/resources/jrouter-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | jrouter与springframework集成的配置文件 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | defaultInterceptorStack = empty 25 | 26 | defaultResultType = empty 27 | 28 | pathSeparator = / 29 | 30 | extension = 31 | 32 | actionCacheNumber = 10000 33 | 34 | bytecode = javassist 35 | 36 | converterFactory = net.jrouter.impl.MultiParameterConverterFactory 37 | 38 | interceptorMethodChecker = 39 | net.jrouter.ActionInvocation.invoke(**)|net.jrouter.ActionInvocation.invokeActionOnly(**) 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | package = net.jrouter 49 | 50 | includeExpression = net.jrouter.impl.** 51 | 52 | excludeExpression = net.jrouter.result.**, net.jrouter.interceptor.** 53 | 54 | 55 | 56 | 57 | 58 | 59 | net.jrouter.interceptor.SampleInterceptor 60 | 61 | 62 | 63 | 64 | 65 | net.jrouter.interceptor.DefaultInterceptorStack 66 | 67 | 68 | 69 | 70 | 71 | net.jrouter.result.DefaultResult 72 | 73 | 74 | 75 | 76 | 77 | net.jrouter.result.DefaultResult 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | includeComponentBeanExpression = 89 | 90 | excludeComponentBeanExpression = 91 | 92 | includeComponentClassExpression = 93 | 94 | excludeComponentClassExpression = 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/main/resources/jrouter.properties: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2010-2111 sunjumper@163.com 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ############################################################################### 15 | ### Properties of PathActionFactory 16 | ### see jrouter-spring.xml "actionFactoryProperties" property 17 | ### Set the limit of ActionInvocation's subclass to pass when invoking action, set null means no limitation. 18 | ### since 1.5.3 19 | ### deprecated since 1.6.6 20 | ### actionInvocationClass = net.jrouter.impl.PathActionInvocation 21 | ### Set the default interceptor stack's name. 22 | ### since 1.5.3 23 | defaultInterceptorStack=empty 24 | ### Set the default result type's name. 25 | ### since 1.5.3 26 | defaultResultType=empty 27 | ### Specifies a single character as the patch separator, should be different from 'extension' value. 28 | ### since 1.5.3 29 | pathSeparator=/ 30 | ### Specifies path Generator. 31 | ### since 1.7.7. 32 | pathGenerator=net.jrouter.impl.PathActionFactory$StringPathGenerator 33 | ### If set a single character, it can't be a letter or digit;If set a string, can be empty but not null. 34 | ### since 1.5.3 35 | extension= 36 | ### Specifies the max number of the action cache. 37 | ### since 1.5.3 38 | actionCacheNumber=10000 39 | ### Specifies bytecode enhancement type. 40 | ### since 1.6.0 41 | ### use java reflect without bytecode enhancement. 42 | #bytecode = default 43 | ### use javassist for bytecode enhancement. 44 | bytecode=javassist 45 | ### Specifies object factory. 46 | ### since 1.5.3 47 | objectFactory= 48 | ### Specifies parameter converter for Action/Interceptor/Result. 49 | ### since 1.7.0 50 | converterFactory=net.jrouter.impl.MultiParameterConverterFactory 51 | ### Specifies method checking pattern(| or & as separator) for Interceptor, subclass methods are not considered. 52 | ### since 1.7.2 53 | interceptorMethodChecker=net.jrouter.ActionInvocation.invoke(**)|net.jrouter.ActionInvocation.invokeActionOnly(**) 54 | ### Specifies ActionFilter implementor. 55 | ### since 1.7.4 56 | actionFilter= 57 | ### Properties of PathActionFactory$ColonString 58 | ### Set the default object result type's name. 59 | ### since 1.7.5 60 | defaultStringResultType= 61 | -------------------------------------------------------------------------------- /src/main/resources/jrouter.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/InterceptorTestAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Namespace; 22 | import net.jrouter.interceptor.DefaultInterceptorStack; 23 | import net.jrouter.interceptor.DemoInterceptorStack; 24 | import net.jrouter.interceptor.SampleInterceptor; 25 | 26 | /** 27 | * 测试Namespace和Action上的拦截器集合。 28 | * 29 | * @see net.jrouter.impl.ActionFactory4Test 30 | */ 31 | public class InterceptorTestAction { 32 | 33 | /** 34 | * Namespace, default interceptorStack。 35 | */ 36 | @Namespace(name = "/test1") 37 | public static class Action1 { 38 | 39 | /** 40 | * no interceptor。 41 | */ 42 | @Action(name = "1") 43 | public void test1() { 44 | } 45 | 46 | /** 47 | * interceptorStack。 48 | */ 49 | @Action(name = "2", interceptorStack = DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK) 50 | public void test2() { 51 | } 52 | 53 | @Action(name = "3", interceptors = { SampleInterceptor.TIMER }) 54 | public void test3() { 55 | } 56 | 57 | } 58 | 59 | /** 60 | * Namespace with interceptorStack。 61 | */ 62 | @Namespace(name = "/test2", interceptorStack = DefaultInterceptorStack.EMPTY_INTERCEPTOR_STACK) 63 | public static class Action2 { 64 | 65 | /** 66 | * no interceptor。 67 | */ 68 | @Action(name = "1") 69 | public void test1() { 70 | } 71 | 72 | /** 73 | * interceptorStack。 74 | */ 75 | @Action(name = "2", interceptorStack = DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK) 76 | public void test2() { 77 | } 78 | 79 | @Action(name = "3", interceptors = { SampleInterceptor.TIMER }) 80 | public void test3() { 81 | } 82 | 83 | } 84 | 85 | /** 86 | * Namespace with interceptors。 87 | */ 88 | @Namespace(name = "/test3", interceptors = { SampleInterceptor.LOGGING }) 89 | public static class Action3 { 90 | 91 | /** 92 | * no interceptor。 93 | */ 94 | @Action(name = "1") 95 | public void test1() { 96 | } 97 | 98 | /** 99 | * interceptorStack。 100 | */ 101 | @Action(name = "2", interceptorStack = DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK) 102 | public void test2() { 103 | } 104 | 105 | @Action(name = "3", interceptors = { SampleInterceptor.TIMER }) 106 | public void test3() { 107 | } 108 | 109 | } 110 | 111 | @Namespace(name = "/test4") 112 | public static class Action4 { 113 | 114 | /** 115 | * @see DemoInterceptorStack#MATCHED_INTERCEPTOR_STACK 116 | */ 117 | @Action(name = "matched") 118 | public void test1() { 119 | } 120 | 121 | @Action(name = "2", interceptorStack = DemoInterceptorStack.MATCHED_INTERCEPTOR_STACK) 122 | public void test2() { 123 | } 124 | 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/PathTestAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.impl.PathTreeTest; 22 | import net.jrouter.interceptor.DemoThreadActionContextInterceptor; 23 | import net.jrouter.interceptor.SampleInterceptor; 24 | import org.springframework.stereotype.Component; 25 | 26 | import static net.jrouter.impl.PathTreeTest.PATHS; 27 | 28 | /** 29 | * PathTestAction。 30 | * 31 | * @see PathTreeTest#PATHS 32 | */ 33 | @Component 34 | public class PathTestAction { 35 | 36 | @Action(name = "/xx/yy/zz", 37 | interceptors = { DemoThreadActionContextInterceptor.DEMO_THREAD, SampleInterceptor.LOGGING }) 38 | public String test0() { 39 | return PATHS[0]; 40 | } 41 | 42 | @Action(value = "/{k1}", interceptors = { DemoThreadActionContextInterceptor.DEMO_THREAD, SampleInterceptor.TIMER }) 43 | public String test1() { 44 | return PATHS[1]; 45 | } 46 | 47 | @Action("/aa/b1/c1/d0") 48 | public String test2() { 49 | return PATHS[2]; 50 | } 51 | 52 | @Action(name = "/aa/b1/c1/d1") 53 | public String test3() { 54 | return PATHS[3]; 55 | } 56 | 57 | @Action(value = "/aa/b2/c2/d2") 58 | public String test4() { 59 | return PATHS[4]; 60 | } 61 | 62 | @Action("/aa/b3/c1/d1/*") 63 | public String test5() { 64 | return PATHS[5]; 65 | } 66 | 67 | @Action("/aa/b3/*/d1") 68 | public String test6() { 69 | return PATHS[6]; 70 | } 71 | 72 | @Action("/aa/b3/*/d1/{k2}") 73 | public String test7() { 74 | return PATHS[7]; 75 | } 76 | 77 | @Action("/aa/*/c1/d1") 78 | public String test8() { 79 | return PATHS[8]; 80 | } 81 | 82 | @Action("/aa/*/c1/d1/e1") 83 | public String test9() { 84 | return PATHS[9]; 85 | } 86 | 87 | @Action("/aa/b4/{k1}/d1") 88 | public String test10() { 89 | return PATHS[10]; 90 | } 91 | 92 | @Action("/aa/b4/{k1}/d2") 93 | public String test11() { 94 | return PATHS[11]; 95 | } 96 | 97 | @Action("/aa/b4/{k1}/d2/e1") 98 | public String test12() { 99 | return PATHS[12]; 100 | } 101 | 102 | @Action("/aa/b4/{k1}/d2/{k2}") 103 | public String test13() { 104 | return PATHS[13]; 105 | } 106 | 107 | @Action("/aa/b5/*/*/*/*") 108 | public String test14() { 109 | return PATHS[14]; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/PathTestAction2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Namespace; 22 | import net.jrouter.impl.PathTreeTest; 23 | import org.springframework.stereotype.Component; 24 | 25 | import static net.jrouter.impl.PathTreeTest.PATHS; 26 | 27 | /** 28 | * PathTestAction2。 29 | * 30 | * @see PathTreeTest#PATHS 31 | */ 32 | @Component 33 | @Namespace(name = "/%s") 34 | public class PathTestAction2 { 35 | 36 | @Action(name = "xx/yy/zz") 37 | public String test0() { 38 | return PATHS[0]; 39 | } 40 | 41 | @Action(value = "{k1}") 42 | public String test1() { 43 | return PATHS[1]; 44 | } 45 | 46 | @Action("aa/b1/c1/d0") 47 | public String test2() { 48 | return PATHS[2]; 49 | } 50 | 51 | @Action(name = "aa/b1/c1/d1") 52 | public String test3() { 53 | return PATHS[3]; 54 | } 55 | 56 | @Action(value = "aa/b2/c2/d2") 57 | public String test4() { 58 | return PATHS[4]; 59 | } 60 | 61 | @Action("aa/b3/c1/d1/*") 62 | public String test5() { 63 | return PATHS[5]; 64 | } 65 | 66 | @Action("aa/b3/*/d1") 67 | public String test6() { 68 | return PATHS[6]; 69 | } 70 | 71 | @Action("aa/b3/*/d1/{k2}") 72 | public String test7() { 73 | return PATHS[7]; 74 | } 75 | 76 | @Action("aa/*/c1/d1") 77 | public String test8() { 78 | return PATHS[8]; 79 | } 80 | 81 | @Action("aa/*/c1/d1/e1") 82 | public String test9() { 83 | return PATHS[9]; 84 | } 85 | 86 | @Action("aa/b4/{k1}/d1") 87 | public String test10() { 88 | return PATHS[10]; 89 | } 90 | 91 | @Action("aa/b4/{k1}/d2") 92 | public String test11() { 93 | return PATHS[11]; 94 | } 95 | 96 | @Action("aa/b4/{k1}/d2/e1") 97 | public String test12() { 98 | return PATHS[12]; 99 | } 100 | 101 | @Action("aa/b4/{k1}/d2/{k2}") 102 | public String test13() { 103 | return PATHS[13]; 104 | } 105 | 106 | @Action("aa/b5/*/*/*/*") 107 | public String test14() { 108 | return PATHS[14]; 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/TestDuplicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.*; 21 | import net.jrouter.interceptor.DemoInterceptor; 22 | import net.jrouter.result.DemoResult; 23 | 24 | /** 25 | * 测试重复Action、Interceptor、InterceptorStack、ResultType、Result。 26 | */ 27 | public class TestDuplicate { 28 | 29 | public static class DuplicateAction1 { 30 | 31 | /** 32 | * @see URLTestAction#test104() 33 | */ 34 | @Action(name = "//") 35 | public String test104_1() { 36 | return "/"; 37 | } 38 | 39 | } 40 | 41 | public static class DuplicateAction2 { 42 | 43 | /** 44 | * @see URLTestAction#test104() 45 | */ 46 | @Action(name = "//////a") 47 | public String test200_1() { 48 | return "/a"; 49 | } 50 | 51 | } 52 | 53 | public static class DuplicateAction3 { 54 | 55 | /** 56 | * @see URLTestAction#test404() 57 | */ 58 | @Action(name = "/test4/abc") 59 | public String test404_1() { 60 | return "/test4/abc"; 61 | } 62 | 63 | } 64 | 65 | /// ///////////////////////////////////////////////////////////////////////////// 66 | 67 | public static class DuplicateInterceptor1 { 68 | 69 | @InterceptorStack(interceptors = { @InterceptorStack.Interceptor("demo") }) 70 | public static final String DEMO = DemoInterceptor.DEMO; 71 | 72 | @Interceptor(name = DemoInterceptor.SPRING_DEMO) 73 | public Object test(ActionInvocation invocation) { 74 | return invocation.invoke(); 75 | } 76 | 77 | } 78 | 79 | /// ///////////////////////////////////////////////////////////////////////////// 80 | 81 | public static class DuplicateResult1 { 82 | 83 | public static final String DEMO_RESULT_TYPE = DemoResult.DEMO_RESULT_TYPE; 84 | 85 | @Result(name = DemoResult.DEMO_RESULT_EXCEPTION) 86 | public static Object resultException(ActionInvocation invocation) { 87 | return null; 88 | } 89 | 90 | @ResultType(type = DEMO_RESULT_TYPE) 91 | public Object test(ActionInvocation invocation) { 92 | return invocation.getResult().location(); 93 | } 94 | 95 | } 96 | //////////////////////////////////////////////////////////////////////////////// 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/URLTestAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Namespace; 22 | 23 | /** 24 | * 测试路径 URLTestAction。 25 | */ 26 | @Namespace(name = "/") 27 | public class URLTestAction { 28 | 29 | @Action 30 | public String test100() { 31 | return "/test100"; 32 | } 33 | 34 | @Action(name = "") 35 | public String test101() { 36 | return "/test101"; 37 | } 38 | 39 | @Action(name = " ") 40 | public String test102() { 41 | return "/test102"; 42 | } 43 | 44 | @Action(name = " ") 45 | public String test103() { 46 | return "/test103"; 47 | } 48 | 49 | @Action(name = "/") 50 | public String test104() { 51 | return "/"; 52 | } 53 | 54 | @Action(name = "a") 55 | public String test200() { 56 | return "/a"; 57 | } 58 | 59 | @Action(name = " b") 60 | public String test201() { 61 | return "/b"; 62 | } 63 | 64 | @Action(name = " c ") 65 | public String test202() { 66 | return "/c"; 67 | } 68 | 69 | @Action(name = "/d/") 70 | public String test203() { 71 | return "/d"; 72 | } 73 | 74 | @Action(name = " //e ////") 75 | public String test204() { 76 | return "/e"; 77 | } 78 | 79 | @Action(name = "test") 80 | public String test300() { 81 | return "/test"; 82 | } 83 | 84 | @Action(name = "/test1") 85 | public String test301() { 86 | return "/test1"; 87 | } 88 | 89 | @Action(name = "test2/") 90 | public String test302() { 91 | return "/test2"; 92 | } 93 | 94 | @Action(name = "/test3/") 95 | public String test303() { 96 | return "/test3"; 97 | } 98 | 99 | @Action(name = "///test4 //") 100 | public String test304() { 101 | return "/test4"; 102 | } 103 | 104 | @Action(name = "test/abc") 105 | public String test400() { 106 | return "/test/abc"; 107 | } 108 | 109 | @Action(name = "/test1/abc") 110 | public String test401() { 111 | return "/test1/abc"; 112 | } 113 | 114 | @Action(name = "/test2//abc/") 115 | public String test402() { 116 | return "/test2/abc"; 117 | } 118 | 119 | @Action(name = "///test3/abc////") 120 | public String test403() { 121 | return "/test3/abc"; 122 | } 123 | 124 | @Action(name = " ///test4/abc /") 125 | public String test404() { 126 | return "/test4/abc"; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/URLTestAction2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.annotation.Namespace; 22 | 23 | /** 24 | * 测试路径 URLTestAction2。 25 | */ 26 | @Namespace(name = "/url") 27 | public class URLTestAction2 extends URLTestAction { 28 | 29 | @Action 30 | public String test100() { 31 | return "/url/test100"; 32 | } 33 | 34 | @Action() 35 | public String test101() { 36 | return "/url/test101"; 37 | } 38 | 39 | @Action("a2") 40 | public String test200() { 41 | return "/url/a2"; 42 | } 43 | 44 | @Action(" b2") 45 | public String test201() { 46 | return "/url/b2"; 47 | } 48 | 49 | @Action(" c2 ") 50 | public String test202() { 51 | return "/url/c2"; 52 | } 53 | 54 | @Action("/url_d2/") 55 | public String test203() { 56 | return "/url_d2"; 57 | } 58 | 59 | @Action(name = " //url_e2 ////") 60 | public String test204() { 61 | return "/url_e2"; 62 | } 63 | 64 | @Action(name = "test") 65 | public String test300() { 66 | return "/url/test"; 67 | } 68 | 69 | @Action(name = "/url_test1") 70 | public String test301() { 71 | return "/url_test1"; 72 | } 73 | 74 | @Action(name = "test2/") 75 | public String test302() { 76 | return "/url/test2"; 77 | } 78 | 79 | @Action(name = "/url_test3/") 80 | public String test303() { 81 | return "/url_test3"; 82 | } 83 | 84 | @Action(name = "///url_test4 //") 85 | public String test304() { 86 | return "/url_test4"; 87 | } 88 | 89 | @Action(name = "test/abc") 90 | public String test400() { 91 | return "/url/test/abc"; 92 | } 93 | 94 | @Action(name = "/url_test1/abc") 95 | public String test401() { 96 | return "/url_test1/abc"; 97 | } 98 | 99 | @Action(name = "/url_test2/abc/") 100 | public String test402() { 101 | return "/url_test2/abc"; 102 | } 103 | 104 | @Action(name = "///url_test3/abc////") 105 | public String test403() { 106 | return "/url_test3/abc"; 107 | } 108 | 109 | @Action(name = " ///url_test4/abc /") 110 | public String test404() { 111 | return "/url_test4/abc"; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/bytecode/javassist/JavassistMethodCheckerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.bytecode.javassist; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.interceptor.DemoInterceptor; 22 | import org.junit.Test; 23 | 24 | import java.lang.reflect.Method; 25 | import java.util.List; 26 | 27 | import static org.junit.Assert.*; 28 | 29 | /** 30 | * JavassistMethodCheckerTest. 31 | */ 32 | public class JavassistMethodCheckerTest { 33 | 34 | // invoke JavassistMethodChecker#toClassNames 35 | private static String[] toClassNames(Method m, String descriptor) throws Exception { 36 | return ((List) m.invoke(null, descriptor)).toArray(new String[0]); 37 | } 38 | 39 | /** 40 | * Test of check method, of class JavassistMethodChecker. 41 | */ 42 | @Test 43 | public void testCheck() throws Exception { 44 | Method method = DemoInterceptor.class.getDeclaredMethod("test", ActionInvocation.class); 45 | assertTrue(new JavassistMethodChecker("").check(method)); 46 | assertTrue(new JavassistMethodChecker("**").check(method)); 47 | assertFalse(new JavassistMethodChecker("*").check(method)); 48 | assertFalse(new JavassistMethodChecker("NoMethod").check(method)); 49 | assertTrue(new JavassistMethodChecker("**.**").check(method)); 50 | assertTrue(new JavassistMethodChecker( 51 | "net.jrouter.ActionInvocation.invoke(**)|net.jrouter.ActionInvocation.invokeActionOnly(**)") 52 | .check(method)); 53 | assertTrue(new JavassistMethodChecker("net.jrouter.ActionInvocation.invoke").check(method)); 54 | assertTrue(new JavassistMethodChecker("net.jrouter.ActionInvocation.invoke(java.lang.Object[])").check(method)); 55 | assertFalse(new JavassistMethodChecker("net.jrouter.ActionInvocation.invoke()").check(method)); 56 | assertFalse(new JavassistMethodChecker("net.jrouter.ActionInvocation.invokeActionOnly(**)").check(method)); 57 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals").check(method)); 58 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals(**)").check(method)); 59 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals(*,*)").check(method)); 60 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals(*, *)").check(method)); 61 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals(Object, Object)").check(method)); 62 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals(Object,java.lang.Object)").check(method)); 63 | assertTrue(new JavassistMethodChecker("org.junit.Assert.assertEquals(Object, java.lang.Object)").check(method)); 64 | assertTrue(new JavassistMethodChecker("net.jrouter.ActionInvocation.invoke & org.junit.Assert.assertEquals") 65 | .check(method)); 66 | assertTrue(new JavassistMethodChecker( 67 | "net.jrouter.ActionInvocation.invoke & org.junit.Assert.assertEquals | NoMethod") 68 | .check(method)); 69 | assertTrue(new JavassistMethodChecker("net.jrouter.ActionInvocation.invoke|NoMethod2|NoMethod3").check(method)); 70 | assertFalse( 71 | new JavassistMethodChecker("**&net.jrouter.ActionInvocation.invoke|NoMethod2|NoMethod3").check(method)); 72 | assertTrue(new JavassistMethodChecker("**&**.**|NoMethod").check(method)); 73 | assertTrue(new JavassistMethodChecker("**|NoMethod2|NoMethod3").check(method)); 74 | assertFalse(new JavassistMethodChecker("NoMethod|NoMethod2|NoMethod3").check(method)); 75 | } 76 | 77 | /** 78 | * Test of toClassNames method, of class JavassistMethodChecker. 79 | */ 80 | @Test 81 | public void test_toClassNames() throws Exception { 82 | Method method = JavassistMethodChecker.class.getDeclaredMethod("toClassNames", String.class); 83 | method.setAccessible(true); 84 | assertArrayEquals(new String[] {}, toClassNames(method, "")); 85 | assertArrayEquals(new String[] {}, toClassNames(method, "()")); 86 | assertArrayEquals(new String[] { "java.lang.String" }, toClassNames(method, "(Ljava/lang/String;)")); 87 | assertArrayEquals(new String[] { "java.lang.String[]" }, toClassNames(method, "([Ljava/lang/String;)")); 88 | assertArrayEquals(new String[] { "net.jrouter.ActionInvocation" }, 89 | toClassNames(method, "Lnet/jrouter/ActionInvocation;")); 90 | assertArrayEquals(new String[] { "net.jrouter.ActionInvocation" }, 91 | toClassNames(method, "(Lnet/jrouter/ActionInvocation;)Ljava/lang/Object;")); 92 | assertArrayEquals(new String[] { "int[][]", "java.util.List", "java.lang.String[][][]" }, 93 | toClassNames(method, "([[ILjava/util/List;[[[Ljava/lang/String;)")); 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/config/Configuration2Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.config; 19 | 20 | import net.jrouter.impl.MultiParameterConverterFactory; 21 | import net.jrouter.impl.PathActionFactory; 22 | import net.jrouter.interceptor.DefaultInterceptorStack; 23 | import net.jrouter.interceptor.DemoInterceptor; 24 | import net.jrouter.interceptor.SampleInterceptor; 25 | import net.jrouter.result.DefaultResult; 26 | import net.jrouter.result.DemoResult; 27 | import org.junit.After; 28 | import org.junit.Assert; 29 | import org.junit.Test; 30 | 31 | /** 32 | * Configuration2Test。 33 | */ 34 | public class Configuration2Test extends Assert { 35 | 36 | private Configuration config = null; 37 | 38 | private PathActionFactory.ColonString factory; 39 | 40 | @After 41 | public void tearDown() { 42 | if (factory != null) { 43 | factory.clear(); 44 | } 45 | } 46 | 47 | /** 48 | * 测试加载配置文件。 49 | */ 50 | @Test 51 | public void test_load() { 52 | config = new Configuration(); 53 | factory = config.load("/jrouter_test.xml").buildActionFactory(); 54 | assertNotNull(factory); 55 | assertEquals("empty", factory.getDefaultInterceptorStack()); 56 | assertEquals("empty", factory.getDefaultResultType()); 57 | assertEquals("empty", factory.getDefaultStringResultType()); 58 | assertEquals(100000, factory.getActionCacheNumber()); 59 | assertEquals(".", factory.getExtension()); 60 | assertEquals('/', factory.getPathSeparator()); 61 | 62 | assertEquals(MultiParameterConverterFactory.NoFixedOrder.class, factory.getConverterFactory().getClass()); 63 | 64 | assertNotNull(factory.getInterceptors().get(SampleInterceptor.LOGGING)); 65 | assertNotNull(factory.getInterceptors().get(SampleInterceptor.TIMER)); 66 | assertNotNull(factory.getInterceptors().get(DemoInterceptor.SPRING_DEMO)); 67 | 68 | assertNotNull(factory.getInterceptorStacks().get(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK)); 69 | assertNotNull(factory.getInterceptorStacks().get(DemoInterceptor.DEMO)); 70 | 71 | assertNotNull(factory.getResultTypes().get(DefaultResult.EMPTY)); 72 | assertNotNull(factory.getResultTypes().get(DefaultResult.FORWARD)); 73 | assertNotNull(factory.getResultTypes().get(DemoResult.DEMO_RESULT_TYPE)); 74 | 75 | assertNotNull(factory.getResults().get(DefaultResult.RESULT_NOT_FOUND)); 76 | assertNotNull(factory.getResults().get(DemoResult.DEMO_RESULT_NOT_FOUND)); 77 | assertNotNull(factory.getResults().get(DemoResult.DEMO_RESULT_EXCEPTION)); 78 | 79 | } 80 | 81 | /** 82 | * 测试循环引用异常。 83 | */ 84 | @Test(expected = ConfigurationException.class) 85 | public void test_loadError() { 86 | config = new Configuration(); 87 | config.load("/jrouter_error.xml"); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/config/ConfigurationAopTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.config; 19 | 20 | import net.jrouter.impl.InterceptorProxy; 21 | import net.jrouter.impl.PathActionFactory; 22 | import org.junit.After; 23 | import org.junit.Assert; 24 | import org.junit.Test; 25 | 26 | import java.util.List; 27 | 28 | /** 29 | * ConfigurationAopTest。 30 | */ 31 | public class ConfigurationAopTest extends Assert { 32 | 33 | private final Configuration config = new Configuration().load("/jrouter_aop.xml"); 34 | 35 | private final PathActionFactory factory = config.buildActionFactory(); 36 | 37 | @After 38 | public void tearDown() { 39 | factory.clear(); 40 | } 41 | 42 | /** 43 | * 测试action aop。 44 | */ 45 | @Test 46 | public void test_aopAction() { 47 | assertNotNull(factory); 48 | 49 | assertInterceptorProxies("/test/param", "[timer, timer, springInject, logging]"); 50 | 51 | assertInterceptorProxies("/test/simple", "[demo, springInject]"); 52 | assertInterceptorProxies("/test/exception", "[logging, timer, demo, springInject]"); 53 | assertInterceptorProxies("/test/springInject", "[springInject, demo, springInject]"); 54 | assertInterceptorProxies("/test/forward", "[demo, springInject]"); 55 | assertInterceptorProxies("/test/forward2", "[demo, springInject]"); 56 | 57 | assertInterceptorProxies("/test1", "[]"); 58 | assertInterceptorProxies("/xx/yy/zz", "[]"); 59 | assertInterceptorProxies("/{k1}", "[]"); 60 | assertInterceptorProxies("/aa/b5/*/*/*/*", "[]"); 61 | } 62 | 63 | /** 64 | * 测试指定path的action的拦截器集合。 65 | */ 66 | private void assertInterceptorProxies(String actionPath, String interceptorProxies) { 67 | assertEquals(interceptorsToString(factory.getActions().get(actionPath).getInterceptorProxies()), 68 | interceptorProxies); 69 | } 70 | 71 | /** 72 | * 拦截器集合字符串显示名称。 73 | */ 74 | private String interceptorsToString(List interceptors) { 75 | if (interceptors == null) 76 | return "null"; 77 | int iMax = interceptors.size() - 1; 78 | if (iMax == -1) 79 | return "[]"; 80 | StringBuilder msg = new StringBuilder(); 81 | msg.append('['); 82 | for (int i = 0;; i++) { 83 | msg.append(interceptors.get(i).getName()); 84 | if (i == iMax) 85 | return msg.append(']').toString(); 86 | msg.append(", "); 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/config/ConfigurationScanComponentTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.config; 19 | 20 | import net.jrouter.ActionFactory; 21 | import net.jrouter.impl.PathActionFactory; 22 | import net.jrouter.interceptor.DefaultInterceptorStack; 23 | import net.jrouter.interceptor.DemoInterceptor; 24 | import net.jrouter.interceptor.SampleInterceptor; 25 | import org.junit.After; 26 | import org.junit.Assert; 27 | import org.junit.Before; 28 | import org.junit.Test; 29 | 30 | /** 31 | * 测试自动扫描类并添加组件。 32 | */ 33 | public class ConfigurationScanComponentTest extends Assert { 34 | 35 | private final Configuration config = new Configuration().load("/jrouter_autoscan.xml"); 36 | 37 | private final ActionFactory factory = config.buildActionFactory(); 38 | 39 | @Before 40 | public void setUp() { 41 | assertNotNull(factory); 42 | } 43 | 44 | @After 45 | public void tearDown() { 46 | factory.clear(); 47 | } 48 | 49 | /** 50 | * Test of scanning components。 51 | */ 52 | @Test 53 | public void test_scanComponent() { 54 | assertEquals("empty", factory.getDefaultInterceptorStack()); 55 | assertEquals("empty", factory.getDefaultResultType()); 56 | 57 | assertSame(PathActionFactory.class, factory.getClass()); 58 | 59 | assertEquals(100000, ((PathActionFactory) factory).getActionCacheNumber()); 60 | assertEquals(".", ((PathActionFactory) factory).getExtension()); 61 | 62 | assertNotNull(factory.getInterceptorStacks().get(DefaultInterceptorStack.EMPTY_INTERCEPTOR_STACK)); 63 | assertNotNull(factory.getInterceptorStacks().get(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK)); 64 | assertNotNull(factory.getInterceptorStacks().get(DemoInterceptor.DEMO)); 65 | 66 | assertNotNull(factory.getInterceptors().get(SampleInterceptor.LOGGING)); 67 | assertNotNull(factory.getInterceptors().get(SampleInterceptor.TIMER)); 68 | assertNotNull(factory.getInterceptors().get(DemoInterceptor.SPRING_DEMO)); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/config/ConfigurationTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.config; 19 | 20 | import net.jrouter.ActionFactory; 21 | import net.jrouter.impl.PathActionFactory; 22 | import org.junit.After; 23 | import org.junit.Assert; 24 | import org.junit.Test; 25 | 26 | /** 27 | * ConfigurationTest。 28 | */ 29 | public class ConfigurationTest extends Assert { 30 | 31 | private Configuration config = null; 32 | 33 | private ActionFactory factory; 34 | 35 | @After 36 | public void tearDown() { 37 | factory.clear(); 38 | } 39 | 40 | /** 41 | * 测试加载配置文件。 42 | */ 43 | @Test 44 | public void test_load() { 45 | 46 | config = new Configuration(); 47 | config.load(); 48 | 49 | factory = config.buildActionFactory(); 50 | 51 | assertNotNull(factory); 52 | assertSame(PathActionFactory.class, factory.getClass()); 53 | assertNotNull(factory.getActions()); 54 | assertNotNull(factory.getDefaultInterceptorStack()); 55 | assertNotNull(factory.getDefaultResultType()); 56 | assertNotNull(factory.getInterceptorStacks()); 57 | assertNotNull(factory.getInterceptors()); 58 | assertNotNull(factory.getResultTypes()); 59 | assertNotNull(factory.getResults()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/impl/ActionFactory4Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.InterceptorTestAction; 21 | import net.jrouter.interceptor.DefaultInterceptorStack; 22 | import net.jrouter.interceptor.DemoInterceptorStack; 23 | import net.jrouter.interceptor.SampleInterceptor; 24 | import org.junit.After; 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | 28 | import static org.junit.Assert.assertEquals; 29 | 30 | /** 31 | * 测试Namespace和Action上的拦截器集合。 32 | */ 33 | public class ActionFactory4Test { 34 | 35 | private PathActionFactory factory; 36 | 37 | @Before 38 | public void init() { 39 | PathActionFactory.Properties prop = new PathActionFactory.Properties(); 40 | prop.setDefaultInterceptorStack(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK); 41 | factory = new PathActionFactory(prop); 42 | 43 | assertEquals(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK, factory.getDefaultInterceptorStack()); 44 | 45 | factory.addInterceptors(SampleInterceptor.class); 46 | factory.addInterceptorStacks(DefaultInterceptorStack.class); 47 | factory.addInterceptorStacks(DemoInterceptorStack.class); 48 | 49 | factory.addActions(InterceptorTestAction.Action1.class); 50 | factory.addActions(InterceptorTestAction.Action2.class); 51 | factory.addActions(InterceptorTestAction.Action3.class); 52 | factory.addActions(InterceptorTestAction.Action4.class); 53 | } 54 | 55 | @After 56 | public void tearDown() { 57 | factory.clear(); 58 | } 59 | 60 | /** 61 | * 测试Action上的拦截器集合。 62 | */ 63 | @Test 64 | public void testActionInterceptors() { 65 | PathActionProxy ap11 = factory.getActions().get("/test1/1"); 66 | PathActionProxy ap12 = factory.getActions().get("/test1/2"); 67 | PathActionProxy ap13 = factory.getActions().get("/test1/3"); 68 | 69 | assertEquals(ap11.getInterceptorProxies(), 70 | factory.getInterceptorStacks().get(factory.getDefaultInterceptorStack()).getInterceptors()); 71 | assertEquals(ap12.getInterceptorProxies(), 72 | factory.getInterceptorStacks().get(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK).getInterceptors()); 73 | assertEquals(1, ap13.getInterceptorProxies().size()); 74 | assertEquals(ap13.getInterceptorProxies().get(0).getName(), SampleInterceptor.TIMER); 75 | 76 | PathActionProxy ap21 = factory.getActions().get("/test2/1"); 77 | PathActionProxy ap22 = factory.getActions().get("/test2/2"); 78 | PathActionProxy ap23 = factory.getActions().get("/test2/3"); 79 | 80 | assertEquals(0, ap21.getInterceptorProxies().size()); 81 | assertEquals(ap21.getInterceptorProxies(), 82 | factory.getInterceptorStacks().get(DefaultInterceptorStack.EMPTY_INTERCEPTOR_STACK).getInterceptors()); 83 | assertEquals(ap22.getInterceptorProxies(), 84 | factory.getInterceptorStacks().get(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK).getInterceptors()); 85 | assertEquals(1, ap23.getInterceptorProxies().size()); 86 | assertEquals(ap23.getInterceptorProxies().get(0).getName(), SampleInterceptor.TIMER); 87 | 88 | PathActionProxy ap31 = factory.getActions().get("/test3/1"); 89 | PathActionProxy ap32 = factory.getActions().get("/test3/2"); 90 | PathActionProxy ap33 = factory.getActions().get("/test3/3"); 91 | 92 | assertEquals(1, ap31.getInterceptorProxies().size()); 93 | assertEquals(ap31.getInterceptorProxies().get(0).getName(), SampleInterceptor.LOGGING); 94 | assertEquals(ap32.getInterceptorProxies(), 95 | factory.getInterceptorStacks().get(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK).getInterceptors()); 96 | assertEquals(1, ap33.getInterceptorProxies().size()); 97 | assertEquals(ap33.getInterceptorProxies().get(0).getName(), SampleInterceptor.TIMER); 98 | 99 | PathActionProxy ap41 = factory.getActions().get("/test4/matched"); 100 | PathActionProxy ap42 = factory.getActions().get("/test4/2"); 101 | assertEquals(ap41.getInterceptorProxies(), 102 | factory.getInterceptorStacks().get(DemoInterceptorStack.MATCHED_INTERCEPTOR_STACK).getInterceptors()); 103 | assertEquals(ap41.getInterceptorProxies(), 104 | factory.getInterceptorStacks().get(DemoInterceptorStack.MATCHED_INTERCEPTOR_STACK).getInterceptors()); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/impl/ConverterParameterActionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.support.ActionInvocationDelegate; 22 | 23 | /** 24 | * 测试ActionFactory的ConverterFactory传递参数的扩展性。 25 | */ 26 | public class ConverterParameterActionFactory extends PathActionFactory { 27 | 28 | public ConverterParameterActionFactory(Properties properties) { 29 | super(properties); 30 | } 31 | 32 | @Override 33 | protected ActionInvocation createActionInvocation(String path, Object... params) { 34 | ActionInvocation ai = super.createActionInvocation(path, params); 35 | DemoActionInvocation invocation = new DefaultDemoActionInvocation("demo", ai); 36 | // 重设调用ActionInvocation的调用参数 37 | invocation.setConvertParameters(invocation); 38 | return invocation; 39 | } 40 | 41 | /** 42 | * 自定义扩展ActionInvocation接口。 43 | */ 44 | public static interface DemoActionInvocation extends ActionInvocation { 45 | 46 | String getName(); 47 | 48 | } 49 | 50 | /** 51 | * 代理ActionInvocation,并添加自定义的属性和实现接口。 52 | */ 53 | public static class DefaultDemoActionInvocation extends ActionInvocationDelegate 54 | implements DemoActionInvocation { 55 | 56 | /* name */ 57 | private final String name; 58 | 59 | public DefaultDemoActionInvocation(String name, ActionInvocation invocation) { 60 | super(); 61 | this.name = name; 62 | this.delegate = invocation; 63 | } 64 | 65 | @Override 66 | public String getName() { 67 | return name; 68 | } 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/impl/ConverterParameterActionFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.annotation.Action; 21 | import net.jrouter.impl.ConverterParameterActionFactory.DemoActionInvocation; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | 25 | import java.util.HashMap; 26 | import java.util.Map; 27 | 28 | import static org.junit.Assert.assertEquals; 29 | 30 | /** 31 | * 测试ActionFactory的ConverterFactory传递参数的扩展性。 32 | */ 33 | public class ConverterParameterActionFactoryTest { 34 | 35 | private ConverterParameterActionFactory factory; 36 | 37 | @Before 38 | public void init() { 39 | Map props = new HashMap<>(); 40 | // manually set converterFactory 41 | props.put("converterFactory", net.jrouter.impl.MultiParameterConverterFactory.class); 42 | // props.put("bytecode", "default"); 43 | factory = new ConverterParameterActionFactory(new PathActionFactory.Properties().properties(props)); 44 | // add test Action 45 | factory.addActions(ConverterParameterAction.class); 46 | } 47 | 48 | /** 49 | * 测试ConverterParameterActionFactory。 50 | * 51 | * @see net.jrouter.impl.ConverterParameterActionFactory.DemoActionInvocation 52 | */ 53 | @Test 54 | public void test_invoke() { 55 | assertEquals("demo", factory.invokeAction("/simple")); 56 | } 57 | 58 | /** 59 | * ConverterParameterAction. 60 | */ 61 | public static class ConverterParameterAction { 62 | 63 | @Action 64 | public String simple(DemoActionInvocation invocation) { 65 | return invocation.getName(); 66 | } 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/impl/PathActionFactory1Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.annotation.ResultType; 22 | import net.jrouter.impl.PathActionFactory.ColonString; 23 | import org.junit.After; 24 | import org.junit.Before; 25 | import org.junit.Test; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | 29 | /** 30 | * 测试PathActionFactory.ColonString正确性。 31 | */ 32 | public class PathActionFactory1Test { 33 | 34 | private PathActionFactory.ColonString factory; 35 | 36 | @Before 37 | public void init() { 38 | ColonString.Properties properties = new ColonString.Properties(); 39 | properties.setExtension(""); 40 | properties.setDefaultResultType(TestResult.DEMO); 41 | factory = new ColonString(properties); 42 | 43 | // path action 44 | factory.addActions(net.jrouter.URLTestAction.class); 45 | } 46 | 47 | /** 48 | * 测试Action路径的正确性。 49 | * 50 | * @see net.jrouter.URLTestAction 51 | */ 52 | @Test 53 | public void test_invoke() { 54 | String prefix = "prefix:"; 55 | // result 56 | factory.addResultTypes(new TestResult(prefix)); 57 | assertEquals(prefix + "/test100", factory.invokeAction("/test100")); 58 | assertEquals(prefix + "/test101", factory.invokeAction("/test101")); 59 | assertEquals(prefix + "/test102", factory.invokeAction("/test102")); 60 | assertEquals(prefix + "/test103", factory.invokeAction("/test103")); 61 | 62 | assertEquals(prefix + "/", factory.invokeAction("/")); 63 | assertEquals(prefix + "/a", factory.invokeAction("/a")); 64 | assertEquals(prefix + "/b", factory.invokeAction("/b")); 65 | assertEquals(prefix + "/c", factory.invokeAction("/c")); 66 | assertEquals(prefix + "/d", factory.invokeAction("/d")); 67 | assertEquals(prefix + "/e", factory.invokeAction("/e")); 68 | 69 | assertEquals(prefix + "/test", factory.invokeAction("/test")); 70 | assertEquals(prefix + "/test1", factory.invokeAction("/test1")); 71 | assertEquals(prefix + "/test2", factory.invokeAction("/test2")); 72 | assertEquals(prefix + "/test3", factory.invokeAction("/test3")); 73 | assertEquals(prefix + "/test4", factory.invokeAction("/test4")); 74 | 75 | assertEquals(prefix + "/test/abc", factory.invokeAction("/test/abc")); 76 | assertEquals(prefix + "/test1/abc", factory.invokeAction("/test1/abc")); 77 | assertEquals(prefix + "/test2/abc", factory.invokeAction("/test2/abc")); 78 | assertEquals(prefix + "/test3/abc", factory.invokeAction("/test3/abc")); 79 | assertEquals(prefix + "/test4/abc", factory.invokeAction("/test4/abc")); 80 | } 81 | 82 | @After 83 | public void tearDown() { 84 | factory.clear(); 85 | } 86 | 87 | // public for javassist 88 | public static class TestResult { 89 | 90 | /** 91 | * 结果类型名称 92 | */ 93 | private static final String DEMO = "demo"; 94 | 95 | private final String prefix; 96 | 97 | public TestResult(String prefix) { 98 | this.prefix = prefix; 99 | } 100 | 101 | @ResultType(type = DEMO) 102 | public Object result(ActionInvocation invocation) { 103 | return prefix + invocation.getInvokeResult(); 104 | } 105 | 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/impl/PathActionFactory2Test.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.impl; 19 | 20 | import lombok.extern.slf4j.Slf4j; 21 | import net.jrouter.result.DefaultResult; 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.Test; 25 | 26 | import java.lang.reflect.Method; 27 | 28 | import static net.jrouter.impl.PathTreeTest.PATHS; 29 | import static org.junit.Assert.assertEquals; 30 | import static org.junit.Assert.assertNotNull; 31 | 32 | /** 33 | * 测试路径匹配的Action。 34 | */ 35 | @Slf4j 36 | public class PathActionFactory2Test { 37 | 38 | private PathActionFactory factory; 39 | 40 | @Before 41 | public void init() { 42 | PathActionFactory.Properties prop = new PathActionFactory.Properties(); 43 | prop.setExtension(""); 44 | prop.setDefaultResultType(DefaultResult.EMPTY); 45 | prop.setPathGenerator(new PathActionFactory.StringPathGenerator() { 46 | 47 | @Override 48 | protected String buildActionPath(String namespace, String aname, Method method) { 49 | try { 50 | // 提供定制化 51 | namespace = String.format(namespace, "test"); 52 | } 53 | catch (Exception e) { 54 | log.error("Exception occurred when building action's path.", e); 55 | } 56 | return super.buildActionPath(namespace, aname, method); 57 | } 58 | }); 59 | factory = new PathActionFactory(prop); 60 | assertEquals(factory, prop.getActionFactory()); 61 | 62 | // result 63 | factory.addResultTypes(DefaultResult.class); 64 | 65 | // path action 66 | factory.addActions(net.jrouter.PathTestAction2.class); 67 | 68 | } 69 | 70 | @After 71 | public void tearDown() { 72 | factory.clear(); 73 | } 74 | 75 | /** 76 | * 测试Action调用。 77 | * 78 | * @see PathTreeTest#testGet 79 | */ 80 | @Test 81 | public void test_invoke() { 82 | assertNotNull(factory); 83 | String prefix = "test"; 84 | 85 | for (String p : PATHS) { 86 | assertEquals(p, factory.invokeAction(String.format("%s/%s", prefix, p))); 87 | } 88 | 89 | assertEquals("/{k1}", factory.invokeAction(String.format("%s/%s", prefix, "/zzz"))); 90 | assertEquals("/{k1}", factory.invokeAction(String.format("%s/%s", prefix, "/aa"))); 91 | 92 | assertEquals("/aa/b3/*/d1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b3/c1/d1"))); 93 | assertEquals("/aa/b3/c1/d1/*", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b3/c1/d1/e1"))); 94 | assertEquals("/aa/b3/c1/d1/*", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b3/c1/d1/null"))); 95 | assertEquals("/aa/b3/*/d1/{k2}", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b3/null/d1/null"))); 96 | 97 | assertEquals("/aa/*/c1/d1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b2/c1/d1"))); 98 | assertEquals("/aa/*/c1/d1/e1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b1/c1/d1/e1"))); 99 | assertEquals("/aa/*/c1/d1/e1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b2/c1/d1/e1"))); 100 | 101 | assertEquals("/aa/b4/{k1}/d1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b4/c1/d1"))); 102 | assertEquals("/aa/b4/{k1}/d2", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b4/c1/d2"))); 103 | 104 | assertEquals("/aa/*/c1/d1/e1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b4/c1/d1/e1"))); 105 | assertEquals("/aa/b4/{k1}/d2/e1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b4/c1/d2/e1"))); 106 | assertEquals("/aa/b4/{k1}/d2/{k2}", factory.invokeAction(String.format("%s/%s", prefix, "/aa/b4/c1/d2/null"))); 107 | assertEquals("/aa/b4/{k1}/d2/{k2}", 108 | factory.invokeAction(String.format("%s/%s", prefix, "/aa/b4/null/d2/null"))); 109 | 110 | assertEquals("/aa/*/c1/d1/e1", factory.invokeAction(String.format("%s/%s", prefix, "/aa/null/c1/d1/e1"))); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/interceptor/DemoInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.interceptor; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.annotation.Interceptor; 22 | import net.jrouter.annotation.InterceptorStack; 23 | import org.junit.Assert; 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.beans.factory.annotation.Qualifier; 26 | 27 | import static org.junit.Assert.assertEquals; 28 | 29 | /** 30 | * DemoInterceptor。 31 | */ 32 | public class DemoInterceptor { 33 | 34 | /** 35 | * demo interceptor & interceptor stack 36 | */ 37 | @InterceptorStack(interceptors = { @InterceptorStack.Interceptor("demo") }) 38 | public static final String DEMO = "demo"; 39 | 40 | /** 41 | * spring inject interceptor 42 | */ 43 | public static final String SPRING_DEMO = "springInject"; 44 | 45 | // 注入的属性 46 | private String value; 47 | 48 | // 注入的属性 49 | private Integer number; 50 | 51 | @Autowired 52 | @Qualifier("springInject") 53 | private String inject; 54 | 55 | /** 56 | * 测试拦截器。 57 | */ 58 | @Interceptor(name = DEMO) 59 | public Object test(ActionInvocation invocation) { 60 | assertEquals("demo interceptor", value); 61 | assertEquals((Integer) 10000, number); 62 | return invocation.invoke(); 63 | } 64 | 65 | /** 66 | * 测试拦截器的springframework注入。 67 | */ 68 | @Interceptor(name = SPRING_DEMO) 69 | public Object springTest(ActionInvocation invocation) { 70 | assertEquals("spring inject", inject); 71 | return invocation.invoke(); 72 | } 73 | 74 | /** 75 | * 注入属性。 76 | */ 77 | public void setValue(String value) { 78 | this.value = value; 79 | } 80 | 81 | /** 82 | * 注入属性。 83 | */ 84 | public void setNumber(Integer number) { 85 | this.number = number; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/interceptor/DemoInterceptorStack.java: -------------------------------------------------------------------------------- 1 | package net.jrouter.interceptor; 2 | 3 | import net.jrouter.InterceptorTestAction; 4 | import net.jrouter.annotation.InterceptorStack; 5 | 6 | /** 7 | * DemoInterceptorStack。 8 | * 9 | * @see InterceptorTestAction.Action4 10 | */ 11 | public class DemoInterceptorStack { 12 | 13 | /** 14 | * 测试拦截栈名称,指定匹配的路径。 15 | * 16 | * @see SampleInterceptor#logging 17 | */ 18 | @InterceptorStack(interceptors = { @InterceptorStack.Interceptor(SampleInterceptor.LOGGING) }, 19 | include = { "/*/matched" }, order = 1) 20 | public static final String MATCHED_INTERCEPTOR_STACK = "matched"; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/interceptor/DemoThreadActionContextInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.interceptor; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.annotation.Interceptor; 22 | import net.jrouter.annotation.InterceptorStack; 23 | 24 | /** 25 | * 使用{@link ThreadLocal}存储{@link ActionInvocation}的拦截器。 26 | * Action调用前存储ActionInvocation,默认调用结束后清除。 27 | */ 28 | public class DemoThreadActionContextInterceptor { 29 | 30 | @InterceptorStack(interceptors = { @InterceptorStack.Interceptor("demoThread") }) 31 | public static final String DEMO_THREAD = "demoThread"; 32 | 33 | /** 34 | * ThreadLocal 35 | */ 36 | private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>(); 37 | 38 | /** 39 | * Action调用结束后是否清除线程变量中的ActionInvocation对象,默认清除 40 | */ 41 | private boolean removeActionInvocation = true; 42 | 43 | public DemoThreadActionContextInterceptor() { 44 | } 45 | 46 | public DemoThreadActionContextInterceptor(boolean removeActionInvocation) { 47 | this.removeActionInvocation = removeActionInvocation; 48 | } 49 | 50 | /** 51 | * 返回线程变量中的ActionInvocation对象。 52 | * @return ActionInvocation对象。 53 | */ 54 | public static ActionInvocation get() { 55 | return THREAD_LOCAL.get(); 56 | } 57 | 58 | /** 59 | * 拦截器。 60 | */ 61 | @Interceptor(name = DEMO_THREAD) 62 | public Object test(ActionInvocation invocation) { 63 | try { 64 | THREAD_LOCAL.set(invocation); 65 | return invocation.invoke(); 66 | } 67 | finally { 68 | // just keep thread local ActionInvocation for test 69 | if (removeActionInvocation) 70 | THREAD_LOCAL.remove(); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/result/DemoResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.result; 19 | 20 | import net.jrouter.ActionInvocation; 21 | import net.jrouter.annotation.Result; 22 | import net.jrouter.annotation.ResultType; 23 | import org.junit.Assert; 24 | 25 | /** 26 | * DemoResult。 27 | */ 28 | public class DemoResult { 29 | 30 | /** 31 | * demo 32 | */ 33 | public static final String DEMO_RESULT_TYPE = "demo"; 34 | 35 | /** 36 | * result not found 37 | */ 38 | public static final String DEMO_RESULT_NOT_FOUND = "demoResultNotFound"; 39 | 40 | /** 41 | * result exception 42 | */ 43 | public static final String DEMO_RESULT_EXCEPTION = "demoResultException"; 44 | 45 | // 注入的属性 46 | private String value; 47 | 48 | /** 49 | * 返回结果未找到的字符串。 50 | * @param invocation Action运行时上下文。 51 | */ 52 | @Result(name = DEMO_RESULT_NOT_FOUND) 53 | public static Object resultNotFound(ActionInvocation invocation) { 54 | return DEMO_RESULT_NOT_FOUND + ":" + invocation.getActionPath(); 55 | } 56 | 57 | /** 58 | * 抛出运行时异常。 59 | * @param invocation Action运行时上下文。 60 | */ 61 | @Result(name = DEMO_RESULT_EXCEPTION) 62 | public static Object resultException(ActionInvocation invocation) { 63 | throw new RuntimeException("Result excpetion : " + invocation.getActionPath()); 64 | } 65 | 66 | /** 67 | * 返回结果对象的路径。 68 | * @param invocation Action运行时上下文。 69 | */ 70 | @ResultType(type = DEMO_RESULT_TYPE) 71 | public Object demo(ActionInvocation invocation) { 72 | Assert.assertEquals("demo result", value); 73 | return invocation.getResult().location(); 74 | } 75 | 76 | /** 77 | * 注入属性。 78 | */ 79 | public void setValue(String value) { 80 | this.value = value; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/spring/DefaultActionFactoryBeanAopTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.spring; 19 | 20 | import net.jrouter.impl.InterceptorProxy; 21 | import net.jrouter.impl.PathActionFactory; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.beans.factory.annotation.Qualifier; 27 | import org.springframework.test.context.ContextConfiguration; 28 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 29 | 30 | import java.util.List; 31 | 32 | import static org.junit.Assert.*; 33 | 34 | /** 35 | * 测试与 springframework 集成自动扫描类并添加组件。 36 | */ 37 | @RunWith(SpringJUnit4ClassRunner.class) 38 | @ContextConfiguration(locations = { "classpath:jrouter-spring_aop.xml" }) 39 | public class DefaultActionFactoryBeanAopTest { 40 | 41 | // singleton ActionFactory 42 | @Autowired 43 | @Qualifier("actionFactoryTest") 44 | private PathActionFactory factory; 45 | 46 | @Before 47 | public void setUp() { 48 | assertNotNull(factory); 49 | } 50 | 51 | /** 52 | * 测试action aop。 53 | */ 54 | @Test 55 | public void test_aopAction() { 56 | 57 | assertSame(PathActionFactory.class, factory.getClass()); 58 | assertSame(SpringObjectFactory.class, factory.getObjectFactory().getClass()); 59 | 60 | assertInterceptorProxies("/test/param", "[timer, timer, springInject, logging]"); 61 | 62 | assertInterceptorProxies("/test/simple", "[demo, springInject]"); 63 | assertInterceptorProxies("/test/exception", "[logging, timer, demo, springInject]"); 64 | assertInterceptorProxies("/test/springInject", "[springInject, demo, springInject]"); 65 | assertInterceptorProxies("/test/forward", "[demo, springInject]"); 66 | assertInterceptorProxies("/test/forward2", "[demo, springInject]"); 67 | 68 | assertInterceptorProxies("/test1", "[]"); 69 | assertInterceptorProxies("/xx/yy/zz", "[]"); 70 | assertInterceptorProxies("/{k1}", "[]"); 71 | assertInterceptorProxies("/aa/b5/*/*/*/*", "[]"); 72 | } 73 | 74 | /** 75 | * 测试指定path的action的拦截器集合。 76 | */ 77 | private void assertInterceptorProxies(String actionPath, String interceptorProxies) { 78 | assertEquals(interceptorsToString(factory.getActions().get(actionPath).getInterceptorProxies()), 79 | interceptorProxies); 80 | } 81 | 82 | /** 83 | * 拦截器集合字符串显示名称。 84 | */ 85 | private String interceptorsToString(List interceptors) { 86 | if (interceptors == null) 87 | return "null"; 88 | int iMax = interceptors.size() - 1; 89 | if (iMax == -1) 90 | return "[]"; 91 | StringBuilder msg = new StringBuilder(); 92 | msg.append('['); 93 | for (int i = 0;; i++) { 94 | msg.append(interceptors.get(i).getName()); 95 | if (i == iMax) 96 | return msg.append(']').toString(); 97 | msg.append(", "); 98 | } 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/test/java/net/jrouter/spring/DefaultActionFactoryBeanScanComponentTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.spring; 19 | 20 | import net.jrouter.ActionFactory; 21 | import net.jrouter.impl.PathActionFactory; 22 | import net.jrouter.interceptor.DefaultInterceptorStack; 23 | import net.jrouter.interceptor.DemoInterceptor; 24 | import net.jrouter.interceptor.SampleInterceptor; 25 | import net.jrouter.result.DefaultResult; 26 | import net.jrouter.result.DemoResult; 27 | import org.junit.Before; 28 | import org.junit.Test; 29 | import org.junit.runner.RunWith; 30 | import org.springframework.beans.factory.annotation.Autowired; 31 | import org.springframework.beans.factory.annotation.Qualifier; 32 | import org.springframework.test.context.ContextConfiguration; 33 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 34 | 35 | import static org.junit.Assert.*; 36 | 37 | /** 38 | * 测试与 springframework 集成自动扫描类并添加组件。 39 | */ 40 | @RunWith(SpringJUnit4ClassRunner.class) 41 | @ContextConfiguration(locations = { "classpath:jrouter-spring_autoscan.xml" }) 42 | public class DefaultActionFactoryBeanScanComponentTest { 43 | 44 | // singleton ActionFactory 45 | @Autowired 46 | @Qualifier("actionFactoryTest") 47 | private ActionFactory factory; 48 | 49 | @Before 50 | public void setUp() { 51 | assertNotNull(factory); 52 | } 53 | 54 | /** 55 | * Test of scanning components。 56 | */ 57 | @Test 58 | public void test_scanComponent() { 59 | 60 | assertSame(PathActionFactory.class, factory.getClass()); 61 | assertSame(SpringObjectFactory.class, factory.getObjectFactory().getClass()); 62 | 63 | assertEquals("empty", factory.getDefaultInterceptorStack()); 64 | assertEquals("empty", factory.getDefaultResultType()); 65 | assertEquals(100000, ((PathActionFactory) factory).getActionCacheNumber()); 66 | assertEquals(".", ((PathActionFactory) factory).getExtension()); 67 | 68 | assertNotNull(factory.getInterceptors().get(SampleInterceptor.LOGGING)); 69 | assertNotNull(factory.getInterceptors().get(SampleInterceptor.TIMER)); 70 | assertNotNull(factory.getInterceptors().get(DemoInterceptor.SPRING_DEMO)); 71 | 72 | assertNotNull(factory.getInterceptorStacks().get(DefaultInterceptorStack.SAMPLE_INTERCEPTOR_STACK)); 73 | assertNotNull(factory.getInterceptorStacks().get(DemoInterceptor.DEMO)); 74 | 75 | assertNotNull(factory.getResultTypes().get(DefaultResult.EMPTY)); 76 | assertNotNull(factory.getResultTypes().get(DefaultResult.FORWARD)); 77 | 78 | // exculde net.jrouter.result 79 | assertNull(factory.getResultTypes().get(DemoResult.DEMO_RESULT_TYPE)); 80 | assertNull(factory.getResults().get(DefaultResult.RESULT_NOT_FOUND)); 81 | assertNull(factory.getResults().get(DemoResult.DEMO_RESULT_NOT_FOUND)); 82 | assertNull(factory.getResults().get(DemoResult.DEMO_RESULT_EXCEPTION)); 83 | 84 | // see @Component in SimpleAction 85 | assertNotNull(factory.getActions().get("/test/simple")); 86 | // see @Component PathTestAction 87 | assertNull(factory.getActions().get("/xx/yy/zz")); 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /src/test/java/net/jrouter/spring/RequestMappingActionFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.spring; 19 | 20 | import net.jrouter.ActionFilter; 21 | import net.jrouter.annotation.*; 22 | import net.jrouter.util.CollectionUtil; 23 | import net.jrouter.util.StringUtil; 24 | import org.springframework.web.bind.annotation.RequestMapping; 25 | 26 | import java.lang.annotation.Annotation; 27 | import java.lang.reflect.Method; 28 | 29 | /** 30 | * 适配{@link RequestMapping}的{@code ActionFilter}实现。 31 | */ 32 | public class RequestMappingActionFilter implements ActionFilter { 33 | 34 | @Override 35 | public boolean accept(Object obj, Method method) { 36 | return method.isAnnotationPresent(Action.class) || method.isAnnotationPresent(RequestMapping.class); 37 | } 38 | 39 | @Override 40 | public Action getAction(Object obj, Method method) { 41 | final Action action = method.getAnnotation(Action.class); 42 | final boolean hasAction = (action != null); 43 | RequestMapping mapping = method.getAnnotation(RequestMapping.class); 44 | if (mapping == null) { 45 | return action; 46 | } 47 | else { 48 | // use mapping's value/name, ignore action's value/name 49 | String[] values = mapping.value(); 50 | if (CollectionUtil.isEmpty(values)) { 51 | values = mapping.path(); 52 | } 53 | if (CollectionUtil.isEmpty(values)) { 54 | String name = mapping.name(); 55 | if (StringUtil.isNotBlank(name)) { 56 | values = new String[] { name }; 57 | } 58 | } 59 | if (CollectionUtil.isEmpty(values)) { 60 | values = new String[] { method.getName() }; 61 | } 62 | 63 | final String[] paths = values; 64 | return new Action() { 65 | 66 | @Override 67 | public String[] value() { 68 | return paths; 69 | } 70 | 71 | @Override 72 | public String[] name() { 73 | return paths; 74 | } 75 | 76 | @Override 77 | public String interceptorStack() { 78 | return hasAction ? action.interceptorStack() : ""; 79 | } 80 | 81 | @Override 82 | public String[] interceptors() { 83 | return hasAction ? action.interceptors() : CollectionUtil.EMPTY_STRING_ARRAY; 84 | } 85 | 86 | @Override 87 | public Result[] results() { 88 | return hasAction ? action.results() : new Result[0]; 89 | } 90 | 91 | @Override 92 | public Scope scope() { 93 | return hasAction ? action.scope() : Scope.SINGLETON; 94 | } 95 | 96 | @Override 97 | public Parameter[] parameters() { 98 | return hasAction ? action.parameters() : new Parameter[0]; 99 | } 100 | 101 | @Override 102 | public Class annotationType() { 103 | return RequestMapping.class; 104 | } 105 | }; 106 | } 107 | } 108 | 109 | @Override 110 | public Namespace getNamespace(Object obj, Method method) { 111 | return method.getDeclaringClass().getAnnotation(Namespace.class); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/spring/SpringObjectFactoryTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.spring; 19 | 20 | import net.jrouter.ObjectFactory; 21 | import net.jrouter.SimpleAction; 22 | import net.jrouter.URLTestAction2; 23 | import net.jrouter.impl.PathActionFactory; 24 | import net.jrouter.interceptor.DemoInterceptor; 25 | import org.junit.After; 26 | import org.junit.Before; 27 | import org.junit.Test; 28 | import org.junit.runner.RunWith; 29 | import org.springframework.test.context.ContextConfiguration; 30 | import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; 31 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 32 | 33 | import static org.junit.Assert.*; 34 | 35 | /** 36 | * SpringObjectFactoryTest。 37 | */ 38 | @RunWith(SpringJUnit4ClassRunner.class) 39 | @ContextConfiguration(locations = { "classpath:jrouter-spring_test.xml" }) 40 | public class SpringObjectFactoryTest extends AbstractJUnit4SpringContextTests { 41 | 42 | // PathActionFactory 43 | private PathActionFactory factory; 44 | 45 | // ObjectFactory 46 | private ObjectFactory objectFactory; 47 | 48 | @Before 49 | public void setUp() { 50 | // SpringObjectFactory 51 | objectFactory = new SpringObjectFactory(applicationContext); 52 | 53 | PathActionFactory.Properties prop = new PathActionFactory.Properties(); 54 | prop.setObjectFactory(objectFactory); 55 | // create ActionFactory not by springframework 56 | factory = new PathActionFactory(prop); 57 | 58 | factory.addInterceptors(DemoInterceptor.class); 59 | factory.addInterceptorStacks(DemoInterceptor.class); 60 | 61 | factory.addActions(SimpleAction.class); 62 | 63 | } 64 | 65 | @After 66 | public void tearDown() { 67 | factory.clear(); 68 | } 69 | 70 | /** 71 | * Test of newInstance method, of class SpringObjectFactory. 72 | */ 73 | @Test 74 | public void testNewInstance() { 75 | SimpleAction sa1 = objectFactory.newInstance(SimpleAction.class); 76 | sa1.springInject(); 77 | SimpleAction sa2 = objectFactory.newInstance(SimpleAction.class); 78 | sa2.springInject(); 79 | assertNotSame(sa1, sa2); 80 | // 注入的为单例bean对象 81 | assertSame(sa1.springInject(), sa2.springInject()); 82 | } 83 | 84 | /** 85 | * 测试 springframework 注入。 86 | * 87 | * @see SimpleAction#springInject() 88 | */ 89 | @Test 90 | public void testSpringInject() { 91 | String url = "/test/springInject"; 92 | 93 | // check interceptors 94 | assertEquals(1, factory.getActions().get(url).getInterceptorProxies().size()); 95 | assertEquals(1, factory.getActions().get(url).getInterceptors().size()); 96 | assertEquals(DemoInterceptor.SPRING_DEMO, 97 | factory.getActions().get(url).getInterceptorProxies().get(0).getName()); 98 | assertEquals(DemoInterceptor.SPRING_DEMO, factory.getActions().get(url).getInterceptors().get(0).name()); 99 | 100 | assertTrue(factory.invokeAction(url) instanceof URLTestAction2); 101 | assertSame(factory.invokeAction(url), factory.invokeAction(url)); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/util/ClassUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.util; 19 | 20 | import org.junit.Test; 21 | 22 | import java.util.Objects; 23 | import java.util.Set; 24 | import java.util.stream.Collectors; 25 | 26 | import static org.junit.Assert.*; 27 | 28 | /** 29 | * ClassUtilTest。 30 | */ 31 | public class ClassUtilTest { 32 | 33 | /** 34 | * Test of getClasses method, of class ClassUtil. 35 | */ 36 | @Test 37 | public void testGetClasses() throws Exception { 38 | assertEquals(0, ClassUtil.getClasses().size()); 39 | assertEquals(0, ClassUtil.getClasses("").size()); 40 | 41 | // System.out.println(ClassUtil.getClasses("net.jrouter.annotation")); 42 | Set> classes1 = ClassUtil.getClasses("net.jrouter.annotation") 43 | .stream() 44 | .filter(cls -> !Objects.equals("package-info", cls.getSimpleName())) 45 | .collect(Collectors.toSet()); 46 | assertEquals(11, classes1.size()); 47 | Set> classes2 = ClassUtil.getClasses("net.jrouter.annotation", "net.jrouter.annotation") 48 | .stream() 49 | .filter(cls -> !Objects.equals("package-info", cls.getSimpleName())) 50 | .collect(Collectors.toSet()); 51 | assertEquals(11, classes2.size()); 52 | 53 | // 包含测试类、内部类,不做个数验证 54 | assertFalse(ClassUtil.getClasses("net.jrouter.impl").isEmpty()); 55 | assertFalse(ClassUtil.getClasses("net.jrouter.util").isEmpty()); 56 | } 57 | 58 | /** 59 | * Test of loadClass method, of class ClassUtil. 60 | */ 61 | @Test 62 | public void testLoadClass() throws Exception { 63 | ClassUtil.loadClass("net.jrouter.ActionFactory"); 64 | ClassUtil.loadClass("net.jrouter.annotation.Action"); 65 | try { 66 | ClassUtil.loadClass("net.jrouter.ActionFactory_Null"); 67 | fail("no exception"); 68 | } 69 | catch (ClassNotFoundException e) { 70 | assertNotNull(e); 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/net/jrouter/util/StringUtilTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010-2111 sunjumper@163.com 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * 16 | */ 17 | 18 | package net.jrouter.util; 19 | 20 | import org.junit.Test; 21 | 22 | import static org.junit.Assert.*; 23 | 24 | /** 25 | * StringUtilTest。 26 | */ 27 | public class StringUtilTest { 28 | 29 | /** 30 | * 路径分隔符 31 | */ 32 | public static final char PATH = '/'; 33 | 34 | /** 35 | * 测试判断空值。 36 | */ 37 | @Test 38 | public void testIsEmpty() { 39 | assertTrue(StringUtil.isEmpty(null)); 40 | assertTrue(StringUtil.isEmpty("")); 41 | assertFalse(StringUtil.isEmpty(" ")); 42 | assertFalse(StringUtil.isEmpty("test")); 43 | 44 | assertFalse(StringUtil.isNotEmpty(null)); 45 | assertFalse(StringUtil.isNotEmpty("")); 46 | assertTrue(StringUtil.isNotEmpty(" ")); 47 | assertTrue(StringUtil.isNotEmpty("test")); 48 | } 49 | 50 | /** 51 | * 测试判断空或空白。 52 | */ 53 | @Test 54 | public void testIsBlank() { 55 | assertTrue(StringUtil.isBlank(null)); 56 | assertTrue(StringUtil.isBlank("")); 57 | assertTrue(StringUtil.isBlank(" ")); 58 | assertFalse(StringUtil.isBlank("test")); 59 | 60 | assertFalse(StringUtil.isNotBlank(null)); 61 | assertFalse(StringUtil.isNotBlank("")); 62 | assertFalse(StringUtil.isNotBlank(" ")); 63 | assertTrue(StringUtil.isNotBlank("test")); 64 | } 65 | 66 | /** 67 | * 测试去除字符串首尾的空格和特定字符。 68 | */ 69 | @Test 70 | public void testTrim() { 71 | assertEquals("", StringUtil.trim("", PATH)); 72 | assertEquals("", StringUtil.trim("/", PATH)); 73 | assertEquals("", StringUtil.trim("/ ", PATH)); 74 | assertEquals("", StringUtil.trim(" /", PATH)); 75 | assertEquals("", StringUtil.trim(" / ", PATH)); 76 | assertEquals("", StringUtil.trim("/// ", PATH)); 77 | assertEquals("x", StringUtil.trim("x", PATH)); 78 | assertEquals("x", StringUtil.trim("x ", PATH)); 79 | assertEquals("x", StringUtil.trim("/x", PATH)); 80 | assertEquals("x", StringUtil.trim("x/", PATH)); 81 | assertEquals("x", StringUtil.trim("//x", PATH)); 82 | assertEquals("x", StringUtil.trim("x///", PATH)); 83 | assertEquals("x", StringUtil.trim("/x/", PATH)); 84 | assertEquals("x", StringUtil.trim("//x///", PATH)); 85 | assertEquals("x/y", StringUtil.trim("/x/y/", PATH)); 86 | assertEquals("test", StringUtil.trim("/test/", PATH)); 87 | assertEquals("test", StringUtil.trim("/test/ ", PATH)); 88 | assertEquals("test", StringUtil.trim(" /test ", PATH)); 89 | assertEquals("test", StringUtil.trim(" test/ ", PATH)); 90 | assertEquals("test/123", StringUtil.trim(" /test/123//// ", PATH)); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/test/resources/jrouter-spring_aop.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | jrouter与springframework集成的配置文件 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | defaultInterceptorStack = empty 29 | defaultResultType = empty 30 | pathSeparator = / 31 | extension = . 32 | actionCacheNumber = 100000 33 | bytecode = default 34 | 35 | 36 | 37 | 38 | 39 | 40 | package = net.jrouter 41 | includeExpression = **.*Interceptor, **.*InterceptorStack 42 | excludeExpression = net.jrouter.result.* 43 | 44 | 45 | 46 | 47 | 48 | net.jrouter.result.DefaultResult 49 | 50 | 51 | 52 | 53 | 54 | net.jrouter.PathTestAction 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/test/resources/jrouter-spring_autoscan.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | jrouter与springframework集成的配置文件 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | defaultInterceptorStack = empty 31 | defaultResultType = empty 32 | pathSeparator = / 33 | extension = . 34 | actionCacheNumber = 100000 35 | bytecode = default 36 | 37 | 38 | 39 | 40 | 41 | 42 | package = net.jrouter 43 | includeExpression = **.*Interceptor, **.*InterceptorStack 44 | excludeExpression = jrouter.result.* 45 | 46 | 47 | 48 | 49 | 50 | net.jrouter.result.DefaultResult 51 | 52 | 53 | 54 | 55 | 56 | net.jrouter.URLTestAction 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | includeComponentBeanExpression = *Action* 65 | excludeComponentBeanExpression = 66 | includeComponentClassExpression = net.jrouter.Simple* 67 | excludeComponentClassExpression = 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/test/resources/jrouter-spring_test.xml: -------------------------------------------------------------------------------- 1 | 8 | jrouter与springframework集成的配置文件 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | extension = 28 | actionCacheNumber = 100000 29 | 30 | 31 | 32 | 33 | net.jrouter.URLTestAction 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/test/resources/jrouter_aop.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/test/resources/jrouter_autoscan.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | -------------------------------------------------------------------------------- /src/test/resources/jrouter_error.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/jrouter_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | |%date{yyyy-MM-dd HH:mm:ss}|%p|%thread|%logger %line|%n%m%n 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/resources/test/include1.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/resources/test/include2.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------