blob: a8412924dd2ce47879f97b19af3d7a12a3cb66f6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/* $Id$ */
package org.apache.lenya.cms.task;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.cocoon.environment.Request;
import org.apache.lenya.ac.Identity;
import org.apache.lenya.ac.Role;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.util.NamespaceMap;
import org.apache.lenya.xml.NamespaceHelper;
import org.apache.log4j.Logger;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* The default task wrapper
* @deprecated Use the usecase framework instead.
*/
public class DefaultTaskWrapper implements TaskWrapper {
private static Logger log = Logger.getLogger(DefaultTaskWrapper.class);
private Map parameters = new HashMap();
private TaskWrapperParameters wrapperParameters = new TaskWrapperParameters(getParameterObject());
private TaskParameters taskParameters;
private ServiceManager manager;
/**
* Default ctor for subclasses.
* @param manager The service manager to use.
*/
protected DefaultTaskWrapper(ServiceManager manager) {
this.manager = manager;
this.taskParameters = new TaskParameters(getParameterObject(), manager);
}
/**
* Ctor to be called when all task wrapper parameters are known. All keys and values must be
* strings or string arrays.
* @param _parameters The prefixed parameters.
* @param manager The service manager to use.
*/
public DefaultTaskWrapper(Map _parameters, ServiceManager manager) {
this(manager);
log.debug("Creating");
List keys = new ArrayList();
for (Iterator i = _parameters.keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
keys.add(key);
}
Collections.sort(keys);
for (Iterator i = keys.iterator(); i.hasNext();) {
String key = (String) i.next();
StringBuffer buf = new StringBuffer();
String value = null;
Object valueObject = _parameters.get(key);
if (valueObject instanceof String) {
buf.append(((String) valueObject).trim());
} else if (valueObject instanceof String[]) {
String[] values = (String[]) valueObject;
for (int j = 0; j < values.length; j++) {
if (j > 0 && !"".equals(buf.toString())) {
buf.append(",");
}
buf.append(values[j].trim());
}
} else {
log.debug("Not a string value: [" + key + "] = [" + valueObject + "]");
}
value = buf.toString();
if (value != null) {
log.debug("Setting parameter: [" + key + "] = [" + value + "]");
this.parameters.put(key, value);
}
}
}
/**
* Ctor. Restores the wrapper parameters from an XML element.
* @param parent The parent of the task wrapper element.
* @param helper The namespace helper of the document.
*/
public DefaultTaskWrapper(NamespaceHelper helper, Element parent) {
log.debug("Creating");
restore(helper, parent);
}
/**
* Initializes the task wrapper.
* @param taskId The task ID.
* @param publication The publication.
* @param webappUrl The webapp URL.
* @param _parameters The task parameters.
* @throws ExecutionException when the task ID is null.
*/
protected void initialize(String taskId, Publication publication, String webappUrl,
Parameters _parameters) throws ExecutionException {
log.debug("Initializing");
if (taskId.equals(""))
throw new ExecutionException();
getTaskParameters().setPublication(publication);
getWrapperParameters().setWebappUrl(webappUrl);
getWrapperParameters().setTaskId(taskId);
getTaskParameters().parameterize(_parameters);
}
/**
* Extracts the task parameters from the given objects.
* @param _parameters A parameters object.
* @param publication A publication.
* @param request A request.
* @return A parameters object.
*/
protected Parameters extractTaskParameters(Parameters _parameters, Publication publication,
Request request) {
Parameters _taskParameters = new Parameters();
_taskParameters.setParameter(Task.PARAMETER_SERVLET_CONTEXT,
publication.getServletContext().getAbsolutePath());
_taskParameters.setParameter(Task.PARAMETER_CONTEXT_PREFIX, request.getContextPath());
_taskParameters.setParameter(Task.PARAMETER_SERVER_PORT,
Integer.toString(request.getServerPort()));
_taskParameters.setParameter(Task.PARAMETER_SERVER_URI, "http://" + request.getServerName());
_taskParameters.setParameter(Task.PARAMETER_PUBLICATION_ID, publication.getId());
for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
String key = (String) e.nextElement();
String value = request.getParameter(key);
if (value != null) {
_taskParameters.setParameter(key, value);
}
}
String[] names = _parameters.getNames();
for (int i = 0; i < names.length; i++) {
String name = names[i];
String value = _parameters.getParameter(name, "");
if (value != null) {
_taskParameters.setParameter(name, value);
}
}
return _taskParameters;
}
/**
* Enables workflow transition invocation.
* @param eventName The event name.
* @param identity The identity that executes the task.
* @param roles The roles of the identity.
*/
public void setWorkflowAware(String eventName, Identity identity, Role[] roles) {
NamespaceMap workflowParameters = WorkflowInvoker.extractParameters(eventName,
identity,
roles);
getParameterObject().putAll(workflowParameters.getPrefixedMap());
}
/**
* Executes the task.
* @throws ExecutionException when something went wrong.
*/
public void execute() throws ExecutionException {
String taskId = getWrapperParameters().getTaskId();
if (taskId == null) {
throw new ExecutionException("No task id provided!");
}
log.info("===================================");
log.info(" Executing task [" + taskId + "]");
log.info("-----------------------------------");
if (!this.wrapperParameters.isComplete()) {
String[] missingKeys = getWrapperParameters().getMissingKeys();
String keyString = "";
for (int i = 0; i < missingKeys.length; i++) {
if (i > 0) {
keyString += ", ";
}
keyString += missingKeys[i];
}
throw new ExecutionException("Parameters missing: [" + keyString + "]");
}
TaskManager manager;
Publication publication = getTaskParameters().getPublication();
WorkflowInvoker workflowInvoker = new WorkflowInvoker(getParameters(), this.manager);
workflowInvoker.setup(publication, getWrapperParameters().getWebappUrl());
Task task;
try {
manager = new TaskManager(publication.getDirectory().getAbsolutePath(), this.manager);
task = manager.getTask(taskId);
Properties properties = new Properties();
properties.putAll(getTaskParameters().getMap());
Parameters _parameters = Parameters.fromProperties(properties);
task.parameterize(_parameters);
} catch (final ConfigurationException e) {
throw new ExecutionException(e);
} catch (final ParameterException e) {
throw new ExecutionException(e);
} catch (final SAXException e) {
throw new ExecutionException(e);
} catch (final IOException e) {
throw new ExecutionException(e);
} catch (ExecutionException e) {
throw e;
}
log.debug("-----------------------------------");
log.debug(" Triggering workflow");
log.debug("-----------------------------------");
// FIXME The new workflow is set before the end of the transition because the document id
// and so the document are sometimes changing during the transition (ex archiving , ...)
workflowInvoker.invokeTransition();
log.debug("-----------------------------------");
log.debug(" Triggering task");
log.debug("-----------------------------------");
task.execute(publication.getServletContext().getAbsolutePath());
log.debug("-----------------------------------");
log.debug(" Triggering notification");
log.debug("-----------------------------------");
Notifier notifier = new Notifier(manager, getParameters());
notifier.sendNotification(getTaskParameters());
log.debug("-----------------------------------");
log.debug(" Executing task finished.");
log.debug("===================================\n\n");
}
/**
* Returns the task wrapper parameters.
* @return A task wrapper parameters object.
*/
public TaskWrapperParameters getWrapperParameters() {
return this.wrapperParameters;
}
/**
* Returns the task parameters.
* @return A task parameters object.
*/
public TaskParameters getTaskParameters() {
return this.taskParameters;
}
protected static final String ELEMENT_TASK = "task";
protected static final String ELEMENT_PARAMETER = "parameter";
protected static final String ATTRIBUTE_NAME = "name";
protected static final String ATTRIBUTE_VALUE = "value";
/**
* Saves the wrapper parameters to an XML element.
* @param helper The namespace helper of the document.
* @return An XML element.
*/
public Element save(NamespaceHelper helper) {
org.w3c.dom.Document document = helper.getDocument();
NamespaceHelper taskHelper = new NamespaceHelper(Task.NAMESPACE,
Task.DEFAULT_PREFIX,
document);
Element element = taskHelper.createElement(ELEMENT_TASK);
List keys = new ArrayList(getParameters().keySet());
Collections.sort(keys);
for (Iterator i = keys.iterator(); i.hasNext();) {
String key = (String) i.next();
Element parameterElement = taskHelper.createElement(ELEMENT_PARAMETER);
parameterElement.setAttribute(ATTRIBUTE_NAME, key);
parameterElement.setAttribute(ATTRIBUTE_VALUE, (String) getParameters().get(key));
element.appendChild(parameterElement);
}
return element;
}
/**
* Restores the wrapper parameters from an XML element.
* @param parent The parent of the task wrapper element.
* @param helper The namespace helper of the document.
*/
public void restore(NamespaceHelper helper, Element parent) {
org.w3c.dom.Document document = helper.getDocument();
NamespaceHelper taskHelper = new NamespaceHelper(Task.NAMESPACE,
Task.DEFAULT_PREFIX,
document);
Element taskElement = taskHelper.getFirstChild(parent, ELEMENT_TASK);
Element[] parameterElements = taskHelper.getChildren(taskElement, ELEMENT_PARAMETER);
for (int i = 0; i < parameterElements.length; i++) {
String key = parameterElements[i].getAttribute(ATTRIBUTE_NAME);
String value = parameterElements[i].getAttribute(ATTRIBUTE_VALUE);
getParameterObject().put(key, value);
}
}
/**
* Returns all prefixed parameters.
* @return A map.
*/
public Map getParameters() {
return Collections.unmodifiableMap(this.parameters);
}
/**
* Returns all prefixed parameters.
* @return A map.
*/
protected Map getParameterObject() {
return this.parameters;
}
/**
* Sets the notification parameters.
* @param notificationParameters The notification parameters.
*/
protected void setNotifying(NamespaceMap notificationParameters) {
log.info("Enabling notification");
getParameterObject().putAll(notificationParameters.getPrefixedMap());
}
}