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;
import com.arsdigita.cms.contentsection.ContentSectionConfig;
import com.arsdigita.cms.contentsection.ContentSectionSetup;
import com.arsdigita.cms.util.Util;
import com.arsdigita.cms.contenttypes.XMLContentTypeHandler;
import com.arsdigita.cms.portlet.ContentDirectoryPortlet;
import com.arsdigita.cms.portlet.ContentItemPortlet;
import com.arsdigita.cms.portlet.ContentSectionsPortlet;
import com.arsdigita.cms.portlet.TaskPortlet;
import com.arsdigita.cms.util.Util;
import com.arsdigita.formbuilder.util.FormbuilderSetup;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.kernel.KernelExcursion;
@ -38,35 +39,31 @@ import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.web.Application;
import com.arsdigita.web.ApplicationType;
import com.arsdigita.xml.XML;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
* <p>Executes nonrecurring at install time and loads (installs and initializes)
* the Content Management System module,including the Content Center, CMS Service
* applications, and CMS Mime Types service persistently into database.</p>
* the Content Management System module,including the Content Center, CMS
* Service applications, and CMS Mime Types service persistently into
* database.</p>
*
* <p>This class also optionally initializes user-defined content types. </p>
* <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>
* <ol>
* <li>create CMS package type(content-section)</li>
* <li>create Workspace package type and instance</li>
* <li>create CMS Service package type and instance</li>
* <li>create CMS package (content-section) instance</li>
* </ol>
* <p>The tasks to perform are:</p> <ol> <li>create CMS package
* type(content-section)</li> <li>create Workspace package type and
* instance</li> <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,
* otherwise hardcoded default values take effect. After processing, the
* installation values can not be modified anymore without a fresh installation
* of the whole system.</p>
* <p>Configuration can be modified by configuration parameters before
* processing, otherwise hardcoded default values take effect. After processing,
* the installation values can not be modified anymore without a fresh
* installation of the whole system.</p>
*
* @author Peter Boy &lt;pboy@barkhof.uni-bremen.de&gt;
* @since ccm-cms version 6.6.0
@ -74,39 +71,38 @@ import org.apache.log4j.Logger;
*/
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);
/** Loader configuration object, singleton design pattern
* NOTE: LoaderConfig only supplies unmutable hard coded defaults! It is
* not possible to alter any of the contained values by specifiying an
* configuration parameter during load step. If a configuration value
* has to be configurable at load time, the parameter must be relocated
* into this Loader class! */
/**
* Loader configuration object, singleton design pattern NOTE: LoaderConfig
* only supplies unmutable hard coded defaults! It is not possible to alter
* any of the contained values by specifiying an configuration parameter
* during load step. If a configuration value has to be configurable at load
* time, the parameter must be relocated into this Loader class!
*/
private static final LoaderConfig s_conf = LoaderConfig.getInstance();
// ///////////////////////////////////////////////////////////////////
// Configurable parameters during load step.
// ///////////////////////////////////////////////////////////////////
/**
* 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
* default section. More sections can always be created during a subsequent
* system startup using initialization parameters.
* system startup using initialization parameters.
*/
private final Parameter m_contentSectionNames = new StringArrayParameter(
"com.arsdigita.cms.loader.section_names",
Parameter.REQUIRED,
new String[] {"content"}
);
/** List of classnames of internal base content types (needed in every
* section created), generated while loading those content types in
* loadContentTypeDefinitions(files) for later use in register step. */
"com.arsdigita.cms.loader.section_names",
Parameter.REQUIRED,
new String[]{"content"});
/**
* List of classnames of internal base content types (needed in every
* section created), generated while loading those content types in
* loadContentTypeDefinitions(files) for later use in register step.
*/
private ArrayList m_content_type_list = new ArrayList();
/**
* Standard constructor.
*/
@ -114,12 +110,12 @@ public class Loader extends PackageLoader {
s_log.debug("CMS.loader (Constructor) invoked");
register(m_contentSectionNames);
s_log.debug("CMS.loader (Constructor) completed");
}
/**
*
*
*/
public void run(final ScriptContext ctx) {
s_log.debug("CMS.loader.run() invoked");
@ -142,7 +138,7 @@ public class Loader extends PackageLoader {
// Step 4) Load CMS content section
// Loads content section application type and instance in one step
loadContentSection( (String[]) get(m_contentSectionNames) );
loadContentSection((String[]) get(m_contentSectionNames));
// Step 5) Loading CMS portlets
s_log.debug("CMS.loader going to load portlets");
@ -154,8 +150,8 @@ public class Loader extends PackageLoader {
// Loading forms widget into database
FormbuilderSetup fbs = new FormbuilderSetup();
fbs.setup(s_conf.getWidgetTypes(),
s_conf.getProcessListenerTypes(),
s_conf.getDataQueries());
s_conf.getProcessListenerTypes(),
s_conf.getDataQueries());
}
@ -165,23 +161,23 @@ public class Loader extends PackageLoader {
/**
* Loads the Workspace subpackage (content-center) into the database.
*
* It is made public to be able to invoke it from the update script
* (e.g. 6.6.1-6.6.2). We need separate steps for loading and instantiating
* It is made public to be able to invoke it from the update script (e.g.
* 6.6.1-6.6.2). We need separate steps for loading and instantiating
* because update skript requires.
*/
public static ApplicationType loadWorkspaceApplicationType() {
s_log.debug("Creating CMS Workspace...");
/* Create new type legacy free application type
* NOTE: The wording in the title parameter of ApplicationType
* determines the name of the subdirectory for the XSL stylesheets.
* It gets "urlized", i.e. trimming leading and trailing blanks and
* replacing blanks between words and illegal characters with an
* hyphen and converted to lower case.
* "Content Center" will become "content-center". */
ApplicationType type = new
ApplicationType(Workspace.INSTANCE_NAME,
Workspace.BASE_DATA_OBJECT_TYPE );
/*
* Create new type legacy free application type NOTE: The wording in the
* title parameter of ApplicationType determines the name of the
* subdirectory for the XSL stylesheets. It gets "urlized", i.e.
* trimming leading and trailing blanks and replacing blanks between
* words and illegal characters with an hyphen and converted to lower
* case. "Content Center" will become "content-center".
*/
ApplicationType type = new ApplicationType(Workspace.INSTANCE_NAME,
Workspace.BASE_DATA_OBJECT_TYPE);
type.setDescription("The content center workspace for content creators.");
type.save();
@ -193,14 +189,14 @@ public class Loader extends PackageLoader {
/**
* Instantiates the Workspace subpackage (content-center) (in the database).
*
* It is made public to be able to invoke it from the update script
* (e.g. 6.6.1-6.6.2). We need separate steps for loading and instantiating
* It is made public to be able to invoke it from the update script (e.g.
* 6.6.1-6.6.2). We need separate steps for loading and instantiating
* because update skript requires.
*
* @param workspaceType
*/
public static void setupDefaultWorkspaceApplicationInstance(
ApplicationType workspaceType) {
ApplicationType workspaceType) {
// create application instance
// Whether a legacy compatible or a legacy free application is
@ -209,10 +205,10 @@ public class Loader extends PackageLoader {
// old-style package key used as url fragment where to install the instance
s_log.debug("Creating CMS Workspace instance ...");
Workspace app = (Workspace) Application.createApplication(
Workspace.BASE_DATA_OBJECT_TYPE, // type
Workspace.PACKAGE_KEY, // url fragment
Workspace.INSTANCE_NAME, // title
null); // parent
Workspace.BASE_DATA_OBJECT_TYPE, // type
Workspace.PACKAGE_KEY, // url fragment
Workspace.INSTANCE_NAME, // title
null); // parent
app.setDescription("The default CMS workspace instance.");
app.save();
@ -220,44 +216,42 @@ public class Loader extends PackageLoader {
s_log.debug("Done loading CMS Workspace.");
}
/**
* CMS Service application is used by the Content Management System as a
* store for global resources and assets.
* It is made public to be able to invoke it from the update script
* (e.g. 6.6.1-6.6.2).
* store for global resources and assets. It is made public to be able to
* invoke it from the update script (e.g. 6.6.1-6.6.2).
*/
public static ApplicationType loadServiceApplicationType() {
s_log.debug("Loading CMS Servce Package...");
/* Create new type legacy free application type
* NOTE: The wording in the title parameter of ApplicationType
* determines the name of the subdirectory for the XSL stylesheets.
* It gets "urlized", i.e. trimming leading and trailing blanks and
* replacing blanks between words and illegal characters with an
* hyphen and converted to lower case.
* "CMS Service" will become "cms-service". */
ApplicationType type = new ApplicationType("CMS Service",
Service.BASE_DATA_OBJECT_TYPE );
/*
* Create new type legacy free application type NOTE: The wording in the
* title parameter of ApplicationType determines the name of the
* subdirectory for the XSL stylesheets. It gets "urlized", i.e.
* trimming leading and trailing blanks and replacing blanks between
* words and illegal characters with an hyphen and converted to lower
* case. "CMS Service" will become "cms-service".
*/
ApplicationType type = new ApplicationType("CMS Service",
Service.BASE_DATA_OBJECT_TYPE);
type.setDescription("Services to store global resources and assets.");
type.save();
return type;
}
/**
*
* @param serviceType
*/
public static void setupDefaultServiceApplicationInstance(
ApplicationType serviceType) {
ApplicationType serviceType) {
// create legacy compatible application instance,
// old-style package key used as url fragment where to install the instance
Service app = (Service) Application.createApplication(
serviceType, // type
Service.PRIMARY_URL_STUB, // url fragment
"CMS Service Instance", // title
serviceType, // type
Service.PRIMARY_URL_STUB, // url fragment
"CMS Service Instance", // title
null); // parent
app.setDescription("The default CMS service instance.");
app.save();
@ -265,40 +259,39 @@ public class Loader extends PackageLoader {
s_log.debug("Done creating CMS Service Package.");
}
/**
* Load a content section application type and an initial default
* content-section instance(s).
* Some configuration values which are to be considered as unmutable are
* specified in LoaderConfig.
* Uses new style application in legacy compatible mode.
* content-section instance(s). Some configuration values which are to be
* considered as unmutable are specified in LoaderConfig. Uses new style
* application in legacy compatible mode.
*
* 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
* process content type package assignment! Instead each content type itself
* must assign itself to an appropriate content section at it's load time.
* must assign itself to an appropriate content section at it's load time.
* Cf. {@link com.arsdigita.cms.contenttype.AbstractContentTypeLoader}.
*
*
* But the load step has to process the cms internal content types!
*/
private void loadContentSection(String[] sectionNames) {
// Step 1: Create content section application type
// prerequisite for concrete content-section instance creation.
/* Create legacy-free application type
* NOTE: The wording in the title parameter of ApplicationType
* determines the name of the subdirectory for the XSL stylesheets.
* It gets "urlized", i.e. trimming leading and trailing blanks and
* replacing blanks between words and illegal characters with an
* hyphen and converted to lower case.
* "Content Section" will become "content-section". */
ApplicationType type = new ApplicationType(
"Content Section",
ContentSection.BASE_DATA_OBJECT_TYPE );
/*
* Create legacy-free application type NOTE: The wording in the title
* parameter of ApplicationType determines the name of the subdirectory
* for the XSL stylesheets. It gets "urlized", i.e. trimming leading and
* trailing blanks and replacing blanks between words and illegal
* characters with an hyphen and converted to lower case. "Content
* Section" will become "content-section".
*/
ApplicationType type = new ApplicationType(
"Content Section",
ContentSection.BASE_DATA_OBJECT_TYPE);
type.setDescription("The CMS Content Section application.");
type.save();
// Step 2: Load CMS specific privileges into central (core) privilege
// system.
createPrivileges();
@ -306,73 +299,27 @@ public class Loader extends PackageLoader {
// Step 3: Create the installation default content section(s).
// ContentSection.create creates a section with several default values
// which have to be adopted for a concrete installation.
for (int i = 0 ; i < sectionNames.length ; i++) {
for (int i = 0; i < sectionNames.length; i++) {
final String sectionName = sectionNames[i];
s_log.debug("Creating content section on /" + sectionName);
// Step 1: Validate name for section
Util.validateURLParameter("name", sectionName);
ContentSectionConfig conf = new ContentSectionConfig();
conf.load();
// Step 2: Create a section using default values
ContentSection section = ContentSection.create(sectionName);
// Step 3: Adopt the created section to site specific requirements
// ContentSectionSetup is a convenient class to adopt a
// section created by ContentSection.create()
ContentSectionSetup setup = new ContentSectionSetup(section);
// 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)
ContentSectionSetup.setupContentSectionAppInstance(sectionName,
conf.getDefaultRoles(),
conf.getDefaultWorkflows(),
s_conf.isPubliclyViewable(),
s_conf.getItemResolverClass(),
s_conf.getTemplateResolverClass(),
m_content_type_list,
s_conf.getUseSectionCategories(),
s_conf.getCategoryFileList());
}
}
@ -381,13 +328,13 @@ public class Loader extends PackageLoader {
* Parses XML file definition of (internal) base content types and loads
* them into database. It fulfills a task similiar to the Loader of external
* content type packages.
*
*
* The XML config looks like the example below, the "parentType" and "name"
* attributes are optional, and only required for creating
* User Defined ContentTypes. Label corresponds to ContentType's label and
* can be multiple words, and "name" to DynamicObject's name property,
* and must be a single word. The objectType attribute is ignored for
* UDCTs, as it gets dynamically generated.
* attributes are optional, and only required for creating User Defined
* ContentTypes. Label corresponds to ContentType's label and can be
* multiple words, and "name" to DynamicObject's name property, and must be
* a single word. The objectType attribute is ignored for UDCTs, as it gets
* dynamically generated.
*
* <b>UDCT Copyright</b>
* <pre>
@ -404,7 +351,7 @@ public class Loader extends PackageLoader {
* &lt;/ccm:authoring-kit&gt;
* &lt;/ccm:content-type&gt;
* &lt;/ccm:content-types&gt;
*</pre>
* </pre>
*
* @see XMLContentTypeHandler
*/

View File

@ -15,8 +15,6 @@
* with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.arsdigita.cms;
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.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import org.apache.log4j.Logger;
// IMPLEMENTATION NOTE
@ -36,45 +31,47 @@ import org.apache.log4j.Logger;
// initialization process and not yet completed. Functionality is
// basically OK so far, but code urgently needs cleaning up and a
// check for useful bits.
/**
* Container for various configuration parameters for ccm-cms package loader.
*
*
* The parameters are basically immutable for users and administrators and only
* accessible to developers and require recompilation. Specifying any of these
* parameters during installation takes no effect at all! Parameters which have
* to be modifiable must be included in Loader class itself!
*
* @author pb
* @version $Id: LoaderConfig.java $
* @author Sören Bernstein (quasi@barkhof.uni-bremen.de)
* @version $Id: LoaderConfig.java $
*/
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 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;
/**
* 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() {
if (s_conf == null) {
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
* Load time!
* s_conf.load();
*/
/*
* Parameters are not stored in registry nor modified by
* installation specification. It is not possible to process a
* config object at Load time! s_conf.load();
*/
}
return s_conf;
}
// /**
// * The name of the workspace package instance, i.e. URL of the workspace,
// * 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",
// Parameter.REQUIRED,
// "content-center");
// /**
// * XML Mapping of the content center tabs to URLs, see
// * {@link ContentCenterDispatcher}
@ -105,7 +101,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.content_center_map",
// Parameter.REQUIRED,
// "/WEB-INF/resources/content-center-map.xml");
// Update master object if upgrading from old versioning
// XXX: shouldn't we just gut this section (and
// VersioningUpgrader)? It is an upgrade fix from 5.1 or
@ -118,7 +113,6 @@ public final class LoaderConfig extends AbstractConfig {
// if (updateMaster) {
// VersioningUpgrader.updateMasterObject();
// }
// XXX: ItemDispatcher is no longer used. Is the following
// still a valid enterprise.init parameter? Do we need to
// set ContentSectionServlet.s_cacheItems instead of the
@ -128,39 +122,33 @@ public final class LoaderConfig extends AbstractConfig {
// ((Boolean)m_conf.getParameter(CACHE_ITEMS)).booleanValue();
// s_log.debug("Set cache items to " + 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).
*
*
* 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
* into permanent storage (equivalent to the Loader of each external
* content type package).
*
* requires an entry in this list in order to get CMS Loader to load it into
* permanent storage (equivalent to the Loader of each external content type
* package).
*
* Each definition file name has to be fully qualified relative to
* application (context) root.
* Example:
* contentTypeDefinitions = { "/WEB-INF/content-types/Template.xml" };
*
* application (context) root. Example: contentTypeDefinitions = {
* "/WEB-INF/content-types/Template.xml" };
*
* This parameter should be altered only by developers!
*/
private final Parameter m_ctDefFiles =
new StringArrayParameter(
"com.arsdigita.cms.loader.internal_cts",
Parameter.REQUIRED,
// Generic*.xml added by Quasi in enterprise.init for
// new generic Basetypes in addition to article
new String[] {"/WEB-INF/content-types/GenericAddress.xml",
"/WEB-INF/content-types/GenericArticle.xml",
"/WEB-INF/content-types/GenericContact.xml",
"/WEB-INF/content-types/GenericOrganizationalUnit.xml",
"/WEB-INF/content-types/GenericPerson.xml",
"/WEB-INF/content-types/Template.xml"}
);
"com.arsdigita.cms.loader.internal_cts",
Parameter.REQUIRED,
// Generic*.xml added by Quasi in enterprise.init for
// new generic Basetypes in addition to article
new String[]{"/WEB-INF/content-types/GenericAddress.xml",
"/WEB-INF/content-types/GenericArticle.xml",
"/WEB-INF/content-types/GenericContact.xml",
"/WEB-INF/content-types/GenericOrganizationalUnit.xml",
"/WEB-INF/content-types/GenericPerson.xml",
"/WEB-INF/content-types/Template.xml"});
// ///////////////////////////////////////////////////////////////////////
//
// 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.
//
// ///////////////////////////////////////////////////////////////////////
// Section Name, configured by Loader parameter
// Root Folder, set autonomously by ContentSection.create() method
// Template Folder, set autonomously by ContentSection.create() method
/**
* Staff Group
* Contains roles and associated privileges. 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.
*
* Staff Group Contains roles and associated privileges. 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.
*
* Not implemented yet! We need a new parameter type "list" which must have
* multidimensional capabilities.
*/
/*
private final Parameter
m_staffGroup = new StringParameter(
"com.arsdigita.cms.loader.section_staff_group",
Parameter.REQUIRED,
null);
* private final Parameter m_staffGroup = new StringParameter(
* "com.arsdigita.cms.loader.section_staff_group", Parameter.REQUIRED,
* null);
*/
private List m_staffGroup;
private List m_defaultRoles;
// Viewer group, set autonomously by ContentSection.create() method. We can
// here specify, whether the first ( probalby only) content section should
// 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.
*/
private final BooleanParameter
m_isPublic = new BooleanParameter(
"com.arsdigita.cms.loader.section_is_public",
Parameter.REQUIRED,
true);
private final BooleanParameter m_isPublic = new BooleanParameter(
"com.arsdigita.cms.loader.section_is_public",
Parameter.REQUIRED,
true);
// Page Resolver Class, set autonomously by ContentSection.create() method.
// Item Resolver Class, configurable.
/**
* Name of the item resolver class to use for the section (defaults to
@ -220,192 +196,174 @@ public final class LoaderConfig extends AbstractConfig {
* Default value (site-wide) is handled via the parameter
* <pre>com.arsdigita.cms.default_item_resolver_class</pre>.
* Section-specific override can be added here. Only do so if you are
* changing from the default for a specific content section. The class
* must implement <pre>com.arsdigita.cms.dispatcher.ItemResolver</pre>.
* changing from the default for a specific content section. The class must
* implement
* <pre>com.arsdigita.cms.dispatcher.ItemResolver</pre>.
*
* Parameter name ITEM_RESOLVER_CLASS in the old initializer system.
* Description: The ItemResolver class to use for the section
* (defaults to MultilingualItemResolver)
* Description: The ItemResolver class to use for the section (defaults to
* MultilingualItemResolver)
*/
private final Parameter
m_itemResolverClass = new StringParameter(
"com.arsdigita.cms.loader.item_resolver_class",
Parameter.OPTIONAL, null );
// , "com.arsdigita.cms.dispatcher.MultilingualItemResolver"
private final Parameter m_itemResolverClass = new StringParameter(
"com.arsdigita.cms.loader.item_resolver_class",
Parameter.OPTIONAL, null);
// , "com.arsdigita.cms.dispatcher.MultilingualItemResolver"
// Template Resolver Class, configurable.
/**
* Name of the template resolver class to use for the section
* (defaults to <pre>com.arsdigita.cms.dispatcher.DefaultTemplateResolver</pre>)
* Name of the template resolver class to use for the section (defaults to
* <pre>com.arsdigita.cms.dispatcher.DefaultTemplateResolver</pre>)
*
* Default value (site-wide) is handled via the parameter
* <pre>com.arsdigita.cms.default_template_resolver_class</pre>.
* Section-specific override can be added here. Only do so if you are
* changing from the default for a specific content section. The class
* must implement <pre>com.arsdigita.cms.dispatcher.TemplateResolver</pre>.
* changing from the default for a specific content section. The class must
* implement
* <pre>com.arsdigita.cms.dispatcher.TemplateResolver</pre>.
*
* Parameter name TEMPLATE_RESOLVER_CLASS in the old initializer system.
*/
private final Parameter
m_templateResolverClass = new StringParameter(
"com.arsdigita.cms.loader.template_resolver_class",
Parameter.OPTIONAL,
null );
// "com.arsdigita.cms.dispatcher.DefaultTemplateResolver" );
private final Parameter m_templateResolverClass = new StringParameter(
"com.arsdigita.cms.loader.template_resolver_class",
Parameter.OPTIONAL,
null);
// "com.arsdigita.cms.dispatcher.DefaultTemplateResolver" );
// XML Generator Class, set autonomously by ContentSection.create() method.
/**
* Determins weather to use section specific category tree(s). Defaults to
* false, so standard navigation is used.
* If set to true loader loads the categories from file(s) specified in the
* next parameter ( m_categoryFileList )
* false, so standard navigation is used. If set to true loader loads the
* categories from file(s) specified in the next parameter (
* m_categoryFileList )
*/
private final Parameter
m_useSectionCategories = new BooleanParameter
("com.arsdigita.cms.loader.use_section_categories",
Parameter.REQUIRED, new Boolean(false));
private final Parameter m_useSectionCategories = new BooleanParameter("com.arsdigita.cms.loader.use_section_categories",
Parameter.REQUIRED, new Boolean(false));
/**
* XML file containing the category tree to load for this content section.
* Usually not loaded {@see m_useSectionCategories). The files listed as
* default values are demo material and must be replaced in a production
* environment.
* Usually not loaded {
*
* @see m_useSectionCategories). The files listed as default values are demo
* material and must be replaced in a production environment.
*/
private final Parameter
m_categoryFileList = new StringArrayParameter(
"com.arsdigita.cms.loader.section_categories_toload",
Parameter.REQUIRED,
new String[] {"/WEB-INF/resources/article-categories.xml",
"/WEB-INF/resources/navigation-categories.xml"} );
private final Parameter m_categoryFileList = new StringArrayParameter(
"com.arsdigita.cms.loader.section_categories_toload",
Parameter.REQUIRED,
new String[]{"/WEB-INF/resources/article-categories.xml",
"/WEB-INF/resources/navigation-categories.xml"});
// private final Parameter
// m_widgetTypes = new StringArrayParameter(
// "com.arsdigita.cms.loader.widget_types",
// Parameter.REQUIRED,
// new String[] {"/WEB-INF/resources/article-categories.xml",
// "/WEB-INF/resources/navigation-categories.xml"} );
/** List of widgets used in applications forms. Each widget is described by
application indicator, widget name (singular & plural), model class name
and model ui class name. These are really not user or administrator
configurabel and therefore not implemented as ccm parameter. */
/**
* List of widgets used in applications forms. Each widget is described by
* application indicator, widget name (singular & plural), model class name
* and model ui class name. These are really not user or administrator
* configurabel and therefore not implemented as ccm parameter.
*/
private static List widgetTypes = Arrays.asList(
Arrays.asList("forms-cms", "Checkbox group", "Checkbox groups",
"com.arsdigita.formbuilder.PersistentCheckboxGroup",
"com.arsdigita.formbuilder.ui.editors.CheckboxGroupEditor"),
Arrays.asList("forms-cms", "Date field", "Date fields",
"com.arsdigita.formbuilder.PersistentDate",
"com.arsdigita.formbuilder.ui.editors.DateForm"),
Arrays.asList("forms-cms", "Hidden field", "Hidden fields",
"com.arsdigita.formbuilder.PersistentHidden",
"com.arsdigita.formbuilder.ui.editors.HiddenForm"),
Arrays.asList( "forms-cms", "Hidden ID Generator field",
"Hidden ID Generator fields",
"com.arsdigita.formbuilder.HiddenIDGenerator",
"com.arsdigita.formbuilder.ui.editors.HiddenIDGeneratorForm"),
Arrays.asList("forms-cms", "Multiple select box",
"Multiple select boxes",
"com.arsdigita.formbuilder.PersistentMultipleSelect",
"com.arsdigita.formbuilder.ui.editors.MultipleSelectEditor"),
Arrays.asList("forms-cms", "Password field", "Password fields",
"com.arsdigita.formbuilder.PersistentPassword",
"com.arsdigita.formbuilder.ui.editors.PasswordForm"),
Arrays.asList("forms-cms", "Radio group", "Radio groups",
"com.arsdigita.formbuilder.PersistentRadioGroup",
"com.arsdigita.formbuilder.ui.editors.RadioGroupEditor"),
Arrays.asList("forms-cms", "Single select box",
"Single select boxes",
"com.arsdigita.formbuilder.PersistentSingleSelect",
"com.arsdigita.formbuilder.ui.editors.SingleSelectEditor"),
Arrays.asList("forms-cms", "Submit button", "Submit buttons",
"com.arsdigita.formbuilder.PersistentSubmit",
"com.arsdigita.formbuilder.ui.editors.SubmitForm"),
Arrays.asList("forms-cms", "Text area", "Text areas",
"com.arsdigita.formbuilder.PersistentTextArea",
"com.arsdigita.formbuilder.ui.editors.TextAreaForm"),
Arrays.asList("forms-cms", "Text field", "Text fields",
"com.arsdigita.formbuilder.PersistentTextField",
"com.arsdigita.formbuilder.ui.editors.TextFieldForm"),
Arrays.asList("forms-cms", "Data Driven Select Box",
"Data Driven Select Boxes",
"com.arsdigita.formbuilder.DataDrivenSelect",
"com.arsdigita.formbuilder.ui.editors.DataDrivenSelectForm"),
Arrays.asList("forms-cms", "Text Description","Text Descriptions",
"com.arsdigita.formbuilder.PersistentText",
"com.arsdigita.formbuilder.ui.editors.TextForm"),
Arrays.asList("forms-cms", "Text Heading", "Text Headings",
"com.arsdigita.formbuilder.PersistentHeading",
"com.arsdigita.formbuilder.ui.editors.HeadingForm"),
Arrays.asList("forms-cms", "Section Break", "Section Break",
"com.arsdigita.formbuilder.PersistentHorizontalRule",
"com.arsdigita.formbuilder.ui.editors.HorizontalRuleForm"),
Arrays.asList("forms-cms", "User Email Field","User Email Fields",
"com.arsdigita.formbuilder.PersistentEmailField",
"com.arsdigita.formbuilder.ui.editors.EmailFieldForm")
);
/** List of process listeners used in applications forms. Each listener is
described by application indicator, process name (singular & plural),
action class name and action ui class name. These are really not user
or administrator configurabel and therefore not implemented as ccm
parameter. */
private static List processListenerTypes = Arrays.asList(
Arrays.asList("forms-cms", "Confirmation email",
"Confirmation emails",
"com.arsdigita.formbuilder.actions.ConfirmEmailListener",
"com.arsdigita.formbuilder.ui.editors.ConfirmEmailForm"),
Arrays.asList("forms-cms", "URL redirect", "URL redirects",
"com.arsdigita.formbuilder.actions.ConfirmRedirectListener",
"com.arsdigita.formbuilder.ui.editors.ConfirmRedirectForm"),
Arrays.asList("forms-cms", "Simple email", "Simple emails",
"com.arsdigita.formbuilder.actions.SimpleEmailListener",
"com.arsdigita.formbuilder.ui.editors.SimpleEmailForm"),
Arrays.asList("forms-cms", "Templated email", "Templated emails",
"com.arsdigita.formbuilder.actions.TemplateEmailListener",
"com.arsdigita.formbuilder.ui.editors.TemplateEmailForm"),
Arrays.asList( "forms-cms", "Remote Server POST",
"Remote Server POSTs",
"com.arsdigita.formbuilder.actions.RemoteServerPostListener",
"com.arsdigita.formbuilder.ui.editors.RemoteServerPostForm" ),
Arrays.asList( "forms-cms", "XML email", "XML emails",
"com.arsdigita.formbuilder.actions.XMLEmailListener",
"com.arsdigita.formbuilder.ui.editors.XMLEmailForm" )
);
private static List dataQueries = Arrays.asList(
Arrays.asList("forms-cms",
"com.arsdigita.formbuilder.DataQueryUsers",
"List of all registered users"),
Arrays.asList("forms-cms",
"com.arsdigita.formbuilder.DataQueryPackages",
"List of all installed packages")
);
Arrays.asList("forms-cms", "Checkbox group", "Checkbox groups",
"com.arsdigita.formbuilder.PersistentCheckboxGroup",
"com.arsdigita.formbuilder.ui.editors.CheckboxGroupEditor"),
Arrays.asList("forms-cms", "Date field", "Date fields",
"com.arsdigita.formbuilder.PersistentDate",
"com.arsdigita.formbuilder.ui.editors.DateForm"),
Arrays.asList("forms-cms", "Hidden field", "Hidden fields",
"com.arsdigita.formbuilder.PersistentHidden",
"com.arsdigita.formbuilder.ui.editors.HiddenForm"),
Arrays.asList("forms-cms", "Hidden ID Generator field",
"Hidden ID Generator fields",
"com.arsdigita.formbuilder.HiddenIDGenerator",
"com.arsdigita.formbuilder.ui.editors.HiddenIDGeneratorForm"),
Arrays.asList("forms-cms", "Multiple select box",
"Multiple select boxes",
"com.arsdigita.formbuilder.PersistentMultipleSelect",
"com.arsdigita.formbuilder.ui.editors.MultipleSelectEditor"),
Arrays.asList("forms-cms", "Password field", "Password fields",
"com.arsdigita.formbuilder.PersistentPassword",
"com.arsdigita.formbuilder.ui.editors.PasswordForm"),
Arrays.asList("forms-cms", "Radio group", "Radio groups",
"com.arsdigita.formbuilder.PersistentRadioGroup",
"com.arsdigita.formbuilder.ui.editors.RadioGroupEditor"),
Arrays.asList("forms-cms", "Single select box",
"Single select boxes",
"com.arsdigita.formbuilder.PersistentSingleSelect",
"com.arsdigita.formbuilder.ui.editors.SingleSelectEditor"),
Arrays.asList("forms-cms", "Submit button", "Submit buttons",
"com.arsdigita.formbuilder.PersistentSubmit",
"com.arsdigita.formbuilder.ui.editors.SubmitForm"),
Arrays.asList("forms-cms", "Text area", "Text areas",
"com.arsdigita.formbuilder.PersistentTextArea",
"com.arsdigita.formbuilder.ui.editors.TextAreaForm"),
Arrays.asList("forms-cms", "Text field", "Text fields",
"com.arsdigita.formbuilder.PersistentTextField",
"com.arsdigita.formbuilder.ui.editors.TextFieldForm"),
Arrays.asList("forms-cms", "Data Driven Select Box",
"Data Driven Select Boxes",
"com.arsdigita.formbuilder.DataDrivenSelect",
"com.arsdigita.formbuilder.ui.editors.DataDrivenSelectForm"),
Arrays.asList("forms-cms", "Text Description", "Text Descriptions",
"com.arsdigita.formbuilder.PersistentText",
"com.arsdigita.formbuilder.ui.editors.TextForm"),
Arrays.asList("forms-cms", "Text Heading", "Text Headings",
"com.arsdigita.formbuilder.PersistentHeading",
"com.arsdigita.formbuilder.ui.editors.HeadingForm"),
Arrays.asList("forms-cms", "Section Break", "Section Break",
"com.arsdigita.formbuilder.PersistentHorizontalRule",
"com.arsdigita.formbuilder.ui.editors.HorizontalRuleForm"),
Arrays.asList("forms-cms", "User Email Field", "User Email Fields",
"com.arsdigita.formbuilder.PersistentEmailField",
"com.arsdigita.formbuilder.ui.editors.EmailFieldForm"));
/**
* List of process listeners used in applications forms. Each listener is
* described by application indicator, process name (singular & plural),
* action class name and action ui class name. These are really not user or
* administrator configurabel and therefore not implemented as ccm
* parameter.
*/
private static List processListenerTypes = Arrays.asList(
Arrays.asList("forms-cms", "Confirmation email",
"Confirmation emails",
"com.arsdigita.formbuilder.actions.ConfirmEmailListener",
"com.arsdigita.formbuilder.ui.editors.ConfirmEmailForm"),
Arrays.asList("forms-cms", "URL redirect", "URL redirects",
"com.arsdigita.formbuilder.actions.ConfirmRedirectListener",
"com.arsdigita.formbuilder.ui.editors.ConfirmRedirectForm"),
Arrays.asList("forms-cms", "Simple email", "Simple emails",
"com.arsdigita.formbuilder.actions.SimpleEmailListener",
"com.arsdigita.formbuilder.ui.editors.SimpleEmailForm"),
Arrays.asList("forms-cms", "Templated email", "Templated emails",
"com.arsdigita.formbuilder.actions.TemplateEmailListener",
"com.arsdigita.formbuilder.ui.editors.TemplateEmailForm"),
Arrays.asList("forms-cms", "Remote Server POST",
"Remote Server POSTs",
"com.arsdigita.formbuilder.actions.RemoteServerPostListener",
"com.arsdigita.formbuilder.ui.editors.RemoteServerPostForm"),
Arrays.asList("forms-cms", "XML email", "XML emails",
"com.arsdigita.formbuilder.actions.XMLEmailListener",
"com.arsdigita.formbuilder.ui.editors.XMLEmailForm"));
private static List dataQueries = Arrays.asList(
Arrays.asList("forms-cms",
"com.arsdigita.formbuilder.DataQueryUsers",
"List of all registered users"),
Arrays.asList("forms-cms",
"com.arsdigita.formbuilder.DataQueryPackages",
"List of all installed packages"));
// Currently not a Loader task. There is no way to persist tasks preferences
// on a per section base.
/**
* When to generate email alerts: by default, generate email alerts
* on enable, finish, and rollback (happens on rejection) changes.
* There are four action types for each task type: enable,
* disable, finish, and rollback. Note that the values below are
* based on the task labels, and as such are not globalized.
/**
* When to generate email alerts: by default, generate email alerts on
* enable, finish, and rollback (happens on rejection) changes. There are
* four action types for each task type: enable, disable, finish, and
* rollback. Note that the values below are based on the task labels, and as
* such are not globalized.
*/
/*
private final Parameter
m_taskAlerts = new StringArrayParameter(
"com.arsdigita.cms.task_alerts",
Parameter.REQUIRED, new String[] {
"Authoring:enable:finish:rollback",
"Approval:enable:finish:rollback",
"Deploy:enable:finish:rollback" } );
* private final Parameter m_taskAlerts = new StringArrayParameter(
* "com.arsdigita.cms.task_alerts", Parameter.REQUIRED, new String[] {
* "Authoring:enable:finish:rollback", "Approval:enable:finish:rollback",
* "Deploy:enable:finish:rollback" } );
*/
// ///////////////////////////////////////////////////////////////////////
//
// 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
// currently not a loader task and commented out here.
// ///////////////////////////////////////////////////////////////////////
// /**
// * 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",
// Parameter.REQUIRED,
// new Boolean(false) );
// /**
// * taskDuration: The time between when a task is enabled (it is made
// * available for completion) and when it is
@ -435,7 +390,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.task_duration",
// Parameter.REQUIRED,
// new Integer(96) );
// /**
// * alertInterval: The time to wait between sending successive alerts on
// * the same overdue task (in HOURS)
@ -445,7 +399,6 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.overdue_alert_interval",
// Parameter.REQUIRED,
// new Integer(24) );
// /**
// * maxAlerts: The maximum number of alerts to send about any one
// * overdue task
@ -455,35 +408,34 @@ public final class LoaderConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.mas_alerts",
// Parameter.REQUIRED,
// new Integer(5) );
/**
* Standard Constructor.
* Standard Constructor.
*/
public LoaderConfig() {
// register(m_workspaceURL);
// register(m_contentCenterMap);
register(m_ctDefFiles);
register(m_ctDefFiles);
// Parameters for creating a content section
register(m_isPublic);
register(m_itemResolverClass);
register(m_templateResolverClass);
// Parameters for creating a content section
register(m_isPublic);
register(m_itemResolverClass);
register(m_templateResolverClass);
register(m_useSectionCategories);
register(m_categoryFileList);
register(m_useSectionCategories);
register(m_categoryFileList);
// (Currently not a loader task)
// (Currently not a loader task)
// register(m_taskAlerts);
// Parameters controlling Overdue Task alerts:
// (Currently not a loader task)
// Parameters controlling Overdue Task alerts:
// (Currently not a loader task)
// register(m_sendOverdueAlerts);
// register(m_taskDuration);
// register(m_overdueAlertInterval);
// register(m_maxAlerts);
// Does not work at load time!
// loadInfo();
// Does not work at load time!
// loadInfo();
}
@ -492,7 +444,6 @@ public final class LoaderConfig extends AbstractConfig {
// Getter Methods
//
// //////////////////////////
// Not used as long as we use old style application (seee above)
// /**
// * 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() {
// return (String) get(m_workspaceURL);
// }
// 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
@ -511,101 +461,11 @@ public final class LoaderConfig extends AbstractConfig {
// public String getContentCenterMap() {
// return (String) get(m_contentCenterMap);
// }
public List getCTDefFiles() {
String[] ctDefFiles = (String[]) get(m_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
* registration and login)
@ -628,10 +488,11 @@ public final class LoaderConfig extends AbstractConfig {
return (String) get(m_templateResolverClass);
}
/**
* 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.
* @return
@ -641,9 +502,9 @@ public final class LoaderConfig extends AbstractConfig {
}
/**
* Retrieve the list of files containing categories to load.
* In old Initialiser: Parameter name: CATEGORIES
* Deskr. "XML file containing the category tree"
* Retrieve the list of files containing categories to load. In old
* Initialiser: Parameter name: CATEGORIES Deskr. "XML file containing the
* category tree"
*/
public List getCategoryFileList() {
String[] catFiles = (String[]) get(m_categoryFileList);
@ -652,14 +513,13 @@ public final class LoaderConfig extends AbstractConfig {
public List getWidgetTypes() {
return widgetTypes;
}
}
public List getProcessListenerTypes() {
return processListenerTypes;
}
}
public List getDataQueries() {
return dataQueries;
}
}
}

View File

@ -23,14 +23,12 @@ import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter;
//import com.arsdigita.util.parameter.ParameterError;
import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
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
* changes during each startup of the system.
* @author pb
* @author Sören Bernstein (quasi@barkhof.uni-bremen.de)
*/
public final class ContentSectionConfig extends AbstractConfig {
private List m_defaultRoles;
private List m_defaultWorkflows;
/** Private Logger instance for debugging purpose. */
private static final Logger s_log =
Logger.getLogger(ContentSectionConfig.class);
@ -216,7 +218,6 @@ public final class ContentSectionConfig extends AbstractConfig {
// "com.arsdigita.cms.loader.section_staff_group",
// Parameter.REQUIRED,
// null);
private List m_staffGroup;
// Viewer group, set autonomously by ContentSection.create() method. We can
@ -312,7 +313,7 @@ public final class ContentSectionConfig extends AbstractConfig {
private final Parameter
m_useSectionCategories = new BooleanParameter
("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.
@ -460,7 +461,12 @@ public final class ContentSectionConfig extends AbstractConfig {
* was burried in enterprise.init and not user available for configuration.
* 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(
"new_item","read_item", "preview_item", "edit_item",
@ -478,43 +484,169 @@ public final class ContentSectionConfig extends AbstractConfig {
"publish",
"staff_admin", "content_type_admin", "lifecycle_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");
add("Creates new content");
add(AUTH_PRIVS);
add("Authoring");
}}
);
m_staffGroup.add
m_defaultRoles.add
( new ArrayList() {{ add("Editor");
add("Reviews and approves the author's work");
add(EDIT_PRIVS);
add("Approval");
}}
);
m_staffGroup.add
m_defaultRoles.add
( new ArrayList() {{ add("Publisher");
add("Deploys the content to the web site");
add(PUBL_PRIVS);
add("Publishing");
}}
);
m_staffGroup.add
m_defaultRoles.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)
}}
);
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
* registration and login)

View File

@ -43,7 +43,6 @@ import com.arsdigita.util.Assert;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.workflow.simple.WorkflowTemplate;
import com.arsdigita.xml.XML;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@ -54,7 +53,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
@ -65,20 +63,21 @@ import org.xml.sax.helpers.DefaultHandler;
* into the database.
*
* @author Peter Boy (pboy@barkhof.uni-bremen.de)
* @author Sören Bernstein (quasi@barkhof.uni-bremen.de)
* @author Jon Orris (jorris@redhat.com)
* @version $Id: $
* @version $Id: $
*/
public final class ContentSectionSetup {
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 WorkflowTemplate m_wf;
final ContentSection m_section;
/**
* Constructor. Using this constructor the content section has to be
* already created using ContentSection.create(name)
* Constructor. Using this constructor the content section has to be already
* created using ContentSection.create(name)
*
* @param section name of a content section previously created by
* ContentSection.create
@ -89,21 +88,22 @@ public final class ContentSectionSetup {
}
/**
* Wrapper class to create and configure a content section instance
* in one step.
* Wrapper class to create and configure a content section instance in one
* step.
*
* 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(
String name,
List staffGroup,
Boolean isPubliclyViewable,
String itemResolverClassName,
String templateResolverClassName,
List sectionContentTypes,
Boolean useSectionCategories,
List categoryFileList) {
public static ContentSection setupContentSectionAppInstance(String name,
List defaultRoles,
List defaultWorkflows,
Boolean isPubliclyViewable,
String itemResolverClassName,
String templateResolverClassName,
List sectionContentTypes,
Boolean useSectionCategories,
List categoryFileList) {
s_log.info("Creating content section on /" + name);
@ -111,10 +111,10 @@ public final class ContentSectionSetup {
ContentSectionSetup setup = new ContentSectionSetup(section);
// Setup the access controls
setup.registerRoles(staffGroup);
setup.registerRoles(defaultRoles);
setup.registerWorkflows(defaultWorkflows);
setup.registerViewers(isPubliclyViewable);
setup.registerPublicationCycles();
setup.registerWorkflowTemplates();
setup.registerResolvers(itemResolverClassName, templateResolverClassName);
// setup.registerContentTypes((List)m_conf.getParameter(TYPES));
@ -131,17 +131,17 @@ public final class ContentSectionSetup {
section.save();
// return section;
return section;
}
/**
* Steps through a list of roles which are part of a staff group and
* Steps through a list of roles which are part of a staff group and
* delegates processing of each role.
*
*
* @param roles
*/
public void registerRoles(List roles) {
public void registerRoles(List<List> roles) {
Iterator i = roles.iterator();
while (i.hasNext()) {
@ -150,21 +150,13 @@ public final class ContentSectionSetup {
String name = (String) role.get(0);
String desc = (String) role.get(1);
List privileges = (List) role.get(2);
String task = (role.size() > 3 ? (String) role.get(3) : null);
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);
}
}
}
/**
@ -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;
}
@ -259,9 +260,9 @@ public final class ContentSectionSetup {
/**
* Checks for specific item resolver and template resolver classes probably
* specified in parameters, otherwise uses system wide default parameters
* specified in CMS global configuration file. Delegates persistence task
* to ContentSection.
*
* specified in CMS global configuration file. Delegates persistence task to
* ContentSection.
*
* @param itemResolverClassName
* @param templateResolverClassName
*/
@ -269,24 +270,22 @@ public final class ContentSectionSetup {
String templateResolverClassName) {
if (itemResolverClassName != null
&& itemResolverClassName.length() > 0) {
&& itemResolverClassName.length() > 0) {
m_section.setItemResolverClass(itemResolverClassName);
s_log.info("Registering " + itemResolverClassName
+ " as the item resolver class");
} else {
m_section.setItemResolverClass(ContentSection.getConfig()
.getDefaultItemResolverClass().getName());
m_section.setItemResolverClass(ContentSection.getConfig().getDefaultItemResolverClass().getName());
s_log.info("Registering " + itemResolverClassName
+ " as the item resolver class");
}
if (templateResolverClassName != null
&& templateResolverClassName.length() > 0) {
&& templateResolverClassName.length() > 0) {
m_section.setTemplateResolverClass(templateResolverClassName);
s_log.info("Registering " + templateResolverClassName
+ " as the template resolver class");
} else {
m_section.setTemplateResolverClass(ContentSection.getConfig()
.getDefaultTemplateResolverClass().getName());
m_section.setTemplateResolverClass(ContentSection.getConfig().getDefaultTemplateResolverClass().getName());
s_log.info("Registering " + templateResolverClassName
+ " as the template resolver class");
}
@ -295,9 +294,9 @@ public final class ContentSectionSetup {
}
/**
* Create a (default) publication cycle and store it in the datavbase
* Create a (default) publication cycle and store it in the datavbase
* (delegated to package com.arsdigita.cms.lifecycle)
*
*
* @throws InitializationException
*/
public void registerPublicationCycles()
@ -323,86 +322,110 @@ public final class ContentSectionSetup {
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
* database.
*
* This one is probably deprecated.
*
* @throws InitializationException
*/
public void registerWorkflowTemplates()
throws ConfigError {
public void registerWorkflowTemplates() throws ConfigError {
// The 3-step production workflow.
WorkflowTemplate wf = new WorkflowTemplate();
wf.setLabel((String) GlobalizationUtil.globalize(
"cms.installer.production_workflow").localize());
wf.setDescription("A process that involves creating and approving content.");
wf.save();
ContentSectionConfig config = new ContentSectionConfig();
config.load();
registerWorkflows(config.getDefaultWorkflows());
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
* 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) {
@ -424,8 +447,9 @@ 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
* @return
*/
@ -456,9 +480,9 @@ public final class ContentSectionSetup {
}
/**
*
*
* @param type
* @param filename
* @param filename
*/
void registerTemplate(ContentType type, String filename) {
// Use the base of the file name (ie without path & extension)
@ -487,7 +511,7 @@ public final class ContentSectionSetup {
if (stream == null) {
throw new IllegalStateException((String) GlobalizationUtil.globalize(
"cms.installer.cannot_find_file").localize() + filename);
"cms.installer.cannot_find_file").localize() + filename);
}
final BufferedReader input = new BufferedReader(new InputStreamReader(stream));
@ -514,8 +538,7 @@ public final class ContentSectionSetup {
temp.save();
TemplateManagerFactory.getInstance()
.addTemplate(m_section, type, temp, "public");
TemplateManagerFactory.getInstance().addTemplate(m_section, type, temp, "public");
temp.publish(m_lcd, new Date());
}
@ -545,6 +568,8 @@ public final class ContentSectionSetup {
alert.setDescription(
"Receive alerts regarding expiration of pubished content");
alert.save();
}
// // Currently there is no way to persists alert preferemces, therefore
@ -602,8 +627,8 @@ public final class ContentSectionSetup {
// }
// ///////////////////// Private Class Section ////////////////////////////
/**
* SAX Handler for category lists. Creates the categories as they are
* defined, with structure, in the xml document.
* SAX Handler for category lists. Creates the categories as they are
* defined, with structure, in the xml document.
*/
private class CategoryHandler extends DefaultHandler {
@ -679,6 +704,4 @@ public final class ContentSectionSetup {
}
}
} // END private class CategoryHandler
}

View File

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

View File

@ -19,215 +19,206 @@
package com.arsdigita.cms.workflow;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentSection;
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.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.messaging.Message;
import com.arsdigita.notification.Notification;
import com.arsdigita.persistence.DataAssociation;
import com.arsdigita.persistence.DataAssociationCursor;
import com.arsdigita.persistence.DataCollection;
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.Session;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.metadata.ObjectType;
import com.arsdigita.util.Assert;
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.HashSet;
import java.util.Iterator;
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
* the behaviour of tasks of that type
* This class represents a task type in the CMS system. The task type has
* attributes that impact on the behaviour of tasks of that type
*
*
* @author chris.gilbert at westsussex.gov.uk
* @version $Id: $
* @version $Id: $
*/
public class CMSTaskType extends DomainObject {
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.cms.workflow.CMSTaskType";
private static Map s_taskURLGeneratorCache = new HashMap();
public static final String BASE_DATA_OBJECT_TYPE =
"com.arsdigita.cms.workflow.CMSTaskType";
private static Map s_taskURLGeneratorCache = new HashMap();
// pdl attribute names
public static final String ID = "taskTypeID";
public static final String NAME = "name";
public static final String DEFAULT_URL_GENERATOR_CLASS =
"defaultUrlGeneratorClass";
public static final String PRIVILEGE = "privilege";
public static final String URL_GENERATORS = "generators";
public static final String ID = "taskTypeID";
public static final String NAME = "name";
public static final String DEFAULT_URL_GENERATOR_CLASS =
"defaultUrlGeneratorClass";
public static final String PRIVILEGE = "privilege";
public static final String URL_GENERATORS = "generators";
private static final Logger s_log = Logger.getLogger(CMSTaskType.class);
// known task types
public static final Integer AUTHOR = new Integer(1);
public static final Integer EDIT = new Integer(2);
public static final Integer DEPLOY = new Integer(3);
// cache task type domain objects to save unnecessary db lookups
public static Map<Integer, CMSTaskType> s_taskTypes = new HashMap<Integer, CMSTaskType>();
private static Map<String, Integer> s_taskNameMap = new HashMap<String, Integer>();
private static final Logger s_log = Logger.getLogger(CMSTaskType.class);
static {
s_taskNameMap.put("Author", AUTHOR);
s_taskNameMap.put("Edit", EDIT);
s_taskNameMap.put("Deploy",DEPLOY);
}
public static CMSTaskType retrieve(Integer id) {
// known task types
public static final Integer AUTHOR = new Integer(1);
public static final Integer EDIT = new Integer(2);
public static final Integer DEPLOY = new Integer(3);
if (id == null) {
throw new IllegalArgumentException("Parameter id must not be null");
}
// cache task type domain objects to save unnecessary db lookups
public static Map s_taskTypes = new HashMap();
CMSTaskType type = s_taskTypes.get(id);
if (type == null) {
type = new CMSTaskType(id);
s_taskTypes.put(id, type);
}
return type;
public static CMSTaskType retrieve (Integer id) {
CMSTaskType type = (CMSTaskType)s_taskTypes.get(id);
if (type == null) {
type = new CMSTaskType(id);
s_taskTypes.put(id, type);
}
return type;
}
private CMSTaskType(Integer id) {
super(new OID(BASE_DATA_OBJECT_TYPE, id));
}
}
public CMSTaskType(DataObject obj) {
super(obj);
}
public static CMSTaskType retrieveByName(String name) {
/**
* create a message object and associate it with the current application instance
*
*/
public CMSTaskType() {
super(BASE_DATA_OBJECT_TYPE);
setID();
}
public Integer getID(){
return ((Integer)get(ID));
}
/**
* allocate a unique integer to the message
*
*/
private void setID() {
DataCollection allTypes =
SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
allTypes.addOrder(ID + " desc");
Integer id = new Integer(1);
if (allTypes.next()) {
CMSTaskType taskType =
(CMSTaskType) DomainObjectFactory.newInstance(
allTypes.getDataObject());
int currentMaxID = taskType.getID().intValue();
id = new Integer(currentMaxID + 1);
allTypes.close();
}
set(ID, id);
}
public String getName() {
return (String)get(NAME);
}
public PrivilegeDescriptor getPrivilege () {
return PrivilegeDescriptor.get((String)get(PRIVILEGE));
}
private TaskURLGenerator getDefaultTaskURLGenerator () throws ClassNotFoundException, IllegalAccessException, InstantiationException {
String generatorClassName = (String)get(DEFAULT_URL_GENERATOR_CLASS);
Class URLGenerator = Class.forName(generatorClassName);
return (TaskURLGenerator)URLGenerator.newInstance();
}
public TaskURLGenerator getURLGenerator(String event, ContentItem item) {
String key = getID() + " " + event + " " + item.getContentType().getID();
s_log.debug("looking up url generator for key " + key);
TaskURLGenerator generator = (TaskURLGenerator)
s_taskURLGeneratorCache.get(key);
if (generator == null) {
s_log.debug("no generator found in cache");
DataAssociationCursor generators = ((DataAssociation)get(URL_GENERATORS)).cursor();
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
generators.addEqualsFilter(TaskEventURLGenerator.CONTENT_TYPE + "." + ContentType.ID, item.getContentType().getID());
try {
while (generators.next()) {
s_log.debug("specific generator found for " + event + " event on task type " + getName() + " for content type " + item.getContentType().getLabel());
// generator class available for this specific event and this specific content type
generator = ((TaskEventURLGenerator)DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
generators.close();
}
if (generator == null) {
generators.reset();
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
generators.addEqualsFilter(TaskEventURLGenerator.CONTENT_TYPE, null);
while (generators.next()) {
s_log.debug("specific generator found for " + event + " event on task type " + getName() + " for any content type");
// generator class available for this specific event
generator = ((TaskEventURLGenerator)DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
generators.close();
}
}
if (generator == null) {
s_log.debug("no specific generator for " + event + " event on task type " + getName()+ ". Revert to default");
// fall back on default
generator = getDefaultTaskURLGenerator();
}
s_taskURLGeneratorCache.put(key, generator);
} catch(Exception e) {
throw new UncheckedWrapperException("Unable to retrieve a URL generator for event " + event + " on task type " + getID() + " ", e);
}
}
return generator;
}
/**
*
* Should be used when UI is implemented for managing task types. If a specific TaskURLGenerator
* is added or removed for an event, then the cached TaskURLGenerator needs to be removed
* @param event
*/
public void clearCachedEntry(String event) {
String key = getID() + " " + event;
s_taskURLGeneratorCache.remove(key);
}
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) {
super(new OID(BASE_DATA_OBJECT_TYPE, id));
}
public CMSTaskType(DataObject obj) {
super(obj);
}
/**
* create a message object and associate it with the current application
* instance
*
*/
public CMSTaskType() {
super(BASE_DATA_OBJECT_TYPE);
setID();
}
public Integer getID() {
return ((Integer) get(ID));
}
/**
* allocate a unique integer to the message
*
*/
private void setID() {
DataCollection allTypes =
SessionManager.getSession().retrieve(BASE_DATA_OBJECT_TYPE);
allTypes.addOrder(ID + " desc");
Integer id = new Integer(1);
if (allTypes.next()) {
CMSTaskType taskType =
(CMSTaskType) DomainObjectFactory.newInstance(
allTypes.getDataObject());
int currentMaxID = taskType.getID().intValue();
id = new Integer(currentMaxID + 1);
allTypes.close();
}
set(ID, id);
}
public String getName() {
return (String) get(NAME);
}
public PrivilegeDescriptor getPrivilege() {
return PrivilegeDescriptor.get((String) get(PRIVILEGE));
}
private TaskURLGenerator getDefaultTaskURLGenerator() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
String generatorClassName = (String) get(DEFAULT_URL_GENERATOR_CLASS);
Class URLGenerator = Class.forName(generatorClassName);
return (TaskURLGenerator) URLGenerator.newInstance();
}
public TaskURLGenerator getURLGenerator(String event, ContentItem item) {
String key = getID() + " " + event + " " + item.getContentType().getID();
s_log.debug("looking up url generator for key " + key);
TaskURLGenerator generator = (TaskURLGenerator) s_taskURLGeneratorCache.get(key);
if (generator == null) {
s_log.debug("no generator found in cache");
DataAssociationCursor generators = ((DataAssociation) get(URL_GENERATORS)).cursor();
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
generators.addEqualsFilter(TaskEventURLGenerator.CONTENT_TYPE + "." + ContentType.ID, item.getContentType().getID());
try {
while (generators.next()) {
s_log.debug("specific generator found for " + event + " event on task type " + getName() + " for content type " + item.getContentType().getLabel());
// generator class available for this specific event and this specific content type
generator = ((TaskEventURLGenerator) DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
generators.close();
}
if (generator == null) {
generators.reset();
generators.addEqualsFilter(TaskEventURLGenerator.EVENT, event);
generators.addEqualsFilter(TaskEventURLGenerator.CONTENT_TYPE, null);
while (generators.next()) {
s_log.debug("specific generator found for " + event + " event on task type " + getName() + " for any content type");
// generator class available for this specific event
generator = ((TaskEventURLGenerator) DomainObjectFactory.newInstance(generators.getDataObject())).getGenerator();
generators.close();
}
}
if (generator == null) {
s_log.debug("no specific generator for " + event + " event on task type " + getName() + ". Revert to default");
// fall back on default
generator = getDefaultTaskURLGenerator();
}
s_taskURLGeneratorCache.put(key, generator);
} catch (Exception e) {
throw new UncheckedWrapperException("Unable to retrieve a URL generator for event " + event + " on task type " + getID() + " ", e);
}
}
return generator;
}
/**
*
* Should be used when UI is implemented for managing task types. If a
* specific TaskURLGenerator is added or removed for an event, then the
* cached TaskURLGenerator needs to be removed
*
* @param event
*/
public void clearCachedEntry(String event) {
String key = getID() + " " + event;
s_taskURLGeneratorCache.remove(key);
}
}