KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > atlassian > seraph > service > WebworkService


1 package com.atlassian.seraph.service;
2
3 import com.atlassian.seraph.util.PathMapper;
4 import com.atlassian.seraph.util.CachedPathMapper;
5 import com.atlassian.seraph.SecurityService;
6 import com.atlassian.seraph.config.SecurityConfig;
7 import com.opensymphony.util.ClassLoaderUtil;
8 import org.apache.log4j.Category;
9 import org.apache.commons.collections.LRUMap;
10 import org.w3c.dom.Element JavaDoc;
11 import org.w3c.dom.NodeList JavaDoc;
12 import webwork.config.Configuration;
13
14 import javax.servlet.http.HttpServletRequest JavaDoc;
15 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
16 import java.net.URL JavaDoc;
17 import java.util.*;
18
19 /**
20  * Configures Seraph based on WebWork 1.x configuration file actions.xml.
21  * <p/>
22  * <p>Takes a single init parameter:<br>
23  * - action.extension=action<br>
24  * (if this parma is not specified, the default is the webwork default 'action')
25  * (this should match your servlet mapping in web.xml)
26  * <p/>
27  * <p> Then in actions.xml specify roles required per action or command, ie:
28  * <pre>
29  * &lt;action name="project.ViewProject" alias="ViewProject" roles-required="RoleFoo, RoleBar"&gt;
30  * <p/>
31  * or
32  * <p/>
33  * &lt;command name="Delete" alias="DeleteProject" roles-required="RoleBat"&gt;
34  * </pre>
35  * <p>(roles can be separated by commas and spaces)
36  */

37 public class WebworkService implements SecurityService
38 {
39     private static final Category log = Category.getInstance(WebworkService.class);
40     private final String JavaDoc ROLES_REQUIRED_ATTR = "roles-required";
41
42
43     // used to check which actions match the current path
44
// This class only uses the "get:" method of the pathmapper, so initialise the map
45
// that caches its results to a large value. The getAll method of the PathMapper is not used
46
// by this class so make the second caching map small.
47
private PathMapper actionMapper = new CachedPathMapper(new LRUMap(500), new LRUMap(10));
48
49     // maps current action to roles required
50
private Map rolesMap = new HashMap();
51
52     // the extension of webwork actions (should match web.xml servlet mapping)
53
private String JavaDoc extension = "action";
54
55     public void init(Map params, SecurityConfig config)
56     {
57         try
58         {
59             extension = (String JavaDoc) params.get("action.extension");
60
61             configureActionMapper(extension);
62         }
63         catch (Exception JavaDoc e)
64         {
65             e.printStackTrace();
66         }
67     }
68
69     private void configureActionMapper(String JavaDoc extension)
70     {
71         try
72         {
73             String JavaDoc actionResourcePath = (String JavaDoc) Configuration.get("webwork.configuration.xml");
74
75             DocumentBuilderFactory JavaDoc factory = DocumentBuilderFactory.newInstance();
76             URL JavaDoc fileUrl = ClassLoaderUtil.getResource(actionResourcePath + ".xml", this.getClass());
77
78             if (fileUrl == null)
79                 fileUrl = ClassLoaderUtil.getResource("/" + actionResourcePath + ".xml", this.getClass());
80
81             if (fileUrl == null)
82                 throw new IllegalArgumentException JavaDoc("No such XML file:/" + actionResourcePath + ".xml");
83
84             // Parse document
85
org.w3c.dom.Document JavaDoc doc = factory.newDocumentBuilder().parse(fileUrl.toString());
86
87             // Get list of actions
88
NodeList JavaDoc actions = doc.getElementsByTagName("action");
89
90             String JavaDoc rootRolesRequired = overrideRoles(null, doc.getDocumentElement());
91
92             // Build list of views
93
for (int i = 0; i < actions.getLength(); i++)
94             {
95                 Element JavaDoc action = (Element JavaDoc) actions.item(i);
96                 String JavaDoc actionName = action.getAttribute("name");
97                 String JavaDoc actionAlias = action.getAttribute("alias");
98                 final String JavaDoc actionRolesRequired = overrideRoles(rootRolesRequired, action);
99
100                 if (actionRolesRequired != null)
101                 {
102
103                     if (actionAlias != null)
104                     {
105                         actionMapper.put(actionAlias, "/" + actionAlias + "." + extension);
106                         rolesMap.put(actionAlias, actionRolesRequired);
107                         actionMapper.put(actionAlias + "!*", "/" + actionAlias + "!*." + extension);
108                         rolesMap.put(actionAlias + "!*", actionRolesRequired);
109                     }
110
111                     if (actionName != null)
112                     {
113                         actionMapper.put(actionName, "/" + actionName + "." + extension);
114                         rolesMap.put(actionName, actionRolesRequired);
115                         actionMapper.put(actionName + "!*", "/" + actionName + "!*." + extension);
116                         rolesMap.put(actionName + "!*", actionRolesRequired);
117                     }
118                 }
119
120                 // Get list of commands
121
NodeList JavaDoc commands = action.getElementsByTagName("command");
122                 for (int j = 0; j < commands.getLength(); j++)
123                 {
124                     Element JavaDoc command = (Element JavaDoc) commands.item(j);
125                     String JavaDoc cmdRolesRequired = overrideRoles(actionRolesRequired, command);
126
127                     String JavaDoc commandAlias = command.getAttribute("alias");
128
129                     if (commandAlias != null && cmdRolesRequired != null)
130                     {
131                         actionMapper.put(commandAlias, "/" + commandAlias + "." + extension);
132                         rolesMap.put(commandAlias, cmdRolesRequired);
133                     }
134                     }
135             }
136         }
137         catch (Exception JavaDoc ex)
138         {
139             log.error("Exception: " + ex, ex);
140         }
141     }
142
143
144     /**
145      * Returns newRolesRequired if it isn't empty, and rolesRequired otherwise.
146      */

147     private String JavaDoc overrideRoles(String JavaDoc rolesRequired, Element JavaDoc action)
148     {
149         if (action.hasAttribute(ROLES_REQUIRED_ATTR))
150         {
151             return action.getAttribute(ROLES_REQUIRED_ATTR);
152         }
153         else
154         {
155             return rolesRequired;
156         }
157     }
158
159 /* Alternative 'additive' implementation of above method.
160     private void addRoles(String rolesRequired, String newRolesRequired)
161     {
162         if (newRolesRequired != null)
163         {
164             if (rolesRequired == null) rolesRequired = newRolesRequired;
165             else rolesRequired += newRolesRequired;
166         }
167     }
168 */

169
170     public void destroy()
171     {
172     }
173
174     public Set getRequiredRoles(HttpServletRequest JavaDoc request)
175     {
176         Set requiredRoles = new HashSet();
177
178         String JavaDoc currentURL = request.getRequestURI();
179
180         int lastSlash = currentURL.lastIndexOf('/');
181         String JavaDoc targetURL;
182
183         // then check webwork mappings
184
if (lastSlash > -1)
185         {
186             targetURL = currentURL.substring(lastSlash);
187         }
188         else
189         {
190             targetURL = currentURL;
191         }
192
193         String JavaDoc actionMatch = actionMapper.get(targetURL);
194
195         if (actionMatch != null)
196         {
197             String JavaDoc rolesStr = (String JavaDoc) rolesMap.get(actionMatch);
198
199             StringTokenizer st = new StringTokenizer(rolesStr, ", ");
200             while (st.hasMoreTokens())
201             {
202                 requiredRoles.add(st.nextToken());
203             }
204         }
205
206         return requiredRoles;
207     }
208 }
209
Popular Tags