001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018:
019: /* $Id: DefaultTaskWrapper.java 473861 2006-11-12 03:51:14Z gregor $ */
020:
021: package org.apache.lenya.cms.task;
022:
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.Enumeration;
027: import java.util.HashMap;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031: import java.util.Properties;
032:
033: import org.apache.avalon.framework.configuration.ConfigurationException;
034: import org.apache.avalon.framework.parameters.ParameterException;
035: import org.apache.avalon.framework.parameters.Parameters;
036: import org.apache.avalon.framework.service.ServiceManager;
037: import org.apache.cocoon.environment.Request;
038: import org.apache.lenya.ac.Identity;
039: import org.apache.lenya.ac.Role;
040: import org.apache.lenya.cms.publication.Publication;
041: import org.apache.lenya.util.NamespaceMap;
042: import org.apache.lenya.xml.NamespaceHelper;
043: import org.apache.log4j.Logger;
044: import org.w3c.dom.Element;
045: import org.xml.sax.SAXException;
046:
047: /**
048: * The default task wrapper
049: * @deprecated Use the usecase framework instead.
050: */
051: public class DefaultTaskWrapper implements TaskWrapper {
052:
053: private static Logger log = Logger
054: .getLogger(DefaultTaskWrapper.class);
055:
056: private Map parameters = new HashMap();
057: private TaskWrapperParameters wrapperParameters = new TaskWrapperParameters(
058: getParameterObject());
059: private TaskParameters taskParameters;
060:
061: private ServiceManager manager;
062:
063: /**
064: * Default ctor for subclasses.
065: * @param manager The service manager to use.
066: */
067: protected DefaultTaskWrapper(ServiceManager manager) {
068: this .manager = manager;
069: this .taskParameters = new TaskParameters(getParameterObject(),
070: manager);
071: }
072:
073: /**
074: * Ctor to be called when all task wrapper parameters are known. All keys and values must be
075: * strings or string arrays.
076: * @param _parameters The prefixed parameters.
077: * @param manager The service manager to use.
078: */
079: public DefaultTaskWrapper(Map _parameters, ServiceManager manager) {
080: this (manager);
081: log.debug("Creating");
082:
083: List keys = new ArrayList();
084: for (Iterator i = _parameters.keySet().iterator(); i.hasNext();) {
085: String key = (String) i.next();
086: keys.add(key);
087: }
088:
089: Collections.sort(keys);
090:
091: for (Iterator i = keys.iterator(); i.hasNext();) {
092: String key = (String) i.next();
093: StringBuffer buf = new StringBuffer();
094: String value = null;
095: Object valueObject = _parameters.get(key);
096: if (valueObject instanceof String) {
097: buf.append(((String) valueObject).trim());
098: } else if (valueObject instanceof String[]) {
099: String[] values = (String[]) valueObject;
100: for (int j = 0; j < values.length; j++) {
101: if (j > 0 && !"".equals(buf.toString())) {
102: buf.append(",");
103: }
104: buf.append(values[j].trim());
105: }
106: } else {
107: log.debug("Not a string value: [" + key + "] = ["
108: + valueObject + "]");
109: }
110:
111: value = buf.toString();
112: if (value != null) {
113: log.debug("Setting parameter: [" + key + "] = ["
114: + value + "]");
115: this .parameters.put(key, value);
116: }
117: }
118:
119: }
120:
121: /**
122: * Ctor. Restores the wrapper parameters from an XML element.
123: * @param parent The parent of the task wrapper element.
124: * @param helper The namespace helper of the document.
125: */
126: public DefaultTaskWrapper(NamespaceHelper helper, Element parent) {
127: log.debug("Creating");
128: restore(helper, parent);
129: }
130:
131: /**
132: * Initializes the task wrapper.
133: * @param taskId The task ID.
134: * @param publication The publication.
135: * @param webappUrl The webapp URL.
136: * @param _parameters The task parameters.
137: * @throws ExecutionException when the task ID is null.
138: */
139: protected void initialize(String taskId, Publication publication,
140: String webappUrl, Parameters _parameters)
141: throws ExecutionException {
142: log.debug("Initializing");
143:
144: if (taskId.equals(""))
145: throw new ExecutionException();
146:
147: getTaskParameters().setPublication(publication);
148: getWrapperParameters().setWebappUrl(webappUrl);
149:
150: getWrapperParameters().setTaskId(taskId);
151: getTaskParameters().parameterize(_parameters);
152: }
153:
154: /**
155: * Extracts the task parameters from the given objects.
156: * @param _parameters A parameters object.
157: * @param publication A publication.
158: * @param request A request.
159: * @return A parameters object.
160: */
161: protected Parameters extractTaskParameters(Parameters _parameters,
162: Publication publication, Request request) {
163: Parameters _taskParameters = new Parameters();
164: _taskParameters.setParameter(Task.PARAMETER_SERVLET_CONTEXT,
165: publication.getServletContext().getAbsolutePath());
166: _taskParameters.setParameter(Task.PARAMETER_CONTEXT_PREFIX,
167: request.getContextPath());
168: _taskParameters.setParameter(Task.PARAMETER_SERVER_PORT,
169: Integer.toString(request.getServerPort()));
170: _taskParameters.setParameter(Task.PARAMETER_SERVER_URI,
171: "http://" + request.getServerName());
172: _taskParameters.setParameter(Task.PARAMETER_PUBLICATION_ID,
173: publication.getId());
174:
175: for (Enumeration e = request.getParameterNames(); e
176: .hasMoreElements();) {
177: String key = (String) e.nextElement();
178: String value = request.getParameter(key);
179: if (value != null) {
180: _taskParameters.setParameter(key, value);
181: }
182: }
183:
184: String[] names = _parameters.getNames();
185: for (int i = 0; i < names.length; i++) {
186: String name = names[i];
187: String value = _parameters.getParameter(name, "");
188: if (value != null) {
189: _taskParameters.setParameter(name, value);
190: }
191: }
192: return _taskParameters;
193: }
194:
195: /**
196: * Enables workflow transition invocation.
197: * @param eventName The event name.
198: * @param identity The identity that executes the task.
199: * @param roles The roles of the identity.
200: */
201: public void setWorkflowAware(String eventName, Identity identity,
202: Role[] roles) {
203: NamespaceMap workflowParameters = WorkflowInvoker
204: .extractParameters(eventName, identity, roles);
205: getParameterObject()
206: .putAll(workflowParameters.getPrefixedMap());
207: }
208:
209: /**
210: * Executes the task.
211: * @throws ExecutionException when something went wrong.
212: */
213: public void execute() throws ExecutionException {
214:
215: String taskId = getWrapperParameters().getTaskId();
216:
217: if (taskId == null) {
218: throw new ExecutionException("No task id provided!");
219: }
220:
221: log.info("===================================");
222: log.info(" Executing task [" + taskId + "]");
223: log.info("-----------------------------------");
224:
225: if (!this .wrapperParameters.isComplete()) {
226:
227: String[] missingKeys = getWrapperParameters()
228: .getMissingKeys();
229: String keyString = "";
230: for (int i = 0; i < missingKeys.length; i++) {
231: if (i > 0) {
232: keyString += ", ";
233: }
234: keyString += missingKeys[i];
235: }
236: throw new ExecutionException("Parameters missing: ["
237: + keyString + "]");
238: }
239:
240: TaskManager manager;
241:
242: Publication publication = getTaskParameters().getPublication();
243:
244: WorkflowInvoker workflowInvoker = new WorkflowInvoker(
245: getParameters(), this .manager);
246: workflowInvoker.setup(publication, getWrapperParameters()
247: .getWebappUrl());
248:
249: Task task;
250: try {
251: manager = new TaskManager(publication.getDirectory()
252: .getAbsolutePath(), this .manager);
253: task = manager.getTask(taskId);
254:
255: Properties properties = new Properties();
256: properties.putAll(getTaskParameters().getMap());
257: Parameters _parameters = Parameters
258: .fromProperties(properties);
259:
260: task.parameterize(_parameters);
261: } catch (final ConfigurationException e) {
262: throw new ExecutionException(e);
263: } catch (final ParameterException e) {
264: throw new ExecutionException(e);
265: } catch (final SAXException e) {
266: throw new ExecutionException(e);
267: } catch (final IOException e) {
268: throw new ExecutionException(e);
269: } catch (ExecutionException e) {
270: throw e;
271: }
272:
273: log.debug("-----------------------------------");
274: log.debug(" Triggering workflow");
275: log.debug("-----------------------------------");
276:
277: // FIXME The new workflow is set before the end of the transition because the document id
278: // and so the document are sometimes changing during the transition (ex archiving , ...)
279: workflowInvoker.invokeTransition();
280:
281: log.debug("-----------------------------------");
282: log.debug(" Triggering task");
283: log.debug("-----------------------------------");
284:
285: task.execute(publication.getServletContext().getAbsolutePath());
286:
287: log.debug("-----------------------------------");
288: log.debug(" Triggering notification");
289: log.debug("-----------------------------------");
290: Notifier notifier = new Notifier(manager, getParameters());
291: notifier.sendNotification(getTaskParameters());
292:
293: log.debug("-----------------------------------");
294: log.debug(" Executing task finished.");
295: log.debug("===================================\n\n");
296: }
297:
298: /**
299: * Returns the task wrapper parameters.
300: * @return A task wrapper parameters object.
301: */
302: public TaskWrapperParameters getWrapperParameters() {
303: return this .wrapperParameters;
304: }
305:
306: /**
307: * Returns the task parameters.
308: * @return A task parameters object.
309: */
310: public TaskParameters getTaskParameters() {
311: return this .taskParameters;
312: }
313:
314: protected static final String ELEMENT_TASK = "task";
315: protected static final String ELEMENT_PARAMETER = "parameter";
316: protected static final String ATTRIBUTE_NAME = "name";
317: protected static final String ATTRIBUTE_VALUE = "value";
318:
319: /**
320: * Saves the wrapper parameters to an XML element.
321: * @param helper The namespace helper of the document.
322: * @return An XML element.
323: */
324: public Element save(NamespaceHelper helper) {
325: org.w3c.dom.Document document = helper.getDocument();
326: NamespaceHelper taskHelper = new NamespaceHelper(
327: Task.NAMESPACE, Task.DEFAULT_PREFIX, document);
328: Element element = taskHelper.createElement(ELEMENT_TASK);
329:
330: List keys = new ArrayList(getParameters().keySet());
331: Collections.sort(keys);
332:
333: for (Iterator i = keys.iterator(); i.hasNext();) {
334: String key = (String) i.next();
335: Element parameterElement = taskHelper
336: .createElement(ELEMENT_PARAMETER);
337: parameterElement.setAttribute(ATTRIBUTE_NAME, key);
338: parameterElement.setAttribute(ATTRIBUTE_VALUE,
339: (String) getParameters().get(key));
340: element.appendChild(parameterElement);
341: }
342:
343: return element;
344: }
345:
346: /**
347: * Restores the wrapper parameters from an XML element.
348: * @param parent The parent of the task wrapper element.
349: * @param helper The namespace helper of the document.
350: */
351: public void restore(NamespaceHelper helper, Element parent) {
352: org.w3c.dom.Document document = helper.getDocument();
353: NamespaceHelper taskHelper = new NamespaceHelper(
354: Task.NAMESPACE, Task.DEFAULT_PREFIX, document);
355: Element taskElement = taskHelper.getFirstChild(parent,
356: ELEMENT_TASK);
357: Element[] parameterElements = taskHelper.getChildren(
358: taskElement, ELEMENT_PARAMETER);
359: for (int i = 0; i < parameterElements.length; i++) {
360: String key = parameterElements[i]
361: .getAttribute(ATTRIBUTE_NAME);
362: String value = parameterElements[i]
363: .getAttribute(ATTRIBUTE_VALUE);
364: getParameterObject().put(key, value);
365: }
366: }
367:
368: /**
369: * Returns all prefixed parameters.
370: * @return A map.
371: */
372: public Map getParameters() {
373: return Collections.unmodifiableMap(this .parameters);
374: }
375:
376: /**
377: * Returns all prefixed parameters.
378: * @return A map.
379: */
380: protected Map getParameterObject() {
381: return this .parameters;
382: }
383:
384: /**
385: * Sets the notification parameters.
386: * @param notificationParameters The notification parameters.
387: */
388: protected void setNotifying(NamespaceMap notificationParameters) {
389: log.info("Enabling notification");
390: getParameterObject().putAll(
391: notificationParameters.getPrefixedMap());
392: }
393:
394: }
|