KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > core > MenuItem


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.core;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30
31 import com.sslexplorer.boot.ContextHolder;
32 import com.sslexplorer.policyframework.Permission;
33 import com.sslexplorer.policyframework.PolicyDatabaseFactory;
34 import com.sslexplorer.policyframework.ResourceType;
35 import com.sslexplorer.policyframework.ResourceUtil;
36 import com.sslexplorer.properties.Property;
37 import com.sslexplorer.properties.impl.systemconfig.SystemConfigKey;
38 import com.sslexplorer.security.SessionInfo;
39
40 /**
41  * Represents a single item in the tree of available menu actions. A menu item
42  * may either be a submenu or a leaf menu item. Whenever a user navigates to a
43  * page, the entire tree of <code>MenuItem</code>s is travered looking for
44  * menu items that are valid for the current state. This is then used to build
45  * up a tree of {@link com.sslexplorer.core.AvailableMenuItem} objects that is
46  * passed to the view for rendering.
47  * <p>
48  * A <code>MenuItem</code> is deemed valid for the current state if
49  * <code>true</code> is returned from {@link #isAvailable(HttpServletRequest)}
50  * method. By default this checks the parmeters parameters passed to this object
51  * when constructing <code>administratorOnly</code>,
52  * <code>availableInSetup</code> and <code>permissionId</code>. If any
53  * actions have any special requirements as to when they are visible,
54  * <code>MenuItem</code> should be sub-classed and
55  * {@link #isAvailable(HttpServletRequest)} should be overidden.
56  * <p>
57  * Every menu item must have two message resources added to a bundle. The keys
58  * must be in the format <strong>menuItem.[id].name</strong> and
59  * <strong>menuItem.[id].description</strong>. The bundle name must be passed
60  * as the contructor parameter <code>messageResourcesKey</code>.
61  *
62  * @author Brett Smith <brett@3sp.com>
63  * @see com.sslexplorer.core.AvailableMenuItem
64  */

