Notifier und Workflow Config verbessert, diverse Formatierungen.

git-svn-id: https://svn.libreccm.org/ccm/trunk@771 8810af33-2d31-482b-a856-94f89814c4df
master
pb 2011-02-28 23:37:34 +00:00
parent 8a6e166826
commit f7b4ce9292
21 changed files with 267 additions and 155 deletions

View File

@ -56,8 +56,6 @@ import org.apache.log4j.Logger;
// The module in its complete version (i.e. all method invocations in run() // The module in its complete version (i.e. all method invocations in run()
// method commented IN(!) does load all packages into database and // method commented IN(!) does load all packages into database and
// ccm/admin/sitemap lists them appropriately. // ccm/admin/sitemap lists them appropriately.
// Not yet found a way to mount them in the URL tree while initializing.
// This is true using the old style application using package / sitenode
// //
// Next Try // Next Try
// Refactor using legacy compatible web/Application and ApplicationSetup // Refactor using legacy compatible web/Application and ApplicationSetup
@ -91,11 +89,10 @@ public class Loader extends PackageLoader {
/** Creates a s_logging category with name = full name of class */ /** Creates a s_logging category with name = full name of class */
private static final Logger s_log = Logger.getLogger(Loader.class); private static final Logger s_log = Logger.getLogger(Loader.class);
// Load main CMS configuration file
private static final LoaderConfig s_conf = new LoaderConfig(); /** Loader configuration object, singleton design pattern */
// static { // requirred to actually read the config file private static final LoaderConfig s_conf = LoaderConfig.getInstance();
// s_config.load();
// }
/** /**
* Constant string used as key for creating CMS (content-section) as a * Constant string used as key for creating CMS (content-section) as a
* legacy application. * legacy application.
@ -106,10 +103,12 @@ public class Loader extends PackageLoader {
*/ */
private final static String CMS_DISPATCHER_CLASS = private final static String CMS_DISPATCHER_CLASS =
"com.arsdigita.cms.dispatcher.ContentSectionDispatcher"; "com.arsdigita.cms.dispatcher.ContentSectionDispatcher";
/**
* Stylesheet which has to be assigned as part of a legacy application // /**
* creation. // * Stylesheet which has to be assigned as part of a legacy application
*/ // * creation.
// */
// Assigned stylesheets no longer used and base class removed.
// private final static String CMS_STYLESHEET = // private final static String CMS_STYLESHEET =
// "/packages/content-section/xsl/cms.xsl"; // "/packages/content-section/xsl/cms.xsl";
// /** // /**

View File

@ -42,8 +42,35 @@ import org.apache.log4j.Logger;
*/ */
public final class LoaderConfig extends AbstractConfig { public final class LoaderConfig extends AbstractConfig {
/** Local logger instance fpr debug support */
private static final Logger s_log = Logger.getLogger(LoaderConfig.class); private static final Logger s_log = Logger.getLogger(LoaderConfig.class);
/** Private Object to hold one's own instance to return to users. */
private static LoaderConfig s_conf;
/**
* Returns the singleton configuration record for Loader configuration.
*
* @return The <code>ContentSectionConfig</code> record; it cannot be null
*/
public static synchronized LoaderConfig getInstance() {
if (s_conf == null) {
s_conf = new LoaderConfig();
/* Currently LoaderConfig does not process parameters stored in a
* properties file. In order to do so the class must be added to
* ccm-cms.config, a storage file specified and the load() commented
* in.
* Before it can be used meaningfully, ccm-xxx-aplaws must be enhanced
* to be able tp process dynamically e.g. section name and other
* parameter values. Currently, section name is hardcoded (content) as
* well as creating terms domains etc.
*/
// s_conf.load();
}
return s_conf;
}
// /** // /**
// * The name of the workspace package instance, i.e. URL of the workspace, // * The name of the workspace package instance, i.e. URL of the workspace,
// * where authors, editors and publishers are working and from which they // * where authors, editors and publishers are working and from which they
@ -145,7 +172,6 @@ public final class LoaderConfig extends AbstractConfig {
"com.arsdigita.cms.loader.section_name", "com.arsdigita.cms.loader.section_name",
Parameter.REQUIRED, Parameter.REQUIRED,
"content"); "content");
//"public");
// Root Folder, set autonomously by ContentSection.create() method // Root Folder, set autonomously by ContentSection.create() method

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. * Copyright (C) 2009 Peter Boy <pb@zes.uni-bremen.de> All Rights Reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -55,7 +55,7 @@ public final class ContentSectionConfig extends AbstractConfig {
* *
* @return The <code>ContentSectionConfig</code> record; it cannot be null * @return The <code>ContentSectionConfig</code> record; it cannot be null
*/ */
public static final synchronized ContentSectionConfig getInstance() { public static synchronized ContentSectionConfig getInstance() {
if (s_config == null) { if (s_config == null) {
s_config = new ContentSectionConfig(); s_config = new ContentSectionConfig();
s_config.load(); s_config.load();

View File

@ -49,10 +49,11 @@ import org.apache.log4j.Logger;
* Initializes the content section sub-package of the CMS package (module). * Initializes the content section sub-package of the CMS package (module).
* *
* XXX Reformulate according to the code development! * XXX Reformulate according to the code development!
* Currently: * This initializer performs:
* - creation of additional content sections during restart (comming soon) * - check whether to create an additional content sections during restart
* - initializes alert preferences for each content section * - initializes alert preferences for each content section
* - initializes overdue alerts for each content section * - initializes overdue alerts for each content section
*
* In the (hopefully) near future: * In the (hopefully) near future:
* Content section specific tasks of cms.Initializer will be moved into this * Content section specific tasks of cms.Initializer will be moved into this
* Initializer. * Initializer.
@ -61,15 +62,15 @@ import org.apache.log4j.Logger;
* @author Daniel Berrange (berrange@redhat.com) * @author Daniel Berrange (berrange@redhat.com)
* @author Michael Pih * @author Michael Pih
* @author pboy (pb@zes.uni-bremen.de) * @author pboy (pb@zes.uni-bremen.de)
* @version $Id: $ * @version $Id: Initializer.java $
*/ */
public class Initializer extends CompoundInitializer { public class Initializer extends CompoundInitializer {
/** Creates a s_logging category with name = to the full name of class */ /** Creates a s_logging category with name = to the full name of class */
private static Logger s_log = Logger.getLogger(Initializer.class); private static Logger s_log = Logger.getLogger(Initializer.class);
/** Local configuration object ContentSectionConfig containing parameters /** Configuration object ContentSectionConfig containing parameters
which may be changed each system startup. */ which may be changed each system startup. */
private static final ContentSectionConfig s_conf = ContentSectionConfig private static final ContentSectionConfig s_conf = ContentSectionConfig
.getInstance(); .getInstance();
@ -83,7 +84,7 @@ public class Initializer extends CompoundInitializer {
//final int database = DbHelper.getDatabaseFromURL(url); //final int database = DbHelper.getDatabaseFromURL(url);
} }
// Currently nothing to do here. Will be changed in the ongoing migration process // Currently nothing to do here. May change during the ongoing migration process
// /** // /**
// * An empty implementation of {@link Initializer#init(DataInitEvent)}. // * An empty implementation of {@link Initializer#init(DataInitEvent)}.
// * // *
@ -96,10 +97,11 @@ public class Initializer extends CompoundInitializer {
* Initializes domain-coupling machinery, usually consisting of * Initializes domain-coupling machinery, usually consisting of
* registering object instantiators and observers. * registering object instantiators and observers.
* *
* Here additionally checks whether to create a new content section.
*/ */
@Override @Override
public void init(DomainInitEvent evt) { public void init(DomainInitEvent evt) {
s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) invoked"); s_log.debug("contentsection.Initializer.init(DomainInitEvent) invoked");
// Recursive invokation of init! // Recursive invokation of init!
// An empty implementations prevents this initializer from being executed. // An empty implementations prevents this initializer from being executed.
@ -119,7 +121,7 @@ public class Initializer extends CompoundInitializer {
// specified in config file. // specified in config file.
checkForNewContentSection(); checkForNewContentSection();
s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) completed"); s_log.debug("contentsection.Initializer.init(DomainInitEvent) completed");
} }
@ -128,8 +130,8 @@ public class Initializer extends CompoundInitializer {
* method. * method.
* *
* Steps through all installed content sections and for each section * Steps through all installed content sections and for each section
* - initializes the allert preferences * - initializes the alert preferences
* - initializes the scheduler background thread to fire all all alert events. * - initializes the scheduler background thread to fire all alert events.
* *
* A delay value of 0 inhibits start of processing. * A delay value of 0 inhibits start of processing.
* @param evt The context init event. * @param evt The context init event.
@ -154,6 +156,7 @@ public class Initializer extends CompoundInitializer {
// file filling a hashmap. // file filling a hashmap.
initializeTaskAlerts(section, s_conf.getTaskAlerts() ); initializeTaskAlerts(section, s_conf.getTaskAlerts() );
// create a standard java util timer object
Timer unfinishedTimer = startNotifierTask( Timer unfinishedTimer = startNotifierTask(
section, section,
s_conf.getSendOverdueAlerts(), s_conf.getSendOverdueAlerts(),
@ -182,7 +185,8 @@ public class Initializer extends CompoundInitializer {
Timer unfinishedTimer = null; Timer unfinishedTimer = null;
if (s_unfinishedTimers.size() > 0) { if (s_unfinishedTimers.size() > 0) {
for (Enumeration el=s_unfinishedTimers.elements(); el.hasMoreElements(); ) { for (Enumeration el=s_unfinishedTimers.elements();
el.hasMoreElements(); ) {
unfinishedTimer = (Timer) el.nextElement(); unfinishedTimer = (Timer) el.nextElement();
if(unfinishedTimer != null) unfinishedTimer.cancel(); if(unfinishedTimer != null) unfinishedTimer.cancel();
unfinishedTimer = null; unfinishedTimer = null;
@ -271,12 +275,12 @@ public class Initializer extends CompoundInitializer {
* @param max * @param max
* @return * @return
*/ */
private final Timer startNotifierTask( ContentSection section, private Timer startNotifierTask( ContentSection section,
Boolean sendOverdue, Boolean sendOverdue,
Integer duration, Integer duration,
Integer alertInterval, Integer alertInterval,
Integer max Integer max
) { ) {
Timer unfinished = null; Timer unfinished = null;
if (sendOverdue.booleanValue()) { if (sendOverdue.booleanValue()) {
if (duration == null || alertInterval == null || max == null) { if (duration == null || alertInterval == null || max == null) {

View File

@ -51,7 +51,7 @@ import com.arsdigita.web.URL;
import com.arsdigita.workflow.simple.TaskComment; import com.arsdigita.workflow.simple.TaskComment;
import com.arsdigita.workflow.simple.TaskException; import com.arsdigita.workflow.simple.TaskException;
import com.arsdigita.workflow.simple.UserTask; import com.arsdigita.workflow.simple.UserTask;
import org.apache.log4j.Logger;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
@ -62,6 +62,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.log4j.Logger;
/** /**
* This class represents a task in the CMS system. This task is * This class represents a task in the CMS system. This task is
* Assignable, and has an associated task type. The task type * Assignable, and has an associated task type. The task type
@ -158,6 +160,7 @@ public class CMSTask extends UserTask {
* Initialize setting the TaskType to Authoring by default. * Initialize setting the TaskType to Authoring by default.
* *
**/ **/
@Override
protected void initialize() { protected void initialize() {
super.initialize(); super.initialize();
if (isNew()) { if (isNew()) {
@ -213,6 +216,11 @@ public class CMSTask extends UserTask {
query.close(); query.close();
} }
} }
/**
*
*/
@Override
public void enableEvt() { public void enableEvt() {
super.enableEvt(); super.enableEvt();
// Remove the record of previously sent "unfinished notifications". // Remove the record of previously sent "unfinished notifications".
@ -224,12 +232,18 @@ public class CMSTask extends UserTask {
oper.execute(); oper.execute();
} }
/**
*
* @param taskTypeID
* @return
*/
private TaskURLGenerator getURLGenerator(Integer taskTypeID) { private TaskURLGenerator getURLGenerator(Integer taskTypeID) {
TaskURLGenerator t = (TaskURLGenerator) TaskURLGenerator t = (TaskURLGenerator)
s_taskURLGeneratorCache.get(taskTypeID); s_taskURLGeneratorCache.get(taskTypeID);
if (t == null) { if (t == null) {
Session s = SessionManager.getSession(); Session s = SessionManager.getSession();
DataQuery query = s.retrieveQuery("com.arsdigita.cms.workflow.getTaskTypes"); DataQuery query = s.retrieveQuery(
"com.arsdigita.cms.workflow.getTaskTypes");
query.addEqualsFilter("Id", taskTypeID); query.addEqualsFilter("Id", taskTypeID);
if (query.next()) { if (query.next()) {
String className = (String)query.get("className"); String className = (String)query.get("className");
@ -251,12 +265,20 @@ public class CMSTask extends UserTask {
return t; return t;
} }
/**
*
* @param operation
* @param sender
* @return
*/
@Override
protected Message generateMessage(String operation, Party sender) { protected Message generateMessage(String operation, Party sender) {
ContentItem item = getItem(); ContentItem item = getItem();
Assert.exists(item, "item associated with this CMSTask"); Assert.exists(item, "item associated with this CMSTask");
String authoringURL = getAuthoringURL(item); String authoringURL = getAuthoringURL(item);
String fullURL = getTaskType().getURLGenerator(operation, item).generateURL(item.getID(), getID()); String fullURL = getTaskType().getURLGenerator(operation, item)
.generateURL(item.getID(), getID());
s_log.debug("URL retrieved from generator: " + fullURL); s_log.debug("URL retrieved from generator: " + fullURL);
if (!fullURL.startsWith("http")) { if (!fullURL.startsWith("http")) {
// url is not fully qualified // url is not fully qualified
@ -282,17 +304,22 @@ public class CMSTask extends UserTask {
if (commenter != null) { if (commenter != null) {
g11nArgs[7] = commenter.getName(); g11nArgs[7] = commenter.getName();
} else { } else {
g11nArgs[7] = (String) GlobalizationUtil.globalize("cms.ui.unknown").localize(); g11nArgs[7] = (String) GlobalizationUtil
.globalize("cms.ui.unknown").localize();
} }
g11nArgs[8] = getStartDate(); g11nArgs[8] = getStartDate();
g11nArgs[9] = URL.there(authoringURL, null).getURL(); g11nArgs[9] = URL.there(authoringURL, null).getURL();
//if added to email, allows recipient to identify if the item is in a folder //if added to email, allows recipient to identify if the item is in a folder
// they are interested in // they are interested in
g11nArgs[10] = ((ContentItem)item.getParent()).getPath(); g11nArgs[10] = ((ContentItem)item.getParent()).getPath();
String subject = (String) GlobalizationUtil.globalize("cms.ui.workflow.email.subject." + operation, String subject = (String) GlobalizationUtil
g11nArgs).localize(); .globalize("cms.ui.workflow.email.subject."
String body = (String) GlobalizationUtil.globalize("cms.ui.workflow.email.body." + operation, + operation,
g11nArgs).localize(); g11nArgs).localize();
String body = (String) GlobalizationUtil
.globalize("cms.ui.workflow.email.body."
+ operation,
g11nArgs).localize();
Message msg = new Message(sender, subject, body); Message msg = new Message(sender, subject, body);
msg.save(); msg.save();
return msg; return msg;
@ -389,30 +416,56 @@ public class CMSTask extends UserTask {
// default if _ALL - send alert to all task assignees // default if _ALL - send alert to all task assignees
String recipients = ALERT_RECIPIENT_ALL; String recipients = ALERT_RECIPIENT_ALL;
if (operation.endsWith(ALERT_RECIPIENT_LASTAUTHOR)) { if (operation.endsWith(ALERT_RECIPIENT_LASTAUTHOR)) {
operation = operation.substring(0,operation.length() - ALERT_RECIPIENT_LASTAUTHOR.length()); operation = operation.substring(0,
operation.length() -
ALERT_RECIPIENT_LASTAUTHOR.length());
authorOnlySet.add(operation); authorOnlySet.add(operation);
recipients = ALERT_RECIPIENT_LASTAUTHOR; recipients = ALERT_RECIPIENT_LASTAUTHOR;
} else if (operation.endsWith(ALERT_RECIPIENT_ALL)) { } else if (operation.endsWith(ALERT_RECIPIENT_ALL)) {
operation = operation.substring(0,operation.length() - ALERT_RECIPIENT_ALL.length()); operation = operation.substring(0,operation.length()
- ALERT_RECIPIENT_ALL.length());
} }
operationSet.add(operation); operationSet.add(operation);
s_log.info("Added alert for \"" + operation + "\" of " + typeLabel + s_log.info("Added alert for \"" + operation + "\" of " + typeLabel +
" task in section \"" + section.getName() + "\" recipients flag: "+recipients); " task in section \"" + section.getName() +
"\" recipients flag: "+recipients);
} }
/**
*
* @param section
* @param typeLabel
* @param operation
* @return
*/
protected static boolean shouldSendAlert(ContentSection section, protected static boolean shouldSendAlert(ContentSection section,
String typeLabel, String typeLabel,
String operation) { String operation) {
return checkAlertsConfig(section, typeLabel, operation, ALERT_OPERATIONS); return checkAlertsConfig(section, typeLabel, operation, ALERT_OPERATIONS);
} }
/**
*
* @param section
* @param typeLabel
* @param operation
* @return
*/
protected static boolean shouldSendToAuthorOnly(ContentSection section, protected static boolean shouldSendToAuthorOnly(ContentSection section,
String typeLabel, String typeLabel,
String operation) { String operation) {
return checkAlertsConfig(section, typeLabel, operation, ALERT_RECIPIENTS); return checkAlertsConfig(section, typeLabel, operation, ALERT_RECIPIENTS);
} }
/**
*
* @param section
* @param typeLabel
* @param operation
* @param field
* @return
*/
private static boolean checkAlertsConfig(ContentSection section, private static boolean checkAlertsConfig(ContentSection section,
String typeLabel, String typeLabel,
String operation, String operation,
@ -440,10 +493,16 @@ public class CMSTask extends UserTask {
if (operationSet != null) { if (operationSet != null) {
send = operationSet.contains(operation); send = operationSet.contains(operation);
} }
s_log.debug("operation " + operation + " field " + field + " of task " + typeLabel + "?: " + send); s_log.debug("operation " + operation + " field " + field + " of task "
+ typeLabel + "?: " + send);
return send; return send;
} }
/**
*
* @param operation
* @return
*/
@Override @Override
protected boolean sendAlerts(String operation) { protected boolean sendAlerts(String operation) {
ContentSection section = getContentSection(); ContentSection section = getContentSection();
@ -475,7 +534,8 @@ public class CMSTask extends UserTask {
// XXX lastModifiedUser in audit trail is overwritten on each save // XXX lastModifiedUser in audit trail is overwritten on each save
// author = item.getLastModifiedUser(); // author = item.getLastModifiedUser();
// workaround: use the latest history record with 'Authored' tag // workaround: use the latest history record with 'Authored' tag
TransactionCollection hist = Versions.getTaggedTransactions(item.getOID()); TransactionCollection hist = Versions
.getTaggedTransactions(item.getOID());
while (author == null && hist.next()) { while (author == null && hist.next()) {
Transaction txn = hist.getTransaction(); Transaction txn = hist.getTransaction();
TagCollection tags = txn.getTags(); TagCollection tags = txn.getTags();
@ -484,13 +544,14 @@ public class CMSTask extends UserTask {
if ("Authored".equals(tag)) { if ("Authored".equals(tag)) {
author = txn.getUser(); author = txn.getUser();
if (s_log.isDebugEnabled()) { if (s_log.isDebugEnabled()) {
s_log.debug("author from hist="+author+" at "+txn.getTimestamp()); s_log.debug("author from hist="+author+" at "+
txn.getTimestamp());
} }
} }
} }
} }
// bugfix - if author is null above then we break out // bugfix - if author is null above then we break out of loop
// of loop early. If normal exit and so cursor has already closed then the // early. If normal exit and so cursor has already closed then the
// next line has no effect // next line has no effect
hist.close(); hist.close();
if (author == null) { if (author == null) {
@ -512,8 +573,8 @@ public class CMSTask extends UserTask {
return; return;
} }
/* NOTE: /* NOTE:
* it would be cleaner to simply change getAssignedUsers() * it would be cleaner to simply change getAssignedUsers() to do what
* to do what we want; however that is used by cms.ui.workflow.UserTaskComponent * we want; however that is used by cms.ui.workflow.UserTaskComponent
* and I didn't want to break that. * and I didn't want to break that.
* Plus the API doesn't state exactly what getAssignedUsers() * Plus the API doesn't state exactly what getAssignedUsers()
* is supposed to return, so I decided to leave it alone. * is supposed to return, so I decided to leave it alone.
@ -540,7 +601,8 @@ public class CMSTask extends UserTask {
uc = User.retrieveAll(); uc = User.retrieveAll();
uc.addFilter("allGroups in :assignedGroups").set("assignedGroups", groups); uc.addFilter("allGroups in :assignedGroups").set("assignedGroups",
groups);
filterUsersAndSendMessage(uc, msg); filterUsersAndSendMessage(uc, msg);
} }

View File

@ -18,6 +18,8 @@
storage="ccm-core/security.properties"/> storage="ccm-core/security.properties"/>
<config class="com.arsdigita.mail.MailConfig" <config class="com.arsdigita.mail.MailConfig"
storage="ccm-core/mail.properties"/> storage="ccm-core/mail.properties"/>
<config class="com.arsdigita.notification.NotificationConfig"
storage="ccm-core/notification.properties"/>
<config class="com.arsdigita.profiler.ProfilerConfig" <config class="com.arsdigita.profiler.ProfilerConfig"
storage="ccm-core/profiler.properties"/> storage="ccm-core/profiler.properties"/>
<config class="com.arsdigita.runtime.RuntimeConfig" <config class="com.arsdigita.runtime.RuntimeConfig"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. * Copyright (C) 2010 pboy (pboy@barkhof.uni-bremen.de) All Rights Reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -45,11 +45,11 @@ import org.apache.log4j.Logger;
* *
* @author David Dao * @author David Dao
* @author Peter Boy (pboy@barkhof.uni-bremen.de) * @author Peter Boy (pboy@barkhof.uni-bremen.de)
* @version $Id: $ * @version $Id: Initializer.java $
*/ */
public class Initializer extends GenericInitializer { public class Initializer extends GenericInitializer {
// Creates a s_logging category with name = to the full name of class /** Creates a s_logging category with name = to the full name of class */
public static final Logger s_log = Logger.getLogger(Initializer.class); public static final Logger s_log = Logger.getLogger(Initializer.class);
// Timer threads. Each one is started as a daemon. // Timer threads. Each one is started as a daemon.
@ -86,10 +86,11 @@ public class Initializer extends GenericInitializer {
* *
* @param evt The context init event. * @param evt The context init event.
**/ **/
@Override
public void init(ContextInitEvent evt) { public void init(ContextInitEvent evt) {
s_log.debug("notification background startup begin."); s_log.debug("notification background startup begin.");
NotificationConfig conf = NotificationConfig.getConfig(); NotificationConfig conf = NotificationConfig.getInstance();
s_log.debug("Notification configuration loaded."); s_log.debug("Notification configuration loaded.");
NotificationRequestManagerTimer.scheduleAtFixedRate( NotificationRequestManagerTimer.scheduleAtFixedRate(
@ -119,6 +120,7 @@ public class Initializer extends GenericInitializer {
* Stops background threads started during initialization so the servlet * Stops background threads started during initialization so the servlet
* container can terminate the applications main thread. * container can terminate the applications main thread.
*/ */
@Override
public void close(ContextCloseEvent evt) { public void close(ContextCloseEvent evt) {
NotificationSimpleQueueTimer.cancel(); NotificationSimpleQueueTimer.cancel();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved. * Copyright (C) 2011 pboy (pboy@barkhof.uni-bremen.de) All Rights Reserved.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -27,19 +27,43 @@ import org.apache.log4j.Logger;
/** /**
* NotificationConfig * NotificationConfig
* *
* FixMe:
* invoking load() breaks for some reason the container startup process.
* As a temporary measure it is disabled and we return constants.
*
* @author Peter Boy &lt;pboy@barkhof.uni-bremen.de&gt; * @author Peter Boy &lt;pboy@barkhof.uni-bremen.de&gt;
* @version $Id: $ * @version $Id: NotificationConfig.java $
*/ */
public class NotificationConfig extends AbstractConfig { public class NotificationConfig extends AbstractConfig {
/** Private Logger instance. */
private static final Logger s_log = Logger.getLogger(NotificationConfig.class); private static final Logger s_log = Logger.getLogger(NotificationConfig.class);
/** Private Object to hold one's own instance to return to users. */
private static NotificationConfig s_conf; private static NotificationConfig s_conf;
/**
* Returns the singleton configuration record for the content section
* environment.
*
* @return The <code>ContentSectionConfig</code> record; it cannot be null
*/
public static synchronized NotificationConfig getInstance() {
if (s_conf == null) {
s_conf = new NotificationConfig();
s_conf.load();
}
return s_conf;
}
// /////////////////////////////////////////////////////////////////////////////
//
// Set of parameters controlling Overdue Task alerts:
// Currently there is no way to persist it nor to persist on a per section base.
// Therefore Initializer has to create overdue task alert mechanism using a
// configuration applied to every content section.
//
// /////////////////////////////////////////////////////////////////////////////
/** /**
* Request manager's delay in seconds. * Request manager's delay in seconds.
@ -85,7 +109,7 @@ public class NotificationConfig extends AbstractConfig {
/** /**
* Constructor. * Constructor.
* Do not use it directly! * Do not use it directly! Singleton design pattern!
*/ */
public NotificationConfig() { public NotificationConfig() {
s_log.debug("Executing NotificationConfig Constructor."); s_log.debug("Executing NotificationConfig Constructor.");
@ -102,29 +126,6 @@ public class NotificationConfig extends AbstractConfig {
s_log.debug("Leaving NotificationConfig Constructor."); s_log.debug("Leaving NotificationConfig Constructor.");
} }
/**
* Get a NotificationConfig instance.
*
* Singelton pattern, don't instantiate a notificationConfig object using
* the constructor directly.
* @return
*/
static synchronized NotificationConfig getConfig() {
s_log.debug("NotificationConfig object requested.");
if (s_conf == null) {
s_log.debug("Instantiating NotificationConfig object.");
s_conf = new NotificationConfig();
s_log.debug("Got NotificationConfig object.");
// FixMe:
// invoking load() breaks for some reason the container startup
// process.
// As a temporary measure it is disabled and we return constants.
// s_conf.load();
s_log.debug("NotificationConfig object instantiated.");
}
return s_conf;
}
/** /**
* Retrieve request manager's delay in seconds. * Retrieve request manager's delay in seconds.

View File

@ -3,10 +3,9 @@
<head> <head>
<title>com.arsdigita.workflow</title> <title>com.arsdigita.workflow</title>
</head> </head>
<body bgcolor="white"> <body>
<p> <p>
<b><font color=red>Experimental</font></b> <b><font color=red>Experimental</font></b>
The Workflow service provides a tool framework for establishing The Workflow service provides a tool framework for establishing

View File

@ -30,12 +30,10 @@ import com.arsdigita.kernel.Group;
* @author Karl GoldStein * @author Karl GoldStein
* @author Khy Huang * @author Khy Huang
* @author Stefan Deusch * @author Stefan Deusch
* * @version $Id: Assignable.java 287 2005-02-22 00:29:02Z sskracic $
**/ */
public interface Assignable { public interface Assignable {
public static final String versionId = "$Id: Assignable.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
/** /**
* Assigns a user to this task. (persistent operation) * Assigns a user to this task. (persistent operation)
* *

View File

@ -30,15 +30,13 @@ import java.util.Date;
* *
* @author Stefan Deusch * @author Stefan Deusch
* @author Khy Huang * @author Khy Huang
* @version $Id: Duration.java 287 2005-02-22 00:29:02Z sskracic $
**/ **/
public class Duration { public class Duration {
public static final String versionId = "$Id: Duration.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
/** the duration in minutes */
/**
* the duration in minutes
*/
private int m_duration = 0; private int m_duration = 0;
/** Start date */
private Date m_startDate = new Date(); private Date m_startDate = new Date();
/** /**
@ -121,7 +119,7 @@ public class Duration {
* @param minutes the duration in minutes * @param minutes the duration in minutes
* *
**/ **/
public void setDuration(int days, int hours, int minutes) { public final void setDuration(int days, int hours, int minutes) {
setDuration(days*24*60 + hours*60 + minutes); setDuration(days*24*60 + hours*60 + minutes);
} }
@ -131,7 +129,7 @@ public class Duration {
* @param minutes the duration in minutes * @param minutes the duration in minutes
* *
**/ **/
public void setDuration(int minutes) { public final void setDuration(int minutes) {
m_duration = minutes; m_duration = minutes;
} }

View File

@ -19,8 +19,11 @@
package com.arsdigita.workflow.simple; package com.arsdigita.workflow.simple;
/**
*
* @version $Id: ProcessDefEvent.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class ProcessDefEvent { public class ProcessDefEvent {
public static final String versionId = "$Id: ProcessDefEvent.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
private String m_action; private String m_action;
private Task m_srcProcessDef; private Task m_srcProcessDef;

View File

@ -21,9 +21,10 @@ package com.arsdigita.workflow.simple;
/** /**
* Standard exception for Process and Task action methods to throw when * Standard exception for Process and Task action methods to throw when
* illegal operations are attempted. * illegal operations are attempted.
*
* @version $Id: ProcessException.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
public class ProcessException extends TaskException { public class ProcessException extends TaskException {
public static final String versionId = "$Id: ProcessException.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
public ProcessException(String s) { public ProcessException(String s) {
super(s); super(s);

View File

@ -18,16 +18,6 @@
*/ */
package com.arsdigita.workflow.simple; package com.arsdigita.workflow.simple;
// duplicate import statements, copy&paste error
// import com.arsdigita.auditing.AuditedACSObject;
// import com.arsdigita.domain.DataObjectNotFoundException;
// import com.arsdigita.kernel.User;
// import com.arsdigita.persistence.DataAssociation;
// import com.arsdigita.persistence.DataAssociationCursor;
// import com.arsdigita.persistence.DataObject;
// import com.arsdigita.persistence.OID;
// import com.arsdigita.persistence.SessionManager;
// import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.auditing.AuditedACSObject; import com.arsdigita.auditing.AuditedACSObject;
import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainObjectFactory;
@ -40,7 +30,6 @@ import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.metadata.ObjectType; import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
// import com.arsdigita.workflow.simple.Workflow;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
@ -73,12 +62,11 @@ import org.apache.log4j.Logger;
* @author Uday Mathur * @author Uday Mathur
* @author Khy Huang * @author Khy Huang
* @author Stefan Deusch * @author Stefan Deusch
* @version $Id: Task.java 1278 2006-07-27 09:09:51Z cgyg9330 $
**/ **/
public class Task extends AuditedACSObject implements Cloneable { public class Task extends AuditedACSObject implements Cloneable {
public static final String versionId =
"$Id: Task.java 1278 2006-07-27 09:09:51Z cgyg9330 $" + private static final Logger s_log = Logger.getLogger(Task.class);
"$Author: cgyg9330 $" +
"$DateTime: 2004/08/16 18:10:38 $";
public static final String BASE_DATA_OBJECT_TYPE = public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.workflow.simple.Task"; "com.arsdigita.workflow.simple.Task";
@ -101,9 +89,6 @@ public class Task extends AuditedACSObject implements Cloneable {
public final static int DELETED = 3; public final static int DELETED = 3;
public final static int INACTIVE = 4; public final static int INACTIVE = 4;
private static final Logger s_log =
Logger.getLogger(Task.class);
//-------------------- Constructors Section ------------------------------- //-------------------- Constructors Section -------------------------------
/** /**
* Creates a new task. Properties of this object are not * Creates a new task. Properties of this object are not
@ -186,6 +171,7 @@ public class Task extends AuditedACSObject implements Cloneable {
* Initializes a task. * Initializes a task.
* *
**/ **/
@Override
protected void initialize() { protected void initialize() {
super.initialize(); super.initialize();
if (isNew()) { if (isNew()) {
@ -199,13 +185,13 @@ public class Task extends AuditedACSObject implements Cloneable {
/** /**
* Sets the label and dDescription for this task. * Sets the label and description for this task.
* *
* @param label the task label * @param label the task label
* @param description the task description * @param description the task description
* *
**/ **/
protected void initAttributes(String label, String description) { protected final void initAttributes(String label, String description) {
setLabel(label); setLabel(label);
setDescription(description); setDescription(description);
} }
@ -219,6 +205,7 @@ public class Task extends AuditedACSObject implements Cloneable {
* @return the basic data object type. * @return the basic data object type.
* *
**/ **/
@Override
protected String getBaseDataObjectType() { protected String getBaseDataObjectType() {
return BASE_DATA_OBJECT_TYPE; return BASE_DATA_OBJECT_TYPE;
} }
@ -969,7 +956,7 @@ public class Task extends AuditedACSObject implements Cloneable {
* @param state the state to set the task * @param state the state to set the task
* *
*/ */
public void setState(int state) { public final void setState(int state) {
set(TASK_STATE, getStateString(state)); set(TASK_STATE, getStateString(state));
} }
@ -1051,8 +1038,10 @@ public class Task extends AuditedACSObject implements Cloneable {
} }
} }
} catch (TaskException taskException) { } catch (TaskException taskException) {
taskException.printStackTrace(); if ( s_log.isDebugEnabled() ) {
s_log.debug("setting state to be enabled " + getID()); taskException.printStackTrace();
s_log.debug("setting state to be enabled " + getID());
}
setState(ENABLED); setState(ENABLED);
} }
} }
@ -1157,11 +1146,13 @@ public class Task extends AuditedACSObject implements Cloneable {
updateState(); updateState();
} }
@Override
public void delete() { public void delete() {
triggerListenerUpdateState(); triggerListenerUpdateState();
super.delete(); super.delete();
} }
@Override
public String getDisplayName() { public String getDisplayName() {
return getLabel(); return getLabel();
} }

View File

@ -30,12 +30,9 @@ import org.apache.log4j.Logger;
* @author Uday Mathur * @author Uday Mathur
* @author Khy Huang * @author Khy Huang
* @version 1.0 * @version 1.0
* @version $Id: TaskCollection.java 287 2005-02-22 00:29:02Z sskracic $
**/ **/
public class TaskCollection extends DomainCollection { public class TaskCollection extends DomainCollection {
public static final String versionId =
"$Id: TaskCollection.java 287 2005-02-22 00:29:02Z sskracic $" +
"$Author: sskracic $" +
"$DateTime: 2004/08/16 18:10:38 $";
private static final Logger s_log = Logger.getLogger(TaskCollection.class); private static final Logger s_log = Logger.getLogger(TaskCollection.class);

View File

@ -42,9 +42,9 @@ import org.apache.log4j.Logger;
* *
* @author Stefan Deusch * @author Stefan Deusch
* @author Khy Huang * @author Khy Huang
* @version $Id: TaskComment.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
public class TaskComment extends ObservableDomainObject { public class TaskComment extends ObservableDomainObject {
public static final String versionId = "$Id: TaskComment.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
private static final Logger s_cat = private static final Logger s_cat =
Logger.getLogger(TaskComment.class.getName()); Logger.getLogger(TaskComment.class.getName());

View File

@ -20,9 +20,11 @@ package com.arsdigita.workflow.simple;
/** /**
* Encapsulates a task event. * Encapsulates a task event.
*
* @version $Id: TaskEvent.java 287 2005-02-22 00:29:02Z sskracic $
*/ */
public class TaskEvent { public class TaskEvent {
public static final String versionId = "$Id: TaskEvent.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
/** /**
* The constructor for a task event should include additional contextual * The constructor for a task event should include additional contextual
* information, possibly the request object. * information, possibly the request object.

View File

@ -18,8 +18,12 @@
*/ */
package com.arsdigita.workflow.simple; package com.arsdigita.workflow.simple;
/**
*
* @version $Id: TaskException.java 287 2005-02-22 00:29:02Z sskracic $
*/
public class TaskException extends Exception { public class TaskException extends Exception {
public static final String versionId = "$Id: TaskException.java 287 2005-02-22 00:29:02Z sskracic $ by $Author: sskracic $, $DateTime: 2004/08/16 18:10:38 $";
// def constructor // def constructor
public TaskException() { public TaskException() {
super(); super();

View File

@ -35,9 +35,6 @@ import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.metadata.ObjectType; import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.util.Assert; import com.arsdigita.util.Assert;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
// deprecated
// use: AbstractConfig#load() instead
// import com.arsdigita.runtime.RuntimeConfigLoader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection; import java.util.Collection;
@ -59,17 +56,11 @@ import org.apache.log4j.Logger;
**/ **/
public class UserTask extends Task implements Assignable { public class UserTask extends Task implements Assignable {
private static WorkflowConfig CONFIG; /** Private logger instance for log4j. */
private static final Logger s_log = Logger.getLogger(UserTask.class);
private static WorkflowConfig getConfig() { /** Private configuration object, singleton design pattern */
if (CONFIG == null) { private static final WorkflowConfig s_conf = WorkflowConfig.getInstance();
CONFIG = new WorkflowConfig();
// CONFIG.load(new RuntimeConfigLoader
// ("ccm-core/workflow.properties", false));
CONFIG.load();
}
return CONFIG;
}
public static final String BASE_DATA_OBJECT_TYPE = public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.workflow.simple.UserTask"; "com.arsdigita.workflow.simple.UserTask";
@ -97,9 +88,6 @@ public class UserTask extends Task implements Assignable {
public static final String ROLLBACK_OP = "rollback"; public static final String ROLLBACK_OP = "rollback";
public static final String FINISH_OP = "finish"; public static final String FINISH_OP = "finish";
private static final Logger s_log =
Logger.getLogger(UserTask.class);
/** /**
* Constructor for a user task with usage information. * Constructor for a user task with usage information.
* *
@ -242,7 +230,7 @@ public class UserTask extends Task implements Assignable {
* @param duration the duration for this task * @param duration the duration for this task
* *
**/ **/
public void setDuration(Duration duration) { private void setDuration(Duration duration) {
setStartDate(duration.getStartDate()); setStartDate(duration.getStartDate());
setDueDate(duration.getDueDate()); setDueDate(duration.getDueDate());
set(DURATION_MINUTES, new BigDecimal(duration.getDuration())); set(DURATION_MINUTES, new BigDecimal(duration.getDuration()));
@ -956,7 +944,7 @@ public class UserTask extends Task implements Assignable {
} }
public static Party getAlertsSender() { public static Party getAlertsSender() {
String email = getConfig().getAlertsSender(); String email = s_conf.getAlertsSender();
if (email == null) { return null; } if (email == null) { return null; }
PartyCollection parties = Party.retrieveAllParties(); PartyCollection parties = Party.retrieveAllParties();
parties.addEqualsFilter("primaryEmail", email.toLowerCase()); parties.addEqualsFilter("primaryEmail", email.toLowerCase());
@ -978,6 +966,6 @@ public class UserTask extends Task implements Assignable {
* as well. * as well.
**/ **/
protected boolean sendAlerts(String operation) { protected boolean sendAlerts(String operation) {
return getConfig().isAlertsEnabled(); return s_conf.isAlertsEnabled();
} }
} }

View File

@ -28,27 +28,64 @@ import com.arsdigita.util.parameter.StringParameter;
* *
* @author Rafael H. Schloming &lt;rhs@mit.edu&gt; * @author Rafael H. Schloming &lt;rhs@mit.edu&gt;
* @version $Id: WorkflowConfig.java 287 2005-02-22 00:29:02Z sskracic $ * @version $Id: WorkflowConfig.java 287 2005-02-22 00:29:02Z sskracic $
**/ */
public final class WorkflowConfig extends AbstractConfig { public final class WorkflowConfig extends AbstractConfig {
/** Private Object to hold one's own instance to return to users. */
private static WorkflowConfig s_config;
/**
* Returns the singleton configuration record for the workflow
* configuration.
*
* @return The <code>ContentSectionConfig</code> record; it cannot be null
*/
public static synchronized WorkflowConfig getInstance() {
if (s_config == null) {
s_config = new WorkflowConfig();
s_config.load();
}
return s_config;
}
// /////////////////////////////////////////////////////////////////////////////
//
// Set of parameters controlling workflow alerts.
//
// /////////////////////////////////////////////////////////////////////////////
/** Turn on or off workflow alerts. */
private BooleanParameter m_alerts = new BooleanParameter private BooleanParameter m_alerts = new BooleanParameter
("waf.workflow.simple.alerts_enabled", Parameter.OPTIONAL, ("waf.workflow.simple.alerts_enabled", Parameter.OPTIONAL,
Boolean.TRUE); Boolean.TRUE);
/** Default sender for workflow alerts, e.g. workflow@example.com */
private StringParameter m_sender = new StringParameter private StringParameter m_sender = new StringParameter
("waf.workflow.simple.alerts_sender", Parameter.OPTIONAL, null); ("waf.workflow.simple.alerts_sender", Parameter.OPTIONAL, null);
/**
* Constructor
*/
public WorkflowConfig() { public WorkflowConfig() {
register(m_alerts); register(m_alerts);
register(m_sender); register(m_sender);
loadInfo(); loadInfo();
} }
/**
* Retrieve whether alerts are to be enabled or not.
* @return true if alerts are enabled.
*/
public boolean isAlertsEnabled() { public boolean isAlertsEnabled() {
return get(m_alerts).equals(Boolean.TRUE); return get(m_alerts).equals(Boolean.TRUE);
} }
/**
* Retrieve alert senders default mail address.
* @return
*/
public String getAlertsSender() { public String getAlertsSender() {
return (String) get(m_sender); return (String) get(m_sender);
} }

View File

@ -3,16 +3,14 @@
<head> <head>
<title>com.arsdigita.workflow.simple</title> <title>com.arsdigita.workflow.simple</title>
</head> </head>
<body bgcolor="white"> <body>
<p> <p>
A tool framework for establishing collaboration among all the A tool framework for establishing collaboration among all the
specialized members of a production staff. It allows groups to set up specialized members of a production staff. It allows groups to set up
standard processes to constrain how content is published. At the same standard processes to constrain how content is published. At the same
time, it allows users to easily modify those processes to reflect time, it allows users to easily modify those processes to reflect
individual needs. individual needs.
</p> </p>
</body> </body>