1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.fridaymvc;
18
19 import java.io.File;
20 import java.security.AccessControlException;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.Map;
26 import java.util.Set;
27
28 import javax.servlet.ServletContext;
29 import javax.servlet.http.HttpServletRequest;
30 import javax.servlet.http.HttpServletResponse;
31
32 import net.sf.fridaymvc.actions.Action;
33 import net.sf.fridaymvc.managers.view.ActionViewManager;
34 import net.sf.fridaymvc.managers.view.LayoutViewManager;
35 import net.sf.fridaymvc.managers.view.LinkViewManager;
36 import net.sf.fridaymvc.metadata.commons.AccessLoggedAttribute;
37 import net.sf.fridaymvc.metadata.commons.AccessPermissionAttribute;
38 import net.sf.fridaymvc.metadata.commons.AccessRoleAttribute;
39 import net.sf.fridaymvc.metadata.commons.ActionAttribute;
40 import net.sf.fridaymvc.metadata.commons.ModelAttribute;
41 import net.sf.fridaymvc.metadata.commons.RegExpValidatorAttribute;
42 import net.sf.fridaymvc.models.Model;
43 import net.sf.fridaymvc.security.accesscontroller.AccessController;
44 import net.sf.fridaymvc.security.accesscontroller.User;
45
46 import org.apache.commons.attributes.Attributes;
47 import org.springframework.beans.BeansException;
48 import org.springframework.context.ApplicationContext;
49 import org.springframework.context.ApplicationContextAware;
50 import org.springframework.web.context.WebApplicationContext;
51 import org.springframework.web.servlet.ViewResolver;
52
53 /***
54 * @author <a href="mailto:arto.pastinen@ofw.fi">Arto Pastinen</a>
55 * @version $Id: RunData.java,v 1.2 2004/11/23 20:35:56 artsi Exp $
56 */
57 public class RunData implements ApplicationContextAware {
58 public static final String ACTION_VALIDATE_FAILED_FIELDS = "ACTION_VALIDATE_FAILED_FIELDS";
59
60 protected final ThreadLocal httpServletRequest = new ThreadLocal();
61 protected final ThreadLocal httpServletResponse = new ThreadLocal();
62
63 protected final ThreadLocal currentViewName = new ThreadLocal();
64 protected final ThreadLocal currentViewUid = new ThreadLocal();
65
66 protected WebApplicationContext webApplicationContext;
67
68 protected LayoutViewManager layoutViewManager;
69 protected LinkViewManager linkViewManager;
70 protected ActionViewManager actionViewManager;
71
72 protected Map preViewMappings;
73 protected ViewResolver viewResolver;
74
75 protected Parameters parameters;
76 protected Map viewMapping;
77
78 protected AccessController accessController;
79
80 private static RunData instance;
81
82 public RunData() {
83 RunData.instance = this;
84 }
85
86 private static boolean initialized = false;
87
88 private void initialize() throws Exception {
89 ServletContext sc = getWebApplicationContext().getServletContext();
90 File f = new File(sc.getRealPath("/WEB-INF/classes"));
91 String rootPath = f.getAbsolutePath();
92 scanDirectories(f, rootPath);
93 initialized = true;
94 }
95
96 private void scanDirectories(File f, String rootPath ) {
97 if(f.isDirectory()) {
98 File files[] = f.listFiles();
99 for(int i = 0; i < files.length; i++) {
100 scanDirectories(files[i], rootPath);
101 }
102 }
103 else {
104 String ap = f.getAbsolutePath();
105 String tmp[] = f.getAbsolutePath().substring(rootPath.length()+1, ap.length()).split("//.");
106 if(tmp.length != 2) return;
107
108 String finalClassName = tmp[0].replace('/', '.');
109
110 try {
111 Class c = Class.forName(finalClassName);
112 ModelAttribute modelAttribute = (ModelAttribute) Attributes.getAttribute(c, ModelAttribute.class);
113 if(modelAttribute != null) {
114 modelClasses.put(modelAttribute.getName(), c);
115 return;
116 }
117 ActionAttribute actionAttribute = (ActionAttribute) Attributes.getAttribute(c, ActionAttribute.class);
118 if(actionAttribute != null) {
119 actionClasses.put(actionAttribute.getName(), c);
120 }
121 }
122 catch(Throwable t) {
123
124 }
125 }
126 }
127
128 protected Map actionClasses = new HashMap();
129 protected Map modelClasses = new HashMap();
130
131 public void handleRequest() throws Exception {
132 if(!initialized) {
133 synchronized(this) {
134 if(!initialized) initialize();
135 }
136 }
137 try {
138 handleAction();
139 }
140 catch(AccessControlException ace) {
141 ace.printStackTrace();
142 renderView("accessdenied", null);
143 return;
144 }
145 includeRootPage();
146 }
147
148 /***
149 *
150 * @throws Exception
151 *
152 */
153 protected void handleAction() throws Exception {
154 Parameters p = getParameters();
155 String actionName = p.get("action");
156 if(actionName == null) return;
157
158 Class actionClass = (Class) actionClasses.get(actionName);
159
160 if(actionClass == null && actionName.equals("setpanel")) actionClass = Class.forName("net.sf.fridaymvc.actions.SetPanel");
161
162 if(actionClass == null) throw new ClassNotFoundException("Cannot find class for action: " + new String(actionName));
163
164 AccessRoleAttribute ara = (AccessRoleAttribute) Attributes.getAttribute(actionClass, AccessRoleAttribute.class);
165 if(ara != null && !getAccessController().hasRole(ara.getName())) throw new AccessControlException("User dont have required role");
166 AccessPermissionAttribute apa = (AccessPermissionAttribute) Attributes.getAttribute(actionClass, AccessPermissionAttribute.class);
167 if(apa != null && !getAccessController().hasPermission(apa.getName())) throw new AccessControlException("User dont have required permission");
168
169 Action action = (Action) actionClass.newInstance();
170 setCurrentAction(action);
171
172 p.setPrefix("action.");
173
174 Collection validators = Attributes.getAttributes(actionClass, RegExpValidatorAttribute.class);
175
176 boolean passValidation = true;
177
178 if(validators.size() > 0) {
179 for (Iterator iter = validators.iterator(); iter.hasNext();) {
180 RegExpValidatorAttribute validator = (RegExpValidatorAttribute) iter.next();
181 if(validator.passValidation() == false) passValidation = false;
182 }
183 }
184
185 if(!passValidation) {
186 p.setPrefix(null);
187 return;
188 }
189
190 try {
191 action.service();
192 }
193 finally {
194 p.setPrefix(null);
195 }
196 }
197
198 public void includePanel(String uid, String viewName) throws Exception {
199 Map tmp = getViewMapping();
200 synchronized(tmp) {
201 if(tmp.containsKey(uid)) viewName = (String) tmp.get(uid);
202 }
203
204 setCurrentViewName(viewName);
205 setCurrentViewUid(uid);
206 try {
207 include(uid, viewName);
208 }
209 catch(Exception e) {
210 e.printStackTrace();
211 setCurrentViewName(null);
212 setCurrentViewUid(null);
213 throw e;
214 }
215 }
216
217 protected void includeRootPage() throws Exception {
218 String viewName = getPreViewMappings().containsKey("root") ? (String) preViewMappings.get("root") : "root";
219 include("root", viewName);
220 }
221
222 protected void include(String uid, String viewName) throws Exception {
223 Model model = null;
224
225 try {
226 model = resolveModel(viewName);
227 }
228 catch(AccessControlException ace) {
229 ace.printStackTrace();
230 renderView("accessdenied", null);
231 return;
232 }
233
234 model.service();
235
236 Map params = getHttpServletRequest().getParameterMap();
237 Set keys = params.keySet();
238 if(keys.size() > 0) {
239 for (Iterator iter = keys.iterator(); iter.hasNext();) {
240 String key = (String) iter.next();
241
242 if(!key.startsWith(viewName)) continue;
243
244 String tmp[] = key.split("//.");
245
246 String value[] = (String[]) params.get(key);
247
248 if(value.length == 1) model.setStatefulAttribute(tmp[tmp.length-1], value[0]);
249 else model.setStatefulAttribute(tmp[tmp.length-1], value);
250 }
251 }
252
253 viewName = viewName.replace('.', '/');
254 renderView(viewName, model);
255 }
256
257
258
259 protected void renderView(String viewName, Model model) throws Exception {
260 Map tmp = new HashMap(5);
261 tmp.put("layout", getLayoutViewManager());
262 tmp.put("link", getLinkViewManager());
263 tmp.put("action", getActionViewManager());
264
265 Map tmp2 = new HashMap(2);
266 if(model != null) {
267 tmp2.putAll(model.getStatefulAttributeMap());
268 tmp2.putAll(model.getStatelessAttributeMap());
269 tmp.put("attributes", tmp2);
270 }
271
272 tmp.put("acl", getAccessController());
273
274 ViewResolver viewResolver = getViewResolver();
275 viewResolver.resolveViewName(viewName, null).render(tmp, getHttpServletRequest(), getHttpServletResponse());
276 }
277
278
279 private Model resolveModel(String modelName) throws Exception {
280
281 Class modelClass = (Class) modelClasses.get(modelName);
282 Model model;
283 if(modelClass == null) modelClass = Class.forName("net.sf.fridaymvc.models.BasicModel");
284
285 AccessRoleAttribute rr = (AccessRoleAttribute) Attributes.getAttribute(modelClass, AccessRoleAttribute.class);
286 if(rr != null && !getAccessController().hasRole(rr.getName())) {
287 throw new AccessControlException("User don't have required role: " + rr.getName());
288 }
289
290 AccessPermissionAttribute rp = (AccessPermissionAttribute) Attributes.getAttribute(modelClass, AccessPermissionAttribute.class);
291 if(rp != null && !getAccessController().hasPermission(rp.getName())) throw new AccessControlException("User don't have required permission: " + rp.getName());
292
293 AccessLoggedAttribute rl = (AccessLoggedAttribute) Attributes.getAttribute(modelClass, AccessLoggedAttribute.class);
294 if(rl != null && getUser() == null) throw new AccessControlException("User hasn't logged");
295
296 model = (Model) modelClass.newInstance();
297
298 return model;
299 }
300
301 /***
302 * @return Returns the httpServletRequest.
303 */
304 public HttpServletRequest getHttpServletRequest() {
305 return (HttpServletRequest) this.httpServletRequest.get();
306 }
307 /***
308 * @param httpServletRequest The httpServletRequest to set.
309 */
310 public void setHttpServletRequest(HttpServletRequest httpServletRequest) {
311 this.httpServletRequest.set(httpServletRequest);
312 }
313 /***
314 * @return Returns the httpServletResponse.
315 */
316 public HttpServletResponse getHttpServletResponse() {
317 return (HttpServletResponse) this.httpServletResponse.get();
318 }
319 /***
320 * @param httpServletResponse The httpServletResponse to set.
321 */
322 public void setHttpServletResponse(HttpServletResponse httpServletResponse) {
323 this.httpServletResponse.set(httpServletResponse);
324 }
325 /***
326 * @return Returns the preViewMappings.
327 */
328 public Map getPreViewMappings() {
329 if(this.preViewMappings == null) {
330 synchronized(this) {
331 if(this.preViewMappings == null) {
332 setPreViewMappings(Collections.unmodifiableMap(Collections.EMPTY_MAP));
333 }
334 }
335 }
336 return this.preViewMappings;
337 }
338 /***
339 * @param preViewMappings The preViewMappings to set.
340 */
341 public void setPreViewMappings(Map viewMappings) {
342 this.preViewMappings = viewMappings;
343 }
344 /***
345 * @return Returns the viewResolver.
346 */
347 public ViewResolver getViewResolver() {
348 if(this.viewResolver == null) {
349 synchronized(this) {
350 if(this.viewResolver == null) {
351 setViewResolver((ViewResolver) getWebApplicationContext().getBean("viewResolver", ViewResolver.class));
352 }
353 }
354 }
355 return this.viewResolver;
356 }
357 /***
358 * @param viewResolver The viewResolver to set.
359 */
360 public void setViewResolver(ViewResolver viewResolver) {
361 this.viewResolver = viewResolver;
362 }
363
364 /***
365 * @return Returns the webApplicationContext.
366 */
367 public WebApplicationContext getWebApplicationContext() {
368 return this.webApplicationContext;
369 }
370
371 /***
372 * @param webApplicationContext The webApplicationContext to set.
373 */
374 public void setApplicationContext(WebApplicationContext webApplicationContext) {
375 this.webApplicationContext = webApplicationContext;
376 }
377
378 /***
379 * @return Returns the layoutViewManager.
380 */
381 public LayoutViewManager getLayoutViewManager() {
382 if(this.layoutViewManager == null) {
383 synchronized(this) {
384 if(this.layoutViewManager == null) {
385 this.layoutViewManager = new LayoutViewManager();
386 }
387 }
388 }
389 return this.layoutViewManager;
390 }
391 /***
392 * @param layoutViewManager The layoutViewManager to set.
393 */
394 public void setLayoutViewManager(LayoutViewManager layoutViewManager) {
395 this.layoutViewManager = layoutViewManager;
396 }
397 /***
398 * @return Returns the linkViewManager.
399 */
400 public LinkViewManager getLinkViewManager() {
401 if(this.linkViewManager == null) {
402 synchronized(this) {
403 if(this.linkViewManager == null) {
404 setLinkViewManager(new LinkViewManager());
405 }
406 }
407 }
408 return this.linkViewManager;
409 }
410 /***
411 * @param linkViewManager The linkViewManager to set.
412 */
413 public void setLinkViewManager(LinkViewManager linkViewManager) {
414 this.linkViewManager = linkViewManager;
415 }
416
417
418 /***
419 * @return Returns the actionViewManager.
420 */
421 public ActionViewManager getActionViewManager() {
422 if(this.actionViewManager == null) {
423 synchronized(this) {
424 if(this.actionViewManager == null) {
425 setActionViewManager(new ActionViewManager());
426 }
427 }
428 }
429 return this.actionViewManager;
430 }
431 /***
432 * @param actionViewManager The actionViewManager to set.
433 */
434 public void setActionViewManager(ActionViewManager actionViewManager) {
435 this.actionViewManager = actionViewManager;
436 }
437
438 public StringBuffer getRelativeServletPath() {
439 HttpServletRequest req = getHttpServletRequest();
440 StringBuffer sb = new StringBuffer(req.getContextPath());
441 sb.append(req.getServletPath());
442 return sb;
443 }
444 /***
445 * @return Returns the parameters.
446 */
447 public Parameters getParameters() {
448 if(this.parameters == null) {
449 synchronized(this) {
450 if(this.parameters == null) {
451 setParameters(new Parameters());
452 }
453 }
454 }
455 return this.parameters;
456 }
457 /***
458 * @param parameters The parameters to set.
459 */
460 public void setParameters(Parameters parameters) {
461 this.parameters = parameters;
462 }
463 /***
464 * @return Returns the viewMapping.
465 */
466 public Map getViewMapping() {
467 if(this.viewMapping == null) {
468 synchronized(this) {
469 if(this.viewMapping == null) {
470 setViewMapping(new HashMap(1));
471 }
472 }
473 }
474 return this.viewMapping;
475 }
476 /***
477 * @param viewMapping The viewMapping to set.
478 */
479 public void setViewMapping(Map viewMapping) {
480 this.viewMapping = viewMapping;
481 }
482
483
484 /***
485 * @return Returns the currentViewName.
486 */
487 public String getCurrentViewName() {
488 return (String) this.currentViewName.get();
489 }
490 /***
491 * @param currentViewName The currentViewName to set.
492 */
493 public void setCurrentViewName(String currentViewName) {
494 this.currentViewName.set(currentViewName);
495 }
496 /***
497 * @return Returns the currentViewUid.
498 */
499 public String getCurrentViewUid() {
500 return (String) this.currentViewUid.get();
501 }
502 /***
503 * @param currentViewUid The currentViewUid to set.
504 */
505 public void setCurrentViewUid(String currentViewUid) {
506 this.currentViewUid.set(currentViewUid);
507 }
508
509 public Object getBean(String id) {
510 return getWebApplicationContext().getBean(id);
511 }
512
513 public static final RunData getInstance() {
514 return RunData.instance;
515 }
516
517 /***
518 * @return Returns the user.
519 */
520 public User getUser() {
521 return (User) getHttpServletRequest().getSession().getAttribute("user");
522 }
523 /***
524 * @param user The user to set.
525 */
526 public void setUser(User user) {
527 getHttpServletRequest().getSession().setAttribute("user", user);
528 }
529 /***
530 * @return Returns the accessController.
531 */
532 public AccessController getAccessController() {
533 if(this.accessController == null) {
534 synchronized(this) {
535 if(this.accessController == null) {
536 setAccessController(new AccessController());
537 }
538 }
539 }
540 return this.accessController;
541 }
542
543 /***
544 * @param accessController The accessController to set.
545 */
546 public void setAccessController(AccessController accessController) {
547 this.accessController = accessController;
548 }
549
550 /***
551 * @return Returns the currentAction.
552 */
553 public Action getCurrentAction() {
554 return (Action) getHttpServletRequest().getAttribute("currentAction");
555 }
556 /***
557 * @param currentAction The currentAction to set.
558 */
559 public void setCurrentAction(Action currentAction) {
560 getHttpServletRequest().setAttribute("currentAction", currentAction);
561 }
562
563
564
565
566 public void setApplicationContext(ApplicationContext arg0) throws BeansException {
567 this.webApplicationContext = (WebApplicationContext) arg0;
568 }
569 }