1
2
3
4
5
6
7
8
9
10
11
12
13 package org.abstracthorizon.danube.beanconsole;
14
15 import org.abstracthorizon.danube.connection.Connection;
16 import org.abstracthorizon.danube.http.HTTPConnection;
17 import org.abstracthorizon.danube.mvc.Controller;
18 import org.abstracthorizon.danube.mvc.ModelAndView;
19
20 import java.beans.MethodDescriptor;
21 import java.beans.PropertyEditor;
22 import java.beans.PropertyEditorManager;
23 import java.io.UnsupportedEncodingException;
24 import java.lang.reflect.Method;
25 import java.net.URLDecoder;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import org.springframework.context.ConfigurableApplicationContext;
32
33
34
35
36
37
38 public class InvokeController implements Controller {
39
40 protected DisplayController displayController;
41
42
43
44
45 public InvokeController() {
46 }
47
48
49
50
51
52 public InvokeController(DisplayController displayController) {
53 this.displayController = displayController;
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public ModelAndView handleRequest(Connection connection) {
81 HTTPConnection httpConnection = (HTTPConnection)connection.adapt(HTTPConnection.class);
82
83 Map<String, Object> model = new HashMap<String, Object>();
84
85 model.put("connection", connection);
86
87 String resourcePath = BeanHelper.createResourcePath(httpConnection.getComponentResourcePath());
88
89 Object current = displayController.getRootObject();
90
91 String methodName;
92 if (resourcePath.length() == 0) {
93 methodName = null;
94 } else {
95 int i = resourcePath.lastIndexOf('/');
96 if (i > 0) {
97 methodName = resourcePath.substring(i+1);
98 resourcePath = resourcePath.substring(0, i);
99 } else {
100 methodName = resourcePath.substring(1);
101 resourcePath = "";
102 }
103 }
104
105 if (resourcePath.length() > 0) {
106 current = BeanHelper.navigate(current, resourcePath);
107 }
108 model.put("name", BeanHelper.createName(resourcePath));
109 model.put("path", BeanHelper.createPath(resourcePath));
110 model.put("type", BeanHelper.toTypeString(current));
111 model.put("resourcePath", resourcePath);
112 model.put("current", current);
113 model.put("methodName", BeanHelper.createName(resourcePath));
114
115 execute(model, current, httpConnection, methodName);
116
117 model.put("returnUri", httpConnection.getContextPath() + displayController.getComponentPath() + resourcePath);
118
119 String accept = httpConnection.getRequestHeaders().getOnly("Accept");
120 String view = null;
121 if (accept != null) {
122 if (accept.indexOf("text/html") >= 0) {
123 view = "html/result";
124 } else if (accept.indexOf("text/xml") >= 0) {
125 view = "xml/result";
126 }
127 }
128 if (view == null) {
129 view = "text/result";
130 }
131
132 ModelAndView modelAndView = new ModelAndView(view, model);
133 return modelAndView;
134 }
135
136
137
138
139
140
141
142
143 protected void execute(Map<String, Object> model, Object current, HTTPConnection httpConnection, String methodName) {
144 if (methodName == null) {
145 model.put("error", "Method name not specified.");
146 return;
147 }
148
149 int paramNumber = 0;
150 while (httpConnection.getRequestParameters().getOnly(Integer.toString(paramNumber)) != null) {
151 paramNumber = paramNumber + 1;
152 }
153
154 Method[] methods = current.getClass().getMethods();
155 ArrayList<Method> foundMethods = new ArrayList<Method>();
156 for (Method method : methods) {
157 if (method.getName().equals(methodName) && (method.getParameterTypes().length == paramNumber)) {
158 foundMethods.add(method);
159 }
160 }
161 if (foundMethods.size() == 0) {
162 model.put("error", "Couldn't find method '" + methodName +"' that has " + paramNumber +" parameters.");
163 return;
164 }
165
166 Method method = null;
167 if (foundMethods.size() > 1) {
168 model.put("error", "Found more then one method '" + methodName +"' that has " + paramNumber +" parameters.\nNot supported at the moment");
169 return;
170 }
171
172 method = foundMethods.get(0);
173
174
175 Class<?>[] types = method.getParameterTypes();
176 Object[] obj = new Object[types.length];
177 for (int j = 0; j < types.length; j++) {
178 String value = (String)httpConnection.getRequestParameters().getOnly(Integer.toString(j));
179 if (value != null) {
180 try {
181 value = URLDecoder.decode(value, "UTF-8");
182 } catch (UnsupportedEncodingException ignore) {
183 }
184 }
185
186 PropertyEditor propertyEditor = PropertyEditorManager.findEditor(types[j]);
187 if (propertyEditor != null) {
188 propertyEditor.setAsText(value);
189 obj[j] = propertyEditor.getValue();
190 } else {
191 obj[j] = value;
192 }
193 }
194 try {
195 Object res = method.invoke(current, obj);
196 StringBuffer result = new StringBuffer();
197 result.append(res);
198
199 model.put("result", result.toString());
200 } catch (Throwable t) {
201 model.put("error", BeanHelper.stackTrace(t));
202 }
203 }
204
205
206
207
208
209 public DisplayController getDisplayController() {
210 return displayController;
211 }
212
213
214
215
216
217 public void setDisplayController(DisplayController displayController) {
218 this.displayController = displayController;
219 }
220
221 }