Trusted User Rolle und Workflow (#1209)

* eingebaut
* Allen Rollen wird beim Erstellen automatisch der Site-wide Admin hinzugefügt
* Vorbereitungen für eine einfacher Erstellung von ContentSections getroffen

git-svn-id: https://svn.libreccm.org/ccm/trunk@1594 8810af33-2d31-482b-a856-94f89814c4df
master
quasi 2012-04-15 08:33:42 +00:00
parent 1f88a7bd25
commit 27796f0c86
6 changed files with 803 additions and 850 deletions

View File

@ -18,13 +18,14 @@
*/ */
package com.arsdigita.cms; package com.arsdigita.cms;
import com.arsdigita.cms.contentsection.ContentSectionConfig;
import com.arsdigita.cms.contentsection.ContentSectionSetup; import com.arsdigita.cms.contentsection.ContentSectionSetup;
import com.arsdigita.cms.util.Util;
import com.arsdigita.cms.contenttypes.XMLContentTypeHandler; import com.arsdigita.cms.contenttypes.XMLContentTypeHandler;
import com.arsdigita.cms.portlet.ContentDirectoryPortlet; import com.arsdigita.cms.portlet.ContentDirectoryPortlet;
import com.arsdigita.cms.portlet.ContentItemPortlet; import com.arsdigita.cms.portlet.ContentItemPortlet;
import com.arsdigita.cms.portlet.ContentSectionsPortlet; import com.arsdigita.cms.portlet.ContentSectionsPortlet;
import com.arsdigita.cms.portlet.TaskPortlet; import com.arsdigita.cms.portlet.TaskPortlet;
import com.arsdigita.cms.util.Util;
import com.arsdigita.formbuilder.util.FormbuilderSetup; import com.arsdigita.formbuilder.util.FormbuilderSetup;
import com.arsdigita.kernel.Kernel; import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.KernelExcursion; import com.arsdigita.kernel.KernelExcursion;
@ -38,35 +39,31 @@ import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.web.Application; import com.arsdigita.web.Application;
import com.arsdigita.web.ApplicationType; import com.arsdigita.web.ApplicationType;
import com.arsdigita.xml.XML; import com.arsdigita.xml.XML;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* <p>Executes nonrecurring at install time and loads (installs and initializes) * <p>Executes nonrecurring at install time and loads (installs and initializes)
* the Content Management System module,including the Content Center, CMS Service * the Content Management System module,including the Content Center, CMS
* applications, and CMS Mime Types service persistently into database.</p> * Service applications, and CMS Mime Types service persistently into
* database.</p>
* *
* <p>This class also optionally initializes user-defined content types. </p> * <p>This class also optionally initializes user-defined content types. </p>
* <p>Additional user-defined content sections can be loaded and initilized * <p>Additional user-defined content sections can be loaded and initilized
* using the recurring <pre>initializer</pre> at any startup. * using the recurring
* <pre>initializer</pre> at any startup.
* *
* <p>The tasks to perform are:</p> * <p>The tasks to perform are:</p> <ol> <li>create CMS package
* <ol> * type(content-section)</li> <li>create Workspace package type and
* <li>create CMS package type(content-section)</li> * instance</li> <li>create CMS Service package type and instance</li>
* <li>create Workspace package type and instance</li> * <li>create CMS package (content-section) instance</li> </ol>
* <li>create CMS Service package type and instance</li>
* <li>create CMS package (content-section) instance</li>
* </ol>
* *
* <p>Configuration can be modified by configuration parameters before processing, * <p>Configuration can be modified by configuration parameters before
* otherwise hardcoded default values take effect. After processing, the * processing, otherwise hardcoded default values take effect. After processing,
* installation values can not be modified anymore without a fresh installation * the installation values can not be modified anymore without a fresh
* of the whole system.</p> * installation of the whole system.</p>
* *
* @author Peter Boy &lt;pboy@barkhof.uni-bremen.de&gt; * @author Peter Boy &lt;pboy@barkhof.uni-bremen.de&gt;
* @since ccm-cms version 6.6.0 * @since ccm-cms version 6.6.0
@ -74,21 +71,21 @@ import org.apache.log4j.Logger;
*/ */
public class Loader extends PackageLoader { 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);
/**
/** Loader configuration object, singleton design pattern * Loader configuration object, singleton design pattern NOTE: LoaderConfig
* NOTE: LoaderConfig only supplies unmutable hard coded defaults! It is * only supplies unmutable hard coded defaults! It is not possible to alter
* not possible to alter any of the contained values by specifiying an * any of the contained values by specifiying an configuration parameter
* configuration parameter during load step. If a configuration value * during load step. If a configuration value has to be configurable at load
* has to be configurable at load time, the parameter must be relocated * time, the parameter must be relocated into this Loader class!
* into this Loader class! */ */
private static final LoaderConfig s_conf = LoaderConfig.getInstance(); private static final LoaderConfig s_conf = LoaderConfig.getInstance();
// /////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////
// Configurable parameters during load step. // Configurable parameters during load step.
// /////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////
/** /**
* The name(s) of the content section(s). In case of more than one name the * The name(s) of the content section(s). In case of more than one name the
* first is treated as default section. Otherwise the section created is the * first is treated as default section. Otherwise the section created is the
@ -98,15 +95,14 @@ public class Loader extends PackageLoader {
private final Parameter m_contentSectionNames = new StringArrayParameter( private final Parameter m_contentSectionNames = new StringArrayParameter(
"com.arsdigita.cms.loader.section_names", "com.arsdigita.cms.loader.section_names",
Parameter.REQUIRED, Parameter.REQUIRED,
new String[] {"content"} new String[]{"content"});
); /**
* List of classnames of internal base content types (needed in every
/** List of classnames of internal base content types (needed in every
* section created), generated while loading those content types in * section created), generated while loading those content types in
* loadContentTypeDefinitions(files) for later use in register step. */ * loadContentTypeDefinitions(files) for later use in register step.
*/
private ArrayList m_content_type_list = new ArrayList(); private ArrayList m_content_type_list = new ArrayList();
/** /**
* Standard constructor. * Standard constructor.
*/ */
@ -165,22 +161,22 @@ public class Loader extends PackageLoader {
/** /**
* Loads the Workspace subpackage (content-center) into the database. * Loads the Workspace subpackage (content-center) into the database.
* *
* It is made public to be able to invoke it from the update script * It is made public to be able to invoke it from the update script (e.g.
* (e.g. 6.6.1-6.6.2). We need separate steps for loading and instantiating * 6.6.1-6.6.2). We need separate steps for loading and instantiating
* because update skript requires. * because update skript requires.
*/ */
public static ApplicationType loadWorkspaceApplicationType() { public static ApplicationType loadWorkspaceApplicationType() {
s_log.debug("Creating CMS Workspace..."); s_log.debug("Creating CMS Workspace...");
/* Create new type legacy free application type /*
* NOTE: The wording in the title parameter of ApplicationType * Create new type legacy free application type NOTE: The wording in the
* determines the name of the subdirectory for the XSL stylesheets. * title parameter of ApplicationType determines the name of the
* It gets "urlized", i.e. trimming leading and trailing blanks and * subdirectory for the XSL stylesheets. It gets "urlized", i.e.
* replacing blanks between words and illegal characters with an * trimming leading and trailing blanks and replacing blanks between
* hyphen and converted to lower case. * words and illegal characters with an hyphen and converted to lower
* "Content Center" will become "content-center". */ * case. "Content Center" will become "content-center".
ApplicationType type = new */
ApplicationType(Workspace.INSTANCE_NAME, ApplicationType type = new ApplicationType(Workspace.INSTANCE_NAME,
Workspace.BASE_DATA_OBJECT_TYPE); Workspace.BASE_DATA_OBJECT_TYPE);
type.setDescription("The content center workspace for content creators."); type.setDescription("The content center workspace for content creators.");
@ -193,8 +189,8 @@ public class Loader extends PackageLoader {
/** /**
* Instantiates the Workspace subpackage (content-center) (in the database). * Instantiates the Workspace subpackage (content-center) (in the database).
* *
* It is made public to be able to invoke it from the update script * It is made public to be able to invoke it from the update script (e.g.
* (e.g. 6.6.1-6.6.2). We need separate steps for loading and instantiating * 6.6.1-6.6.2). We need separate steps for loading and instantiating
* because update skript requires. * because update skript requires.
* *
* @param workspaceType * @param workspaceType
@ -220,23 +216,22 @@ public class Loader extends PackageLoader {
s_log.debug("Done loading CMS Workspace."); s_log.debug("Done loading CMS Workspace.");
} }
/** /**
* CMS Service application is used by the Content Management System as a * CMS Service application is used by the Content Management System as a
* store for global resources and assets. * store for global resources and assets. It is made public to be able to
* It is made public to be able to invoke it from the update script * invoke it from the update script (e.g. 6.6.1-6.6.2).
* (e.g. 6.6.1-6.6.2).
*/ */
public static ApplicationType loadServiceApplicationType() { public static ApplicationType loadServiceApplicationType() {
s_log.debug("Loading CMS Servce Package..."); s_log.debug("Loading CMS Servce Package...");
/* Create new type legacy free application type /*
* NOTE: The wording in the title parameter of ApplicationType * Create new type legacy free application type NOTE: The wording in the
* determines the name of the subdirectory for the XSL stylesheets. * title parameter of ApplicationType determines the name of the
* It gets "urlized", i.e. trimming leading and trailing blanks and * subdirectory for the XSL stylesheets. It gets "urlized", i.e.
* replacing blanks between words and illegal characters with an * trimming leading and trailing blanks and replacing blanks between
* hyphen and converted to lower case. * words and illegal characters with an hyphen and converted to lower
* "CMS Service" will become "cms-service". */ * case. "CMS Service" will become "cms-service".
*/
ApplicationType type = new ApplicationType("CMS Service", ApplicationType type = new ApplicationType("CMS Service",
Service.BASE_DATA_OBJECT_TYPE); Service.BASE_DATA_OBJECT_TYPE);
type.setDescription("Services to store global resources and assets."); type.setDescription("Services to store global resources and assets.");
@ -245,7 +240,6 @@ public class Loader extends PackageLoader {
return type; return type;
} }
/** /**
* *
* @param serviceType * @param serviceType
@ -265,13 +259,11 @@ public class Loader extends PackageLoader {
s_log.debug("Done creating CMS Service Package."); s_log.debug("Done creating CMS Service Package.");
} }
/** /**
* Load a content section application type and an initial default * Load a content section application type and an initial default
* content-section instance(s). * content-section instance(s). Some configuration values which are to be
* Some configuration values which are to be considered as unmutable are * considered as unmutable are specified in LoaderConfig. Uses new style
* specified in LoaderConfig. * application in legacy compatible mode.
* Uses new style application in legacy compatible mode.
* *
* NOTE: At ccm-cms load time no content type packages are available because * NOTE: At ccm-cms load time no content type packages are available because
* any content type depends on ccm-cms. Therefore, the loading step can not * any content type depends on ccm-cms. Therefore, the loading step can not
@ -286,13 +278,14 @@ public class Loader extends PackageLoader {
// Step 1: Create content section application type // Step 1: Create content section application type
// prerequisite for concrete content-section instance creation. // prerequisite for concrete content-section instance creation.
/* Create legacy-free application type /*
* NOTE: The wording in the title parameter of ApplicationType * Create legacy-free application type NOTE: The wording in the title
* determines the name of the subdirectory for the XSL stylesheets. * parameter of ApplicationType determines the name of the subdirectory
* It gets "urlized", i.e. trimming leading and trailing blanks and * for the XSL stylesheets. It gets "urlized", i.e. trimming leading and
* replacing blanks between words and illegal characters with an * trailing blanks and replacing blanks between words and illegal
* hyphen and converted to lower case. * characters with an hyphen and converted to lower case. "Content
* "Content Section" will become "content-section". */ * Section" will become "content-section".
*/
ApplicationType type = new ApplicationType( ApplicationType type = new ApplicationType(
"Content Section", "Content Section",
ContentSection.BASE_DATA_OBJECT_TYPE); ContentSection.BASE_DATA_OBJECT_TYPE);
@ -314,65 +307,19 @@ public class Loader extends PackageLoader {
// Step 1: Validate name for section // Step 1: Validate name for section
Util.validateURLParameter("name", sectionName); Util.validateURLParameter("name", sectionName);
// Step 2: Create a section using default values ContentSectionConfig conf = new ContentSectionConfig();
ContentSection section = ContentSection.create(sectionName); conf.load();
// Step 3: Adopt the created section to site specific requirements ContentSectionSetup.setupContentSectionAppInstance(sectionName,
// ContentSectionSetup is a convenient class to adopt a conf.getDefaultRoles(),
// section created by ContentSection.create() conf.getDefaultWorkflows(),
ContentSectionSetup setup = new ContentSectionSetup(section); s_conf.isPubliclyViewable(),
s_conf.getItemResolverClass(),
s_conf.getTemplateResolverClass(),
m_content_type_list,
s_conf.getUseSectionCategories(),
s_conf.getCategoryFileList());
// Step 3a: Roles (staff group) used in this content section.
// Register roles using a complete set of default roles
// defined in ContentSectionSetup
setup.registerRoles(s_conf.getStuffGroup());
// ViewerGroup populated in ContentSection, public access is determined
// by parameter (affecting characteristics of the viewer group)
setup.registerViewers(s_conf.isPubliclyViewable());
// Page resolver class, set autonomously by ContentSection.create()
// Item resolver class, configurable, defaults in place.
// Template resolver class, configurable, defaults in place.
// We should not overwrite the default in the initial default configuration
// register a predefined one-phase lifecycle for items.
setup.registerPublicationCycles();
// registers predefined "Authoring", "Approval", "Publishing' steps
setup.registerWorkflowTemplates();
setup.registerResolvers(s_conf.getItemResolverClass(),
s_conf.getTemplateResolverClass());
// XML generator class, set autonomously by ContentSection.create()
/* Register internal base content types. Paramter is a list of
* class names created by internal content type load method.
* @see loadContentTypeDefinitions(List)
* External content types (provided by additional packages) are
* not available at CMS load time and can not processed by Loader.
* Registration of those content types are dealt with in the
* respective Loader or in the CMS workspace GUI.
* For each created section the base types get registered. */
setup.registerContentTypes(m_content_type_list);
// Section specific categories, usually not used.
// During initial load at install time nor used at all!
// default value is false so no categories get loaded.
if (s_conf.getUseSectionCategories()) {
Iterator files = ((List) s_conf.getCategoryFileList()).iterator();
while (files.hasNext()) {
setup.registerCategories((String) files.next());
}
}
// registers a predefined standard recipient for alerts
setup.registerAlerts();
// Load a list of cms tasks and associated alert events
// Currently no functionality to persist them. Not a loader task yet
// setup.loadTaskAlerts(s_conf.getTaskAlerts());
section.save(); //persists any changes in the database (DomainObject)
//i.e. creates an object (instance)
} }
} }
@ -383,11 +330,11 @@ public class Loader extends PackageLoader {
* content type packages. * content type packages.
* *
* The XML config looks like the example below, the "parentType" and "name" * The XML config looks like the example below, the "parentType" and "name"
* attributes are optional, and only required for creating * attributes are optional, and only required for creating User Defined
* User Defined ContentTypes. Label corresponds to ContentType's label and * ContentTypes. Label corresponds to ContentType's label and can be
* can be multiple words, and "name" to DynamicObject's name property, * multiple words, and "name" to DynamicObject's name property, and must be
* and must be a single word. The objectType attribute is ignored for * a single word. The objectType attribute is ignored for UDCTs, as it gets
* UDCTs, as it gets dynamically generated. * dynamically generated.
* *
* <b>UDCT Copyright</b> * <b>UDCT Copyright</b>
* <pre> * <pre>

View File

@ -15,8 +15,6 @@
* with this library; if not, write to the Free Software Foundation, Inc., * with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
package com.arsdigita.cms; package com.arsdigita.cms;
import com.arsdigita.runtime.AbstractConfig; import com.arsdigita.runtime.AbstractConfig;
@ -24,11 +22,8 @@ import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.Parameter; import com.arsdigita.util.parameter.Parameter;
import com.arsdigita.util.parameter.StringArrayParameter; import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter; import com.arsdigita.util.parameter.StringParameter;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.ArrayList;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
// IMPLEMENTATION NOTE // IMPLEMENTATION NOTE
@ -36,8 +31,6 @@ import org.apache.log4j.Logger;
// initialization process and not yet completed. Functionality is // initialization process and not yet completed. Functionality is
// basically OK so far, but code urgently needs cleaning up and a // basically OK so far, but code urgently needs cleaning up and a
// check for useful bits. // check for useful bits.
/** /**
* Container for various configuration parameters for ccm-cms package loader. * Container for various configuration parameters for ccm-cms package loader.
* *
@ -47,34 +40,38 @@ import org.apache.log4j.Logger;
* to be modifiable must be included in Loader class itself! * to be modifiable must be included in Loader class itself!
* *
* @author pb * @author pb
* @author Sören Bernstein (quasi@barkhof.uni-bremen.de)
* @version $Id: LoaderConfig.java $ * @version $Id: LoaderConfig.java $
*/ */
public final class LoaderConfig extends AbstractConfig { public final class LoaderConfig extends AbstractConfig {
/** Local logger instance fpr debug support */ /**
* 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 Object to hold one's own instance to return to users.
*/
private static LoaderConfig s_conf; private static LoaderConfig s_conf;
/** /**
* Returns the singleton configuration record for Loader configuration. * Returns the singleton configuration record for Loader configuration.
* *
* @return The <code>ContentSectionConfig</code> record; it cannot be null * @return The
* <code>ContentSectionConfig</code> record; it cannot be null
*/ */
public static synchronized LoaderConfig getInstance() { public static synchronized LoaderConfig getInstance() {
if (s_conf == null) { if (s_conf == null) {
s_conf = new LoaderConfig(); s_conf = new LoaderConfig();
/* Parameters are not stored in registry nor modified by installation /*
* specification. It is not possible to process a config object at * Parameters are not stored in registry nor modified by
* Load time! * installation specification. It is not possible to process a
* s_conf.load(); * config object at Load time! s_conf.load();
*/ */
} }
return s_conf; 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
@ -91,7 +88,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.workspace_url", // "com.arsdigita.cms.loader.workspace_url",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// "content-center"); // "content-center");
// /** // /**
// * XML Mapping of the content center tabs to URLs, see // * XML Mapping of the content center tabs to URLs, see
// * {@link ContentCenterDispatcher} // * {@link ContentCenterDispatcher}
@ -105,7 +101,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.content_center_map", // "com.arsdigita.cms.loader.content_center_map",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// "/WEB-INF/resources/content-center-map.xml"); // "/WEB-INF/resources/content-center-map.xml");
// Update master object if upgrading from old versioning // Update master object if upgrading from old versioning
// XXX: shouldn't we just gut this section (and // XXX: shouldn't we just gut this section (and
// VersioningUpgrader)? It is an upgrade fix from 5.1 or // VersioningUpgrader)? It is an upgrade fix from 5.1 or
@ -118,7 +113,6 @@ public final class LoaderConfig extends AbstractConfig {
// if (updateMaster) { // if (updateMaster) {
// VersioningUpgrader.updateMasterObject(); // VersioningUpgrader.updateMasterObject();
// } // }
// XXX: ItemDispatcher is no longer used. Is the following // XXX: ItemDispatcher is no longer used. Is the following
// still a valid enterprise.init parameter? Do we need to // still a valid enterprise.init parameter? Do we need to
// set ContentSectionServlet.s_cacheItems instead of the // set ContentSectionServlet.s_cacheItems instead of the
@ -128,21 +122,18 @@ public final class LoaderConfig extends AbstractConfig {
// ((Boolean)m_conf.getParameter(CACHE_ITEMS)).booleanValue(); // ((Boolean)m_conf.getParameter(CACHE_ITEMS)).booleanValue();
// s_log.debug("Set cache items to " + cacheItems); // s_log.debug("Set cache items to " + cacheItems);
// ItemDispatcher.setCacheItems(cacheItems); // ItemDispatcher.setCacheItems(cacheItems);
/** /**
* Comma separated list of XML definition files for internal content types * Comma separated list of XML definition files for internal content types
* (base types). * (base types).
* *
* Each internal content type (see package com/arsdigita/cms/contenttypes) * Each internal content type (see package com/arsdigita/cms/contenttypes)
* requires an entry in this list in order to get CMS Loader to load it * requires an entry in this list in order to get CMS Loader to load it into
* into permanent storage (equivalent to the Loader of each external * permanent storage (equivalent to the Loader of each external content type
* content type package). * package).
* *
* Each definition file name has to be fully qualified relative to * Each definition file name has to be fully qualified relative to
* application (context) root. * application (context) root. Example: contentTypeDefinitions = {
* Example: * "/WEB-INF/content-types/Template.xml" };
* contentTypeDefinitions = { "/WEB-INF/content-types/Template.xml" };
* *
* This parameter should be altered only by developers! * This parameter should be altered only by developers!
*/ */
@ -157,10 +148,7 @@ public final class LoaderConfig extends AbstractConfig {
"/WEB-INF/content-types/GenericContact.xml", "/WEB-INF/content-types/GenericContact.xml",
"/WEB-INF/content-types/GenericOrganizationalUnit.xml", "/WEB-INF/content-types/GenericOrganizationalUnit.xml",
"/WEB-INF/content-types/GenericPerson.xml", "/WEB-INF/content-types/GenericPerson.xml",
"/WEB-INF/content-types/Template.xml"} "/WEB-INF/content-types/Template.xml"});
);
// /////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////
// //
// Parameters for creating a default content section at installation time. // Parameters for creating a default content section at installation time.
@ -168,50 +156,38 @@ public final class LoaderConfig extends AbstractConfig {
// We list all information here, the code needs to create a section. // We list all information here, the code needs to create a section.
// //
// /////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////
// Section Name, configured by Loader parameter // Section Name, configured by Loader parameter
// Root Folder, set autonomously by ContentSection.create() method // Root Folder, set autonomously by ContentSection.create() method
// Template Folder, set autonomously by ContentSection.create() method // Template Folder, set autonomously by ContentSection.create() method
/** /**
* Staff Group * Staff Group Contains roles and associated privileges. In loading step a
* Contains roles and associated privileges. In loading step a complete * complete default configuration is persisted in database, immutable at
* default configuration is persisted in database, immutable at this point. * this point. See contentsection.ContentSectionSetup.registerRoles() In
* See contentsection.ContentSectionSetup.registerRoles() * enterprise.init: name roles, List of roles to create.
* In enterprise.init: name roles, List of roles to create.
* *
* Not implemented yet! We need a new parameter type "list" which must have * Not implemented yet! We need a new parameter type "list" which must have
* multidimensional capabilities. * multidimensional capabilities.
*/ */
/* /*
private final Parameter * private final Parameter m_staffGroup = new StringParameter(
m_staffGroup = new StringParameter( * "com.arsdigita.cms.loader.section_staff_group", Parameter.REQUIRED,
"com.arsdigita.cms.loader.section_staff_group", * null);
Parameter.REQUIRED,
null);
*/ */
private List m_staffGroup; private List m_defaultRoles;
// Viewer group, set autonomously by ContentSection.create() method. We can // Viewer group, set autonomously by ContentSection.create() method. We can
// here specify, whether the first ( probalby only) content section should // here specify, whether the first ( probalby only) content section should
// have a public viewer, i.e. without registration and login. // have a public viewer, i.e. without registration and login.
/** /**
* Whether to make content viewable to 'The Public', ie non-registered users. * Whether to make content viewable to 'The Public', ie non-registered
* users.
* *
* Parameter name in the old initializer code: PUBLIC. Default true. * Parameter name in the old initializer code: PUBLIC. Default true.
*/ */
private final BooleanParameter private final BooleanParameter m_isPublic = new BooleanParameter(
m_isPublic = new BooleanParameter(
"com.arsdigita.cms.loader.section_is_public", "com.arsdigita.cms.loader.section_is_public",
Parameter.REQUIRED, Parameter.REQUIRED,
true); true);
// Page Resolver Class, set autonomously by ContentSection.create() method. // Page Resolver Class, set autonomously by ContentSection.create() method.
// Item Resolver Class, configurable. // Item Resolver Class, configurable.
/** /**
* Name of the item resolver class to use for the section (defaults to * Name of the item resolver class to use for the section (defaults to
@ -220,79 +196,70 @@ public final class LoaderConfig extends AbstractConfig {
* Default value (site-wide) is handled via the parameter * Default value (site-wide) is handled via the parameter
* <pre>com.arsdigita.cms.default_item_resolver_class</pre>. * <pre>com.arsdigita.cms.default_item_resolver_class</pre>.
* Section-specific override can be added here. Only do so if you are * Section-specific override can be added here. Only do so if you are
* changing from the default for a specific content section. The class * changing from the default for a specific content section. The class must
* must implement <pre>com.arsdigita.cms.dispatcher.ItemResolver</pre>. * implement
* <pre>com.arsdigita.cms.dispatcher.ItemResolver</pre>.
* *
* Parameter name ITEM_RESOLVER_CLASS in the old initializer system. * Parameter name ITEM_RESOLVER_CLASS in the old initializer system.
* Description: The ItemResolver class to use for the section * Description: The ItemResolver class to use for the section (defaults to
* (defaults to MultilingualItemResolver) * MultilingualItemResolver)
*/ */
private final Parameter private final Parameter m_itemResolverClass = new StringParameter(
m_itemResolverClass = new StringParameter(
"com.arsdigita.cms.loader.item_resolver_class", "com.arsdigita.cms.loader.item_resolver_class",
Parameter.OPTIONAL, null); Parameter.OPTIONAL, null);
// , "com.arsdigita.cms.dispatcher.MultilingualItemResolver" // , "com.arsdigita.cms.dispatcher.MultilingualItemResolver"
// Template Resolver Class, configurable. // Template Resolver Class, configurable.
/** /**
* Name of the template resolver class to use for the section * Name of the template resolver class to use for the section (defaults to
* (defaults to <pre>com.arsdigita.cms.dispatcher.DefaultTemplateResolver</pre>) * <pre>com.arsdigita.cms.dispatcher.DefaultTemplateResolver</pre>)
* *
* Default value (site-wide) is handled via the parameter * Default value (site-wide) is handled via the parameter
* <pre>com.arsdigita.cms.default_template_resolver_class</pre>. * <pre>com.arsdigita.cms.default_template_resolver_class</pre>.
* Section-specific override can be added here. Only do so if you are * Section-specific override can be added here. Only do so if you are
* changing from the default for a specific content section. The class * changing from the default for a specific content section. The class must
* must implement <pre>com.arsdigita.cms.dispatcher.TemplateResolver</pre>. * implement
* <pre>com.arsdigita.cms.dispatcher.TemplateResolver</pre>.
* *
* Parameter name TEMPLATE_RESOLVER_CLASS in the old initializer system. * Parameter name TEMPLATE_RESOLVER_CLASS in the old initializer system.
*/ */
private final Parameter private final Parameter m_templateResolverClass = new StringParameter(
m_templateResolverClass = new StringParameter(
"com.arsdigita.cms.loader.template_resolver_class", "com.arsdigita.cms.loader.template_resolver_class",
Parameter.OPTIONAL, Parameter.OPTIONAL,
null); null);
// "com.arsdigita.cms.dispatcher.DefaultTemplateResolver" ); // "com.arsdigita.cms.dispatcher.DefaultTemplateResolver" );
// XML Generator Class, set autonomously by ContentSection.create() method. // XML Generator Class, set autonomously by ContentSection.create() method.
/** /**
* Determins weather to use section specific category tree(s). Defaults to * Determins weather to use section specific category tree(s). Defaults to
* false, so standard navigation is used. * false, so standard navigation is used. If set to true loader loads the
* If set to true loader loads the categories from file(s) specified in the * categories from file(s) specified in the next parameter (
* next parameter ( m_categoryFileList ) * m_categoryFileList )
*/ */
private final Parameter private final Parameter m_useSectionCategories = new BooleanParameter("com.arsdigita.cms.loader.use_section_categories",
m_useSectionCategories = new BooleanParameter
("com.arsdigita.cms.loader.use_section_categories",
Parameter.REQUIRED, new Boolean(false)); Parameter.REQUIRED, new Boolean(false));
/** /**
* XML file containing the category tree to load for this content section. * XML file containing the category tree to load for this content section.
* Usually not loaded {@see m_useSectionCategories). The files listed as * Usually not loaded {
* default values are demo material and must be replaced in a production *
* environment. * @see m_useSectionCategories). The files listed as default values are demo
* material and must be replaced in a production environment.
*/ */
private final Parameter private final Parameter m_categoryFileList = new StringArrayParameter(
m_categoryFileList = new StringArrayParameter(
"com.arsdigita.cms.loader.section_categories_toload", "com.arsdigita.cms.loader.section_categories_toload",
Parameter.REQUIRED, Parameter.REQUIRED,
new String[]{"/WEB-INF/resources/article-categories.xml", new String[]{"/WEB-INF/resources/article-categories.xml",
"/WEB-INF/resources/navigation-categories.xml"}); "/WEB-INF/resources/navigation-categories.xml"});
// private final Parameter // private final Parameter
// m_widgetTypes = new StringArrayParameter( // m_widgetTypes = new StringArrayParameter(
// "com.arsdigita.cms.loader.widget_types", // "com.arsdigita.cms.loader.widget_types",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// new String[] {"/WEB-INF/resources/article-categories.xml", // new String[] {"/WEB-INF/resources/article-categories.xml",
// "/WEB-INF/resources/navigation-categories.xml"} ); // "/WEB-INF/resources/navigation-categories.xml"} );
/**
/** List of widgets used in applications forms. Each widget is described by * List of widgets used in applications forms. Each widget is described by
application indicator, widget name (singular & plural), model class name * application indicator, widget name (singular & plural), model class name
and model ui class name. These are really not user or administrator * and model ui class name. These are really not user or administrator
configurabel and therefore not implemented as ccm parameter. */ * configurabel and therefore not implemented as ccm parameter.
*/
private static List widgetTypes = Arrays.asList( private static List widgetTypes = Arrays.asList(
Arrays.asList("forms-cms", "Checkbox group", "Checkbox groups", Arrays.asList("forms-cms", "Checkbox group", "Checkbox groups",
"com.arsdigita.formbuilder.PersistentCheckboxGroup", "com.arsdigita.formbuilder.PersistentCheckboxGroup",
@ -345,14 +312,14 @@ public final class LoaderConfig extends AbstractConfig {
"com.arsdigita.formbuilder.ui.editors.HorizontalRuleForm"), "com.arsdigita.formbuilder.ui.editors.HorizontalRuleForm"),
Arrays.asList("forms-cms", "User Email Field", "User Email Fields", Arrays.asList("forms-cms", "User Email Field", "User Email Fields",
"com.arsdigita.formbuilder.PersistentEmailField", "com.arsdigita.formbuilder.PersistentEmailField",
"com.arsdigita.formbuilder.ui.editors.EmailFieldForm") "com.arsdigita.formbuilder.ui.editors.EmailFieldForm"));
); /**
* List of process listeners used in applications forms. Each listener is
/** List of process listeners used in applications forms. Each listener is * described by application indicator, process name (singular & plural),
described by application indicator, process name (singular & plural), * action class name and action ui class name. These are really not user or
action class name and action ui class name. These are really not user * administrator configurabel and therefore not implemented as ccm
or administrator configurabel and therefore not implemented as ccm * parameter.
parameter. */ */
private static List processListenerTypes = Arrays.asList( private static List processListenerTypes = Arrays.asList(
Arrays.asList("forms-cms", "Confirmation email", Arrays.asList("forms-cms", "Confirmation email",
"Confirmation emails", "Confirmation emails",
@ -373,39 +340,30 @@ public final class LoaderConfig extends AbstractConfig {
"com.arsdigita.formbuilder.ui.editors.RemoteServerPostForm"), "com.arsdigita.formbuilder.ui.editors.RemoteServerPostForm"),
Arrays.asList("forms-cms", "XML email", "XML emails", Arrays.asList("forms-cms", "XML email", "XML emails",
"com.arsdigita.formbuilder.actions.XMLEmailListener", "com.arsdigita.formbuilder.actions.XMLEmailListener",
"com.arsdigita.formbuilder.ui.editors.XMLEmailForm" ) "com.arsdigita.formbuilder.ui.editors.XMLEmailForm"));
);
private static List dataQueries = Arrays.asList( private static List dataQueries = Arrays.asList(
Arrays.asList("forms-cms", Arrays.asList("forms-cms",
"com.arsdigita.formbuilder.DataQueryUsers", "com.arsdigita.formbuilder.DataQueryUsers",
"List of all registered users"), "List of all registered users"),
Arrays.asList("forms-cms", Arrays.asList("forms-cms",
"com.arsdigita.formbuilder.DataQueryPackages", "com.arsdigita.formbuilder.DataQueryPackages",
"List of all installed packages") "List of all installed packages"));
);
// Currently not a Loader task. There is no way to persist tasks preferences // Currently not a Loader task. There is no way to persist tasks preferences
// on a per section base. // on a per section base.
/** /**
* When to generate email alerts: by default, generate email alerts * When to generate email alerts: by default, generate email alerts on
* on enable, finish, and rollback (happens on rejection) changes. * enable, finish, and rollback (happens on rejection) changes. There are
* There are four action types for each task type: enable, * four action types for each task type: enable, disable, finish, and
* disable, finish, and rollback. Note that the values below are * rollback. Note that the values below are based on the task labels, and as
* based on the task labels, and as such are not globalized. * such are not globalized.
*/ */
/* /*
private final Parameter * private final Parameter m_taskAlerts = new StringArrayParameter(
m_taskAlerts = new StringArrayParameter( * "com.arsdigita.cms.task_alerts", Parameter.REQUIRED, new String[] {
"com.arsdigita.cms.task_alerts", * "Authoring:enable:finish:rollback", "Approval:enable:finish:rollback",
Parameter.REQUIRED, new String[] { * "Deploy:enable:finish:rollback" } );
"Authoring:enable:finish:rollback",
"Approval:enable:finish:rollback",
"Deploy:enable:finish:rollback" } );
*/ */
// /////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////
// //
// Parameters controlling Overdue Task alerts: // Parameters controlling Overdue Task alerts:
@ -414,8 +372,6 @@ public final class LoaderConfig extends AbstractConfig {
// per section base of to store them in the database at all. So it is // per section base of to store them in the database at all. So it is
// currently not a loader task and commented out here. // currently not a loader task and commented out here.
// /////////////////////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////////////////////
// /** // /**
// * sendOverdueAlerts: Should we send alerts about overdue tasks at all? // * sendOverdueAlerts: Should we send alerts about overdue tasks at all?
// */ // */
@ -424,7 +380,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.send_overdue_alerts", // "com.arsdigita.cms.loader.send_overdue_alerts",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// new Boolean(false) ); // new Boolean(false) );
// /** // /**
// * taskDuration: The time between when a task is enabled (it is made // * taskDuration: The time between when a task is enabled (it is made
// * available for completion) and when it is // * available for completion) and when it is
@ -435,7 +390,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.task_duration", // "com.arsdigita.cms.loader.task_duration",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// new Integer(96) ); // new Integer(96) );
// /** // /**
// * alertInterval: The time to wait between sending successive alerts on // * alertInterval: The time to wait between sending successive alerts on
// * the same overdue task (in HOURS) // * the same overdue task (in HOURS)
@ -445,7 +399,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.overdue_alert_interval", // "com.arsdigita.cms.loader.overdue_alert_interval",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// new Integer(24) ); // new Integer(24) );
// /** // /**
// * maxAlerts: The maximum number of alerts to send about any one // * maxAlerts: The maximum number of alerts to send about any one
// * overdue task // * overdue task
@ -455,7 +408,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.mas_alerts", // "com.arsdigita.cms.loader.mas_alerts",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// new Integer(5) ); // new Integer(5) );
/** /**
* Standard Constructor. * Standard Constructor.
*/ */
@ -492,7 +444,6 @@ public final class LoaderConfig extends AbstractConfig {
// Getter Methods // Getter Methods
// //
// ////////////////////////// // //////////////////////////
// Not used as long as we use old style application (seee above) // Not used as long as we use old style application (seee above)
// /** // /**
// * Fetch name (URL) of the workspace package instance, e.g. content-center // * Fetch name (URL) of the workspace package instance, e.g. content-center
@ -501,7 +452,6 @@ public final class LoaderConfig extends AbstractConfig {
// public String getWorkspaceURL() { // public String getWorkspaceURL() {
// return (String) get(m_workspaceURL); // return (String) get(m_workspaceURL);
// } // }
// Moved to CMSConfig as long as it is not a Loader task. (see above) // Moved to CMSConfig as long as it is not a Loader task. (see above)
// /** // /**
// * Fetch the file name contaning XML Mapping of the content center tabs // * Fetch the file name contaning XML Mapping of the content center tabs
@ -511,101 +461,11 @@ public final class LoaderConfig extends AbstractConfig {
// public String getContentCenterMap() { // public String getContentCenterMap() {
// return (String) get(m_contentCenterMap); // return (String) get(m_contentCenterMap);
// } // }
public List getCTDefFiles() { public List getCTDefFiles() {
String[] ctDefFiles = (String[]) get(m_ctDefFiles); String[] ctDefFiles = (String[]) get(m_ctDefFiles);
return Arrays.asList(ctDefFiles); return Arrays.asList(ctDefFiles);
} }
/**
* Retrieve the STAFF GROUP, i.e. a set of roles (author, editor, publisher,
* manager) and associated privileges for the content section to be created
* (m_contentSectionName).
*
* In loading step a complete default configuration is persisted in database,
* immutable at this point.
* See contentsection.ContentSectionSetup.registerRoles()
* In enterprise.init: name roles, List of roles to create.
*
* Set consists of a set of roles, for each role first field is the role name,
* second is the description, third is a list of privileges, and (optional)
* fourth is the workflow task to assign to.
*
* The set of roles constructed here is a complete set which reflects all
* functions of CMS and forms a necessary base for operations. When the first
* content section is created and loaded into database (during installation)
* this set is created, immutable by installer / administrator. Additional
* content section may be created using a subset. For a very special purpose
* a developer may alter the set.
*
* This method is typically used to construct the initial content section
* during installation.
*
* Not really implemented yet! We need a new parameter type "list" which
* must have multidimensional capabilities.
*
* As a temporary measure a constant list is retrieved. Until now the list
* was burried in enterprise.init and not user available for configuration.
* So it may turn into a permanent solution.
*/
public List getStuffGroup() {
final List<String> AUTH_PRIVS = Arrays.asList(
"new_item","read_item", "preview_item", "edit_item",
"categorize_items");
final List<String> EDIT_PRIVS = Arrays.asList(
"new_item","read_item", "preview_item", "edit_item",
"categorize_items", "delete_item", "approve_item" );
final List<String> PUBL_PRIVS = Arrays.asList(
"new_item","read_item", "preview_item", "edit_item",
"categorize_items", "delete_item", "approve_item",
"publish");
final List<String> MNGR_PRIVS = Arrays.asList(
"new_item","read_item", "preview_item", "edit_item",
"categorize_items", "delete_item", "approve_item",
"publish",
"staff_admin", "content_type_admin", "lifecycle_admin",
"workflow_admin", "category_admin");
m_staffGroup = new ArrayList();
m_staffGroup.add
( new ArrayList() {{ add("Author");
add("Creates new content");
add(AUTH_PRIVS);
add("Authoring");
}}
);
m_staffGroup.add
( new ArrayList() {{ add("Editor");
add("Reviews and approves the author's work");
add(EDIT_PRIVS);
add("Approval");
}}
);
m_staffGroup.add
( new ArrayList() {{ add("Publisher");
add("Deploys the content to the web site");
add(PUBL_PRIVS);
add("Publishing");
}}
);
m_staffGroup.add
( new ArrayList() {{ add("Manager");
add("Manages the overall content section");
add(MNGR_PRIVS);
// NB, manager doesn't have any assigned
// task for workflow - (as usual)
}}
);
return (List) m_staffGroup ;
}
/** /**
* Retrieve whether the content-section is publicly viewable (i.e. without * Retrieve whether the content-section is publicly viewable (i.e. without
* registration and login) * registration and login)
@ -628,10 +488,11 @@ public final class LoaderConfig extends AbstractConfig {
return (String) get(m_templateResolverClass); return (String) get(m_templateResolverClass);
} }
/** /**
* Retrieve weather to use section specific categories. If true they are * Retrieve weather to use section specific categories. If true they are
* loaded using the next parameters file list {@see getUseSectionCategories()} * loaded using the next parameters file list {
*
* @see getUseSectionCategories()}
* *
* Default value is false, so standard navigation is used. * Default value is false, so standard navigation is used.
* @return * @return
@ -641,9 +502,9 @@ public final class LoaderConfig extends AbstractConfig {
} }
/** /**
* Retrieve the list of files containing categories to load. * Retrieve the list of files containing categories to load. In old
* In old Initialiser: Parameter name: CATEGORIES * Initialiser: Parameter name: CATEGORIES Deskr. "XML file containing the
* Deskr. "XML file containing the category tree" * category tree"
*/ */
public List getCategoryFileList() { public List getCategoryFileList() {
String[] catFiles = (String[]) get(m_categoryFileList); String[] catFiles = (String[]) get(m_categoryFileList);
@ -661,5 +522,4 @@ public final class LoaderConfig extends AbstractConfig {
public List getDataQueries() { public List getDataQueries() {
return dataQueries; return dataQueries;
} }
} }

View File

@ -23,14 +23,12 @@ import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.BooleanParameter; import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.IntegerParameter; import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter; import com.arsdigita.util.parameter.Parameter;
//import com.arsdigita.util.parameter.ParameterError;
import com.arsdigita.util.parameter.StringArrayParameter; import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter; import com.arsdigita.util.parameter.StringParameter;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
@ -39,9 +37,13 @@ import org.apache.log4j.Logger;
* Configures parameter which are not persisted in the database and may be * Configures parameter which are not persisted in the database and may be
* changes during each startup of the system. * changes during each startup of the system.
* @author pb * @author pb
* @author Sören Bernstein (quasi@barkhof.uni-bremen.de)
*/ */
public final class ContentSectionConfig extends AbstractConfig { public final class ContentSectionConfig extends AbstractConfig {
private List m_defaultRoles;
private List m_defaultWorkflows;
/** Private Logger instance for debugging purpose. */ /** Private Logger instance for debugging purpose. */
private static final Logger s_log = private static final Logger s_log =
Logger.getLogger(ContentSectionConfig.class); Logger.getLogger(ContentSectionConfig.class);
@ -216,7 +218,6 @@ public final class ContentSectionConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.section_staff_group", // "com.arsdigita.cms.loader.section_staff_group",
// Parameter.REQUIRED, // Parameter.REQUIRED,
// null); // null);
private List m_staffGroup;
// Viewer group, set autonomously by ContentSection.create() method. We can // Viewer group, set autonomously by ContentSection.create() method. We can
@ -312,7 +313,7 @@ public final class ContentSectionConfig extends AbstractConfig {
private final Parameter private final Parameter
m_useSectionCategories = new BooleanParameter m_useSectionCategories = new BooleanParameter
("com.arsdigita.cms.section.use_section_categories", ("com.arsdigita.cms.section.use_section_categories",
Parameter.REQUIRED, new Boolean(false)); Parameter.REQUIRED, false);
/** /**
* XML file containing the category tree to load for this content section. * XML file containing the category tree to load for this content section.
@ -460,7 +461,12 @@ public final class ContentSectionConfig extends AbstractConfig {
* was burried in enterprise.init and not user available for configuration. * was burried in enterprise.init and not user available for configuration.
* So it may turn into a permanent solution. * So it may turn into a permanent solution.
*/ */
public List getStuffGroup() {
/**
* Changed: The forth field is not used anymore
*
*/
public List getDefaultRoles() {
final List<String> AUTH_PRIVS = Arrays.asList( final List<String> AUTH_PRIVS = Arrays.asList(
"new_item","read_item", "preview_item", "edit_item", "new_item","read_item", "preview_item", "edit_item",
@ -478,43 +484,169 @@ public final class ContentSectionConfig extends AbstractConfig {
"publish", "publish",
"staff_admin", "content_type_admin", "lifecycle_admin", "staff_admin", "content_type_admin", "lifecycle_admin",
"workflow_admin", "category_admin"); "workflow_admin", "category_admin");
final List<String> TRST_PRIVS = Arrays.asList(
"new_item","read_item", "preview_item", "edit_item",
"categorize_items", "delete_item", "approve_item",
"publish", "apply_alternate_workflows");
m_staffGroup = new ArrayList(); m_defaultRoles = new ArrayList();
m_staffGroup.add m_defaultRoles.add
( new ArrayList() {{ add("Author"); ( new ArrayList() {{ add("Author");
add("Creates new content"); add("Creates new content");
add(AUTH_PRIVS); add(AUTH_PRIVS);
add("Authoring");
}} }}
); );
m_staffGroup.add m_defaultRoles.add
( new ArrayList() {{ add("Editor"); ( new ArrayList() {{ add("Editor");
add("Reviews and approves the author's work"); add("Reviews and approves the author's work");
add(EDIT_PRIVS); add(EDIT_PRIVS);
add("Approval");
}} }}
); );
m_staffGroup.add m_defaultRoles.add
( new ArrayList() {{ add("Publisher"); ( new ArrayList() {{ add("Publisher");
add("Deploys the content to the web site"); add("Deploys the content to the web site");
add(PUBL_PRIVS); add(PUBL_PRIVS);
add("Publishing");
}} }}
); );
m_staffGroup.add m_defaultRoles.add
( new ArrayList() {{ add("Manager"); ( new ArrayList() {{ add("Manager");
add("Manages the overall content section"); add("Manages the overall content section");
add(MNGR_PRIVS); add(MNGR_PRIVS);
// NB, manager doesn't have any assigned }}
// task for workflow - (as usual) );
m_defaultRoles.add
( new ArrayList() {{ add("Trusted User");
add("A trusted user is allowed to create and publish items without review");
add(TRST_PRIVS);
}} }}
); );
return (List) m_staffGroup ; return (List) m_defaultRoles ;
} }
public List getDefaultWorkflows() {
if(m_defaultWorkflows == null) {
m_defaultWorkflows = new ArrayList();
// Prodcution Workflow
m_defaultWorkflows.add(
new HashMap<String, Object>() {{ put("name", "Redigierte Veröffentlichung");
put("description", "A process that involves creating and approving content.");
put("isDefault", "true");
put("tasks",
new ArrayList() {{ add(
new HashMap<String, Object>() {{ put("name", "Verfassen");
put("description", "Create content.");
put("type", "Author");
put("role",
new ArrayList<String>() {{ add("Author");
}}
);
}}
);
add(
new HashMap<String, Object>() {{ put("name", "Überprüfen");
put("description", "Approve content.");
put("type", "Edit");
put("role",
new ArrayList<String>() {{ add("Editor");
}}
);
put("dependOn",
new ArrayList<String>() {{ add("Verfassen");
}}
);
}}
);
add(
new HashMap<String, Object>() {{ put("name", "Veröffentlichen");
put("description", "Deploy content.");
put("type", "Deploy");
put("role",
new ArrayList<String>() {{ add("Publisher");
}}
);
put("dependOn",
new ArrayList<String>() {{ add("Überprüfen");
}}
);
}}
);
}}
);
}}
);
// TrustedUser Workflow
m_defaultWorkflows.add(
new HashMap<String, Object>() {{ put("name", "Direkte Veröffentlichung");
put("description", "Create and publish content without review");
put("isDefault", "false");
put("tasks",
new ArrayList() {{ add(
new HashMap<String, Object>() {{ put("name", "Verfassen");
put("description", "Create content.");
put("type", "Author");
put("role",
new ArrayList<String>() {{ add("Author");
add("Trusted User");
}}
);
}}
);
add(
new HashMap<String, Object>() {{ put("name", "Veröffentlichen");
put("description", "Deploy content.");
put("type", "Deploy");
put("role",
new ArrayList<String>() {{ add("Publisher");
add("Trusted User");
}}
);
put("dependOn",
new ArrayList<String>() {{ add("Verfassen");
}}
);
}}
);
}}
);
}}
);
/*
// Addiditonal Workflows
m_defaultWorkflows.add(
new HashMap<String, Object>() {{ put("name", "");
put("description", "");
put("tasks",
new ArrayList() {{ add(
new HashMap<String, Object>() {{ put("name", "");
put("description", "");
put("type", "");
put("role",
new ArrayList<String>() {{ add("");
}}
);
put("dependOn",
new ArrayList<String>() {{ add("");
}}
);
}}
);
}}
);
}}
);
*/
}
return m_defaultWorkflows;
}
/** /**
* Retrieve whether the content-section is publicly viewable (i.e. without * Retrieve whether the content-section is publicly viewable (i.e. without
* registration and login) * registration and login)

View File

@ -43,7 +43,6 @@ import com.arsdigita.util.Assert;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.workflow.simple.WorkflowTemplate; import com.arsdigita.workflow.simple.WorkflowTemplate;
import com.arsdigita.xml.XML; import com.arsdigita.xml.XML;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -54,7 +53,6 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Stack; import java.util.Stack;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
@ -65,20 +63,21 @@ import org.xml.sax.helpers.DefaultHandler;
* into the database. * into the database.
* *
* @author Peter Boy (pboy@barkhof.uni-bremen.de) * @author Peter Boy (pboy@barkhof.uni-bremen.de)
* @author Sören Bernstein (quasi@barkhof.uni-bremen.de)
* @author Jon Orris (jorris@redhat.com) * @author Jon Orris (jorris@redhat.com)
* @version $Id: $ * @version $Id: $
*/ */
public final class ContentSectionSetup { public final class ContentSectionSetup {
private static Logger s_log = Logger.getLogger(ContentSectionSetup.class); private static Logger s_log = Logger.getLogger(ContentSectionSetup.class);
private HashMap m_tasks = new HashMap(); private HashMap<String, Role> m_roles = new HashMap<String, Role>();
private LifecycleDefinition m_lcd; private LifecycleDefinition m_lcd;
private WorkflowTemplate m_wf; private WorkflowTemplate m_wf;
final ContentSection m_section; final ContentSection m_section;
/** /**
* Constructor. Using this constructor the content section has to be * Constructor. Using this constructor the content section has to be already
* already created using ContentSection.create(name) * created using ContentSection.create(name)
* *
* @param section name of a content section previously created by * @param section name of a content section previously created by
* ContentSection.create * ContentSection.create
@ -89,15 +88,16 @@ public final class ContentSectionSetup {
} }
/** /**
* Wrapper class to create and configure a content section instance * Wrapper class to create and configure a content section instance in one
* in one step. * step.
* *
* Method needs a transaction to proceed successfully. * Method needs a transaction to proceed successfully.
* {@link com.arsdigita.cms.contentsection.Initializer#checkForNewContentSection() } * {@link com.arsdigita.cms.contentsection.Initializer#checkForNewContentSection()
* }
*/ */
public static void setupContentSectionAppInstance( public static ContentSection setupContentSectionAppInstance(String name,
String name, List defaultRoles,
List staffGroup, List defaultWorkflows,
Boolean isPubliclyViewable, Boolean isPubliclyViewable,
String itemResolverClassName, String itemResolverClassName,
String templateResolverClassName, String templateResolverClassName,
@ -111,10 +111,10 @@ public final class ContentSectionSetup {
ContentSectionSetup setup = new ContentSectionSetup(section); ContentSectionSetup setup = new ContentSectionSetup(section);
// Setup the access controls // Setup the access controls
setup.registerRoles(staffGroup); setup.registerRoles(defaultRoles);
setup.registerWorkflows(defaultWorkflows);
setup.registerViewers(isPubliclyViewable); setup.registerViewers(isPubliclyViewable);
setup.registerPublicationCycles(); setup.registerPublicationCycles();
setup.registerWorkflowTemplates();
setup.registerResolvers(itemResolverClassName, templateResolverClassName); setup.registerResolvers(itemResolverClassName, templateResolverClassName);
// setup.registerContentTypes((List)m_conf.getParameter(TYPES)); // setup.registerContentTypes((List)m_conf.getParameter(TYPES));
@ -131,7 +131,7 @@ public final class ContentSectionSetup {
section.save(); section.save();
// return section; return section;
} }
@ -141,7 +141,7 @@ public final class ContentSectionSetup {
* *
* @param roles * @param roles
*/ */
public void registerRoles(List roles) { public void registerRoles(List<List> roles) {
Iterator i = roles.iterator(); Iterator i = roles.iterator();
while (i.hasNext()) { while (i.hasNext()) {
@ -150,23 +150,15 @@ public final class ContentSectionSetup {
String name = (String) role.get(0); String name = (String) role.get(0);
String desc = (String) role.get(1); String desc = (String) role.get(1);
List privileges = (List) role.get(2); List privileges = (List) role.get(2);
String task = (role.size() > 3 ? (String) role.get(3) : null);
s_log.info("Creating role " + name); s_log.info("Creating role " + name);
Role newRole = registerRole(name, desc, privileges);
m_roles.put(name, newRole);
Role group = registerRole(
name,
desc,
privileges);
if (task != null) {
m_tasks.put(task, group);
} }
} }
}
/** /**
* Takes the characteristics of a role and persists them in the database. * Takes the characteristics of a role and persists them in the database.
* *
@ -204,6 +196,15 @@ public final class ContentSectionSetup {
} }
} }
// Add site-wide administrator group by default to all roles
PartyCollection partyColl = Party.retrieveAllParties();
// FIXME: String for Site-wide Admininistrators is hardcoded because
// this group in inserted via sql-command during setup
partyColl.filter("Site-wide Administrators");
if(partyColl.next()) {
role.add(partyColl.getParty());
}
return role; return role;
} }
@ -259,8 +260,8 @@ public final class ContentSectionSetup {
/** /**
* Checks for specific item resolver and template resolver classes probably * Checks for specific item resolver and template resolver classes probably
* specified in parameters, otherwise uses system wide default parameters * specified in parameters, otherwise uses system wide default parameters
* specified in CMS global configuration file. Delegates persistence task * specified in CMS global configuration file. Delegates persistence task to
* to ContentSection. * ContentSection.
* *
* @param itemResolverClassName * @param itemResolverClassName
* @param templateResolverClassName * @param templateResolverClassName
@ -274,8 +275,7 @@ public final class ContentSectionSetup {
s_log.info("Registering " + itemResolverClassName s_log.info("Registering " + itemResolverClassName
+ " as the item resolver class"); + " as the item resolver class");
} else { } else {
m_section.setItemResolverClass(ContentSection.getConfig() m_section.setItemResolverClass(ContentSection.getConfig().getDefaultItemResolverClass().getName());
.getDefaultItemResolverClass().getName());
s_log.info("Registering " + itemResolverClassName s_log.info("Registering " + itemResolverClassName
+ " as the item resolver class"); + " as the item resolver class");
} }
@ -285,8 +285,7 @@ public final class ContentSectionSetup {
s_log.info("Registering " + templateResolverClassName s_log.info("Registering " + templateResolverClassName
+ " as the template resolver class"); + " as the template resolver class");
} else { } else {
m_section.setTemplateResolverClass(ContentSection.getConfig() m_section.setTemplateResolverClass(ContentSection.getConfig().getDefaultTemplateResolverClass().getName());
.getDefaultTemplateResolverClass().getName());
s_log.info("Registering " + templateResolverClassName s_log.info("Registering " + templateResolverClassName
+ " as the template resolver class"); + " as the template resolver class");
} }
@ -323,86 +322,110 @@ public final class ContentSectionSetup {
m_section.save(); m_section.save();
} }
private void registerWorkflows(List workflows) {
Iterator workflowsIter = workflows.iterator();
while (workflowsIter.hasNext()) {
HashMap<String, CMSTask> newTasks = new HashMap<String, CMSTask>();
HashMap<String, Object> workflow = (HashMap) workflowsIter.next();
// Create a new WorkflowTemplate
WorkflowTemplate wf = new WorkflowTemplate();
wf.setLabel((String) workflow.get("name"));
wf.setDescription((String) workflow.get("description"));
wf.save();
// Add tasks to workflow
Iterator tasksIter = ((List) workflow.get("tasks")).iterator();
while (tasksIter.hasNext()) {
HashMap<String, Object> task = (HashMap) tasksIter.next();
// Setup new task
CMSTask newTask = new CMSTask();
newTask.setLabel((String) task.get("name"));
newTask.setDescription((String) task.get("description"));
newTask.setTaskType(CMSTaskType.retrieveByName((String) task.get("type")));
// Add roles to task
if (task.containsKey("role")) {
Iterator<String> roleIter = ((List<String>) task.get("role")).iterator();
while (roleIter.hasNext()) {
Role role = m_roles.get(roleIter.next());
if (role != null) {
newTask.assignGroup(role.getGroup());
}
}
}
// Save task
newTask.save();
// Save task to HashMap for fast access in the next loop
newTasks.put((String) task.get("name"), newTask);
}
// Setup task dependencies (easier to do it after creating all task)
tasksIter = ((List) workflow.get("tasks")).iterator();
while (tasksIter.hasNext()) {
HashMap<String, Object> task = (HashMap) tasksIter.next();
CMSTask newTask = newTasks.get((String) task.get("name"));
if (task.containsKey("dependOn")) {
Iterator<String> dependOnIter = ((List<String>) task.get("dependOn")).iterator();
while (dependOnIter.hasNext()) {
CMSTask dependOn = newTasks.get(dependOnIter.next());
if (dependOn != null) {
newTask.addDependency(dependOn);
}
}
}
newTask.save();
}
// Add tasks to the workflow
for (CMSTask newTask : newTasks.values()) {
wf.addTask(newTask);
}
// Save workflow
wf.save();
// Add Workflow to current section
m_section.addWorkflowTemplate(wf);
m_section.save();
// If this workflow should be the default or is the first one
// save it for easy access in registerContentType
if(m_wf == null || (workflow.containsKey("isDefault") && workflow.get("isDefault").equals("true"))) {
m_wf = wf;
}
}
}
/** /**
* Defines a (default for section) workflow which gets persisted in tne * Defines a (default for section) workflow which gets persisted in tne
* database. * database.
* *
* This one is probably deprecated.
*
* @throws InitializationException * @throws InitializationException
*/ */
public void registerWorkflowTemplates() public void registerWorkflowTemplates() throws ConfigError {
throws ConfigError {
// The 3-step production workflow. ContentSectionConfig config = new ContentSectionConfig();
WorkflowTemplate wf = new WorkflowTemplate(); config.load();
wf.setLabel((String) GlobalizationUtil.globalize( registerWorkflows(config.getDefaultWorkflows());
"cms.installer.production_workflow").localize());
wf.setDescription("A process that involves creating and approving content.");
wf.save();
CMSTask authoring = new CMSTask();
authoring.setLabel((String) GlobalizationUtil.globalize(
"cms.installer.authoring").localize());
authoring.setDescription("Create content.");
authoring.save();
Role author = (Role) m_tasks.get("Authoring");
if (author != null) {
authoring.assignGroup(author.getGroup());
}
authoring.setTaskType(CMSTaskType.retrieve(CMSTaskType.AUTHOR));
authoring.save();
CMSTask approval = new CMSTask();
approval.setLabel((String) GlobalizationUtil.globalize(
"cms.installer.approval").localize());
approval.setDescription("Approve content.");
approval.save();
approval.addDependency(authoring);
approval.save();
Role approver = (Role) m_tasks.get("Approval");
if (approver != null) {
approval.assignGroup(approver.getGroup());
}
approval.setTaskType(CMSTaskType.retrieve(CMSTaskType.EDIT));
approval.save();
CMSTask deploy = new CMSTask();
deploy.setLabel((String) GlobalizationUtil.globalize(
"cms.installer.deploy").localize());
deploy.setDescription("Deploy content.");
deploy.save();
deploy.addDependency(approval);
deploy.save();
Role publisher = (Role) m_tasks.get("Publishing");
if (publisher != null) {
deploy.assignGroup(publisher.getGroup());
}
deploy.setTaskType(CMSTaskType.retrieve(CMSTaskType.DEPLOY));
deploy.save();
wf.addTask(authoring);
wf.addTask(approval);
wf.addTask(deploy);
wf.save();
m_section.addWorkflowTemplate(wf);
m_section.save();
m_wf = wf;
} }
/** /**
* Steps through a list of content types to be available for this content * Steps through a list of content types to be available for this content
* section and delegates processing of each type. * section and delegates processing of each type.
* *
* @param types list of content types to be available for this content section * @param types list of content types to be available for this content
* section
*/ */
public void registerContentTypes(List types) { public void registerContentTypes(List types) {
@ -424,7 +447,8 @@ public final class ContentSectionSetup {
} }
/** /**
* Process one content type and registers it with the current content section. * Process one content type and registers it with the current content
* section.
* *
* @param name * @param name
* @return * @return
@ -514,8 +538,7 @@ public final class ContentSectionSetup {
temp.save(); temp.save();
TemplateManagerFactory.getInstance() TemplateManagerFactory.getInstance().addTemplate(m_section, type, temp, "public");
.addTemplate(m_section, type, temp, "public");
temp.publish(m_lcd, new Date()); temp.publish(m_lcd, new Date());
} }
@ -545,6 +568,8 @@ public final class ContentSectionSetup {
alert.setDescription( alert.setDescription(
"Receive alerts regarding expiration of pubished content"); "Receive alerts regarding expiration of pubished content");
alert.save(); alert.save();
} }
// // Currently there is no way to persists alert preferemces, therefore // // Currently there is no way to persists alert preferemces, therefore
@ -679,6 +704,4 @@ public final class ContentSectionSetup {
} }
} }
} // END private class CategoryHandler } // END private class CategoryHandler
} }

View File

@ -22,26 +22,23 @@ package com.arsdigita.cms.contentsection;
import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentSectionCollection; import com.arsdigita.cms.ContentSectionCollection;
import com.arsdigita.cms.workflow.CMSTask;
import com.arsdigita.cms.workflow.UnfinishedTaskNotifier; import com.arsdigita.cms.workflow.UnfinishedTaskNotifier;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;
import com.arsdigita.domain.DomainObject; import com.arsdigita.domain.DomainObject;
import com.arsdigita.kernel.ACSObjectInstantiator; import com.arsdigita.kernel.ACSObjectInstantiator;
import com.arsdigita.persistence.DataObject; import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;
import com.arsdigita.runtime.CompoundInitializer; import com.arsdigita.runtime.CompoundInitializer;
import com.arsdigita.runtime.ContextInitEvent;
import com.arsdigita.runtime.ContextCloseEvent; import com.arsdigita.runtime.ContextCloseEvent;
// import com.arsdigita.runtime.DataInitEvent; import com.arsdigita.runtime.ContextInitEvent;
import com.arsdigita.runtime.DomainInitEvent; import com.arsdigita.runtime.DomainInitEvent;
import com.arsdigita.web.Application; import com.arsdigita.web.Application;
import com.arsdigita.cms.workflow.CMSTask;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.Timer; import java.util.Timer;
import java.util.Vector; import java.util.Vector;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -188,7 +185,9 @@ public class Initializer extends CompoundInitializer {
for (Enumeration el=s_unfinishedTimers.elements(); for (Enumeration el=s_unfinishedTimers.elements();
el.hasMoreElements(); ) { el.hasMoreElements(); ) {
unfinishedTimer = (Timer) el.nextElement(); unfinishedTimer = (Timer) el.nextElement();
if(unfinishedTimer != null) unfinishedTimer.cancel(); if(unfinishedTimer != null) {
unfinishedTimer.cancel();
}
unfinishedTimer = null; unfinishedTimer = null;
// s_unfinishedTimer = null; // s_unfinishedTimer = null;
} }
@ -221,7 +220,8 @@ public class Initializer extends CompoundInitializer {
txn.beginTxn(); txn.beginTxn();
ContentSectionSetup.setupContentSectionAppInstance ContentSectionSetup.setupContentSectionAppInstance
(newSectionName, (newSectionName,
s_conf.getStuffGroup(), s_conf.getDefaultRoles(),
s_conf.getDefaultWorkflows(),
s_conf.isPubliclyViewable(), s_conf.isPubliclyViewable(),
s_conf.getItemResolverClass(), s_conf.getItemResolverClass(),
s_conf.getTemplateResolverClass(), s_conf.getTemplateResolverClass(),

View File

@ -19,56 +19,24 @@
package com.arsdigita.cms.workflow; package com.arsdigita.cms.workflow;
import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.SecurityManager;
import com.arsdigita.cms.ui.ContentItemPage;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObject; import com.arsdigita.domain.DomainObject;
import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.kernel.Group;
import com.arsdigita.kernel.KernelHelper;
import com.arsdigita.kernel.Party;
import com.arsdigita.kernel.User;
import com.arsdigita.kernel.UserCollection;
import com.arsdigita.kernel.permissions.PermissionService;
import com.arsdigita.kernel.permissions.PrivilegeDescriptor; import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.messaging.Message;
import com.arsdigita.notification.Notification;
import com.arsdigita.persistence.DataAssociation; import com.arsdigita.persistence.DataAssociation;
import com.arsdigita.persistence.DataAssociationCursor; import com.arsdigita.persistence.DataAssociationCursor;
import com.arsdigita.persistence.DataCollection; import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.DataObject; import com.arsdigita.persistence.DataObject;
import com.arsdigita.persistence.DataOperation;
import com.arsdigita.persistence.DataQuery;
import com.arsdigita.persistence.Filter;
import com.arsdigita.persistence.OID; import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.Session;
import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.util.Assert;
import com.arsdigita.util.UncheckedWrapperException; import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.versioning.TagCollection;
import com.arsdigita.versioning.Transaction;
import com.arsdigita.versioning.TransactionCollection;
import com.arsdigita.versioning.Versions;
import com.arsdigita.web.URL;
import com.arsdigita.workflow.simple.TaskComment;
import com.arsdigita.workflow.simple.TaskException;
import com.arsdigita.workflow.simple.UserTask;
import org.apache.log4j.Logger;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import org.apache.log4j.Logger;
/** /**
* This class represents a task type in the CMS system. The task type has attributes that impact on * This class represents a task type in the CMS system. The task type has
* the behaviour of tasks of that type * attributes that impact on the behaviour of tasks of that type
* *
* *
* @author chris.gilbert at westsussex.gov.uk * @author chris.gilbert at westsussex.gov.uk
@ -78,10 +46,7 @@ public class CMSTaskType extends DomainObject {
public static final String BASE_DATA_OBJECT_TYPE = public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.cms.workflow.CMSTaskType"; "com.arsdigita.cms.workflow.CMSTaskType";
private static Map s_taskURLGeneratorCache = new HashMap(); private static Map s_taskURLGeneratorCache = new HashMap();
// pdl attribute names // pdl attribute names
public static final String ID = "taskTypeID"; public static final String ID = "taskTypeID";
public static final String NAME = "name"; public static final String NAME = "name";
@ -89,20 +54,28 @@ public class CMSTaskType extends DomainObject {
"defaultUrlGeneratorClass"; "defaultUrlGeneratorClass";
public static final String PRIVILEGE = "privilege"; public static final String PRIVILEGE = "privilege";
public static final String URL_GENERATORS = "generators"; public static final String URL_GENERATORS = "generators";
private static final Logger s_log = Logger.getLogger(CMSTaskType.class); private static final Logger s_log = Logger.getLogger(CMSTaskType.class);
// known task types // known task types
public static final Integer AUTHOR = new Integer(1); public static final Integer AUTHOR = new Integer(1);
public static final Integer EDIT = new Integer(2); public static final Integer EDIT = new Integer(2);
public static final Integer DEPLOY = new Integer(3); public static final Integer DEPLOY = new Integer(3);
// cache task type domain objects to save unnecessary db lookups // cache task type domain objects to save unnecessary db lookups
public static Map s_taskTypes = new HashMap(); public static Map<Integer, CMSTaskType> s_taskTypes = new HashMap<Integer, CMSTaskType>();
private static Map<String, Integer> s_taskNameMap = new HashMap<String, Integer>();
static {
s_taskNameMap.put("Author", AUTHOR);
s_taskNameMap.put("Edit", EDIT);
s_taskNameMap.put("Deploy",DEPLOY);
}
public static CMSTaskType retrieve(Integer id) { public static CMSTaskType retrieve(Integer id) {
CMSTaskType type = (CMSTaskType)s_taskTypes.get(id);
if (id == null) {
throw new IllegalArgumentException("Parameter id must not be null");
}
CMSTaskType type = s_taskTypes.get(id);
if (type == null) { if (type == null) {
type = new CMSTaskType(id); type = new CMSTaskType(id);
s_taskTypes.put(id, type); s_taskTypes.put(id, type);
@ -110,6 +83,28 @@ public class CMSTaskType extends DomainObject {
return type; return type;
} }
public static CMSTaskType retrieveByName(String name) {
if (name == null || name.isEmpty()) {
throw new IllegalArgumentException("Parameter name must not be null or empty");
}
Integer id = s_taskNameMap.get(name);
if (id == null) {
for (CMSTaskType type : s_taskTypes.values()) {
if (!s_taskNameMap.containsKey(type.getName())) {
s_taskNameMap.put(type.getName(), type.getID());
}
if (name.equals(type.getName())) {
id = type.getID();
}
}
}
return retrieve(id);
}
private CMSTaskType(Integer id) { private CMSTaskType(Integer id) {
super(new OID(BASE_DATA_OBJECT_TYPE, id)); super(new OID(BASE_DATA_OBJECT_TYPE, id));
} }
@ -119,7 +114,8 @@ public class CMSTaskType extends DomainObject {
} }
/** /**
* create a message object and associate it with the current application instance * create a message object and associate it with the current application
* instance
* *
*/ */
public CMSTaskType() { public CMSTaskType() {
@ -170,8 +166,7 @@ public class CMSTaskType extends DomainObject {
public TaskURLGenerator getURLGenerator(String event, ContentItem item) { public TaskURLGenerator getURLGenerator(String event, ContentItem item) {
String key = getID() + " " + event + " " + item.getContentType().getID(); String key = getID() + " " + event + " " + item.getContentType().getID();
s_log.debug("looking up url generator for key " + key); s_log.debug("looking up url generator for key " + key);
TaskURLGenerator generator = (TaskURLGenerator) TaskURLGenerator generator = (TaskURLGenerator) s_taskURLGeneratorCache.get(key);
s_taskURLGeneratorCache.get(key);
if (generator == null) { if (generator == null) {
s_log.debug("no generator found in cache"); s_log.debug("no generator found in cache");
DataAssociationCursor generators = ((DataAssociation) get(URL_GENERATORS)).cursor(); DataAssociationCursor generators = ((DataAssociation) get(URL_GENERATORS)).cursor();
@ -213,11 +208,12 @@ public class CMSTaskType extends DomainObject {
return generator; return generator;
} }
/** /**
* *
* Should be used when UI is implemented for managing task types. If a specific TaskURLGenerator * Should be used when UI is implemented for managing task types. If a
* is added or removed for an event, then the cached TaskURLGenerator needs to be removed * specific TaskURLGenerator is added or removed for an event, then the
* cached TaskURLGenerator needs to be removed
*
* @param event * @param event
*/ */
public void clearCachedEntry(String event) { public void clearCachedEntry(String event) {
@ -225,9 +221,4 @@ public class CMSTaskType extends DomainObject {
s_taskURLGeneratorCache.remove(key); s_taskURLGeneratorCache.remove(key);
} }
} }