57 |
58 |
--------------------------------------------------------------------------------
/example/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 | COOKIE
8 |
9 |
10 | works.cirno.mocha.StartupPerformanceListener
11 |
12 |
13 |
31 |
32 |
33 |
34 |
35 | works.cirno.mocha.example.guice.GuicedListener
36 |
37 |
38 | dispatcher
39 | works.cirno.mocha.GuicedDispatcherFilter
40 |
41 | configurator
42 | works.cirno.mocha.example.ExampleConfigurator
43 |
44 |
45 |
46 |
47 |
48 |
49 | dispatcher
50 | /*
51 |
52 |
--------------------------------------------------------------------------------
/example/src/main/webapp/default.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}
2 |
3 | body {
4 | padding: 8px 12px;
5 | }
6 |
7 | .form-group {
8 | margin: 8px 0;
9 | }
10 |
11 | label {
12 | display: block;
13 | font-weight: bold;
14 | }
15 |
16 | input {
17 | width: 100%;
18 | height: 2em;
19 | line-height: 2em;
20 | border: solid 1px #999;
21 | border-radius: 3px;
22 | text-rendering: optimizeLegibility;
23 | }
24 |
25 | .btn {
26 | line-height: 2em;
27 | height: 2em;
28 | padding: 0 2em;
29 | display: block;
30 | border-radius: 3px;
31 | border: solid 1px transparent;
32 | }
33 |
34 | .btn.btn-primary{
35 | color: white;
36 | background-color: dodgerblue;
37 | }
--------------------------------------------------------------------------------
/mvc-core/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/mvc-core/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | works.cirno.mocha
6 | mvc
7 | 0.1-SNAPSHOT
8 |
9 | mvc-core
10 | Mocha MVC Core
11 |
12 |
13 |
14 | javax.servlet
15 | servlet-api
16 | 2.5
17 | provided
18 |
19 |
20 |
21 | org.slf4j
22 | slf4j-api
23 | 1.7.12
24 |
25 |
26 |
27 | org.ow2.asm
28 | asm-tree
29 | 4.2
30 |
31 |
32 |
33 | javax.inject
34 | javax.inject
35 | 1
36 |
37 |
38 |
39 | commons-fileupload
40 | commons-fileupload
41 | 1.3.1
42 |
43 |
44 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/BasicMVCFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.util.concurrent.ConcurrentHashMap;
27 |
28 | /**
29 | * BasicObjectFactory will treat all beans as singleton,
30 | */
31 | public class BasicMVCFactory implements ObjectFactory {
32 |
33 | private final ConcurrentHashMap, Object> instances = new ConcurrentHashMap<>();
34 |
35 | @Override
36 | public T getInstance(TypeOrInstance param) {
37 | switch (param.getInjectBy()) {
38 | case TYPE:
39 | return getInstance(param.getType());
40 | case INSTANCE:
41 | return param.getInstance();
42 | default:
43 | throw new UnsupportedOperationException("Can't inject by " + param.getInjectBy());
44 | }
45 |
46 | }
47 |
48 | private T getInstance(Class clazz) {
49 | @SuppressWarnings("unchecked")
50 | T result = (T) instances.get(clazz);
51 | if (result == null) {
52 | try {
53 | result = clazz.newInstance();
54 | } catch (InstantiationException | IllegalAccessException e) {
55 | throw new RuntimeException(e);
56 | }
57 | instances.put(clazz, result);
58 | }
59 | return result;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ClassComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.util.Comparator;
27 |
28 | /**
29 | *
Compares class by hierarchy,
30 | *
31 | *
Ensures following rules:
32 | * Given A and B are classes
33 | *
34 | *
compare(A, B) = 0 when A is same as B
35 | *
compare(A, B) < 0 when A is subclass of B
36 | *
If compare(A, B) <= 0 and compare(B, C) <= 0, then compare(A, C) <= 0
37 | *
38 | */
39 | public class ClassComparator implements Comparator> {
40 |
41 | @Override
42 | public int compare(Class> o1, Class> o2) {
43 | if (o2.equals(o1)) {
44 | return 0;
45 | } else if (o2.isAssignableFrom(o1)) {
46 | return -1;
47 | } else if (o1.isAssignableFrom(o2)) {
48 | return 1;
49 | } else {
50 | Class> commonParent = null;
51 | Class> lastEx = null;
52 | Class> lastOther = null;
53 | for (Class> clz = o1; clz != null; clz = clz.getSuperclass()) {
54 | if (clz.isAssignableFrom(o2)) {
55 | commonParent = clz;
56 | break;
57 | }
58 | lastEx = clz;
59 | }
60 | if (commonParent == null || lastEx == null) {
61 | throw new IllegalStateException(
62 | "Can't find common parent for class " + o1.getName() + " and " + o2.getName());
63 | }
64 | for (Class> clz = o2; clz != null; clz = clz.getSuperclass()) {
65 | if (commonParent.equals(clz)) {
66 | break;
67 | }
68 | lastOther = clz;
69 | }
70 | if (lastOther == null) {
71 | throw new IllegalStateException(
72 | "Can't find common parent for class " + o1.getName() + " and " + o2.getName());
73 | }
74 | return lastEx.getName().compareTo(lastOther.getName());
75 | }
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/CloseableResource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.Closeable;
27 | import java.io.IOException;
28 |
29 | final class CloseableResource implements Closeable {
30 |
31 | private final T content;
32 | private final String name;
33 |
34 | public CloseableResource(T content, String name) {
35 | super();
36 | this.content = content;
37 | this.name = name;
38 | }
39 |
40 | public T getContent() {
41 | return content;
42 | }
43 |
44 | public String getName() {
45 | return name;
46 | }
47 |
48 | @Override
49 | public void close() throws IOException {
50 | content.close();
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ConfigBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.File;
27 |
28 | import works.cirno.mocha.result.Renderer;
29 |
30 | /**
31 | *
32 | */
33 | public interface ConfigBuilder {
34 | /**
35 | * Handle request with specified controller and method
36 | */
37 | ConfigBuilder with(String controllerName, String methodName);
38 |
39 | /**
40 | * Handle request with specified controller and method
41 | */
42 | ConfigBuilder with(Class> controller, String methodName);
43 |
44 | /**
45 | * Handle request with specified controller and method
46 | */
47 | ConfigBuilder with(String controllerName);
48 |
49 | /**
50 | * Handle request with specified controller and method
51 | */
52 | ConfigBuilder with(Class> controller);
53 |
54 | /**
55 | * Handle request with specified controller and method
56 | */
57 | ConfigBuilder withMethod(String methodName);
58 |
59 | /**
60 | * Handle
61 | *
62 | * @param exception
63 | * @param result
64 | * @return
65 | */
66 | ConfigBuilder exception(Class exception, Renderer result);
67 |
68 | ConfigBuilder exception(Class exception, Class extends Renderer> result);
69 |
70 | ConfigBuilder exception(Class exception, String resultName);
71 |
72 | /**
73 | * Forward a view result to a specific path (likely forward to JSP)
74 | * Following by a to(path) method, you will specify path to forward to there
75 | *
76 | * @param resultName
77 | * "name" in a View object
78 | * @return
79 | */
80 | ServletResultRendererConfig forward(String resultName);
81 |
82 | /**
83 | * Redirect a view result to a specific path (forward to JSP)
84 | * Following by a to(path) method, you will specify path to redirect to
85 | * there
86 | *
87 | * @param resultName
88 | * "name" in a View object
89 | * @return
90 | */
91 | ServletResultRendererConfig redirect(String resultName);
92 |
93 | /**
94 | * Add a custom works.cirno.mocha.result.ResultRenderer to handle result
95 | *
96 | * @param renderer
97 | * @return
98 | */
99 | ConfigBuilder prependResultRenderer(Renderer renderer);
100 |
101 | ConfigBuilder prependResultRenderer(Class extends Renderer> renderer);
102 |
103 | ConfigBuilder prependResultRenderer(String rendererName);
104 |
105 | /**
106 | * Add a custom works.cirno.mocha.result.ResultRenderer to handle result
107 | *
108 | * @param renderer
109 | * @return
110 | */
111 | ConfigBuilder appendResultRenderer(Renderer renderer);
112 |
113 | ConfigBuilder appendResultRenderer(Class extends Renderer> renderer);
114 |
115 | ConfigBuilder appendResultRenderer(String rendererName);
116 |
117 | /**
118 | * Don't parse http body posted, you can fetch the body from a InputStream
119 | * parameter in controller method
120 | *
121 | * @return
122 | */
123 | ConfigBuilder raw();
124 |
125 | /**
126 | * Set directory which will store temporary uploaded data
127 | *
128 | * @param tempDirectory
129 | * @return
130 | */
131 | ConfigBuilder uploadTemp(File tempDirectory);
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ConfigBuilderImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.File;
27 | import java.util.HashMap;
28 | import java.util.List;
29 | import java.util.Map;
30 |
31 | import works.cirno.mocha.result.Renderer;
32 |
33 | /**
34 | *
35 | */
36 | class ConfigBuilderImpl implements ConfigBuilder {
37 |
38 | private String path;
39 | private String method;
40 | private boolean pathRegex;
41 |
42 | private MVCConfig config;
43 |
44 | ConfigBuilderImpl(String path, boolean pathRegex, MVCConfig parent) {
45 | this(path, pathRegex, null, parent);
46 | }
47 |
48 | ConfigBuilderImpl(String path, boolean pathRegex, String method, MVCConfig parent) {
49 | this.path = path;
50 | this.method = method;
51 | this.config = new MVCConfig(parent);
52 | }
53 |
54 | String getPath() {
55 | return path;
56 | }
57 |
58 | boolean isPathRegex() {
59 | return pathRegex;
60 | }
61 |
62 | String getMethod() {
63 | return method;
64 | }
65 |
66 | TypeOrInstance> getController() {
67 | return config.getController();
68 | }
69 |
70 | String getMethodName() {
71 | return config.getMethodName();
72 | }
73 |
74 | Map, TypeOrInstance extends Renderer>> getExceptionHandlers() {
75 | return config.getHandlers();
76 | }
77 |
78 | List> getResultRenderers() {
79 | return config.getResultRenderers();
80 | }
81 |
82 | HashMap getPendingServletResultRendererConfig() {
83 | return config.getPendingServletResultRendererConfig();
84 | }
85 |
86 | boolean isRaw() {
87 | return config.isRaw();
88 | }
89 |
90 | File getUploadTemp() {
91 | return config.getUploadTemp();
92 | }
93 |
94 | public ConfigBuilder with(Class> controller, String methodName) {
95 | return config.with(controller, methodName);
96 | }
97 |
98 | public ConfigBuilder with(String controllerName, String methodName) {
99 | return config.with(controllerName, methodName);
100 | }
101 |
102 | public ConfigBuilder with(String controllerName) {
103 | return config.with(controllerName);
104 | }
105 |
106 | public ConfigBuilder with(Class> controller) {
107 | return config.with(controller);
108 | }
109 |
110 | public ConfigBuilder withMethod(String methodName) {
111 | return config.withMethod(methodName);
112 | }
113 |
114 | public ConfigBuilder exception(Class exception, Renderer result) {
115 | return config.exception(exception, result);
116 | }
117 |
118 | public ConfigBuilder exception(Class exception,
119 | Class extends Renderer> resultType) {
120 | return config.exception(exception, resultType);
121 | }
122 |
123 | public ConfigBuilder exception(Class exception, String resultName) {
124 | return config.exception(exception, resultName);
125 | }
126 |
127 | public ServletResultRendererConfig forward(String resultName) {
128 | return config.forward(resultName);
129 | }
130 |
131 | public ServletResultRendererConfig redirect(String resultName) {
132 | return config.redirect(resultName);
133 | }
134 |
135 | public ConfigBuilder prependResultRenderer(Renderer renderer) {
136 | return config.prependResultRenderer(renderer);
137 | }
138 |
139 | public ConfigBuilder prependResultRenderer(Class extends Renderer> renderer) {
140 | return config.prependResultRenderer(renderer);
141 | }
142 |
143 | public ConfigBuilder prependResultRenderer(String rendererName) {
144 | return config.prependResultRenderer(rendererName);
145 | }
146 |
147 | public ConfigBuilder appendResultRenderer(Renderer renderer) {
148 | return config.appendResultRenderer(renderer);
149 | }
150 |
151 | public ConfigBuilder appendResultRenderer(Class extends Renderer> renderer) {
152 | return config.appendResultRenderer(renderer);
153 | }
154 |
155 | public ConfigBuilder appendResultRenderer(String rendererName) {
156 | return config.appendResultRenderer(rendererName);
157 | }
158 |
159 | public ConfigBuilder raw() {
160 | return config.raw();
161 | }
162 |
163 | public ConfigBuilder uploadTemp(File tempDirectory) {
164 | return config.uploadTemp(tempDirectory);
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/DispatcherFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.IOException;
27 | import java.util.Enumeration;
28 | import java.util.HashMap;
29 |
30 | import javax.servlet.Filter;
31 | import javax.servlet.FilterChain;
32 | import javax.servlet.FilterConfig;
33 | import javax.servlet.ServletException;
34 | import javax.servlet.ServletRequest;
35 | import javax.servlet.ServletResponse;
36 | import javax.servlet.http.HttpServletRequest;
37 | import javax.servlet.http.HttpServletResponse;
38 |
39 | import org.slf4j.Logger;
40 | import org.slf4j.LoggerFactory;
41 |
42 | /**
43 | *
44 | */
45 | public class DispatcherFilter extends Dispatcher implements Filter {
46 |
47 | private static final Logger log = LoggerFactory.getLogger(DispatcherFilter.class);
48 |
49 | @Override
50 | public void init(FilterConfig config) throws ServletException {
51 | long begin = System.currentTimeMillis();
52 | log.info("Initializing dispatcher servlet {}", config.getFilterName());
53 | try {
54 | HashMap initParameters = new HashMap<>();
55 | @SuppressWarnings("unchecked")
56 | Enumeration keys = config.getInitParameterNames();
57 | while (keys.hasMoreElements()) {
58 | String key = keys.nextElement();
59 | String value = config.getInitParameter(key);
60 | initParameters.put(key, value);
61 | }
62 |
63 | init(config.getFilterName(), config.getServletContext(), initParameters);
64 | log.info("Dispatcher filter {} initialized in {}ms", config.getFilterName(),
65 | System.currentTimeMillis() - begin);
66 | } catch (ServletException e) {
67 | log.error("Initialization failed", e);
68 | throw e;
69 | }
70 | }
71 |
72 | @Override
73 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
74 | throws IOException, ServletException {
75 | HttpServletRequest req = (HttpServletRequest) request;
76 | HttpServletResponse resp = (HttpServletResponse) response;
77 | if (!invoke(req, resp)) {
78 | chain.doFilter(request, response);
79 | }
80 | }
81 |
82 | @Override
83 | public void destroy() {
84 |
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/DispatcherServlet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.IOException;
27 | import java.util.Enumeration;
28 | import java.util.HashMap;
29 |
30 | import javax.servlet.Servlet;
31 | import javax.servlet.ServletConfig;
32 | import javax.servlet.ServletException;
33 | import javax.servlet.ServletRequest;
34 | import javax.servlet.ServletResponse;
35 | import javax.servlet.http.HttpServletRequest;
36 | import javax.servlet.http.HttpServletResponse;
37 |
38 | import org.slf4j.Logger;
39 | import org.slf4j.LoggerFactory;
40 |
41 | /**
42 | *
43 | */
44 | public class DispatcherServlet extends Dispatcher implements Servlet {
45 |
46 | private static final Logger log = LoggerFactory.getLogger(DispatcherFilter.class);
47 | private ServletConfig config;
48 |
49 | @Override
50 | public void init(ServletConfig config) throws ServletException {
51 | long begin = System.currentTimeMillis();
52 | log.info("Initializing dispatcher servlet {}", config.getServletName());
53 | this.config = config;
54 | try {
55 | HashMap initParameters = new HashMap<>();
56 | Enumeration keys = config.getInitParameterNames();
57 | while (keys.hasMoreElements()) {
58 | String key = keys.nextElement();
59 | String value = config.getInitParameter(key);
60 | initParameters.put(key, value);
61 | }
62 |
63 | init(config.getServletName(), config.getServletContext(), initParameters);
64 | log.info("Dispatcher servlet {} initialized in {}ms", config.getServletName(),
65 | System.currentTimeMillis() - begin);
66 | } catch (ServletException e) {
67 | log.error("Initialization failed", e);
68 | throw e;
69 | }
70 | }
71 |
72 | @Override
73 | public ServletConfig getServletConfig() {
74 | return this.config;
75 | }
76 |
77 | @Override
78 | public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
79 | HttpServletRequest req = (HttpServletRequest) request;
80 | HttpServletResponse resp = (HttpServletResponse) response;
81 | if (!this.invoke(req, resp)) {
82 | resp.sendError(404, "Request path not found");
83 | }
84 | }
85 |
86 | @Override
87 | public String getServletInfo() {
88 | return "Dispatcher servlet";
89 | }
90 |
91 | @Override
92 | public void destroy() {
93 |
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ExceptionHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import javax.servlet.http.HttpServletRequest;
27 | import javax.servlet.http.HttpServletResponse;
28 |
29 | /**
30 | *
31 | */
32 | public interface ExceptionHandler {
33 | void handle(InvokeContext ctx, HttpServletRequest req, HttpServletResponse resp, T exception);
34 | }
35 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/InvokeContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.Closeable;
27 | import java.io.IOException;
28 | import java.util.ArrayList;
29 | import java.util.HashMap;
30 | import java.util.Set;
31 | import java.util.regex.Matcher;
32 |
33 | import javax.servlet.http.HttpServletRequest;
34 | import javax.servlet.http.HttpServletResponse;
35 |
36 | import org.slf4j.Logger;
37 | import org.slf4j.LoggerFactory;
38 |
39 | /**
40 | *
41 | */
42 | public class InvokeContext implements Closeable {
43 | private static final Logger log = LoggerFactory.getLogger(InvokeContext.class);
44 | private InvokeTarget target;
45 | private Matcher uriMatcher;
46 | private Set groupNames;
47 | private HashMap attributes;
48 | private HttpServletRequest req;
49 | private HttpServletResponse resp;
50 | private boolean multipart;
51 | private HashMap> parts;
52 | private String characterEncoding = "UTF-8"; // TODO make it configurable
53 | private ArrayList> closeables;
54 |
55 | public InvokeContext(InvokeTarget target, Matcher uriMatcher, Set groupNames) {
56 | this.target = target;
57 | this.uriMatcher = uriMatcher;
58 | this.groupNames = groupNames;
59 | }
60 |
61 | public InvokeTarget getTarget() {
62 | return target;
63 | }
64 |
65 | public Matcher getUriMatcher() {
66 | return uriMatcher;
67 | }
68 |
69 | public boolean isGroupName(String str) {
70 | return groupNames.contains(str);
71 | }
72 |
73 | public Object getAttribute(String key) {
74 | return attributes == null ? null : attributes.get(key);
75 | }
76 |
77 | public Object setAttribute(String key, Object value) {
78 | if (attributes == null) {
79 | attributes = new HashMap<>();
80 | }
81 | return attributes.put(key, value);
82 | }
83 |
84 | public void addPart(MultiPartItem part) {
85 | if (parts == null) {
86 | parts = new HashMap<>();
87 | }
88 | String name = part.getFieldName();
89 | ArrayList list = parts.get(name);
90 | if (list == null) {
91 | list = new ArrayList<>(1);
92 | parts.put(name, list);
93 | }
94 | list.add(part);
95 | }
96 |
97 | public MultiPartItem getPart(String name) {
98 | if (parts == null) {
99 | return null;
100 | }
101 | ArrayList list = parts.get(name);
102 | return (list == null || list.size() == 0) ? null : list.get(0);
103 | }
104 |
105 | public MultiPartItem[] getParts(String name) {
106 | if (parts == null) {
107 | return null;
108 | }
109 | ArrayList list = parts.get(name);
110 | return list == null ? null : list.toArray(new MultiPartItem[list.size()]);
111 | }
112 |
113 | public HttpServletRequest getRequest() {
114 | return req;
115 | }
116 |
117 | void setRequest(HttpServletRequest req) {
118 | this.req = req;
119 | }
120 |
121 | public HttpServletResponse getResponse() {
122 | return resp;
123 | }
124 |
125 | void setResponse(HttpServletResponse resp) {
126 | this.resp = resp;
127 | }
128 |
129 | public String getCharacterEncoding() {
130 | return characterEncoding;
131 | }
132 |
133 | void setCharacterEncoding(String characterEncoding) {
134 | this.characterEncoding = characterEncoding;
135 | }
136 |
137 | public void registerCloseable(Closeable closeable, String name) {
138 | if (closeables == null) {
139 | closeables = new ArrayList<>();
140 | }
141 | closeables.add(new CloseableResource(closeable, name));
142 | }
143 |
144 | public boolean isMultipart() {
145 | return multipart;
146 | }
147 |
148 | void setMultipart(boolean multipart) {
149 | this.multipart = multipart;
150 | }
151 |
152 | @Override
153 | public void close() throws IOException {
154 | if (closeables != null) {
155 | for (int i = closeables.size() - 1; i >= 0; i--) {
156 | CloseableResource> closeable = closeables.get(i);
157 | log.debug("Closing " + closeable.getName());
158 | try {
159 | closeable.close();
160 | } catch (Exception e) {
161 | log.warn("Can't close resource: " + closeable.getName() + " ("
162 | + closeable.getContent().getClass().getName() + ")", e);
163 | }
164 | }
165 | }
166 | }
167 |
168 | }
169 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/MVCInternalException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | public class MVCInternalException extends RuntimeException {
27 |
28 | /**
29 | *
30 | */
31 | private static final long serialVersionUID = -4736592789363537011L;
32 |
33 | public MVCInternalException() {
34 | super();
35 | }
36 |
37 | public MVCInternalException(String message, Throwable cause, boolean enableSuppression,
38 | boolean writableStackTrace) {
39 | super(message, cause, enableSuppression, writableStackTrace);
40 | }
41 |
42 | public MVCInternalException(String message, Throwable cause) {
43 | super(message, cause);
44 | }
45 |
46 | public MVCInternalException(String message) {
47 | super(message);
48 | }
49 |
50 | public MVCInternalException(Throwable cause) {
51 | super(cause);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/MultiPartItem.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.Closeable;
27 | import java.io.File;
28 | import java.io.IOException;
29 | import java.io.InputStream;
30 | import java.io.UnsupportedEncodingException;
31 | import java.nio.charset.Charset;
32 | import java.util.Iterator;
33 |
34 | public interface MultiPartItem extends Closeable {
35 | String getHeader(String name);
36 |
37 | Iterator getHeaders(String name);
38 |
39 | Iterator getHeaderNames();
40 |
41 | InputStream getInputStream() throws IOException;
42 |
43 | String getContentType();
44 |
45 | String getName();
46 |
47 | String getString(Charset charset);
48 |
49 | String getString(String charset) throws UnsupportedEncodingException;
50 |
51 | String getString();
52 |
53 | long getSize();
54 |
55 | void write(File file) throws IOException;
56 |
57 | String getFieldName();
58 |
59 | boolean isFormField();
60 | }
61 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/MultiPartItemCommon.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.io.File;
27 | import java.io.IOException;
28 | import java.io.InputStream;
29 | import java.io.UnsupportedEncodingException;
30 | import java.nio.charset.Charset;
31 | import java.util.Iterator;
32 |
33 | import org.apache.commons.fileupload.FileItem;
34 |
35 | class MultiPartItemCommon implements MultiPartItem {
36 |
37 | private FileItem item;
38 |
39 | public MultiPartItemCommon(FileItem item) {
40 | this.item = item;
41 | }
42 |
43 | public String getHeader(String name) {
44 | return item.getHeaders().getHeader(name);
45 | }
46 |
47 | public Iterator getHeaders(String name) {
48 | return item.getHeaders().getHeaders(name);
49 | }
50 |
51 | public Iterator getHeaderNames() {
52 | return item.getHeaders().getHeaderNames();
53 | }
54 |
55 | public InputStream getInputStream() throws IOException {
56 | return item.getInputStream();
57 | }
58 |
59 | public String getContentType() {
60 | return item.getContentType();
61 | }
62 |
63 | public String getName() {
64 | return item.getName();
65 | }
66 |
67 | public long getSize() {
68 | return item.getSize();
69 | }
70 |
71 | public void write(File file) throws IOException {
72 | try {
73 | item.write(file);
74 | } catch (IOException | Error e) {
75 | throw e;
76 | } catch (Exception e) {
77 | throw new IOException("Can't write part to file " + file, e);
78 | }
79 | }
80 |
81 | public String getFieldName() {
82 | return item.getFieldName();
83 | }
84 |
85 | public boolean isFormField() {
86 | return item.isFormField();
87 | }
88 |
89 | public String getString(Charset charset) {
90 | try {
91 | return item.getString(charset.name());
92 | } catch (UnsupportedEncodingException e) {
93 | throw new RuntimeException(e);
94 | }
95 | }
96 |
97 | public String getString(String charset) throws UnsupportedEncodingException {
98 | return item.getString(charset);
99 | }
100 |
101 | public String getString() {
102 | return item.getString();
103 | }
104 |
105 | @Override
106 | public void close() throws IOException {
107 | item.delete();
108 | }
109 |
110 | @Override
111 | public String toString() {
112 | return "MultiPartItem(CommonUpload): " + item;
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ObjectFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | /**
27 | *
28 | */
29 | public interface ObjectFactory {
30 | T getInstance(TypeOrInstance param);
31 | }
32 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ServletResultRendererConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | public interface ServletResultRendererConfig {
27 | /**
28 | * Forward or redirect to following path
29 | * @param path The path to forward or redirect to
30 | * @return
31 | */
32 | ConfigBuilder to(String path);
33 | }
34 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/ServletResultRendererConfigImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import works.cirno.mocha.result.ResultType;
27 |
28 | public class ServletResultRendererConfigImpl implements ServletResultRendererConfig {
29 |
30 | private ConfigBuilder configBuilder;
31 | private ResultType resultType;
32 | private String path;
33 |
34 | public ServletResultRendererConfigImpl(ConfigBuilder configBuilder, ResultType resultType) {
35 | super();
36 | this.configBuilder = configBuilder;
37 | this.resultType = resultType;
38 | }
39 |
40 | @Override
41 | public ConfigBuilder to(String path) {
42 | this.path = path;
43 | return configBuilder;
44 | }
45 |
46 | public ResultType getResultType() {
47 | return resultType;
48 | }
49 |
50 | public String getPath() {
51 | return path;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/StartupPerformanceListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import javax.servlet.ServletContext;
27 | import javax.servlet.ServletContextEvent;
28 | import javax.servlet.ServletContextListener;
29 |
30 | import org.slf4j.Logger;
31 | import org.slf4j.LoggerFactory;
32 |
33 | public class StartupPerformanceListener implements ServletContextListener {
34 |
35 | private static final Logger log = LoggerFactory.getLogger(StartupPerformanceListener.class);
36 |
37 | public final static String KEY_PERF_START = "PERF.START.TS";
38 |
39 | @Override
40 | public void contextInitialized(ServletContextEvent sce) {
41 | log.info("Put startup timestamp to servlet context: {}", KEY_PERF_START);
42 | ServletContext sc = sce.getServletContext();
43 | sc.setAttribute(KEY_PERF_START, System.currentTimeMillis());
44 | }
45 |
46 | @Override
47 | public void contextDestroyed(ServletContextEvent sce) {
48 |
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/TypeOrInstance.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | public class TypeOrInstance {
27 |
28 | public static enum InjectBy {
29 | NAME_TYPE, TYPE, INSTANCE
30 | }
31 |
32 | private InjectBy injectBy;
33 | private Class extends T> type;
34 | private T instance;
35 | private String name;
36 |
37 | public TypeOrInstance(String name, Class extends T> type) {
38 | this.injectBy = InjectBy.NAME_TYPE;
39 | this.name = name;
40 | this.type = type;
41 | }
42 |
43 | public TypeOrInstance(T instance) {
44 | this.injectBy = InjectBy.INSTANCE;
45 | this.instance = instance;
46 | }
47 |
48 | public TypeOrInstance(Class extends T> type) {
49 | this.injectBy = InjectBy.TYPE;
50 | this.type = type;
51 | }
52 |
53 | public InjectBy getInjectBy() {
54 | return injectBy;
55 | }
56 |
57 | public Class extends T> getType() {
58 | return type;
59 | }
60 |
61 | public T getInstance() {
62 | return instance;
63 | }
64 |
65 | public String getName() {
66 | return name;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/name/AnnotationParameterAnalyzer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.name;
25 |
26 | import java.lang.annotation.Annotation;
27 | import java.lang.reflect.Method;
28 |
29 | import works.cirno.mocha.InvokeTarget;
30 |
31 | /**
32 | *
33 | */
34 | public class AnnotationParameterAnalyzer implements ParameterAnalyzer {
35 |
36 | @Override
37 | public Parameter[] getParameters(InvokeTarget target) {
38 | return getParameters(target, null);
39 | }
40 |
41 | @Override
42 | public Parameter[] getParameters(InvokeTarget target, Parameter[] parameters) {
43 | Method method = target.getMethod();
44 |
45 | Class>[] parameterTypes = method.getParameterTypes();
46 | Annotation[][] parameterAnnotations = method.getParameterAnnotations();
47 | int length = parameterAnnotations.length;
48 | if (parameters == null) {
49 | parameters = new Parameter[length];
50 | } else if (parameters.length != length) {
51 | throw new IllegalArgumentException("Input parameters' length is different than parameters of target");
52 | }
53 | for (int i = 0; i < length; i++) {
54 | if (parameters[i] == null || parameters[i].getName() == null) {
55 | Class> type = parameterTypes[i];
56 | for (Annotation annotation : parameterAnnotations[i]) {
57 | if (annotation instanceof NamedParam) {
58 | NamedParam np = ((NamedParam) annotation);
59 | String name = np.value();
60 | parameters[i] = new Parameter(name, type);
61 | break;
62 | }
63 | }
64 | if (parameters[i] == null) {
65 | parameters[i] = new Parameter(null, type);
66 | }
67 | }
68 | }
69 | return parameters;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/name/NamedParam.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.name;
25 |
26 | import java.lang.annotation.ElementType;
27 | import java.lang.annotation.Retention;
28 | import java.lang.annotation.RetentionPolicy;
29 | import java.lang.annotation.Target;
30 |
31 | /**
32 | *
33 | */
34 | @Target(ElementType.PARAMETER)
35 | @Retention(RetentionPolicy.RUNTIME)
36 | public @interface NamedParam {
37 |
38 | public String value();
39 | }
40 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/name/Parameter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.name;
25 |
26 | import java.util.Arrays;
27 | import java.util.Collection;
28 |
29 | import works.cirno.mocha.parameter.value.DefaultParameterSource;
30 | import works.cirno.mocha.parameter.value.ParameterSource;
31 |
32 | public class Parameter {
33 |
34 | private Collection DEFAULT_PARAMETER_SOURCES = Arrays
35 | . asList(DefaultParameterSource.INSTANCE);
36 |
37 | private final String name;
38 | private final Class> type;
39 |
40 | private Collection parameterSources = DEFAULT_PARAMETER_SOURCES;
41 |
42 | public Parameter(String name, Class> type) {
43 | this.name = name;
44 | this.type = type;
45 | }
46 |
47 | public String getName() {
48 | return name;
49 | }
50 |
51 | public Class> getType() {
52 | return type;
53 | }
54 |
55 | public Collection getParameterSources() {
56 | return parameterSources;
57 | }
58 |
59 | public void setParameterSources(Collection parameterSources) {
60 | this.parameterSources = parameterSources;
61 | }
62 |
63 | @Override
64 | public String toString() {
65 | return "Parameter[" + name + "](" + type.getName() + ")";
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/name/ParameterAnalyzer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.name;
25 |
26 | import works.cirno.mocha.InvokeTarget;
27 |
28 | /**
29 | *
30 | */
31 | public interface ParameterAnalyzer {
32 | Parameter[] getParameters(InvokeTarget target);
33 |
34 | Parameter[] getParameters(InvokeTarget target, Parameter[] parameters);
35 | }
36 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/AbstractStringArrayConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.lang.reflect.Array;
27 |
28 | import works.cirno.mocha.InvokeContext;
29 |
30 | public abstract class AbstractStringArrayConverter implements ValueConverter {
31 |
32 | public static Class> getArrayType(Class> componentType) throws ClassNotFoundException {
33 | String name;
34 | if (componentType.isArray()) {
35 | // just add a leading "["
36 | name = "[" + componentType.getName();
37 | } else if (componentType.isPrimitive()) {
38 | if (componentType == boolean.class) {
39 | name = "[Z";
40 | } else if (componentType == byte.class) {
41 | name = "[B";
42 | } else if (componentType == char.class) {
43 | name = "[C";
44 | } else if (componentType == double.class) {
45 | name = "[D";
46 | } else if (componentType == float.class) {
47 | name = "[F";
48 | } else if (componentType == int.class) {
49 | name = "[I";
50 | } else if (componentType == long.class) {
51 | name = "[J";
52 | } else if (componentType == short.class) {
53 | name = "[S";
54 | } else {
55 | throw new UnsupportedOperationException("Unsupported component type: " + componentType.getName());
56 | }
57 | } else {
58 | name = "[L" + componentType.getName() + ";";
59 | }
60 | return Class.forName(name);
61 | }
62 |
63 | @Override
64 | public Object convert(Class> type, InvokeContext ctx, Object from) {
65 | if (type.isArray()) {
66 | if (from == null || Array.getLength(from) == 0) {
67 | Object one = convertOne(type.getComponentType(), ctx, null);
68 | if (one == NOT_CONVERTABLE) {
69 | return NOT_CONVERTABLE;
70 | } else if (one == null) {
71 | return Array.newInstance(type.getComponentType(), 0);
72 | } else {
73 | Object ret = Array.newInstance(type.getComponentType(), 1);
74 | Array.set(ret, 0, one);
75 | return ret;
76 | }
77 | } else {
78 | Class> componentType = type.getComponentType();
79 | Object one = convertOne(componentType, ctx, Array.get(from, 0));
80 | if (one == NOT_CONVERTABLE) {
81 | return NOT_CONVERTABLE;
82 | } else {
83 | int len = Array.getLength(from);
84 | Object ret = Array.newInstance(componentType, len);
85 | Array.set(ret, 0, one);
86 | for (int i = 1; i < len; i++) {
87 | one = convertOne(componentType, ctx, Array.get(from, i));
88 | if (one == NOT_CONVERTABLE) {
89 | return NOT_CONVERTABLE;
90 | }
91 | Array.set(ret, 0, one);
92 | }
93 | return ret;
94 | }
95 | }
96 | } else {
97 | return convertOne(type, ctx, from);
98 | }
99 | }
100 |
101 | protected abstract Object convertOne(Class> type, InvokeContext ctx, Object from);
102 | }
103 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/AbstractValueSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | public abstract class AbstractValueSource implements ValueSource {
27 |
28 | private ConvertStrategy strategy = ConvertStrategy.NULL_WHEN_UNCONVERTABLE;
29 |
30 | ValueSource withConvertStrategy(ConvertStrategy strategy) {
31 | this.strategy = strategy;
32 | return this;
33 | }
34 |
35 | @Override
36 | public ConvertStrategy getConvertStrategy() {
37 | return strategy;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/BeanParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.beans.BeanInfo;
27 | import java.beans.IntrospectionException;
28 | import java.beans.Introspector;
29 | import java.beans.PropertyDescriptor;
30 | import java.lang.reflect.Constructor;
31 | import java.lang.reflect.InvocationTargetException;
32 | import java.lang.reflect.Method;
33 | import java.lang.reflect.Modifier;
34 | import java.util.concurrent.ConcurrentHashMap;
35 |
36 | import works.cirno.mocha.InvokeContext;
37 | import works.cirno.mocha.parameter.name.Parameter;
38 |
39 | public class BeanParameterSource implements ParameterSource {
40 |
41 | private ConcurrentHashMap, Boolean> notBean = new ConcurrentHashMap, Boolean>();
42 |
43 | private ParameterSource propertySource;
44 |
45 | ParameterSource getPropertySource() {
46 | return propertySource;
47 | }
48 |
49 | void setPropertySource(ParameterSource propertySource) {
50 | this.propertySource = propertySource;
51 | }
52 |
53 | @Override
54 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
55 | Class> type = parameter.getType();
56 | String paramName = parameter.getName();
57 | if (notBean.contains(type)) {
58 | return NOT_HERE;
59 | } else {
60 | try {
61 | BeanInfo info;
62 | Constructor> constructor;
63 | try {
64 | if ((type.getModifiers() & (Modifier.ABSTRACT)) != 0) {
65 | notBean.put(type, true);
66 | return NOT_HERE;
67 | }
68 | info = Introspector.getBeanInfo(type);
69 | constructor = type.getConstructor();
70 | if ((constructor.getModifiers() & (Modifier.PUBLIC)) == 0) {
71 | notBean.put(type, true);
72 | return NOT_HERE;
73 | }
74 | } catch (NoSuchMethodException | IntrospectionException e) {
75 | notBean.put(type, true);
76 | return NOT_HERE;
77 | }
78 | Object result = constructor.newInstance();
79 | PropertyDescriptor[] propertyDescriptors = info
80 | .getPropertyDescriptors();
81 | StringBuilder nameBuilder = new StringBuilder(64);
82 | boolean propertyGot = false;
83 |
84 | for (PropertyDescriptor pd : propertyDescriptors) {
85 | Class> propertyType = pd.getPropertyType();
86 | Method writeMethod = pd.getWriteMethod();
87 | if (propertyType != null && writeMethod != null) {
88 | String propertyName = pd.getName();
89 | nameBuilder.setLength(0);
90 | nameBuilder.append(paramName).append('.')
91 | .append(propertyName);
92 |
93 | Parameter propertyParameter = new Parameter(nameBuilder.toString(), propertyType);
94 | Object value = propertySource.getParameterValue(ctx, propertyParameter);
95 | if (value != NOT_HERE) {
96 | propertyGot = true;
97 | if (writeMethod != null) {
98 | try{
99 | writeMethod.invoke(result, value);
100 | }catch(IllegalArgumentException e){
101 | throw new IllegalArgumentException(
102 | "Expected type: " + writeMethod.getParameterTypes()[0].getName()
103 | + " actual type: " + value.getClass().getName(),
104 | e);
105 | }
106 | }
107 | }
108 | }
109 | }
110 | return propertyGot ? result : NOT_HERE;
111 | } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
112 | | InvocationTargetException ex) {
113 | throw new RuntimeException("Can't setup bean parameter " + paramName + "(" + type + ")", ex);
114 | }
115 | }
116 | }
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/CombianParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.util.Collection;
27 |
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | import works.cirno.mocha.InvokeContext;
32 | import works.cirno.mocha.parameter.name.Parameter;
33 |
34 | public class CombianParameterSource implements ParameterSource {
35 |
36 | private static final Logger log = LoggerFactory.getLogger(CombianParameterSource.class);
37 | private static final Logger perfLog = LoggerFactory.getLogger("perf." + CombianParameterSource.class.getName());
38 |
39 | private Collection sources;
40 |
41 | public CombianParameterSource() {
42 |
43 | }
44 |
45 | public CombianParameterSource(Collection sources) {
46 | this.sources = sources;
47 | }
48 |
49 | public Collection getSources() {
50 | return sources;
51 | }
52 |
53 | public void setSources(Collection sources) {
54 | this.sources = sources;
55 | }
56 |
57 | @Override
58 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
59 | long paramBeginTime = 0;
60 | for (ParameterSource source : sources) {
61 | if (perfLog.isDebugEnabled()) {
62 | paramBeginTime = System.nanoTime();
63 | }
64 | Object value = source.getParameterValue(ctx, parameter);
65 | if (perfLog.isDebugEnabled()) {
66 | perfLog.debug("Resolve parameter[{}] by {} in {}ms", parameter.getType().getName(),
67 | source.getClass().getName(), (System.nanoTime() - paramBeginTime) / 1000000f);
68 | }
69 | log.debug("Getting parameter {}, result {}", parameter, value);
70 | if (value != NOT_HERE) {
71 | return value;
72 | }
73 | }
74 | return NOT_HERE;
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/ConvertStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | public enum ConvertStrategy {
27 | EXCEPTION_WHEN_UNCONVERTABLE, SKIP_WHEN_UNCONVERTABLE, NOT_FOUND_WHEN_UNCONVERTABLE, NULL_WHEN_UNCONVERTABLE
28 | }
29 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/DefaultParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.util.ArrayList;
27 |
28 | public class DefaultParameterSource extends CombianParameterSource {
29 |
30 | public static final DefaultParameterSource INSTANCE = new DefaultParameterSource();
31 |
32 | public DefaultParameterSource() {
33 |
34 | ArrayList sources = new ArrayList<>();
35 |
36 | sources.add(new TypedParameterSource());
37 | sources.add(new RawParameterSource());
38 | sources.add(new FilePartArrayParameterSource());
39 | sources.add(new FilePartParameterSource());
40 |
41 | MatrixParameterSource matrix = new MatrixParameterSource();
42 | ArrayList vs = new ArrayList<>();
43 | vs.add(new MatcherValueSource().withConvertStrategy(ConvertStrategy.NULL_WHEN_UNCONVERTABLE));
44 | vs.add(new MultiPartStringArraySource().withConvertStrategy(ConvertStrategy.SKIP_WHEN_UNCONVERTABLE));
45 | vs.add(new MultiPartStringSource().withConvertStrategy(ConvertStrategy.NULL_WHEN_UNCONVERTABLE));
46 | vs.add(new RequestValueSource().withConvertStrategy(ConvertStrategy.SKIP_WHEN_UNCONVERTABLE));
47 | vs.add(new RequestArrayValueSource().withConvertStrategy(ConvertStrategy.NULL_WHEN_UNCONVERTABLE));
48 | matrix.setSources(vs);
49 | ArrayList vc = new ArrayList<>();
50 | vc.add(new StringPEConverter());
51 | vc.add(new StringEnumConverter());
52 | matrix.setConverters(vc);
53 | sources.add(matrix);
54 |
55 | BeanParameterSource beanParameterSource = new BeanParameterSource();
56 | beanParameterSource.setPropertySource(this);
57 | sources.add(beanParameterSource);
58 |
59 | this.setSources(sources);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/FilePartArrayParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.InputStreamReader;
29 | import java.io.Reader;
30 | import java.io.UnsupportedEncodingException;
31 |
32 | import works.cirno.mocha.InvokeContext;
33 | import works.cirno.mocha.MultiPartItem;
34 | import works.cirno.mocha.parameter.name.Parameter;
35 |
36 | public class FilePartArrayParameterSource implements ParameterSource {
37 |
38 | @Override
39 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
40 | if (!ctx.isMultipart()) {
41 | return NOT_HERE;
42 | }
43 |
44 | String name = parameter.getName();
45 | Class> type = parameter.getType();
46 | if (!type.isArray()) {
47 | return NOT_HERE;
48 | }
49 | MultiPartItem[] parts = ctx.getParts(name);
50 |
51 | if (parts == null || parts.length == 0) {
52 | return NOT_HERE;
53 | }
54 | if (type == MultiPartItem.class) {
55 | return parts;
56 | } else if (type == Reader.class || type == InputStream.class) {
57 | int len = 0;
58 | for (MultiPartItem part : parts) {
59 | if (!part.isFormField()) {
60 | len++;
61 | }
62 | }
63 |
64 | if (len == 0) {
65 | return NOT_HERE;
66 | }
67 | if (type == Reader[].class) {
68 | String encoding = ctx.getCharacterEncoding();
69 | Reader[] result = new Reader[len];
70 | int i = 0;
71 | for (MultiPartItem part : parts) {
72 | if (!part.isFormField()) {
73 | try {
74 | ctx.registerCloseable(
75 | result[i++] = new InputStreamReader(part.getInputStream(), encoding),
76 | part.toString());
77 | } catch (UnsupportedEncodingException e) {
78 | throw new RuntimeException("Encoding " + encoding + " not supported", e);
79 | } catch (IOException e) {
80 | throw new RuntimeException("Can't get inputstream from part", e);
81 | }
82 | }
83 | }
84 | return result;
85 | } else if (type == InputStream[].class) {
86 | String encoding = ctx.getCharacterEncoding();
87 | InputStream[] result = new InputStream[len];
88 | int i = 0;
89 | for (MultiPartItem part : parts) {
90 | if (!part.isFormField()) {
91 | try {
92 | ctx.registerCloseable(
93 | result[i++] = part.getInputStream(),
94 | part.toString());
95 | } catch (IOException e) {
96 | throw new RuntimeException("Can't get inputstream from part", e);
97 | }
98 | }
99 | }
100 | return result;
101 | } else if (type == MultiPartItem[].class) {
102 | MultiPartItem[] result = new MultiPartItem[len];
103 | int i = 0;
104 | for (MultiPartItem part : parts) {
105 | if (!part.isFormField()) {
106 | result[i++] = part;
107 | }
108 | }
109 | return result;
110 | }
111 | }
112 | return NOT_HERE;
113 | }
114 |
115 | }
116 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/FilePartParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.InputStreamReader;
29 | import java.io.Reader;
30 | import java.io.UnsupportedEncodingException;
31 |
32 | import works.cirno.mocha.InvokeContext;
33 | import works.cirno.mocha.MultiPartItem;
34 | import works.cirno.mocha.parameter.name.Parameter;
35 |
36 | public class FilePartParameterSource implements ParameterSource {
37 |
38 | @Override
39 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
40 | if (!ctx.isMultipart()) {
41 | return NOT_HERE;
42 | }
43 | String name = parameter.getName();
44 | Class> type = parameter.getType();
45 | if(type.isArray()){
46 | return NOT_HERE;
47 | }
48 | MultiPartItem part = ctx.getPart(name);
49 |
50 | if (part == null) {
51 | return NOT_HERE;
52 | } else if (part.isFormField()) {
53 | return NOT_HERE;
54 | } else if (type == Reader.class) {
55 | String encoding = ctx.getCharacterEncoding();
56 | try {
57 | Reader result = new InputStreamReader(part.getInputStream(), encoding);
58 | ctx.registerCloseable(result, part.toString());
59 | return result;
60 | } catch (UnsupportedEncodingException e) {
61 | throw new RuntimeException("Encoding " + encoding + " not supported", e);
62 | } catch (IOException e) {
63 | throw new RuntimeException("Can't get inputstream from part", e);
64 | }
65 | } else if (type == InputStream.class) {
66 | try {
67 | InputStream result = part.getInputStream();
68 | ctx.registerCloseable(result, part.toString());
69 | return result;
70 | } catch (IOException e) {
71 | throw new RuntimeException("Can't get inputstream from part", e);
72 | }
73 | } else if (type == MultiPartItem.class) {
74 | return part;
75 | } else {
76 | return NOT_HERE;
77 | }
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/MapValueSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.util.Map;
27 |
28 | import works.cirno.mocha.InvokeContext;
29 |
30 | public class MapValueSource extends AbstractValueSource {
31 |
32 | private final Map map;
33 |
34 | public MapValueSource(Map map) {
35 | super();
36 | this.map = map;
37 | }
38 |
39 | @Override
40 | public Object getParameter(InvokeContext ctx, String key) {
41 | return map.containsKey(key) ? map.get(key) : NOT_FOUND;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/MatcherValueSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public class MatcherValueSource extends AbstractValueSource {
29 |
30 | @Override
31 | public Object getParameter(InvokeContext ctx, String key) {
32 | if(ctx.isGroupName(key)){
33 | return ctx.getUriMatcher().group(key);
34 | }
35 | return NOT_FOUND;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/MatrixParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.util.List;
27 |
28 | import org.slf4j.Logger;
29 | import org.slf4j.LoggerFactory;
30 |
31 | import works.cirno.mocha.InvokeContext;
32 | import works.cirno.mocha.parameter.name.Parameter;
33 |
34 | public class MatrixParameterSource implements ParameterSource {
35 |
36 | private static final Logger log = LoggerFactory.getLogger(MatrixParameterSource.class);
37 | private static final Logger perfLog = LoggerFactory.getLogger("perf." + MatrixParameterSource.class.getName());
38 |
39 | private List sources;
40 | private List converters;
41 |
42 | public List getSources() {
43 | return sources;
44 | }
45 |
46 | public void setSources(List sources) {
47 | this.sources = sources;
48 | }
49 |
50 | public List getConverters() {
51 | return converters;
52 | }
53 |
54 | public void setConverters(List converters) {
55 | this.converters = converters;
56 | }
57 |
58 | @Override
59 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
60 | long beginTime = 0;
61 | boolean usePerfLog = perfLog.isDebugEnabled();
62 | Class> type = parameter.getType();
63 | String name = parameter.getName();
64 | for (ValueSource source : sources) {
65 | if (usePerfLog) {
66 | beginTime = System.nanoTime();
67 | }
68 | Object sourceValue = source.getParameter(ctx, name);
69 | if (usePerfLog) {
70 | perfLog.debug("Get parameter-value named[{}] from source {} in {}ms", parameter.getName(),
71 | source.getClass().getName(), (System.nanoTime() - beginTime) / 1000000f);
72 | }
73 | log.debug("Get parameter[{}]({}) from {}: {}", name, type.getName(), source.getClass().getName(),
74 | sourceValue);
75 | if (sourceValue != ValueSource.NOT_FOUND) {
76 |
77 | Object value = ValueConverter.NOT_CONVERTABLE;
78 | for (ValueConverter converter : converters) {
79 | if (usePerfLog) {
80 | beginTime = System.nanoTime();
81 | }
82 | value = converter.convert(type, ctx, sourceValue);
83 | if (usePerfLog) {
84 | perfLog.debug("Convert parameter-value named[{}] by converter {} in {}ms", parameter.getName(),
85 | converter.getClass().getName(), (System.nanoTime() - beginTime) / 1000000f);
86 | }
87 | if (value != ValueConverter.NOT_CONVERTABLE) {
88 | return value;
89 | }
90 | }
91 | switch (source.getConvertStrategy()) {
92 | case EXCEPTION_WHEN_UNCONVERTABLE:
93 | throw new RuntimeException(
94 | String.format("Can't find converter to convert parameter[%s] from %s to %s", name,
95 | sourceValue == null ? "null" : sourceValue.getClass().getName(), type.getName()));
96 | case NOT_FOUND_WHEN_UNCONVERTABLE:
97 | return NOT_HERE;
98 | case SKIP_WHEN_UNCONVERTABLE:
99 | break;
100 | case NULL_WHEN_UNCONVERTABLE:
101 | default:
102 | log.warn("Can't find converter to convert parameter[{}] from {} to {}", name,
103 | sourceValue == null ? "null" : sourceValue.getClass().getName(), type.getName());
104 | return null;
105 | }
106 | }
107 | }
108 | log.debug("Can't find value for parameter[{}]", name);
109 | return NOT_HERE;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/MultiPartStringArraySource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.nio.charset.Charset;
27 |
28 | import works.cirno.mocha.InvokeContext;
29 | import works.cirno.mocha.MultiPartItem;
30 |
31 | public class MultiPartStringArraySource extends AbstractValueSource {
32 |
33 | @Override
34 | public Object getParameter(InvokeContext ctx, String key) {
35 | MultiPartItem[] parts = ctx.getParts(key);
36 | if (parts == null) {
37 | return NOT_FOUND;
38 | }
39 | int len = 0;
40 | for (MultiPartItem part : parts) {
41 | if (part.isFormField()) {
42 | len++;
43 | }
44 | }
45 | if (len == 0) {
46 | return NOT_FOUND;
47 | }
48 | String encoding = ctx.getCharacterEncoding();
49 | Charset cs = Charset.forName(encoding);
50 | String[] result = new String[len];
51 | int i = 0;
52 | for (MultiPartItem part : parts) {
53 | if (part.isFormField()) {
54 | result[i] = part.getString(cs);
55 | i++;
56 | }
57 | }
58 | return result;
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/MultiPartStringSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.nio.charset.Charset;
27 |
28 | import works.cirno.mocha.InvokeContext;
29 | import works.cirno.mocha.MultiPartItem;
30 |
31 | public class MultiPartStringSource extends AbstractValueSource {
32 |
33 | @Override
34 | public Object getParameter(InvokeContext ctx, String key) {
35 | MultiPartItem part = ctx.getPart(key);
36 | if (part != null && part.isFormField()) {
37 | String encoding = ctx.getCharacterEncoding();
38 | return part.getString(Charset.forName(encoding));
39 | } else {
40 | return NOT_FOUND;
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/ParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 | import works.cirno.mocha.parameter.name.Parameter;
28 |
29 | public interface ParameterSource {
30 | static final Object NOT_HERE = new Object(){
31 | public String toString() {
32 | return "NOT_HERE";
33 | };
34 | };
35 |
36 | Object getParameterValue(InvokeContext ctx, Parameter parameter);
37 | }
38 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/RawParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.Reader;
29 |
30 | import works.cirno.mocha.InvokeContext;
31 | import works.cirno.mocha.parameter.name.Parameter;
32 |
33 | public class RawParameterSource implements ParameterSource {
34 |
35 | @Override
36 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
37 | if (ctx.getTarget().isRaw()) {
38 | Class> type = parameter.getType();
39 | try {
40 | if (type == InputStream.class) {
41 | return ctx.getRequest().getInputStream();
42 | } else if (type == Reader.class) {
43 | return ctx.getRequest().getReader();
44 | }
45 | } catch (IOException e) {
46 | throw new RuntimeException(e);
47 | }
48 | }
49 | return NOT_HERE;
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/RequestArrayValueSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public class RequestArrayValueSource extends AbstractValueSource {
29 |
30 | @Override
31 | public Object getParameter(InvokeContext ctx, String key) {
32 | String[] ret = ctx.getRequest().getParameterValues(key);
33 | if (ret == null) {
34 | return NOT_FOUND;
35 | } else {
36 | return ret;
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/RequestValueSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public class RequestValueSource extends AbstractValueSource {
29 |
30 | @Override
31 | public Object getParameter(InvokeContext ctx, String key) {
32 | String ret = ctx.getRequest().getParameter(key);
33 | if (ret == null) {
34 | return NOT_FOUND;
35 | } else {
36 | return ret;
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/StringEnumConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public class StringEnumConverter extends AbstractStringArrayConverter {
29 |
30 | @Override
31 | @SuppressWarnings("unchecked")
32 | protected Object convertOne(Class> type, InvokeContext ctx, Object from) {
33 | if (!type.isEnum()) {
34 | return NOT_CONVERTABLE;
35 | }
36 | if (from != null && from.getClass() != String.class) {
37 | return NOT_CONVERTABLE;
38 | }
39 | return Enum.valueOf(type.asSubclass(Enum.class), (String) from);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/StringPEConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.beans.PropertyEditor;
27 | import java.beans.PropertyEditorManager;
28 |
29 | import org.slf4j.Logger;
30 | import org.slf4j.LoggerFactory;
31 |
32 | import works.cirno.mocha.InvokeContext;
33 |
34 | public class StringPEConverter extends AbstractStringArrayConverter {
35 |
36 | private static final Logger log = LoggerFactory.getLogger(StringPEConverter.class);
37 |
38 | @Override
39 | public Object convertOne(Class> type, InvokeContext ctx, Object from) {
40 | if (from != null && !(from instanceof String)) {
41 | return NOT_CONVERTABLE;
42 | }
43 | PropertyEditor pe = PropertyEditorManager.findEditor(type);
44 | if (pe == null) {
45 | return NOT_CONVERTABLE;
46 | }
47 | if (from == null) {
48 | return null;
49 | } else {
50 | try {
51 | pe.setAsText((String) from);
52 | return pe.getValue();
53 | } catch (Exception e) {
54 | log.warn("Can't convert parameter to {}", type.getName(), e);
55 | return NOT_CONVERTABLE;
56 | }
57 | }
58 | }
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/TypedParameterSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import java.io.IOException;
27 | import java.io.OutputStream;
28 | import java.io.PrintWriter;
29 | import java.io.Writer;
30 | import java.util.concurrent.ConcurrentHashMap;
31 |
32 | import javax.servlet.ServletOutputStream;
33 | import javax.servlet.ServletRequest;
34 | import javax.servlet.ServletResponse;
35 | import javax.servlet.http.HttpServletRequest;
36 | import javax.servlet.http.HttpServletResponse;
37 |
38 | import works.cirno.mocha.InvokeContext;
39 | import works.cirno.mocha.parameter.name.Parameter;
40 |
41 | public class TypedParameterSource implements ParameterSource {
42 |
43 | private final ParameterSource NULL_FETCHER = new ParameterSource() {
44 |
45 | @Override
46 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
47 | return NOT_HERE;
48 | }
49 | };
50 | private final ConcurrentHashMap, ParameterSource> fetchers = new ConcurrentHashMap<>();
51 |
52 | @Override
53 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
54 | Class> type = parameter.getType();
55 | ParameterSource fetcher = fetchers.get(type);
56 | if (fetcher == null) {
57 | if (type.isAssignableFrom(HttpServletRequest.class) && ServletRequest.class.isAssignableFrom(type)) {
58 | fetcher = new ParameterSource() {
59 |
60 | @Override
61 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
62 | return ctx.getRequest();
63 | }
64 | };
65 | } else if (type.isAssignableFrom(HttpServletResponse.class)
66 | && ServletResponse.class.isAssignableFrom(type)) {
67 | fetcher = new ParameterSource() {
68 |
69 | @Override
70 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
71 | return ctx.getResponse();
72 | }
73 | };
74 | } else if (type.isAssignableFrom(ServletOutputStream.class) && OutputStream.class.isAssignableFrom(type)) {
75 | fetcher = new ParameterSource() {
76 |
77 | @Override
78 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
79 | try {
80 | return ctx.getResponse().getOutputStream();
81 | } catch (IOException e) {
82 | throw new RuntimeException(e);
83 | }
84 | }
85 | };
86 | } else if (type.isAssignableFrom(PrintWriter.class) && Writer.class.isAssignableFrom(type)) {
87 | fetcher = new ParameterSource() {
88 |
89 | @Override
90 | public Object getParameterValue(InvokeContext ctx, Parameter parameter) {
91 | try {
92 | return ctx.getResponse().getWriter();
93 | } catch (IOException e) {
94 | throw new RuntimeException(e);
95 | }
96 | }
97 | };
98 | } else {
99 | fetcher = NULL_FETCHER;
100 | }
101 | fetchers.putIfAbsent(type, fetcher);
102 | }
103 | return fetcher.getParameterValue(ctx, parameter);
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/ValueConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public interface ValueConverter {
29 | static final Object NOT_CONVERTABLE = new Object() {
30 | public String toString() {
31 | return "##NOT_CONVERTABLE";
32 | };
33 | };
34 |
35 | Object convert(Class> type, InvokeContext ctx, Object from);
36 | }
37 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/parameter/value/ValueSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.parameter.value;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public interface ValueSource {
29 | static final Object NOT_FOUND = new Object() {
30 | public String toString() {
31 | return "##NOT_FOUND";
32 | };
33 | };
34 |
35 | Object getParameter(InvokeContext ctx, String key);
36 |
37 | ConvertStrategy getConvertStrategy();
38 | }
39 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/InvokeTargetCriteria.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver;
25 |
26 | import java.util.Collections;
27 | import java.util.HashSet;
28 | import java.util.Set;
29 | import java.util.regex.Matcher;
30 | import java.util.regex.Pattern;
31 |
32 | import works.cirno.mocha.InvokeTarget;
33 |
34 | /**
35 | *
36 | */
37 | public class InvokeTargetCriteria {
38 | protected static final Pattern GROUP_NAME = Pattern.compile("\\(\\?<(.*?)>");
39 |
40 | private final String uri;
41 | private final Pattern pattern;
42 | private final Set groupNames;
43 | private final String method;
44 | private final InvokeTarget target;
45 |
46 | public InvokeTargetCriteria(String uri, Pattern pattern, String method, InvokeTarget target) {
47 | this.uri = uri;
48 | this.pattern = pattern;
49 | this.method = method;
50 | this.target = target;
51 |
52 | Matcher matcher = GROUP_NAME.matcher(uri);
53 | if (matcher.find()) {
54 | HashSet groupNames = new HashSet<>(3);
55 | do {
56 | groupNames.add(matcher.group(1));
57 | } while (matcher.find());
58 | this.groupNames = Collections.unmodifiableSet(groupNames);
59 | } else {
60 | groupNames = Collections. emptySet();
61 | }
62 | }
63 |
64 | public String getUri() {
65 | return uri;
66 | }
67 |
68 | public Pattern getPattern() {
69 | return pattern;
70 | }
71 |
72 | public String getMethod() {
73 | return method;
74 | }
75 |
76 | public InvokeTarget getTarget() {
77 | return target;
78 | }
79 |
80 | public Set getGroupNames() {
81 | return groupNames;
82 | }
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/InvokeTargetResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 | import works.cirno.mocha.InvokeTarget;
28 |
29 | /**
30 | *
31 | */
32 | public interface InvokeTargetResolver {
33 | public static final InvokeTarget[] NO_TARGET = new InvokeTarget[0];
34 |
35 | InvokeTargetCriteria addServe(String uri, String method, InvokeTarget target);
36 |
37 | InvokeContext resolve(String uri, String method);
38 | }
39 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/PrefixDictInvokeTargetResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver;
25 |
26 | import java.util.ArrayList;
27 | import java.util.Collections;
28 | import java.util.HashMap;
29 | import java.util.List;
30 | import java.util.regex.Matcher;
31 | import java.util.regex.Pattern;
32 |
33 | import works.cirno.mocha.InvokeContext;
34 | import works.cirno.mocha.InvokeTarget;
35 | import works.cirno.mocha.resolver.prd.LongTreePrefixDict;
36 | import works.cirno.mocha.resolver.prd.PrefixDict;
37 |
38 | /**
39 | *
40 | */
41 | public class PrefixDictInvokeTargetResolver implements InvokeTargetResolver {
42 | private static final Pattern REGEX_META = Pattern.compile("[(\\[.\\\\?*+|]");
43 |
44 | private HashMap> fullMatchUris = new HashMap<>();
45 | private PrefixDict dict;
46 |
47 | public PrefixDictInvokeTargetResolver() {
48 | this.dict = new LongTreePrefixDict<>();
49 | }
50 |
51 | public PrefixDictInvokeTargetResolver(PrefixDict dict) {
52 | this.dict = dict;
53 | }
54 |
55 | private String getPrefix(String uri) {
56 | int trimStart = 0;
57 | int trimEnd = 0;
58 | if (uri.startsWith("^")) {
59 | trimStart = 1;
60 | }
61 | if (uri.endsWith("$")) {
62 | trimEnd = 1;
63 | }
64 | if (trimStart + trimEnd > 0) {
65 | uri = uri.substring(trimStart, uri.length() - trimEnd);
66 | }
67 | int idx = -1;
68 | Matcher matcher = REGEX_META.matcher(uri);
69 | if (matcher.find()) {
70 | switch (matcher.group().charAt(0)) {
71 | case '?':
72 | case '*':
73 | case '+':
74 | case '|':
75 | idx = 0;
76 | break;
77 | default:
78 | idx = matcher.start();
79 | break;
80 | }
81 | }
82 | switch (idx) {
83 | case -1:
84 | return null;
85 | case 0:
86 | return "";
87 | default:
88 | return uri.substring(0, idx);
89 | }
90 | }
91 |
92 | @Override
93 | public InvokeTargetCriteria addServe(String uri, String method, InvokeTarget target) {
94 | String prefix = getPrefix(uri);
95 | if (prefix == null) {
96 | ArrayList params = fullMatchUris.get(uri);
97 | if (params == null) {
98 | params = new ArrayList<>();
99 | fullMatchUris.put(uri, params);
100 | }
101 | InvokeTargetCriteria criteria = new InvokeTargetCriteria(uri, null, method, target);
102 | params.add(criteria);
103 | return criteria;
104 | } else {
105 | PrefixedInvokeTargetCriteria criteria = new PrefixedInvokeTargetCriteria(uri,
106 | Pattern.compile(uri.substring(prefix.length())), method, target, prefix);
107 | dict.add(prefix, criteria);
108 | return criteria;
109 | }
110 | }
111 |
112 | @Override
113 | public InvokeContext resolve(String uri, String method) {
114 | List fullMatches = fullMatchUris.get(uri);
115 | if (fullMatches != null) {
116 | for (InvokeTargetCriteria criteria : fullMatches) {
117 | if (criteria.getMethod() == null || criteria.getMethod().equals(method)) {
118 | return new InvokeContext(criteria.getTarget(), null, Collections. emptySet());
119 | }
120 | }
121 | }
122 |
123 | List prefixMatches = dict.select(uri);
124 | for (int i = prefixMatches.size() - 1; i >= 0; i--) {
125 | PrefixedInvokeTargetCriteria criteria = prefixMatches.get(i);
126 | Matcher matcher = criteria.getPattern().matcher(uri.substring(criteria.getPrefix().length()));
127 | if ((criteria.getMethod() == null || criteria.getMethod().equals(method)) && matcher.matches()) {
128 | return new InvokeContext(criteria.getTarget(), matcher, criteria.getGroupNames());
129 | }
130 | }
131 | return null;
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/PrefixedInvokeTargetCriteria.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver;
25 |
26 | import java.util.regex.Pattern;
27 |
28 | import works.cirno.mocha.InvokeTarget;
29 |
30 | /**
31 | *
32 | */
33 | public class PrefixedInvokeTargetCriteria extends InvokeTargetCriteria {
34 | private final String prefix;
35 |
36 | public PrefixedInvokeTargetCriteria(String uri, Pattern pattern, String method, InvokeTarget target, String prefix) {
37 | super(uri, pattern, method, target);
38 | this.prefix = prefix;
39 | }
40 |
41 | public String getPrefix() {
42 | return prefix;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/RegexInvokeTargetResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver;
25 |
26 | import java.util.ArrayList;
27 | import java.util.Collections;
28 | import java.util.regex.Matcher;
29 | import java.util.regex.Pattern;
30 |
31 | import works.cirno.mocha.InvokeContext;
32 | import works.cirno.mocha.InvokeTarget;
33 |
34 | /**
35 | *
36 | */
37 | public class RegexInvokeTargetResolver implements InvokeTargetResolver {
38 | private ArrayList targets = new ArrayList<>();
39 |
40 | @Override
41 | public InvokeTargetCriteria addServe(String uri, String method, InvokeTarget target) {
42 | InvokeTargetCriteria criteria = new InvokeTargetCriteria(uri, Pattern.compile(uri), method, target);
43 | targets.add(criteria);
44 | return criteria;
45 | }
46 |
47 | @Override
48 | public InvokeContext resolve(String uri, String method) {
49 | for (InvokeTargetCriteria criteria : targets) {
50 | Pattern pattern = criteria.getPattern();
51 | Matcher matcher = pattern.matcher(uri);
52 | if (matcher.matches() && (criteria.getMethod() == null || criteria.getMethod().equals(method))) {
53 | return new InvokeContext(criteria.getTarget(), matcher, Collections. emptySet());
54 | }
55 | }
56 | return null;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/prd/LongTreePrefixDict.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver.prd;
25 |
26 | /**
27 | *
28 | */
29 | public class LongTreePrefixDict extends TreePrefixDict implements PrefixDict {
30 |
31 | @Override
32 | protected TreePrefixDict createNode() {
33 | return new LongTreePrefixDict();
34 | }
35 |
36 | @Override
37 | protected int getNewSize(String prefix) {
38 | if (this.size == 0) {
39 | return prefix.length();
40 | }
41 |
42 | return Math.min(prefix.length(), size);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/prd/PrefixDict.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver.prd;
25 |
26 | import java.util.List;
27 |
28 | /**
29 | *
30 | */
31 | public interface PrefixDict {
32 | void add(String prefix, T value);
33 |
34 | List select(String string);
35 |
36 | List select(String string, List values);
37 | }
38 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/resolver/prd/TreePrefixDict.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.resolver.prd;
25 |
26 | import java.util.*;
27 |
28 | /**
29 | *
30 | */
31 | public class TreePrefixDict implements PrefixDict {
32 |
33 | protected HashMap> nodes = new HashMap<>();
34 | protected int size = 0;
35 | protected final ArrayList values = new ArrayList<>(4);
36 |
37 | protected TreePrefixDict createNode() {
38 | return new TreePrefixDict();
39 | }
40 |
41 | private void changeSize(int newSize) {
42 | assert newSize > 0;
43 | assert newSize < size;
44 | int diffSize = size - newSize;
45 | HashMap> newNodes = new HashMap<>();
46 | for (Map.Entry> entry : nodes.entrySet()) {
47 | String key = entry.getKey();
48 | String newKey1 = key.substring(0, newSize);
49 | String newKey2 = key.substring(newSize);
50 | TreePrefixDict node = newNodes.get(newKey1);
51 | if (node == null) {
52 | node = createNode();
53 | newNodes.put(newKey1, node);
54 | }
55 | node.size = diffSize;
56 | node.nodes.put(newKey2, entry.getValue());
57 | }
58 | this.nodes = newNodes;
59 | this.size = newSize;
60 | }
61 |
62 | protected int getNewSize(String prefix) {
63 | if (this.size == 0) {
64 | return prefix.length();
65 | } else {
66 | Set others = nodes.keySet();
67 | int cps = Math.min(prefix.length(), size);
68 | all:
69 | for (String other : others) {
70 | for (int i = 0; i < cps; i++) {
71 | if (prefix.charAt(i) != other.charAt(i)) {
72 | cps = i;
73 | if (cps == 0) {
74 | break all;
75 | } else {
76 | break;
77 | }
78 | }
79 | }
80 | }
81 | return Math.min(cps + 1, Math.min(prefix.length(), size));
82 | }
83 | }
84 |
85 | public void add(String prefix, T value) {
86 | if (prefix.length() == 0) {
87 | values.add(value);
88 | } else if (this.size == 0) {
89 | this.size = prefix.length();
90 | TreePrefixDict node = createNode();
91 | nodes.put(prefix, node);
92 | node.add("", value);
93 | } else {
94 | int newSize = getNewSize(prefix);
95 | if (newSize < size) {
96 | changeSize(newSize);
97 | }
98 | String key1 = prefix.substring(0, this.size);
99 | String key2 = prefix.substring(this.size);
100 | TreePrefixDict node = nodes.get(key1);
101 | if (node == null) {
102 | node = createNode();
103 | nodes.put(key1, node);
104 | }
105 | node.add(key2, value);
106 | }
107 | }
108 |
109 | public List select(String string) {
110 | return select(string, null);
111 | }
112 |
113 | public List select(String string, List values) {
114 | if (values == null) {
115 | values = new ArrayList<>();
116 | }
117 | values.addAll(this.values);
118 | int len = string.length();
119 | if (len >= size) {
120 | String prefix = string.substring(0, size);
121 | TreePrefixDict node = nodes.get(prefix);
122 | if (node != null) {
123 | string = string.substring(size);
124 | node.select(string, values);
125 | }
126 | }
127 | return values;
128 | }
129 |
130 | public void printNodes(int indent) {
131 | for (int i = 0; i < indent; i++) {
132 | System.out.print("\t");
133 | }
134 | System.out.println("\"\": " + values);
135 | for (Map.Entry> entry : nodes.entrySet()) {
136 | for (int i = 0; i < indent; i++) {
137 | System.out.print("\t");
138 | }
139 | System.out.println("\"" + entry.getKey() + "\":");
140 | entry.getValue().printNodes(indent + 1);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/result/CodeResultRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.result;
25 |
26 | import java.io.IOException;
27 |
28 | import javax.servlet.http.HttpServletResponse;
29 |
30 | import org.slf4j.Logger;
31 | import org.slf4j.LoggerFactory;
32 |
33 | import works.cirno.mocha.InvokeContext;
34 |
35 | /**
36 | *
37 | */
38 | public class CodeResultRenderer implements Renderer {
39 | private static Logger log = LoggerFactory.getLogger(CodeResultRenderer.class);
40 |
41 | private static final CodeResultRenderer instance = new CodeResultRenderer();
42 |
43 | public static CodeResultRenderer instance() {
44 | return instance;
45 | }
46 |
47 | @Override
48 | public boolean renderResult(InvokeContext ctx, Object resultObj) {
49 | HttpServletResponse resp = ctx.getResponse();
50 | if (resultObj instanceof Number) {
51 | try {
52 | resp.sendError(((Number) resultObj).intValue());
53 | } catch (IOException e) {
54 | log.warn("Can't send error to client", e);
55 | }
56 | return true;
57 | }
58 | return false;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/result/InputStreamResultRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.result;
25 |
26 | import java.io.IOException;
27 | import java.io.InputStream;
28 | import java.io.OutputStream;
29 |
30 | import javax.servlet.http.HttpServletResponse;
31 |
32 | import works.cirno.mocha.InvokeContext;
33 |
34 | public class InputStreamResultRenderer implements Renderer {
35 |
36 | @Override
37 | public boolean renderResult(InvokeContext ctx, Object resultObj) {
38 | HttpServletResponse resp = ctx.getResponse();
39 | if (resultObj instanceof InputStream) {
40 | try (InputStream is = (InputStream) resultObj; OutputStream os = resp.getOutputStream()) {
41 | byte[] buf = new byte[4096];
42 | int read;
43 | while ((read = is.read(buf)) >= 0) {
44 | os.write(buf, 0, read);
45 | }
46 | } catch (IOException e) {
47 | ctx.getTarget().log().error("Can't write stream to client", e);
48 | }
49 | return true;
50 | }
51 | return false;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/result/Renderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.result;
25 |
26 | import works.cirno.mocha.InvokeContext;
27 |
28 | public interface Renderer {
29 | boolean renderResult(InvokeContext ctx, Object resultObj);
30 | }
31 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/result/ResultType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.result;
25 |
26 | public enum ResultType {
27 | forward, redirect
28 | }
29 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/result/ServletResultRenderer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.result;
25 |
26 | import java.io.IOException;
27 | import java.util.AbstractMap.SimpleEntry;
28 | import java.util.Collections;
29 | import java.util.HashMap;
30 | import java.util.Map;
31 | import java.util.Map.Entry;
32 |
33 | import javax.servlet.ServletException;
34 | import javax.servlet.http.HttpServletRequest;
35 | import javax.servlet.http.HttpServletResponse;
36 |
37 | import works.cirno.mocha.InvokeContext;
38 |
39 | public class ServletResultRenderer implements Renderer {
40 |
41 | private HashMap> results = new HashMap<>();
42 |
43 | public void addResult(String name, ResultType type, String path) {
44 | if (name == null) {
45 | throw new NullPointerException("name");
46 | }
47 | results.put(name, new SimpleEntry(type, path));
48 | }
49 |
50 | public boolean renderResult(InvokeContext ctx, Object resultObj) {
51 | HttpServletRequest req = ctx.getRequest();
52 | HttpServletResponse resp = ctx.getResponse();
53 | try {
54 | String name;
55 | Iterable> attributes;
56 | if (resultObj instanceof String) {
57 | name = (String) resultObj;
58 | attributes = Collections.emptyList();
59 | } else if (resultObj instanceof View) {
60 | View view = (View) resultObj;
61 | name = view.getName();
62 | attributes = view.getAttributes();
63 | } else {
64 | return false;
65 | }
66 | Entry result = results.get(name);
67 | if (result != null) {
68 | ResultType type = result.getKey();
69 | String path = result.getValue();
70 | switch (type) {
71 | case forward:
72 | for (Map.Entry attribute : attributes) {
73 | req.setAttribute(attribute.getKey(), attribute.getValue());
74 | }
75 | req.getRequestDispatcher(path).forward(req, resp);
76 | return true;
77 | case redirect:
78 | resp.sendRedirect(path);
79 | return true;
80 | }
81 | }
82 | return false;
83 | } catch (ServletException | IOException e) {
84 | ctx.getTarget().handleException(ctx, e);
85 | return true;
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/mvc-core/src/main/java/works/cirno/mocha/result/View.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha.result;
25 |
26 | import java.util.HashMap;
27 | import java.util.Map.Entry;
28 |
29 | public class View {
30 | private String name;
31 | private HashMap attributes = new HashMap<>();
32 |
33 | public View(String name) {
34 | this.name = name;
35 | }
36 |
37 | public View attribute(String key, Object value) {
38 | attributes.put(key, value);
39 | return this;
40 | }
41 |
42 | public Object getAttribute(String key) {
43 | return attributes.get(key);
44 | }
45 |
46 | public String getName() {
47 | return name;
48 | }
49 |
50 | public Iterable> getAttributes() {
51 | return attributes.entrySet();
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/InvokeTargetResolverTest.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import works.cirno.mocha.InvokeContext;
7 | import works.cirno.mocha.resolver.InvokeTargetResolver;
8 | import works.cirno.mocha.resolver.PrefixDictInvokeTargetResolver;
9 | import works.cirno.mocha.resolver.RegexInvokeTargetResolver;
10 |
11 | import java.io.BufferedReader;
12 | import java.io.IOException;
13 | import java.io.InputStream;
14 | import java.io.InputStreamReader;
15 | import java.nio.charset.Charset;
16 | import java.util.Collection;
17 | import java.util.Properties;
18 | import java.util.concurrent.ThreadLocalRandom;
19 |
20 | /**
21 | *
22 | */
23 | public class InvokeTargetResolverTest {
24 |
25 | private long doBenchmark(InvokeTargetResolver resolver, Collection keys) {
26 | long ret = 0;
27 | long begin = System.nanoTime();
28 | for (String key : keys) {
29 | int hash = resolver.resolve(key, "GET").hashCode();
30 | ret += hash;
31 | }
32 | long dur = System.nanoTime() - begin;
33 | if (ThreadLocalRandom.current().nextInt(100000) == 1) {
34 | System.out.println("Please ignore: " + ret);
35 | }
36 | return dur;
37 | }
38 |
39 | public void doTest(InvokeTargetResolver resolver) {
40 |
41 | try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/uris.list"), Charset.forName("utf-8")))) {
42 | String line;
43 | while ((line = br.readLine()) != null) {
44 | line = line.trim();
45 | if (line.length() > 0) {
46 | resolver.addServe(line, "GET", new MockInvokeTarget(line));
47 | }
48 | }
49 | } catch (IOException e) {
50 | throw new RuntimeException(e);
51 | }
52 |
53 | Properties p = new Properties();
54 | try (InputStream testIs = getClass().getResourceAsStream("/uritest.properties")) {
55 | p.load(testIs);
56 | } catch (IOException e) {
57 | throw new RuntimeException(e);
58 | }
59 |
60 | for (String key : p.stringPropertyNames()) {
61 | InvokeContext ctx = resolver.resolve(key, "GET");
62 | MockInvokeTarget target = (MockInvokeTarget) ctx.getTarget();
63 | String[] expected = p.getProperty(key).split(",");
64 | Assert.assertEquals(target.getTestData(), expected[0]);
65 | if (expected.length == 1) {
66 | // Assert.assertNull(ctx.getUriMatcher());
67 | } else {
68 | for (int i = 1, max = expected.length; i < max; i++) {
69 | int idx = expected[i].indexOf('=');
70 | if (idx < 0) {
71 | throw new IllegalArgumentException("Illegal test descriptor line: " + key + "=" + p.getProperty(key));
72 | }
73 | String ek = expected[i].substring(0, idx);
74 | String ev = expected[i].substring(idx + 1);
75 | Assert.assertEquals(ev, ctx.getUriMatcher().group(ek));
76 | }
77 | }
78 | }
79 |
80 | long total = 0;
81 | for (int i = 0; i < 50; i++) {
82 | long dur = doBenchmark(resolver, p.stringPropertyNames());
83 | if (i > 39) {
84 | total += dur;
85 | }
86 | }
87 | System.out.println(resolver.getClass().getName() + ": " + (p.stringPropertyNames().size() * 20) + " / " + p.stringPropertyNames().size() + " uris resolved in " + (total / 1000000.0) + "ms");
88 | }
89 |
90 | @Test
91 | public void testRegexInvokeTargetResolver() {
92 | doTest(new RegexInvokeTargetResolver());
93 | }
94 |
95 | @Test
96 | public void testPrefixedInvokeTargetResolver() {
97 | doTest(new PrefixDictInvokeTargetResolver());
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/MockInvokeTarget.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha;
2 |
3 | import works.cirno.mocha.InvokeTarget;
4 | import works.cirno.mocha.parameter.name.ASMTestController;
5 |
6 | /**
7 | *
8 | */
9 | public class MockInvokeTarget extends InvokeTarget {
10 |
11 | private String testData;
12 |
13 | public MockInvokeTarget(String testData) {
14 | super(null, new ASMTestController(), "method1");
15 | this.testData = testData;
16 | }
17 |
18 | public String getTestData() {
19 | return testData;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/parameter/name/ASMParameterAnalyzerTest.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha.parameter.name;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import works.cirno.mocha.InvokeTarget;
7 | import works.cirno.mocha.parameter.name.ASMParameterAnalyzer;
8 | import works.cirno.mocha.parameter.name.Parameter;
9 |
10 | /**
11 | *
12 | */
13 | public class ASMParameterAnalyzerTest {
14 |
15 | private ThreadLocal analyzer = new ThreadLocal() {
16 | @Override
17 | protected ASMParameterAnalyzer initialValue() {
18 | return new ASMParameterAnalyzer();
19 | }
20 | };
21 |
22 | @Test
23 | public void testNamedArguments1() throws Exception {
24 | ASMParameterAnalyzer analyzer = this.analyzer.get();
25 | Class> controllerClass = ASMTestController.class;
26 | Object controller = controllerClass.newInstance();
27 |
28 | InvokeTarget target = new InvokeTarget(null, controller, "method1");
29 | Parameter[] parameters = analyzer.getParameters(target);
30 | Assert.assertEquals(0, parameters.length);
31 | }
32 |
33 | @Test
34 | public void testNamedArguments2() throws Exception {
35 | ASMParameterAnalyzer analyzer = this.analyzer.get();
36 | Class> controllerClass = ASMTestController.class;
37 | Object controller = controllerClass.newInstance();
38 |
39 | InvokeTarget target = new InvokeTarget(null, controller, "method2");
40 | Parameter[] parameters = analyzer.getParameters(target);
41 |
42 | Assert.assertEquals(3, parameters.length);
43 | Assert.assertEquals("name", parameters[0].getName());
44 | Assert.assertEquals("id", parameters[1].getName());
45 | Assert.assertEquals("uuid", parameters[2].getName());
46 | }
47 |
48 | @Test
49 | public void testNamedArguments3() throws Exception {
50 | ASMParameterAnalyzer analyzer = this.analyzer.get();
51 | Class> controllerClass = ASMTestController.class;
52 | Object controller = controllerClass.newInstance();
53 |
54 | InvokeTarget target = new InvokeTarget(null, controller, "method3");
55 | Parameter[] parameters = analyzer.getParameters(target);
56 |
57 | Assert.assertEquals(3, parameters.length);
58 | Assert.assertEquals("name", parameters[0].getName());
59 | Assert.assertEquals("id", parameters[1].getName());
60 | Assert.assertEquals("uuid", parameters[2].getName());
61 | }
62 |
63 | @Test
64 | public void testNamedArguments4() throws Exception {
65 | ASMParameterAnalyzer analyzer = this.analyzer.get();
66 | Class> controllerClass = ASMTestController.class;
67 | Object controller = controllerClass.newInstance();
68 |
69 | InvokeTarget target = new InvokeTarget(null, controller, "method4");
70 | Parameter[] parameters = analyzer.getParameters(target);
71 |
72 | Assert.assertEquals(3, parameters.length);
73 | Assert.assertEquals("name", parameters[0].getName());
74 | Assert.assertEquals("id", parameters[1].getName());
75 | Assert.assertEquals("uuid", parameters[2].getName());
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/parameter/name/ASMTestController.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha.parameter.name;
2 |
3 | /**
4 | *
5 | */
6 | public class ASMTestController {
7 | public void methodD() {
8 |
9 | }
10 |
11 | public void methodD(String arg) {
12 |
13 | }
14 |
15 | public void method1() {
16 |
17 | }
18 |
19 | public String method2(String name, Integer id, String uuid) {
20 | return name + id;
21 | }
22 |
23 | public String method3(String name, Integer id, String uuid) {
24 | {
25 | Integer j = name.hashCode() + id + uuid.hashCode();
26 | id = j;
27 | }
28 |
29 | Integer i = 15;
30 | return i + "a";
31 | }
32 |
33 | public String method4(String name, Integer id, String uuid) {
34 | return 1 + uuid;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/parameter/name/AnnotationParameterAnalyzerTest.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha.parameter.name;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import works.cirno.mocha.InvokeTarget;
7 |
8 | /**
9 | *
10 | */
11 | public class AnnotationParameterAnalyzerTest {
12 |
13 | private ThreadLocal analyzer = new ThreadLocal() {
14 | @Override
15 | protected AnnotationParameterAnalyzer initialValue() {
16 | return new AnnotationParameterAnalyzer();
17 | }
18 | };
19 |
20 | @Test
21 | public void testNamedArguments1() throws Exception {
22 | AnnotationParameterAnalyzer analyzer = this.analyzer.get();
23 | Class> controllerClass = TestController.class;
24 | Object controller = controllerClass.newInstance();
25 |
26 | InvokeTarget target = new InvokeTarget(null, controller, "method1");
27 | Parameter[] parameters = analyzer.getParameters(target);
28 | Assert.assertEquals(0, parameters.length);
29 | }
30 |
31 | @Test
32 | public void testNamedArguments2() throws Exception {
33 | AnnotationParameterAnalyzer analyzer = this.analyzer.get();
34 | Class> controllerClass = TestController.class;
35 | Object controller = controllerClass.newInstance();
36 |
37 | InvokeTarget target = new InvokeTarget(null, controller, "method2");
38 | Parameter[] parameters = analyzer.getParameters(target);
39 |
40 | Assert.assertEquals(3, parameters.length);
41 | Assert.assertEquals("name", parameters[0].getName());
42 | Assert.assertEquals("id", parameters[1].getName());
43 | Assert.assertEquals("uuid", parameters[2].getName());
44 | }
45 |
46 | @Test
47 | public void testNamedArguments3() throws Exception {
48 | AnnotationParameterAnalyzer analyzer = this.analyzer.get();
49 | Class> controllerClass = TestController.class;
50 | Object controller = controllerClass.newInstance();
51 |
52 | InvokeTarget target = new InvokeTarget(null, controller, "method3");
53 | Parameter[] parameters = analyzer.getParameters(target);
54 |
55 | Assert.assertEquals(3, parameters.length);
56 | Assert.assertEquals("name", parameters[0].getName());
57 | Assert.assertEquals("id", parameters[1].getName());
58 | Assert.assertEquals("uuid", parameters[2].getName());
59 | }
60 |
61 | @Test
62 | public void testNamedArguments4() throws Exception {
63 | AnnotationParameterAnalyzer analyzer = this.analyzer.get();
64 | Class> controllerClass = TestController.class;
65 | Object controller = controllerClass.newInstance();
66 |
67 | InvokeTarget target = new InvokeTarget(null, controller, "method4");
68 | Parameter[] parameters = analyzer.getParameters(target);
69 |
70 | Assert.assertEquals(3, parameters.length);
71 | Assert.assertEquals("name", parameters[0].getName());
72 | Assert.assertEquals("id", parameters[1].getName());
73 | Assert.assertEquals("uuid", parameters[2].getName());
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/parameter/name/TestController.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha.parameter.name;
2 |
3 | import works.cirno.mocha.parameter.name.NamedParam;
4 |
5 | /**
6 | *
7 | */
8 | public class TestController {
9 | public void methodD() {
10 |
11 | }
12 |
13 | public void methodD(@NamedParam("arg") String arg) {
14 |
15 | }
16 |
17 | public void method1() {
18 |
19 | }
20 |
21 | public String method2(@NamedParam("name") String name, @NamedParam("id") Integer id, @NamedParam("uuid") String uuid) {
22 | return name + id;
23 | }
24 |
25 | public String method3(@NamedParam("name") String name, @NamedParam("id") Integer id, @NamedParam("uuid") String uuid) {
26 | {
27 | Integer j = name.hashCode() + id + uuid.hashCode();
28 | id = j;
29 | }
30 |
31 | Integer i = 15;
32 | return i + "a";
33 | }
34 |
35 | public String method4(@NamedParam("name") String name, @NamedParam("id") Integer id, @NamedParam("uuid") String uuid) {
36 | return 1 + uuid;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/mvc-core/src/test/java/works/cirno/mocha/resolver/prd/TreePrefixDictTest.java:
--------------------------------------------------------------------------------
1 | package works.cirno.mocha.resolver.prd;
2 |
3 | import org.junit.Assert;
4 | import org.junit.Test;
5 |
6 | import works.cirno.mocha.resolver.prd.LongTreePrefixDict;
7 | import works.cirno.mocha.resolver.prd.TreePrefixDict;
8 |
9 | /**
10 | *
11 | */
12 |
13 | public class TreePrefixDictTest {
14 |
15 | private void add(TreePrefixDict prd, String prefix) {
16 | prd.add(prefix, prefix);
17 | }
18 |
19 | private void testDict(TreePrefixDict prd) {
20 | System.out.println("Testing " + prd.getClass().getName());
21 | add(prd, "/json/user/manage");
22 | add(prd, "/json/user/manage/");
23 | add(prd, "/json/user/manage/add");
24 | add(prd, "/json/user/manage/add/1");
25 | add(prd, "/json/user/manage/add/2");
26 | add(prd, "/json/user/manage/add/3");
27 | add(prd, "/json/user/manage/delete");
28 | add(prd, "/json/user/manage/modify");
29 | add(prd, "/json/user");
30 | add(prd, "/json/unit");
31 | add(prd, "/json/unit/manage");
32 | add(prd, "/");
33 | add(prd, "/login");
34 | add(prd, "/login.do");
35 | add(prd, "aaaaaab");
36 | add(prd, "aaaaaac");
37 | add(prd, "aaaaaad");
38 | add(prd, "abaaaab");
39 | add(prd, "abaaaac");
40 | add(prd, "abaaaad");
41 | prd.printNodes(0);
42 | add(prd, "aaaa");
43 | add(prd, "aa");
44 | prd.printNodes(0);
45 |
46 | java.util.List var = prd.select("/login");
47 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"/", "/login"});
48 | var = prd.select("/login.do");
49 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"/", "/login", "/login.do"});
50 |
51 | var = prd.select("/json/user/manage/add");
52 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"/", "/json/user", "/json/user/manage", "/json/user/manage/", "/json/user/manage/add"});
53 | var = prd.select("/json/user/manage/45");
54 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"/", "/json/user", "/json/user/manage", "/json/user/manage/"});
55 | var = prd.select("/json/user/manage/add/45");
56 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"/", "/json/user", "/json/user/manage", "/json/user/manage/", "/json/user/manage/add"});
57 | var = prd.select("/json/user/manage/delete/45");
58 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"/", "/json/user", "/json/user/manage", "/json/user/manage/", "/json/user/manage/delete"});
59 | var = prd.select("aaaaaac");
60 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"aa", "aaaa", "aaaaaac"});
61 | var = prd.select("abaaaac");
62 | Assert.assertArrayEquals(var.toArray(new String[var.size()]), new String[]{"abaaaac"});
63 | }
64 |
65 | @Test
66 | public void testPrefixReverseDict() {
67 | TreePrefixDict prd = new TreePrefixDict<>();
68 | testDict(prd);
69 | }
70 |
71 | @Test
72 | public void testLongPrefixDict() {
73 | LongTreePrefixDict prd = new LongTreePrefixDict<>();
74 | testDict(prd);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/mvc-core/src/test/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | # Root logger option
2 | log4j.rootLogger=DEBUG, stdout
3 |
4 | # Direct log messages to stdout
5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
6 | log4j.appender.stdout.Target=System.out
7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
9 |
--------------------------------------------------------------------------------
/mvc-core/src/test/resources/uris.list:
--------------------------------------------------------------------------------
1 | /api/contactlist
2 | /api/contactdetail
3 | /api/contactsInfo
4 | /api/projectlist
5 | /api/foundchatlist
6 | /api/chatlist
7 | /api/chatattr
8 | /api/chatgrouplist
9 | /api/chatNameIcon
10 | /api/symposiumSign
11 | /api/updateTopicRemind
12 | /api/pns
13 | /api/timesync
14 | /api/check4updates
15 | /api/userhead
16 | /api/topichead
17 | /api/roomhead
18 | /api/grouplist
19 | /api/feedback
20 | /api/topichistory
21 | /copyright
22 | /api/pushMessage
23 | /api/push/notify
24 | /tapi/clearCache/(?.*?)
25 | /api/web/login
26 | /api/web/messages
27 | /api/web/messagesBy
28 | /api/web/messagesp2p/(?.*?)
29 | /api/web/userhead/i/(?.*?)
30 | /api/web/userhead/t/(?.*?)
31 | /api/web/topichead/(?.*?)/(?.*?)
32 | /mail/attachment/(?.*?)
33 | /tapi/topic/create
34 | /tapi/topic/update
35 | /tapi/topic/history
36 | /tapi/topic/group/create
37 | /tapi/topic/group/update
38 | /account
39 | /api/easterEgg
40 | /api/web/getJFToken
41 | /api/web/ssoLogout
42 | /api/web/validateJFToken
43 | /api/web/getRefreshToken
44 | /api/web/log
45 | /img/upload
46 | /img64/upload
47 | /img/download
48 | /img/grapeupload
49 | /img/i/(?.*?)/get
50 | /img/i/(?.*?)/upload
51 | /img/t/(?.*?)/get
52 | /img/t/(?.*?)/upload
53 | /app/upload
54 | /app/beta/upload
55 | /
56 | /app
57 | /app/beta
58 | /app/fix
59 | /ios/(?.*?)
60 | /android
61 | /iosBeta/(?.*?)
62 | /androidBeta
63 | /api/fileUpload
64 | /api/fileDownload
65 | /iosDownload
66 | /androidDownload
67 | /admin/init/group
68 | /admin/init/groupTopic
69 | /api/fav/mock/store
70 | /api/fav/list/(?.*?)/(?.*?)
71 | /api/fav/get/(?.*?)/(?.*?)
72 | /api/fav/remove
73 | /api/fav/quota/(?.*?)
74 | /api/fav/store
75 | /api/fav/template
76 | /api/fav/template/list
77 | /api/fav/template/show
78 | /api/fav/template/save
79 | /api/fav/template/edit/(?.*?)
80 | /api/fav/template/update
81 | /api/fav/template/delete/(?.*?)
82 | /api/fav/template/reload
83 | /bbs/rooms
84 | /bbs/forward
85 | /bbs/roomhead
86 | /kf/choose
87 | /kf/close
88 | /api/kf/choose
89 | /api/config/user/set
90 | /api/config/user/list
91 | /api/config/global/list
92 | /config/global
93 | /config/global/update
94 | /config/cmd/send
95 | /tapi/topic/history/count
96 | /tapi/topic/chatinfo
--------------------------------------------------------------------------------
/mvc-core/src/test/resources/uritest.properties:
--------------------------------------------------------------------------------
1 | /api/contactlist=/api/contactlist
2 | /api/contactdetail=/api/contactdetail
3 | /api/contactsInfo=/api/contactsInfo
4 | /api/projectlist=/api/projectlist
5 | /api/foundchatlist=/api/foundchatlist
6 | /api/chatlist=/api/chatlist
7 | /api/chatattr=/api/chatattr
8 | /api/chatgrouplist=/api/chatgrouplist
9 | /api/chatNameIcon=/api/chatNameIcon
10 | /api/symposiumSign=/api/symposiumSign
11 | /api/updateTopicRemind=/api/updateTopicRemind
12 | /api/pns=/api/pns
13 | /api/timesync=/api/timesync
14 | /api/check4updates=/api/check4updates
15 | /api/userhead=/api/userhead
16 | /api/topichead=/api/topichead
17 | /api/roomhead=/api/roomhead
18 | /api/grouplist=/api/grouplist
19 | /api/feedback=/api/feedback
20 | /api/topichistory=/api/topichistory
21 | /copyright=/copyright
22 | /api/pushMessage=/api/pushMessage
23 | /api/push/notify=/api/push/notify
24 | /tapi/clearCache/1=/tapi/clearCache/(?.*?),type=1
25 | /api/web/login=/api/web/login
26 | /api/web/messages=/api/web/messages
27 | /api/web/messagesBy=/api/web/messagesBy
28 | /api/web/messagesp2p/abbabab=/api/web/messagesp2p/(?.*?),sender=abbabab
29 | /api/web/userhead/i/abbabab=/api/web/userhead/i/(?.*?),personId=abbabab
30 | /api/web/userhead/t/abbabab=/api/web/userhead/t/(?.*?),personId=abbabab
31 | /api/web/topichead/abbabab/abc=/api/web/topichead/(?.*?)/(?.*?),roomType=abbabab,roomJid=abc
32 | /mail/attachment/kkkkpptt=/mail/attachment/(?.*?),key=kkkkpptt
33 | /tapi/topic/create=/tapi/topic/create
34 | /tapi/topic/update=/tapi/topic/update
35 | /tapi/topic/history=/tapi/topic/history
36 | /tapi/topic/group/create=/tapi/topic/group/create
37 | /tapi/topic/group/update=/tapi/topic/group/update
38 | /account=/account
39 | /api/easterEgg=/api/easterEgg
40 | /api/web/getJFToken=/api/web/getJFToken
41 | /api/web/ssoLogout=/api/web/ssoLogout
42 | /api/web/validateJFToken=/api/web/validateJFToken
43 | /api/web/getRefreshToken=/api/web/getRefreshToken
44 | /api/web/log=/api/web/log
45 | /img/upload=/img/upload
46 | /img64/upload=/img64/upload
47 | /img/download=/img/download
48 | /img/grapeupload=/img/grapeupload
49 | /img/i/1.png/get=/img/i/(?.*?)/get,filename=1.png
50 | /img/i/1.png/upload=/img/i/(?.*?)/upload,filename=1.png
51 | /img/t/1.png/get=/img/t/(?.*?)/get,filename=1.png
52 | /img/t/1.png/upload=/img/t/(?.*?)/upload,filename=1.png
53 | /app/upload=/app/upload
54 | /app/beta/upload=/app/beta/upload
55 | /=/
56 | /app=/app
57 | /app/beta=/app/beta
58 | /app/fix=/app/fix
59 | /ios/sku.plist=/ios/(?.*?),filename=sku.plist
60 | /android=/android
61 | /iosBeta/skub.plist=/iosBeta/(?.*?),filename=skub.plist
62 | /androidBeta=/androidBeta
63 | /api/fileUpload=/api/fileUpload
64 | /api/fileDownload=/api/fileDownload
65 | /iosDownload=/iosDownload
66 | /androidDownload=/androidDownload
67 | /admin/init/group=/admin/init/group
68 | /admin/init/groupTopic=/admin/init/groupTopic
69 | /api/fav/mock/store=/api/fav/mock/store
70 | /api/fav/list/1234/aaa=/api/fav/list/(?.*?)/(?.*?),timestamp=1234,jid=aaa
71 | /api/fav/get/15/67=/api/fav/get/(?.*?)/(?.*?),id=15,jid=67
72 | /api/fav/remove=/api/fav/remove
73 | /api/fav/quota/abcd=/api/fav/quota/(?.*?),jid=abcd
74 | /api/fav/store=/api/fav/store
75 | /api/fav/template=/api/fav/template
76 | /api/fav/template/list=/api/fav/template/list
77 | /api/fav/template/show=/api/fav/template/show
78 | /api/fav/template/save=/api/fav/template/save
79 | /api/fav/template/edit/123=/api/fav/template/edit/(?.*?),id=123
80 | /api/fav/template/update=/api/fav/template/update
81 | /api/fav/template/delete/566788=/api/fav/template/delete/(?.*?),ids=566788
82 | /api/fav/template/reload=/api/fav/template/reload
83 | /bbs/rooms=/bbs/rooms
84 | /bbs/forward=/bbs/forward
85 | /bbs/roomhead=/bbs/roomhead
86 | /kf/choose=/kf/choose
87 | /kf/close=/kf/close
88 | /api/kf/choose=/api/kf/choose
89 | /api/config/user/set=/api/config/user/set
90 | /api/config/user/list=/api/config/user/list
91 | /api/config/global/list=/api/config/global/list
92 | /config/global=/config/global
93 | /config/global/update=/config/global/update
94 | /config/cmd/send=/config/cmd/send
95 | /tapi/topic/history/count=/tapi/topic/history/count
96 | /tapi/topic/chatinfo=/tapi/topic/chatinfo
--------------------------------------------------------------------------------
/mvc-inject-guice/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/mvc-inject-guice/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | works.cirno.mocha
6 | mvc
7 | 0.1-SNAPSHOT
8 |
9 | mvc-inject-guice
10 | Mocha MVC injector-bridge for guice
11 |
12 |
13 |
14 | works.cirno.mocha
15 | mvc-core
16 | ${project.version}
17 |
18 |
19 |
20 | javax.servlet
21 | javax.servlet-api
22 | 3.0.1
23 | provided
24 |
25 |
26 |
27 | javax.inject
28 | javax.inject
29 | 1
30 |
31 |
32 | com.google.inject
33 | guice
34 | 3.0
35 |
36 |
37 | com.google.inject.extensions
38 | guice-servlet
39 | 3.0
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/mvc-inject-guice/src/main/java/works/cirno/mocha/GuiceMVCFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import javax.inject.Inject;
27 | import javax.inject.Singleton;
28 |
29 | import com.google.inject.Injector;
30 | import com.google.inject.Key;
31 | import com.google.inject.name.Names;
32 |
33 | @Singleton
34 | public class GuiceMVCFactory implements ObjectFactory {
35 |
36 | @Inject
37 | private Injector injector;
38 |
39 | void setInjector(Injector injector) {
40 | this.injector = injector;
41 | }
42 |
43 | @Override
44 | public T getInstance(TypeOrInstance param) {
45 | switch (param.getInjectBy()) {
46 | case INSTANCE:
47 | return param.getInstance();
48 | case NAME_TYPE:
49 | return injector.getInstance(Key.get(param.getType(), Names.named(param.getName())));
50 | case TYPE:
51 | return injector.getInstance(param.getType());
52 | }
53 | throw new UnsupportedOperationException("Unknown injection type " + param.getInjectBy());
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/mvc-inject-guice/src/main/java/works/cirno/mocha/GuicedDispatcherFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import javax.inject.Inject;
27 |
28 | import com.google.inject.Injector;
29 |
30 | import works.cirno.mocha.DispatcherFilter;
31 | import works.cirno.mocha.ObjectFactory;
32 |
33 | public class GuicedDispatcherFilter extends DispatcherFilter {
34 |
35 | @Inject
36 | private Injector injector;
37 |
38 | @Override
39 | protected ObjectFactory getMVCFactory() {
40 | if (injector == null) {
41 | // not configured in guice servlet, will try fetch injector from
42 | // servlet context
43 | final String INJECTOR_NAME = Injector.class.getName();
44 | injector = (Injector) servletContext.getAttribute(INJECTOR_NAME);
45 | }
46 |
47 | if (injector == null) {
48 | throw new IllegalStateException("Can't find guice injector.");
49 | }
50 | GuiceMVCFactory factory = new GuiceMVCFactory();
51 | factory.setInjector(injector);
52 | return factory;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/mvc-inject-guice/src/main/java/works/cirno/mocha/GuicedDispatcherServlet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import javax.inject.Inject;
27 |
28 | import com.google.inject.Injector;
29 |
30 | import works.cirno.mocha.DispatcherServlet;
31 | import works.cirno.mocha.ObjectFactory;
32 |
33 | public class GuicedDispatcherServlet extends DispatcherServlet {
34 |
35 | @Inject
36 | private Injector injector;
37 |
38 | @Override
39 | protected ObjectFactory getMVCFactory() {
40 | if (injector == null) {
41 | // not configured in guice servlet, will try fetch injector from
42 | // servlet context
43 | final String INJECTOR_NAME = Injector.class.getName();
44 | injector = (Injector) servletContext.getAttribute(INJECTOR_NAME);
45 | }
46 |
47 | if (injector == null) {
48 | throw new IllegalStateException("Can't find guice injector.");
49 | }
50 | GuiceMVCFactory factory = new GuiceMVCFactory();
51 | factory.setInjector(injector);
52 | return factory;
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/mvc-inject-spring/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/mvc-inject-spring/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | works.cirno.mocha
6 | mvc
7 | 0.1-SNAPSHOT
8 |
9 | mvc-inject-spring
10 | Mocha MVC injector-bridge for spring
11 |
12 |
13 |
14 | works.cirno.mocha
15 | mvc-core
16 | ${project.version}
17 |
18 |
19 |
20 | javax.servlet
21 | javax.servlet-api
22 | 3.0.1
23 | provided
24 |
25 |
26 |
27 | javax.inject
28 | javax.inject
29 | 1
30 |
31 |
32 | org.springframework
33 | spring-context-support
34 | 3.0.0.RELEASE
35 |
36 |
37 | org.springframework
38 | spring-web
39 | 3.0.0.RELEASE
40 | true
41 |
42 |
43 |
--------------------------------------------------------------------------------
/mvc-inject-spring/src/main/java/works/cirno/mocha/SpringDispatcherFilter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import org.springframework.context.ApplicationContext;
27 | import org.springframework.web.context.support.WebApplicationContextUtils;
28 |
29 | import works.cirno.mocha.DispatcherFilter;
30 | import works.cirno.mocha.ObjectFactory;
31 |
32 | public class SpringDispatcherFilter extends DispatcherFilter {
33 |
34 | @Override
35 | protected ObjectFactory getMVCFactory() {
36 | ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
37 | return SpringMVCFactory.fromCustomApplicationContext(ctx);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/mvc-inject-spring/src/main/java/works/cirno/mocha/SpringMVCFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2014-2015 Cloudee Huang ( https://github.com/cloudeecn / cloudeecn@gmail.com )
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package works.cirno.mocha;
25 |
26 | import java.util.concurrent.ConcurrentHashMap;
27 |
28 | import javax.inject.Named;
29 | import javax.inject.Singleton;
30 |
31 | import org.slf4j.Logger;
32 | import org.slf4j.LoggerFactory;
33 | import org.springframework.beans.BeansException;
34 | import org.springframework.beans.factory.NoSuchBeanDefinitionException;
35 | import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
36 | import org.springframework.context.ApplicationContext;
37 | import org.springframework.context.ApplicationContextAware;
38 | import org.springframework.web.context.support.SpringBeanAutowiringSupport;
39 |
40 | @Named
41 | @Singleton
42 | public class SpringMVCFactory implements ObjectFactory, ApplicationContextAware {
43 | private static final Logger log = LoggerFactory.getLogger(SpringMVCFactory.class);
44 | private ApplicationContext applicationContext;
45 |
46 | private ConcurrentHashMap, Object> unmanagedBeans = new ConcurrentHashMap<>(4);
47 |
48 | AutowiredAnnotationBeanPostProcessor processer;
49 |
50 | @Override
51 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
52 | this.applicationContext = applicationContext;
53 | processer = new AutowiredAnnotationBeanPostProcessor();
54 | processer.setBeanFactory(applicationContext.getAutowireCapableBeanFactory());
55 | }
56 |
57 | public static ObjectFactory fromCustomApplicationContext(ApplicationContext ac) {
58 | ObjectFactory factory;
59 | try {
60 | factory = ac.getBean(SpringMVCFactory.class);
61 | log.info("SpringObjectFactory got from application context");
62 | } catch (NoSuchBeanDefinitionException e) {
63 | factory = ac.getAutowireCapableBeanFactory().createBean(SpringMVCFactory.class);
64 | log.info("SpringObjectFactory created");
65 | }
66 | return factory;
67 | }
68 |
69 | @Override
70 | public T getInstance(TypeOrInstance param) {
71 | switch (param.getInjectBy()) {
72 | case INSTANCE:
73 | return param.getInstance();
74 | case NAME_TYPE:
75 | return applicationContext.getBean(param.getName(), param.getType());
76 | case TYPE:
77 | try {
78 | return applicationContext.getBean(param.getType());
79 | } catch (NoSuchBeanDefinitionException e) {
80 | Class extends T> type = param.getType();
81 |
82 | @SuppressWarnings("unchecked")
83 | T result = (T) unmanagedBeans.get(type);
84 | if (result == null) {
85 | log.warn("Can't find bean for type {} will manage bean as singleton", type);
86 | try {
87 | result = type.newInstance();
88 | } catch (InstantiationException | IllegalAccessException e1) {
89 | log.error("Can't instantiate {}.", type.getName(), e1);
90 | throw new NoSuchBeanDefinitionException(type);
91 | }
92 | processer.processInjection(result);
93 | unmanagedBeans.put(type, result);
94 | }
95 | return result;
96 | }
97 | }
98 | throw new UnsupportedOperationException("Unknown injection type " + param.getInjectBy());
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | works.cirno.mocha
5 | mvc
6 | pom
7 | 0.1-SNAPSHOT
8 | Mocha MVC
9 | https://github.com/cloudee/mocha-mvc/
10 |
11 | scm:git:git@github.com:cloudeecn/mocha-mvc.git
12 | https://github.com/cloudeecn/mocha-mvc/
13 | HEAD
14 |
15 |
16 | UTF-8
17 |
18 |
19 |
20 |
21 |
22 | org.apache.maven.plugins
23 | maven-compiler-plugin
24 | 3.3
25 |
26 | 1.7
27 | 1.7
28 |
29 |
30 |
31 |
32 |
33 |
34 | mvc-core
35 | mvc-inject-spring
36 | mvc-inject-guice
37 | example
38 |
39 |
40 |
41 | junit
42 | junit
43 | 4.12
44 | test
45 |
46 |
47 | org.slf4j
48 | slf4j-log4j12
49 | 1.7.12
50 | test
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------