1 /*
2 * Copyright 2003 - 2013 The eFaps Team
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * Revision: $Rev$
17 * Last Changed: $Date$
18 * Last Changed By: $Author$
19 */
20
21 package org.efaps.admin.ui;
22
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.TreeMap;
27
28 import org.apache.commons.lang3.builder.ToStringBuilder;
29 import org.efaps.ci.CIAdminUserInterface;
30 import org.efaps.db.Instance;
31 import org.efaps.db.MultiPrintQuery;
32 import org.efaps.db.QueryBuilder;
33 import org.efaps.jaas.AppAccessHandler;
34 import org.efaps.util.EFapsException;
35 import org.efaps.util.cache.CacheReloadException;
36
37 /**
38 * @author The eFaps Team
39 * @version $Id$
40 */
41 public abstract class AbstractMenu
42 extends AbstractCommand
43 {
44 /**
45 * Needed for serialization.
46 */
47 private static final long serialVersionUID = 1L;
48
49 /**
50 * All sub commands or menus are store in the tree map. The tree map is used
51 * to sort the commands / menus belonging to their id.
52 *
53 * @see #getCommands
54 * @add
55 */
56 private final Map<Long, AbstractCommand> commands = new TreeMap<Long, AbstractCommand>();
57
58 /**
59 * Constructor to set the id,uuid and name of the menu object.
60 *
61 * @param _id id of the command to set
62 * @param _uuid UUID of the command to set
63 * @param _name name of the command to set
64 */
65 protected AbstractMenu(final long _id,
66 final String _uuid,
67 final String _name)
68 {
69 super(_id, _uuid, _name);
70 }
71
72 /**
73 * Adds a command or menu to this menu instance. The method must be specific
74 * implemented by all menu implementations.
75 *
76 * @param _sortId id used to sort
77 * @param _id id of the sub command / menu to add
78 * @throws CacheReloadException on error
79 */
80 protected abstract void add(final long _sortId,
81 final long _id)
82 throws CacheReloadException;
83
84 /**
85 * Add a command to the menu structure.
86 *
87 * @param _sortId id used to sort
88 * @param _command command to add
89 */
90 public void add(final long _sortId,
91 final AbstractCommand _command)
92 {
93 this.commands.put(_sortId, _command);
94 }
95
96 /**
97 * Add all sub commands and menus of the given menu to this menu structure.
98 *
99 * @param _menu menu with sub structure
100 */
101 public void addAll(final AbstractMenu _menu)
102 {
103 this.commands.putAll(_menu.commands);
104 }
105
106 /**
107 * Check, if the user of the context has access to this user interface
108 * object. First, the instance method checks, if some access configuration
109 * exists for this menu instance object. If the user has access for this
110 * menu, it is test, if the context user has access to minimum one sub
111 * command command / menu. If yes, the user is allowed to access this menu
112 * instance, other the user is not allowed to access this menu.
113 *
114 * @param _targetMode TargetMode of the Command
115 * @param _instance the field will represent, e.g. on edit mode
116 * @return <i>true</i>if context user has access, otherwise <i>false</i> is
117 * returned
118 * @throws EFapsException on error
119 */
120 @Override
121 public boolean hasAccess(final TargetMode _targetMode,
122 final Instance _instance)
123 throws EFapsException
124 {
125 boolean ret = super.hasAccess(_targetMode, _instance);
126
127 if (ret && getCommands().size() > 0 && !AppAccessHandler.excludeMode()) {
128 ret = false;
129 for (final AbstractCommand cmd : getCommands()) {
130 if (cmd.hasAccess(_targetMode, _instance)) {
131 ret = true;
132 break;
133 }
134 }
135 }
136 return ret;
137 }
138
139 /**
140 * Returns all information from the menu as string.
141 *
142 * @return String representation of this AbstractMenu
143 */
144 @Override
145 public String toString()
146 {
147 final ToStringBuilder buf = new ToStringBuilder(this).appendSuper(super.toString());
148
149 for (final AbstractCommand cmd : getCommands()) {
150 buf.append(" ").append(cmd);
151 }
152 return buf.toString();
153 }
154
155 /**
156 * The method takes values of the {@link #commands} and returnes them as
157 * {@link java.util.ArrayList}.
158 *
159 * @return the values of the {@link #commands} map instance as array list
160 * @see #commands
161 * @see #add(Command)
162 * @see #add(Menu)
163 */
164 public List<AbstractCommand> getCommands()
165 {
166 return new ArrayList<AbstractCommand>(this.commands.values());
167 }
168
169 /**
170 * The instance method reads all needed information for this user interface
171 * object. The method extends the original method, because the sub menus and
172 * commands must be read.
173 *
174 * @see #readFromDB4Childs
175 * @throws CacheReloadException on error during load
176 */
177 @Override
178 protected void readFromDB()
179 throws CacheReloadException
180 {
181 super.readFromDB();
182 readFromDB4Childs();
183 }
184
185 /**
186 * The instance method gets all sub menus and commands and adds them to this
187 * menu instance via method {@link #add(long)}.
188 *
189 * @see #readFromDB
190 * @see #add(long)
191 * @throws CacheReloadException on error during load
192 */
193 private void readFromDB4Childs()
194 throws CacheReloadException
195 {
196 try {
197 final QueryBuilder queryBldr = new QueryBuilder(CIAdminUserInterface.Menu2Command);
198 queryBldr.addWhereAttrEqValue(CIAdminUserInterface.Menu2Command.FromMenu, getId());
199 final MultiPrintQuery multi = queryBldr.getPrint();
200 multi.addAttribute(CIAdminUserInterface.Menu2Command.ToCommand);
201 multi.executeWithoutAccessCheck();
202
203 while (multi.next()) {
204 final long commandId = multi.<Long> getAttribute(CIAdminUserInterface.Menu2Command.ToCommand);
205 add(multi.getCurrentInstance().getId(), commandId);
206 }
207 } catch (final EFapsException e) {
208 throw new CacheReloadException("could not read childs for menu '" + getName() + "'", e);
209 }
210 }
211
212 @Override
213 public boolean equals(final Object _obj)
214 {
215 boolean ret;
216 if (_obj instanceof AbstractMenu) {
217 ret = ((AbstractMenu) _obj).getId() == getId();
218 } else {
219 ret = super.equals(_obj);
220 }
221 return ret;
222 }
223
224 @Override
225 public int hashCode()
226 {
227 return Long.valueOf(getId()).intValue();
228 }
229 }