1 /**
2 *
3 */
4 package sf.net.kayestry.components.menu;
5
6 import java.io.IOException;
7 import java.util.ArrayList;
8 import java.util.Collection;
9 import java.util.HashSet;
10 import java.util.List;
11 import java.util.Set;
12
13 import org.apache.commons.digester.Digester;
14 import org.springframework.core.io.ClassPathResource;
15 import org.xml.sax.SAXException;
16
17 import sf.net.kayestry.Globals;
18 import sf.net.kayestry.KayaBaseComponent;
19 import sf.net.kayestry.Visit;
20
21 import ar.com.jiji.kaya.KayaRuntimeException;
22 import ar.com.jiji.kaya.model.Role;
23 import ar.com.jiji.kaya.model.User;
24
25 /**
26 * Genera un menu con JavaScript. El menu esta compuesto de items, que pueden
27 * tener items hijos (submenues) o no. Soporta control de acceso en cada item. Y
28 * el menu se lee desde menu.xml, desde el raiz del classpath.<br/> Un menu de
29 * ejemplo para ver la estructura del xml es el siguiente:
30 *
31 * <pre>
32 *
33 * <?xml version="1.0"?>
34 * <root>
35 * <item id="0" name="Inicio" pageName="Home"/>
36 * <item id="1" name="Administracion">
37 * <item name="Beneficiarios" pageName="BeneficiarioBrowse">
38 * <allowed-roles>
39 * <role>admin</role>
40 * </allowed-roles>
41 * </item>
42 * </item>
43 * <item id="2" name="Reportes">
44 * <allowed-roles>
45 * <role>usuario</role>
46 * </allowed-roles>
47 * </item>
48 * ...
49 * </root>
50 *
51 * </pre>
52 *
53 * Los roles permitidos son los que existan en la aplicacion, utilizando el
54 * esquema de seguridad que ofrece kommons. Estos roles no se heredan en los
55 * subitems. El id del menu debe ser unico en toda la definicion. Este id es
56 * utilizado para establecer el nombre del elemento <SPAN> que contiene el item.
57 *
58 *
59 * @author jmile
60 * @author lparra
61 *
62 */
63 public abstract class MenuComponent extends KayaBaseComponent {
64
65 private static final String DEFAULT_MENU = "menu.xml";
66
67 protected abstract String getDefinition();
68
69 protected abstract boolean getShowLogin();
70
71 private MenuItem currItem;
72
73 private MenuItem currSubItem;
74
75 public Collection getMenu() {
76 List<MenuItem> menu = loadMenu();
77 User usr = getLoggedUser();
78
79 List<MenuItem> tmpmenu = filterMenu(menu, usr);
80
81 if (getShowLogin()) {
82 MenuItem auxItem;
83 if (usr != null)
84 auxItem = new MenuItem("Logout", Globals.LOGOUT_PAGE);
85 else
86 auxItem = new MenuItem("Login", Globals.LOGIN_PAGE);
87 tmpmenu.add(auxItem);
88 }
89
90 return tmpmenu;
91 }
92
93 private User getLoggedUser() {
94 Visit visit = getVisit();
95 User usr = null;
96
97 if (visit != null)
98 usr = visit.getLoggedUser();
99
100 return usr;
101 }
102
103 private List<MenuItem> filterMenu(List<MenuItem> menu, User usr) {
104
105 Set<String> roles;
106 if (usr == null)
107 roles = new HashSet<String>();
108 else
109 roles = getRoleNames(usr.getRoles());
110 return filterMenu(menu, roles);
111 }
112
113 private List<MenuItem> filterMenu(List<MenuItem> menu, Set<String> roles) {
114 if (menu == null)
115 return null;
116 List<MenuItem> result = new ArrayList<MenuItem>();
117 for (MenuItem item : menu) {
118 Set<String> allowed = item.getAllowedRoles();
119 boolean add = (allowed == null);
120 if (!add)
121 for (String aux : roles)
122 if (allowed.contains(aux)) {
123 add = true;
124 break;
125 }
126 if (add) {
127 List<MenuItem> items = item.getSubItems();
128 List<MenuItem> filtered = filterMenu(items, roles);
129 item.setSubItems(filtered);
130 result.add(item);
131 }
132 }
133 return result;
134 }
135
136 private Set<String> getRoleNames(Set<Role> roles) {
137 Set<String> rolesNames = new HashSet<String>();
138 for (Role r : roles)
139 rolesNames.add(r.getName());
140 return rolesNames;
141 }
142
143 @SuppressWarnings("unchecked")
144 private List<MenuItem> loadMenu() {
145 String menuDef = getDefinition();
146 if (menuDef == null)
147 menuDef = DEFAULT_MENU;
148
149
150 Digester digester = new Digester();
151 digester.setValidating(false);
152 digester.addObjectCreate("root", ArrayList.class);
153 digester.addObjectCreate("root/item", MenuItem.class);
154 digester.addSetProperties("root/item");
155 digester.addCallMethod("root/item/allowed-roles/role",
156 "addAllowedRole", 0);
157 digester.addSetNext("root/item", "add");
158 digester.addObjectCreate("*/item", MenuItem.class);
159 digester.addSetProperties("*/item");
160 digester.addSetNext("*/item", "addSubItem");
161 digester
162 .addCallMethod("*/item/allowed-roles/role", "addAllowedRole", 0);
163 try {
164
165 return (List<MenuItem>) digester.parse(new ClassPathResource(
166 menuDef).getInputStream());
167 } catch (IOException e) {
168 throw new KayaRuntimeException(e);
169 } catch (SAXException e) {
170 throw new KayaRuntimeException(e);
171 }
172 }
173
174 public void setCurrentMenuItem(MenuItem value) {
175 currItem = value;
176 }
177
178 public void setCurrentMenuSubItem(MenuItem value) {
179 currSubItem = value;
180 }
181
182 public MenuItem getMenuSubItem() {
183 return currSubItem;
184 }
185
186 public MenuItem getMenuItem() {
187 return currItem;
188 }
189 }