65 public class MenuItem implements Comparable JavaDoc {
66
67     final static Log log = LogFactory.getLog(MenuItem.class);
68
69     // Protected instance variables
70

71     protected String JavaDoc messageResourcesKey;
72     protected String JavaDoc path;
73     protected List JavaDoc children;
74     protected MenuItem parent;
75     protected boolean leaf;
76     protected int weight;
77     protected int navigationContext;
78     protected ResourceType resourceTypeOfPermissionsRequired;
79     protected ResourceType resourcesOfTypeRequired;
80     protected Permission[] permissionsRequired;
81
82     // Private instance variables
83

84     private String JavaDoc id;
85     private String JavaDoc target = "_self";
86
87     /**
88      * Construct a new <code>MenuItem</code>.
89      *
90      * @param id menu item item
91      * @param messageResourcesKey the name of the resource bundle to retrieve
92      * menu name displayed to user
93      * @param part the URL or relative path that will be navigated to upon
94      * selecting this menu item
95      * @param weight weight of item in its parent menu used to order the items.
96      * @param leaf <code>true</code> if this item is not a sub-menu.
97      * @param navigationContext the navigation context this menu item should
98      * appear in. This should be a bitmask of the constants
99      * {@link com.sslexplorer.security.SessionInfo#USER_CONSOLE_CONTEXT}
100      * and
101      * {@link com.sslexplorer.security.SessionInfo#MANAGEMENT_CONSOLE_CONTEXT}.
102      */

103     public MenuItem(String JavaDoc id, String JavaDoc messageResourcesKey, String JavaDoc path, int weight, boolean leaf, int navigationContext) {
104         this(id, messageResourcesKey, path, weight, leaf, null, navigationContext, null, null, null);
105     }
106
107     /**
108      * Construct a new <code>MenuItem</code>.
109      *
110      * @param id menu item item
111      * @param messageResourcesKey the name of the resource bundle to retrieve
112      * menu name displayed to user
113      * @param part the URL or relative path that will be navigated to upon
114      * selecting this menu item
115      * @param weight weight of item in its parent menu used to order the items.
116      * @param availableInSetup the action is only valid when in setup mode
117      * @param leaf <code>true</code> if this item is not a sub-menu.
118      * @param target the browser target (i.e. _self, _blank etc). A value of
119      * null means _self.
120      * @param navigationContext the navigation context this menu item should
121      * appear in. This should be a bitmask of the constants
122      * {@link com.sslexplorer.security.SessionInfo#USER_CONSOLE_CONTEXT}
123      * and
124      * {@link com.sslexplorer.security.SessionInfo#MANAGEMENT_CONSOLE_CONTEXT}.
125      */

126     public MenuItem(String JavaDoc id, String JavaDoc messageResourcesKey, String JavaDoc path, int weight, boolean leaf, String JavaDoc target,
127                     int navigationContext) {
128         this(id, messageResourcesKey, path, weight, leaf, target, navigationContext, null, null, null);
129     }
130
131     /**
132      * Construct a new <code>MenuItem</code>. Because resource type can be
133      * supplied, this implies that the menu item is for the management console
134      *
135      * @param id menu item item
136      * @param messageResourcesKey the name of the resource bundle to retrieve
137      * menu name displayed to user
138      * @param part the URL or relative path that will be navigated to upon
139      * selecting this menu item
140      * @param weight weight of item in its parent menu used to order the items
141      * @param leaf <code>true</code> if this item is not a sub-menu.
142      * @param navigationContext the navigation context this menu item should
143      * appear in. This should be a bitmask of the constants
144      * {@link com.sslexplorer.security.SessionInfo#USER_CONSOLE_CONTEXT}
145      * and
146      * {@link com.sslexplorer.security.SessionInfo#MANAGEMENT_CONSOLE_CONTEXT}.
147      * @param resourceTypeOfPermissionsRequired resource type of any resource
148      * permissions required. May be <code>null</code> if you do not
149      * wish to check for permissions
150      * @param permissionsRequired array of required permission. Must be supplied
151      * if you have specified a
152      * <code>resourceTypeOfPermissionsRequired</code> otherwise may be
153      * null.
154      */

155     public MenuItem(String JavaDoc id, String JavaDoc messageResourcesKey, String JavaDoc path, int weight, boolean leaf,
156                     ResourceType resourceTypeOfPermissionsRequired, Permission[] permissionsRequired) {
157         this(id, messageResourcesKey, path, weight, leaf, null, SessionInfo.MANAGEMENT_CONSOLE_CONTEXT,
158                         resourceTypeOfPermissionsRequired, permissionsRequired, null);
159     }
160
161     /**
162      * Construct a new <code>MenuItem</code>.
163      *
164      * @param id menu item item
165      * @param messageResourcesKey the name of the resource bundle to retrieve
166      * menu name displayed to user
167      * @param part the URL or relative path that will be navigated to upon
168      * selecting this menu item
169      * @param weight weight of item in its parent menu used to order the items.
170      * @param leaf <code>true</code> if this item is not a sub-menu.
171      * @param target the browser target (i.e. _self, _blank etc). A value of
172      * null means _self.
173      * @param navigationContext the navigation context this menu item should
174      * appear in. This should be a bitmask of the constants
175      * {@link com.sslexplorer.security.SessionInfo#USER_CONSOLE_CONTEXT}
176      * and
177      * {@link com.sslexplorer.security.SessionInfo#MANAGEMENT_CONSOLE_CONTEXT}.
178      * @param resourceTypeOfPermissionsRequired resource type of any resource
179      * permissions required. May be <code>null</code> if you do not
180      * wish to check for permissions
181      * @param permissionsRequired array of required permission. Must be supplied
182      * if you have specified a
183      * <code>resourceTypeOfPermissionsRequired</code> otherwise may be
184      * null.
185      */

186     public MenuItem(String JavaDoc id, String JavaDoc messageResourcesKey, String JavaDoc path, int weight, boolean leaf, String JavaDoc target,
187                     int navigationContext, ResourceType resourceTypeOfPermissionsRequired, Permission[] permissionsRequired) {
188         this(id, messageResourcesKey, path, weight, leaf, target, navigationContext, resourceTypeOfPermissionsRequired,
189                         permissionsRequired, null);
190     }
191
192     /**
193      * Construct a new <code>MenuItem</code>.
194      *
195      * @param id menu item item
196      * @param messageResourcesKey the name of the resource bundle to retrieve
197      * menu name displayed to user
198      * @param part the URL or relative path that will be navigated to upon
199      * selecting this menu item
200      * @param weight weight of item in its parent menu used to order the items.
201      * @param leaf <code>true</code> if this item is not a sub-menu.
202      * @param target the browser target (i.e. _self, _blank etc). A value of
203      * null means _self.
204      * @param navigationContext the navigation context this menu item should
205      * appear in. This should be a bitmask of the constants
206      * {@link com.sslexplorer.security.SessionInfo#USER_CONSOLE_CONTEXT}
207      * and
208      * {@link com.sslexplorer.security.SessionInfo#MANAGEMENT_CONSOLE_CONTEXT}.
209      * @param resourceTypeOfPermissionsRequired resource type of any resource
210      * permissions required. May be <code>null</code> if you do not
211      * wish to check for permissions
212      * @param permissionsRequired array of required permission. Must be supplied
213      * if you have specified a
214      * <code>resourceTypeOfPermissionsRequired</code> otherwise may be
215      * null.
216      * @param resourcesOfTypeRequired if specified the user must have access to
217      * at least one resource of the type.
218      */

219     public MenuItem(String JavaDoc id, String JavaDoc messageResourcesKey, String JavaDoc path, int weight, boolean leaf, String JavaDoc target,
220                     int navigationContext, ResourceType resourceTypeOfPermissionsRequired, Permission[] permissionsRequired,
221                     ResourceType resourcesOfTypeRequired) {
222         super();
223         this.navigationContext = navigationContext;
224         this.target = target == null ? "_self" : target;
225         this.id = id;
226         this.leaf = leaf;
227         this.weight = weight;
228         this.messageResourcesKey = messageResourcesKey;
229         this.path = path;
230         this.permissionsRequired = permissionsRequired;
231         this.resourceTypeOfPermissionsRequired = resourceTypeOfPermissionsRequired;
232         this.resourcesOfTypeRequired = resourcesOfTypeRequired;
233     }
234
235     /**
236      * Add a child to this submenu.
237      *
238      * @param menuItem menu item to add
239      * @throws IllegalArgumentException if this menu item is a leaf
240      */

241     public void addChild(MenuItem menuItem) throws IllegalArgumentException JavaDoc {
242         if (isLeaf()) {
243             throw new IllegalArgumentException JavaDoc("Cannot add child menu items to leaf menu items.");
244         }
245         if (children == null) {
246             children = new ArrayList JavaDoc();
247         }
248         children.add(menuItem);
249     }
250
251     /**
252      * Remove a child from this menu
253      *
254      * @param menuItem menu item to remove
255      * @throws IllegalArgumentException if this menu item is a leaf
256      */

257     public void removeChild(MenuItem menuItem) throws IllegalArgumentException JavaDoc {
258         if (isLeaf()) {
259             throw new IllegalArgumentException JavaDoc("Cannot remove child menu items from leaf menu items.");
260         }
261         if (children != null) {
262             children.remove(menuItem);
263         }
264     }
265
266     /**
267      * Get a child menu item given its name
268      *
269      * @param id id
270      * @return menu item
271      */

272     public MenuItem getChild(String JavaDoc id) {
273         if (children != null) {
274             for (Iterator JavaDoc i = children.iterator(); i.hasNext();) {
275                 MenuItem it = (MenuItem) i.next();
276                 if (it.getId().equals(id)) {
277                     return it;
278                 }
279             }
280         }
281         return null;
282     }
283
284     /**
285      * Get if this menu item is a leaf. <code>false</code> means it is a
286      * sub-menu
287      *
288      * @return menu item is a leaf
289      */

290     public boolean isLeaf() {
291         return leaf;
292     }
293
294     /**
295      * Set the parent of menu item
296      *
297      * @param parent
298      */

299     public void setParent(MenuItem parent) {
300         this.parent = parent;
301     }
302
303     /**
304      * Return the id of this menu item
305      *
306      * @return
307      */

308     public String JavaDoc getId() {
309         return id;
310     }
311
312     /**
313      * Get the name of the bundle to use for the message resources required for
314      * this menu item.
315      *
316      * @return bunlde name
317      */

318     public String JavaDoc getMessageResourcesKey() {
319         return messageResourcesKey;
320     }
321
322     /**
323      * Get the browser target (e.g. _self, _blank etc). If a value of
324      * <code>null</code> is returned, the default <strong>_self</strong>
325      * should be used.
326      *
327      * @return browser targe
328      */

329     public String JavaDoc getTarget() {
330         return target;
331     }
332
333     /**
334      * Return the URL or relative path that should be navigated to if this menu
335      * item is actioned.
336      *
337      * @return path
338      */

339     public String JavaDoc getPath() {
340         return path;
341     }
342
343     /**
344      * Determine if this menu item should be available based on the current
345      * state. By default, this will check the current navigation context and
346      * {@link #getPermissionId()}.
347      * <p>
348      * If the menu item has any other checks it should perform (checking if a
349      * property is enabled for example), it should override this method
350      * (probably calling the super implementation as well).
351      *
352      *
353      * @param checkNavigationContext navigation context to check against
354      * @param info user to check against permissions
355      * @param request request
356      * @return item is available
357      */

358     public boolean isAvailable(int checkNavigationContext, SessionInfo info, HttpServletRequest JavaDoc request) {
359         if ((ContextHolder.getContext().isSetupMode() && ((navigationContext & SessionInfo.SETUP_CONSOLE_CONTEXT) != 0))
360                         || (navigationContext & checkNavigationContext) != 0 || navigationContext == 0 ) {
361             
362             // not available if there are no granted resources.
363
try {
364                 if (Property.getPropertyBoolean(new SystemConfigKey("security.enforce.policy.resource.access"))) {
365                     if (resourcesOfTypeRequired != null) {
366                         if (ResourceUtil.getGrantedResource(info, resourcesOfTypeRequired).size() == 0) {
367                             return false;
368                         }
369                     }
370                 }
371             } catch (Exception JavaDoc e) {
372                 log.error("Failed to check auth schemes restrictions.", e);
373                 return false;
374             }
375             if (resourceTypeOfPermissionsRequired != null) {
376                 try {
377                     boolean allowed = info != null && PolicyDatabaseFactory.getInstance().isPermitted(
378                                     resourceTypeOfPermissionsRequired, permissionsRequired, info.getUser(), false);
379                     if (!allowed) {
380                         if (resourcesOfTypeRequired != null) {
381                             return PolicyDatabaseFactory.getInstance().isPrincipalGrantedResourcesOfType(info.getUser(),
382                                             resourcesOfTypeRequired, null);
383                         }
384                         return false;
385                     }
386                     return true;
387                 } catch (Exception JavaDoc e) {
388                     log.error("Failed to check delegation rights.", e);
389                     return false;
390                 }
391             } else {
392                 try {
393                     if (resourcesOfTypeRequired != null) {
394                         return info != null && PolicyDatabaseFactory.getInstance().isPrincipalGrantedResourcesOfType(info.getUser(),
395                                         resourcesOfTypeRequired, null);
396                     }
397                 } catch (Exception JavaDoc e) {
398                     log.error("Failed to check delegation rights.", e);
399                     return false;
400                 }
401             }
402             return true;
403         }
404         return false;
405     }
406
407     /**
408      * Return an {@link List} of all child menu items that are valid for the
409      * current state (as determined by {@link #isAvailable(HttpServletRequest)}.
410      *
411      * @param checkNavigationContext navigation context to check against
412      * @param info session info
413      * @param request request
414      *
415      * @return list of available children
416      */

417     public List JavaDoc availableChildren(int checkNavigationContext, SessionInfo info, HttpServletRequest JavaDoc request) {
418         List JavaDoc l = new ArrayList JavaDoc();
419         if (children != null) {
420             for (Iterator JavaDoc i = children.iterator(); i.hasNext();) {
421                 MenuItem it = (MenuItem) i.next();
422                 if (it.isAvailable(navigationContext, info, request)) {
423                     l.add(it);
424                 }
425             }
426         }
427         return l;
428     }
429
430     /**
431      * Get if the menu is empty (i.e. contains no child items).
432      *
433      * @return menu is empty
434      */

435     public boolean isEmpty() {
436         return children == null || children.size() == 0;
437     }
438
439     /*
440      * (non-Javadoc)
441      *
442      * @see java.lang.Comparable#compareTo(java.lang.Object)
443      */

444     public int compareTo(Object JavaDoc arg0) {
445         return new Integer JavaDoc(weight).compareTo(new Integer JavaDoc(((MenuItem) arg0).weight));
446     }
447
448     /**
449      * Get the navigation context the menu item should appear in. This should be
450      * a bitmask of the contstants
451      * {@link com.sslexplorer.security.SessionInfo#USER_CONSOLE_CONTEXT} and
452      * {@link com.sslexplorer.security.SessionInfo#MANAGEMENT_CONSOLE_CONTEXT}.
453      *
454      * @return navigation context mask
455      */

456     public int getNavigationContext() {
457         return navigationContext;
458     }
459 }
Popular Tags