blob: 1b2c2f2a7839a91ade3b8d18de5d80093be66eee [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation
*
* Licensed 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.
*
*/
package org.apache.lenya.cms.workflow;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Locale;
import org.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.lenya.ac.Identity;
import org.apache.lenya.cms.publication.DocumentException;
import org.apache.lenya.cms.publication.ResourceType;
import org.apache.lenya.cms.repo.ContentNode;
import org.apache.lenya.cms.repo.Document;
import org.apache.lenya.cms.repo.DocumentType;
import org.apache.lenya.cms.repo.RepositoryException;
import org.apache.lenya.cms.repo.Session;
import org.apache.lenya.cms.repo.metadata.MetaData;
import org.apache.lenya.workflow.Version;
import org.apache.lenya.workflow.Workflow;
import org.apache.lenya.workflow.Workflowable;
/**
* Workflowable around a CMS document.
*
* @version $Id$
*/
public class DocumentWorkflowable extends AbstractLogEnabled implements Workflowable {
/**
* Ctor.
* @param manager The service manager.
* @param document The document.
* @param logger The logger.
*/
public DocumentWorkflowable(ServiceManager manager, Document document, Logger logger) {
this.document = document;
this.manager = manager;
ContainerUtil.enableLogging(this, logger);
}
private ServiceManager manager;
/**
* @return The service manager.
*/
public ServiceManager getServiceManager() {
return this.manager;
}
/**
* @return The repository session.
*/
public Session getSession() {
try {
return getDocument().getContentNode()
.getContent()
.getArea()
.getPublication()
.getSession();
} catch (RepositoryException e) {
throw new RuntimeException(e);
}
}
private Document document;
protected Document getDocument() {
return this.document;
}
/**
* @return The name of the workflow schema.
*/
protected String getWorkflowSchema() {
String workflowName = null;
try {
ContentNode node = document.getContentNode();
DocumentType doctype = node.getDocumentType();
if (doctype != null) {
workflowName = node.getContent()
.getArea()
.getPublication()
.getWorkflowSchema(doctype);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return workflowName;
}
private Version[] versions = null;
/**
* @see org.apache.lenya.workflow.Workflowable#getVersions()
*/
public Version[] getVersions() {
if (this.versions == null) {
try {
MetaData meta = this.document.getMetaData("workflow");
String[] versionStrings = meta.getValues("version");
this.versions = new Version[versionStrings.length];
for (int i = 0; i < versionStrings.length; i++) {
String string = versionStrings[i];
int spaceIndex = string.indexOf(" ");
String numberString = string.substring(0, spaceIndex);
int number = Integer.parseInt(numberString);
String versionString = string.substring(spaceIndex + 1);
Version version = decodeVersion(versionString);
this.versions[number] = version;
}
} catch (RepositoryException e) {
throw new RuntimeException();
}
}
return this.versions;
}
/**
* @see org.apache.lenya.workflow.Workflowable#getLatestVersion()
*/
public Version getLatestVersion() {
Version version = null;
Version[] versions = getVersions();
if (versions.length > 0) {
version = versions[versions.length - 1];
}
return version;
}
/**
* @see org.apache.lenya.workflow.Workflowable#newVersion(org.apache.lenya.workflow.Workflow,
* org.apache.lenya.workflow.Version)
*/
public void newVersion(Workflow workflow, Version version) {
Version[] newVersions = new Version[getVersions().length + 1];
for (int i = 0; i < getVersions().length; i++) {
newVersions[i] = getVersions()[i];
}
int number = newVersions.length - 1;
newVersions[number] = version;
String string = number + " " + encodeVersion(workflow, version);
try {
MetaData meta = this.document.getMetaData("workflow");
meta.addValue("version", string);
} catch (RepositoryException e) {
throw new RuntimeException(e);
}
}
protected String encodeVersion(Workflow workflow, Version version) {
String string = "event:" + version.getEvent();
string += " state:" + version.getState();
Identity identity = getSession().getUnitOfWork().getIdentity();
string += " user:" + identity.getUser().getId();
string += " machine:" + identity.getMachine().getIp();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
string += " date:" + format.format(new Date());
String names[] = workflow.getVariableNames();
for (int i = 0; i < names.length; i++) {
String value = Boolean.toString(version.getValue(names[i]));
string += " var:" + names[i] + "=" + value;
}
return string;
}
protected Version decodeVersion(String string) {
String event = null;
String state = null;
String user = null;
String machine = null;
Date date = null;
Map variables = new HashMap();
String[] parts = string.split(" ");
for (int i = 0; i < parts.length; i++) {
String[] steps = parts[i].split(":", 2);
if (steps[0].equals("event")) {
event = steps[1];
} else if (steps[0].equals("state")) {
state = steps[1];
} else if (steps[0].equals("user")) {
user = steps[1];
} else if (steps[0].equals("date")) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.US);
date = sdf.parse(steps[1], new ParsePosition(0));
} else if (steps[0].equals("machine")) {
machine = steps[1];
} else if (steps[0].equals("var")) {
String[] nameValue = steps[1].split("=");
variables.put(nameValue[0], nameValue[1]);
}
}
Version version = new LenyaVersion(event, state);
for (Iterator i = variables.keySet().iterator(); i.hasNext();) {
String name = (String) i.next();
String value = (String) variables.get(name);
version.setUserId(user);
version.setDate(date);
version.setIPAddress(machine);
version.setValue(name, Boolean.valueOf(value).booleanValue());
}
return version;
}
/**
* @see org.apache.lenya.workflow.Workflowable#getWorkflowSchemaURI()
*/
public String getWorkflowSchemaURI() {
String uri = null;
String schema = getWorkflowSchema();
if (schema != null) {
if (schema.indexOf("://") != -1) {
return schema;
} else {
uri = this.document.getPublication().getSourceURI() + "/config/workflow/" + schema;
uri = uri.substring("lenya://".length());
uri = "context://" + uri;
}
}
return uri;
}
}