001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.rm.commands;
020:
021: import java.util.*;
022:
023: import org.openharmonise.commons.dsi.AbstractDataStoreInterface;
024: import org.openharmonise.rm.PopulateException;
025: import org.openharmonise.rm.logging.*;
026: import org.openharmonise.rm.publishing.State;
027: import org.openharmonise.rm.resources.AbstractEditableObject;
028: import org.openharmonise.rm.resources.users.User;
029: import org.openharmonise.rm.security.authorization.AuthorizationValidator;
030: import org.openharmonise.rm.workflow.WorkflowLogEvent;
031:
032: /**
033: * An abstract class which provides the base functionality and sets the main
034: * interface for a class which can execute an operation with in the Harmonise
035: * framework, possibly on a specified 'command object'. Role based security
036: * and event logging are implemented in Harmonise through the command objects.
037: *
038: * @author Michael Bell
039: * @version $Revision: 1.4 $
040: *
041: */
042: public abstract class AbstractCmd {
043:
044: private static final String PARAM_INPUT = "input";
045: private static final String PARAM_RESULT = "result";
046: /**
047: * User executing the command
048: */
049:
050: private User m_commandUser = null;
051:
052: /**
053: * The <code>State</code> to be used for the context of the execution of the command
054: */
055: private State m_state = null;
056: /**
057: * Tag name for the element which represents a command
058: */
059: public static final String TAG_COMMAND = "Event";
060:
061: /**
062: * Tag name for the 'Parameter' element, used to specify parameters to the command
063: */
064: public static final String TAG_COMMAND_PARAM = "Parameter";
065:
066: /**
067: * Template id parameter name
068: */
069: public final static String PARAM_TEMPLATE_ID = "form_id";
070:
071: /**
072: * Output text parameter name
073: */
074: public final static String PARAM_OUT_TEXT = "out_text";
075:
076: /**
077: * Object this command shall execute upon
078: */
079: protected Object m_commandObj = null;
080:
081: /**
082: * Map of paramter names to values for this command
083: */
084: protected Map m_cmd_params;
085:
086: /**
087: * Data store interface for this command
088: */
089: private AbstractDataStoreInterface m_dsi = null;
090:
091: /**
092: * Creates new instance of a command object
093: *
094: */
095: public AbstractCmd() {
096: }
097:
098: /**
099: * Excutes command, on command object given if appropriate, and will return the
100: * result of the execution. If there is no result from the execution of the
101: * command it will return a <code>null</code>.
102: * @param context
103: *
104: * @return the result of the execution of the command
105: * @throws CommandException if any errors occur
106: */
107: public abstract Object execute(Context context)
108: throws CommandException;
109:
110: /**
111: * Returns the name of the command
112: *
113: * @return Name of the command
114: */
115: public abstract String getName();
116:
117: /**
118: * Sets the object on which the command will be executed
119: *
120: * @param obj object on which the command will be executed
121: */
122: public void setCommandObject(Object obj) {
123: m_commandObj = obj;
124: }
125:
126: /**
127: * Returns the object which this command will be executed on, if appropriate.
128: * @param context
129: *
130: * @return the object which this command will be executed on, if appropriate.
131: */
132: public Object getCommandObject(Context context) {
133:
134: Object cmdObj = m_commandObj;
135:
136: String sInput = (String) getParameter(PARAM_INPUT);
137:
138: if (sInput != null && context != null) {
139: cmdObj = context.getContextParameter(sInput);
140: }
141:
142: return cmdObj;
143: }
144:
145: /**
146: * Returns the user executing the commands from the <code>State</code>,
147: * if a <code>State</code> has been given to this command.
148: *
149: * @return the user executing the commands from the <code>State</code>
150: */
151: public User getExecutingUser() {
152: User usr = null;
153:
154: if (m_state != null) {
155: usr = m_state.getLoggedInUser();
156: }
157:
158: return usr;
159: }
160:
161: /**
162: * Adds a <code>State</code> object to this command, providing a context for the command
163: * to execute in.
164: *
165: * @param state the state/context for the execution of the command
166: */
167: public void setState(State state) {
168: m_state = state;
169: }
170:
171: /**
172: * Returns the <code>State</code> associated to this command.
173: *
174: * @return the <code>State</code> associated to this command.
175: */
176: public State getState() {
177: return m_state;
178: }
179:
180: /**
181: * Sets up an interface to the DB for this command.
182: *
183: * @param dsi the data store interface
184: */
185: public void setDataStoreInteface(AbstractDataStoreInterface dsi) {
186: m_dsi = dsi;
187: }
188:
189: /**
190: * Returns the data store interface associated to this command.
191: *
192: * @return the data store interface associated to this command.
193: */
194: public AbstractDataStoreInterface getDataStoreInteface() {
195: return m_dsi;
196: }
197:
198: /**
199: * Sets the parameters for this command.
200: *
201: * @param cmd_params the parameters for this command
202: */
203: public void setParameters(Map cmd_params) {
204: m_cmd_params = cmd_params;
205: }
206:
207: /**
208: * Returns the list of values for the parameter of the specified parameter
209: * name .
210: *
211: * @param parameter_name the parameter name
212: * @return the list of values for the parameter
213: */
214: public List getParameters(String parameter_name) {
215: List param = null;
216:
217: if (m_cmd_params != null) {
218: param = (List) m_cmd_params.get(parameter_name);
219: }
220:
221: return param;
222: }
223:
224: /**
225: * Returns the first value of the parameter of the specified parameter
226: * name
227: *
228: * @param parameter_name the parameter name
229: * @return the first value of the parameter
230: */
231: public String getParameter(String parameter_name) {
232: String sParam = null;
233:
234: if (m_cmd_params != null) {
235: List parameter_values = (List) m_cmd_params
236: .get(parameter_name);
237:
238: if ((parameter_values != null)
239: && (parameter_values.size() > 1)) {
240: throw new RuntimeException(
241: "Call getParameters if parameter has multiple values"
242: + " parameter_name:" + parameter_name
243: + ", returns :" + parameter_values);
244: }
245:
246: sParam = (parameter_values == null) ? null
247: : (String) parameter_values.get(0);
248: }
249:
250: return sParam;
251: }
252:
253: /**
254: * Returns <code>true</code> if this command is valid for the given object.
255: *
256: * @param obj
257: * @return
258: */
259: public abstract boolean isValidCommandObject(Object obj);
260:
261: /**
262: * Logs the command with the Harmonise logger.
263: * @param context TODO
264: *
265: * @throws CommandException if any errors occur logging the command
266: */
267: protected void logCommand(Context context) throws CommandException {
268: try {
269: EventLogController logger = EventLogController
270: .getInstance();
271:
272: WorkflowLogEvent event = new WorkflowLogEvent();
273:
274: event.setEventObject(getCommandObject(context));
275: event.setState(getState());
276: event.setLabel(getName());
277:
278: logger.logEvent(event);
279: } catch (LogException e) {
280: throw new CommandException("Error occured logging event", e);
281: } catch (PopulateException e) {
282: throw new CommandException(
283: "Error occured setting state for logging event", e);
284: }
285: }
286:
287: /**
288: * Returns <code>true</code> if this command is available to the user
289: * executing the command.
290: * @param context TODO
291: *
292: * @return <code>true</code> if this command is available to the user
293: * executing the command
294: * @throws InvalidCommandException if an error occurs
295: */
296: public boolean isAvailable(Context context)
297: throws InvalidCommandException {
298: User usr = getExecutingUser();
299:
300: return isAvailable(usr,
301: (AbstractEditableObject) getCommandObject(context));
302: }
303:
304: /**
305: * Returns <code>true</code> if this command is available to the
306: * specified user for the specified object
307: *
308: * @param usr the User
309: * @return <code>true</code> if this command is available to the
310: * specified user
311: * @throws InvalidCommandException if an error occurs
312: */
313: public boolean isAvailable(User usr, AbstractEditableObject obj)
314: throws InvalidCommandException {
315: boolean bIsAvailable = false;
316:
317: if (usr == null) {
318: throw new InvalidCommandException(
319: "Command is not valid with out specifying a user");
320: }
321:
322: try {
323: bIsAvailable = AuthorizationValidator.isCommandAvailable(
324: usr, (AbstractEditableObject) obj, getName());
325: } catch (org.openharmonise.rm.security.authorization.AuthorizationException e1) {
326: throw new InvalidCommandException(
327: "Command is not available for this object:"
328: + m_commandObj.getClass(), e1);
329: }
330:
331: return bIsAvailable;
332: }
333:
334: /**
335: * Returns <code>true</code> if this command is available to the
336: * specified user for the specified <code>Class</code>.
337: *
338: * @param usr the User
339: * @param objClass class to be tested
340: * @return <code>true</code> if this command is available to the
341: * specified user
342: * @throws InvalidCommandException if an error occurs
343: */
344: public boolean isAvailable(User usr, Class objClass)
345: throws InvalidCommandException {
346: boolean bIsAvailable = false;
347:
348: if (usr == null) {
349: throw new InvalidCommandException(
350: "Command is not valid with out specifying a user");
351: }
352:
353: try {
354: bIsAvailable = AuthorizationValidator.isCommandAvailable(
355: usr, objClass, getName());
356: } catch (org.openharmonise.rm.security.authorization.AuthorizationException e1) {
357: throw new InvalidCommandException(
358: "Command is not available for this object:"
359: + m_commandObj.getClass(), e1);
360: }
361:
362: return bIsAvailable;
363: }
364:
365: /**
366: * Adds the result to the context if the 'result' parameter
367: * exists to give the result a name in the context
368: *
369: * @param result
370: * @param context
371: */
372: protected void addResultContext(Object result, Context context) {
373: String sResult = getParameter(PARAM_RESULT);
374:
375: if (sResult != null) {
376: context.addContextParameter(sResult, result);
377: }
378: }
379: }
|