From 1dca0d0ebd78bd96efe93e9acc7e7777ff65e4bb Mon Sep 17 00:00:00 2001 From: pb Date: Tue, 17 Aug 2010 11:01:59 +0000 Subject: [PATCH] Weiterer Schritt im Prozess, Legacy Initializer aus ccm-cms zu entfernen. * Initialisierung von * Portlet * LifeCycle * publishToFile ist komplett in einen eigenen, neuen Initializer verlegt. * Initialisierung content-section ist auf Loader und Initializer neuen Typs verlegt. * Initialisierung von content-center und cms-service ist in Initializer neuen Typs verlegt. * Legacy Init wird nur noch im Rahmen der Initialisierung von Forms durch ccm-core benutzt. Es funktioniert (noch) nicht (wieder): * Background Thread fuer Alerts * Erstellen weiterer Content Section bei einem restart via Parameter. git-svn-id: https://svn.libreccm.org/ccm/trunk@509 8810af33-2d31-482b-a856-94f89814c4df --- .../src/com/arsdigita/cms/Initializer.java | 70 ++- ccm-cms/src/com/arsdigita/cms/Loader.java | 538 ++++++++++++++++-- .../src/com/arsdigita/cms/LoaderConfig.java | 242 ++++---- .../contentsection/ContentSectionConfig.java | 152 +++-- .../cms/contentsection/Initializer.java | 189 +++--- .../cms/contentsection/enterprise.init | 1 + .../cms/installer/ContentCenterSetup.java | 28 +- .../cms/installer/ContentSectionSetup.java | 8 + .../arsdigita/cms/installer/Initializer.java | 15 +- ...a => LegacyInitializer.java.nolongerInUse} | 0 ...ctionLegacyInitializer.java.nolongerInUse} | 44 +- .../cms/installer/WorkspaceInstaller.java | 9 +- ...ise.init => enterprise.init.nolongerInUse} | 0 .../Initializer.java.nolongerInUse} | 8 + ...tTypeLegacyInitializer.java.nolongerInUse} | 0 ...ise.init => enterprise.init.nolongerInUse} | 0 .../cms/search/IntermediaQueryEngine.java | 4 +- .../com/arsdigita/cms/workflow/CMSTask.java | 2 +- .../cms/workflow/UnfinishedTaskNotifier.java | 21 +- 19 files changed, 951 insertions(+), 380 deletions(-) rename ccm-cms/src/com/arsdigita/cms/installer/{LegacyInitializer.java => LegacyInitializer.java.nolongerInUse} (100%) rename ccm-cms/src/com/arsdigita/cms/installer/{SectionLegacyInitializer.java => SectionLegacyInitializer.java.nolongerInUse} (86%) rename ccm-cms/src/com/arsdigita/cms/installer/{enterprise.init => enterprise.init.nolongerInUse} (100%) rename ccm-cms/src/com/arsdigita/cms/installer/{portlet/Initializer.java => portlet.nolongerInUse/Initializer.java.nolongerInUse} (95%) rename ccm-cms/src/com/arsdigita/cms/installer/xml/{ContentTypeLegacyInitializer.java => ContentTypeLegacyInitializer.java.nolongerInUse} (100%) rename ccm-cms/src/com/arsdigita/cms/installer/xml/{enterprise.init => enterprise.init.nolongerInUse} (100%) diff --git a/ccm-cms/src/com/arsdigita/cms/Initializer.java b/ccm-cms/src/com/arsdigita/cms/Initializer.java index d64e94aa1..8b0a88b2c 100755 --- a/ccm-cms/src/com/arsdigita/cms/Initializer.java +++ b/ccm-cms/src/com/arsdigita/cms/Initializer.java @@ -23,6 +23,7 @@ import com.arsdigita.cms.dispatcher.AssetURLFinder; import com.arsdigita.cms.dispatcher.ItemDelegatedURLPatternGenerator; import com.arsdigita.cms.dispatcher.ItemTemplatePatternGenerator; import com.arsdigita.cms.dispatcher.ItemURLFinder; +import com.arsdigita.cms.installer.WorkspaceInstaller; import com.arsdigita.cms.publishToFile.PublishToFileListener; import com.arsdigita.cms.publishToFile.QueueManager; import com.arsdigita.cms.search.AssetMetadataProvider; @@ -48,6 +49,10 @@ import com.arsdigita.domain.DomainObjectInstantiator; import com.arsdigita.domain.xml.TraversalHandler; import com.arsdigita.kernel.ACSObjectInstantiator; import com.arsdigita.kernel.NoValidURLException; +import com.arsdigita.kernel.PackageInstance; +import com.arsdigita.kernel.PackageInstanceCollection; +import com.arsdigita.kernel.PackageType; +import com.arsdigita.kernel.SiteNode; import com.arsdigita.kernel.URLFinder; import com.arsdigita.kernel.URLFinderNotFoundException; import com.arsdigita.kernel.URLService; @@ -57,6 +62,7 @@ import com.arsdigita.persistence.OID; import com.arsdigita.persistence.pdl.ManifestSource; import com.arsdigita.persistence.pdl.NameFilter; import com.arsdigita.runtime.CompoundInitializer; +import com.arsdigita.runtime.ConfigError; import com.arsdigita.runtime.DomainInitEvent; import com.arsdigita.runtime.LegacyInitializer; import com.arsdigita.runtime.PDLInitializer; @@ -80,14 +86,23 @@ import com.arsdigita.templating.PatternStylesheetResolver; import com.arsdigita.cms.util.LanguageUtil; import com.arsdigita.kernel.Kernel; +// For Id. +import java.math.BigDecimal; + +import org.apache.log4j.Logger; + /** - * The CMS initializer. + * The main CMS initializer. * * @author Justin Ross <jross@redhat.com> * @version $Id: Initializer.java 2070 2010-01-28 08:47:41Z pboy $ */ public class Initializer extends CompoundInitializer { + + /** Creates a s_logging category with name = to the full name of class */ + private static Logger s_log = Logger.getLogger(Initializer.class); + /** * Constructor */ @@ -95,32 +110,58 @@ public class Initializer extends CompoundInitializer { final String url = RuntimeConfig.getConfig().getJDBCURL(); final int database = DbHelper.getDatabaseFromURL(url); + s_log.debug("CMS.Initializer.(Constructor) invoked"); + add(new PDLInitializer (new ManifestSource ("ccm-cms.pdl.mf", new NameFilter(DbHelper.getDatabaseSuffix(database), "pdl")))); + // Step 1: + // Old type initializer "com.arsdigita.cms.installer.Initializer" + // Used to be the first initializer in old enterprise.init + // + // Replaced by new type initializer com.arsdigita.cms.installer.Initializer() + // Simple migration of the old code to the new initializer system with as + // less code change as possible. + // + // Invokes ContentCenterSetup (without any LegacyInitializer) + // performs mainly loader tasks and should be migrated to Loader. add(new com.arsdigita.cms.installer.Initializer()); - // Experimental: Moved into c.ad.cms.loader - add(new LegacyInitializer("com/arsdigita/cms/contentsection/enterprise.init")); + // Step 2: + // Old type initializer "com.arsdigita.cms.installer.xml.ContentTypeInitializer" + // Completely moved into Loader + + // Step 4: + // Old type initializer "com.arsdigita.cms.installer.SectionInitializer" + // Invoking the Initializer rewritten to a separate enterprise.init in + // c.ad.cms.contentsection and modified in c.ad.cms.initializer + // Mainly loader tasks, to be moved into c.ad.cms.Loader + // 2010-08-16: Moved to Loader, works OK +// add(new LegacyInitializer("com/arsdigita/cms/contentsection/enterprise.init")); + + // Step 4a new + // Initializer for content section, needed when LegacyInitializer in step 3 + // has been moved to c.ad.Loader in order to register the application and + // optionally to install additional content sections. // add(new com.arsdigita.cms.contentsection.Initializer()); + // Used to be step 3 in old enterprise.init migrated to loader/new init. add(new com.arsdigita.cms.publishToFile.Initializer()); + // Used to be step 6 in old enterprise.init migrated to loader/new init. add(new com.arsdigita.cms.lifecycle.Initializer()); + // Used to be step 7 in old enterprise.init migrated to loader/new init. add(new com.arsdigita.cms.portlet.Initializer()); - // add(new LegacyInitializer("com/arsdigita/cms/enterprise.init")); - // Replaced by c.ad.cms.installer.Initializer() (NEW initializer!) - // add(new LegacyInitializer("com/arsdigita/cms/installer/enterprise.init")); - - // Moved into c.ad.cms.loader - // add(new LegacyInitializer("com/arsdigita/cms/installer/xml/enterprise.init")); - - // now used to initialize the forms in ccm-core only! + // Used to be step 5 in old enterprise.init + // Old type initializer "com.arsdigita.formbuilder.installer.Initializer" + // Used to initialize CMS forms using the forms in ccm-core // Can be replaced in ccm after ccm-core is migrated to new initializer. add(new LegacyInitializer("com/arsdigita/cms/enterprise.init")); + + s_log.debug("CMS.Initializer.(Constructor) completed"); } @@ -133,7 +174,9 @@ public class Initializer extends CompoundInitializer { */ @Override public void init(DomainInitEvent e) { + s_log.debug("CMS.Initializer.init(DomainInitEvent) invoked"); super.init(e); + LanguageUtil.setSupportedLanguages( Kernel.getConfig().getSupportedLanguages()); @@ -212,6 +255,11 @@ public class Initializer extends CompoundInitializer { MetadataProviderRegistry.registerAdapter( FileAsset.BASE_DATA_OBJECT_TYPE, new AssetMetadataProvider()); + + // Mount the content-center sidenode + + + s_log.debug("CMS.Initializer.init(DomainInitEvent) completed"); } // END init(DomainInitEvent e) diff --git a/ccm-cms/src/com/arsdigita/cms/Loader.java b/ccm-cms/src/com/arsdigita/cms/Loader.java index d62153502..4d538dcbd 100755 --- a/ccm-cms/src/com/arsdigita/cms/Loader.java +++ b/ccm-cms/src/com/arsdigita/cms/Loader.java @@ -18,29 +18,87 @@ */ package com.arsdigita.cms; -import com.arsdigita.kernel.Kernel; -import com.arsdigita.kernel.KernelExcursion; -import com.arsdigita.loader.PackageLoader; -import com.arsdigita.runtime.ScriptContext; - -import com.arsdigita.cms.installer.ContentCenterSetup; +import com.arsdigita.cms.installer.ContentSectionSetup; +import com.arsdigita.cms.installer.PageClassConfigHandler; +import com.arsdigita.cms.installer.Util; import com.arsdigita.cms.installer.xml.XMLContentTypeHandler; +import com.arsdigita.cms.installer.WorkspaceInstaller; //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.domain.DataObjectNotFoundException; +import com.arsdigita.kernel.Kernel; +import com.arsdigita.kernel.KernelExcursion; +import com.arsdigita.kernel.PackageInstance; +import com.arsdigita.kernel.PackageType; +import com.arsdigita.kernel.SiteNode; +import com.arsdigita.kernel.Stylesheet; +import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +import com.arsdigita.loader.PackageLoader; +import com.arsdigita.persistence.DataQuery; +import com.arsdigita.persistence.SessionManager; +import com.arsdigita.runtime.ConfigError; +import com.arsdigita.runtime.ScriptContext; +import com.arsdigita.util.UncheckedWrapperException; +//import com.arsdigita.util.parameter.Parameter; +// import com.arsdigita.util.parameter.BooleanParameter; +//import com.arsdigita.util.parameter.StringParameter; +//import com.arsdigita.util.parameter.URLParameter; +// import com.arsdigita.web.Application; +// import com.arsdigita.web.ApplicationType; import com.arsdigita.xml.XML; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; import java.util.Iterator; import java.util.List; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + import org.apache.log4j.Logger; + +// Migration status +// +// The module in its complete version (i.e. all method invocations in run() +// method commented IN(!) does load all packages into database and +// ccm/admin/sitemap lists them appropriately. +// Not yet found a way to mount them in the URL tree while initializing. + + /** - * The CMS loader. + *

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.

* - * @author Justin Ross <jross@redhat.com> - * @version $Id: Loader.java 2070 2010-01-28 08:47:41Z pboy $ + *

This class also optionally initializes user-defined content types.

+ *

Additional user-defined content sections can be loaded and initilized + * using the recurring

initializer
at any startup. + * + *

The tasks to perform are:

+ *
    + *
  1. create CMS package type(content-section)
  2. + *
  3. create Workspace package type and instance
  4. + *
  5. create CMS Service package type and instance
  6. + *
  7. create CMS package (content-section) instance
  8. + *
+ * + *

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.

+ * + * @author Peter Boy <pboy@barkhof.uni-bremen.de> + * @since ccm-cms version 6.6.0 + * @version $Id: $ */ public class Loader extends PackageLoader { @@ -50,59 +108,475 @@ public class Loader extends PackageLoader { // Load main CMS configuration file private static final LoaderConfig s_conf = new LoaderConfig(); +// static { // requirred to actually read the config file +// s_config.load(); +// } /** - * Constructor + * Constant string used as key for creating CMS (content-section) as a + * legacy application. + */ + private final static String CMS_PACKAGE_KEY = "content-section"; + /** + * Dispatcher class for CMS (needed to be assigned to a legacy application). + */ + private final static String CMS_DISPATCHER_CLASS = + "com.arsdigita.cms.dispatcher.ContentSectionDispatcher"; + /** + * Stylesheet which has to be assigned as part of a legacy application + * creation. + */ + private final static String CMS_STYLESHEET = + "/packages/content-section/xsl/cms.xsl"; + + /** + * Constant string used as key for creating Workspace (content-center) as a + * legacy application. + */ + public static final String WORKSPACE_PACKAGE_KEY = "content-center"; + private static final String WORKSPACE_INSTANCE_NAME = "Content Center"; + /** + * Dispatcher class for Workspace (content-center) (needed to be assigned + * to a legacy application). + */ + private static final String WORKSPACE_DISPATCHER_CLASS = + "com.arsdigita.cms.dispatcher.ContentCenterDispatcher"; + // To be updated soon... + // "com.arsdigita.dispatcher.DefaultPackageDispatcher"; + /** + * Stylesheet which has to be assigned as part of a legacy application + * creation. + */ + private final static String WORKSPACE_STYLESHEET = + "/packages/content-section/xsl/content-center.xsl"; + + /** + * Name of the CMS service package instance, i.e. its URL. + */ + private final static String SERVICE_URL = "cms-service"; + /** + * Constant string used as key for creating service package as a + * legacy application. + */ + public final static String SERVICE_PACKAGE_KEY = "cms-service"; + + + private static HashMap s_pageClasses = new HashMap(); + private static HashMap s_pageURLs = new HashMap(); + + + /** + * Standard constructor. */ public Loader() { + s_log.debug("CMS.loader (Constructor) invoked"); + s_log.debug("CMS.loader (Constructor) completed"); } public void run(final ScriptContext ctx) { // XXX: Should move on demand initialization stuff here. + s_log.debug("CMS.loader.run() invoked"); + new KernelExcursion() { public void excurse() { setEffectiveParty(Kernel.getSystemParty()); - // //////////////////////////////// - // Experimental: - // Put ContentCenterSetup in Loader - // //////////////////////////////// -// final String workspaceURL = s_conf.getWorkspaceURL(); -// final String contentCenterMap = s_conf.getContentCenterMap(); -// ContentCenterSetup centerSetup = new ContentCenterSetup( -// workspaceURL, -// contentCenterMap); -// -// centerSetup.run(); // //////////////////////// + // Loading CMS package (esp. content center, cms service + // Used to be step 1 in former enterprise.init file + // Implemented by + // com.arsdigita.cms.installer.xml.ContentTypeInitializer + // //////////////////////////////// + // 1 - step 1a) Setup the CMS package. +// loadCMSPackageType(); + // loadContentSectionPackageType using (new) c.ad.web package. + // ContentSectionSetup.setupContentSectionAppType(); + + // createPrivileges(); + + // 2 - step 1b) Setup the Workspace package. +// loadWorkspacePackage(); + + // 3 - step 1c) Setup the CMS global services package. +// loadServicePackage(); + + // 4 - stgep 1d) Load the content-center page mappings +// loadContentCenterMapping(s_conf.getContentCenterMap() ); + + // //////////////////////// + // 5) load content type definition(s) // Loading content type definitions // Used to be step 2 in former enterprise.init file + // Implemented by + // com.arsdigita.cms.installer.xml.ContentTypeInitializer // //////////////////////////////// - List contentTypes = s_conf.getCTDefFiles(); - if ( contentTypes != null) { - Iterator i = contentTypes.iterator(); - while (i.hasNext()) { - String xmlFile = (String)i.next(); - s_log.debug("Processing contentTypes in: " + xmlFile); - XML.parseResource(xmlFile, new XMLContentTypeHandler()); - } - } + loadContentTypeDefinitions(s_conf.getCTDefFiles() ); + + // //////////////////////// + // 6) Load CMS (content section) package application instance + // Loading content section application type and instance + // Used to be step 4 in former enterprise.init file + // (step 3 being initialize publishToFile, not to handle in Loader) + // Implemented by + // com.arsdigita.cms.installer.SectionInitializer + // //////////////////////////////// + loadContentSection(s_conf.getContentSectionName()); // /////////////////////////////////////////////////////// // Loading CMS portlets - // Used to be step 5 (last step) in former enterprise.init + // Used to be step 7 (last step) in former enterprise.init // /////////////////////////////////////////////////////// + s_log.debug("CMS.loader going to load portlets"); //ContentDirectoryPortlet.loadPortletType(); ContentItemPortlet.loadPortletType(); //ContentSectionsPortlet.loadPortletType(); TaskPortlet.loadPortletType(); - + + } }.run(); } + + /** + * Loads the CMS package type in the database, i.e. content-section, + * the main CMS domain (application) class. + * + * (pb) WRONG: + * Creates content-section PackageType. Is replaced by newer ApplicationType + * mechanisam (see loadContentSection). Must nolonger be used except of + * createPrivileges! + */ + private void loadCMSPackageType() { + s_log.debug("Loading the CMS package type..."); + + // creating appl. type using the deprecated legacy application style. + // Should be refactored to c.ad.web.Application. + // CMS_PACKAGE_KEY = "content-section" +// PackageType type = PackageType.create +// (CMS_PACKAGE_KEY, +// "Content Management System", +// "Content Management Systems", +// "http://cms-java.arsdigita.com/"); + +// type.setDispatcherClass(CMS_DISPATCHER_CLASS); + //type.addListener(LISTENER_CLASS); (commented out) + + // Register a stylesheets to the CMS package. +// Stylesheet ss = Stylesheet.createStylesheet(CMS_STYLESHEET); +// ss.save(); +// type.addStylesheet(ss); +// type.save(); + + +// Creating of CMS package using new style c.ad.web.Application could +// be done like the following. +// ApplicationType type = ApplicationType +// .createApplicationType(ContentSection.PACKAGE_TYPE, +// "Conten Management Application (i.e. content-section)", +// ContentSection.BASE_DATA_OBJECT_TYPE); +// type.setDescription("The content management application."); +// // Question: Do we need to use deprectated (with no replacement) method +// // setDispatcherClass in web.Application or does it work magically without? +// type.setDispatcherClass(CMS_DISPATCHER_CLASS); +// type.addStylesheet(ss); + + + createPrivileges(); + + s_log.debug("Done creating the CMS package type."); + } + + + /** + * Loads and instantiates the Workspace package (content-center) in the + * database. + */ + private void loadWorkspacePackage() { + s_log.debug("Creating CMS Workspace..."); + + WorkspaceInstaller workspaceInstaller = new WorkspaceInstaller(); + try { + workspaceInstaller.createPackageType(); + // type.setDispatcherClass(WORKSPACE_DISPATCHER_CLASS); + +// PackageInstance instance = workspaceInstaller.createPackageInstance(); + // Does the following: + // type = PackageType.findByKey(WORKSPACE_PACKAGE_KEY); + // PackageInstance instance = type.createInstance(WORKSPACE_INSTANCE_NAME); + // instance.save(); + PackageInstance instance = workspaceInstaller.createPackageInstance(); + +// workspaceInstaller.mountPackageInstance(instance, m_workspaceURL); + // Does the following: + // SiteNode node = SiteNode.createSiteNode( + // s_conf.getWorkspaceURL(), + // SiteNode.getRootSiteNode()); + // node.mountPackage(instance); + // node.save(); + + // m_workspaceURL == WORKSPACE_PACKAGE_KEY + // workspaceInstaller.mountPackageInstance(instance, m_workspaceURL); + workspaceInstaller.mountPackageInstance(instance, WORKSPACE_PACKAGE_KEY); + + } catch (DataObjectNotFoundException e) { + throw new ConfigError( + "Failed to initialize the Workspace package: "); + } + + + +// Creating of Workspace package using new style c.ad.web.Application could +// be done like the following (legacy compatible style!). +// Needs refactoring of the Workspace package. +// // Step 1: Create application type +// ApplicationType type = ApplicationType +// .createApplicationType("content-center", +// "The Content Center Workspace", +// ContentCenter.BASE_DATA_OBJECT_TYPE); NEEDED! +// type.setDescription("The content center workspace for content creators."); +// +// // Step 2: Create application +// Application app = Application.createRootApplication( +// type, +// "Content Center Workspace"); +// app.setPath((String) get(m_workspaceURL)); + + 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. + * + */ + private void loadServicePackage() { + s_log.debug("Loading CMS Servce Package..."); + + try { +// ServiceInstaller.createPackageType(); + PackageType type = PackageType.create + (SERVICE_PACKAGE_KEY, + "Content Management System Services", + "Content Management System Services", + "http://cms-service.arsdigita.com/"); + type.setDispatcherClass( + "com.arsdigita.cms.dispatcher.ServiceDispatcher"); + type.save(); + +// PackageInstance instance = ServiceInstaller.createPackageInstance(); + type = PackageType.findByKey(SERVICE_PACKAGE_KEY); + PackageInstance instance = type.createInstance(SERVICE_PACKAGE_KEY); + instance.save(); + +// ServiceInstaller.mountPackageInstance(instance, url); + SiteNode node = SiteNode.createSiteNode(SERVICE_URL, + SiteNode.getRootSiteNode()); + node.mountPackage(instance); + node.save(); + + } catch (DataObjectNotFoundException e) { + throw new ConfigError + ("Failed to initialize CMS global services package."); + } + + + +// Creating of Service package using new style c.ad.web.Application could +// be done like the following (legacy compatible style!). +// Needs refactoring of the Servcie package. +// // Step 1: Create application type +// ApplicationType type = ApplicationType +// .createApplicationType("cms-service", // Type = PACKAGE_KEY, +// "Content Management System Services", +// SERVICE_BASE_DATA_OBJECT_TYPE); +// // Step 2: Create application +// Application workspace = Application.createRootApplication( +// type, +// "Content Center Workspace"); +// app.setPath((String) get(m_workspaceURL)); + + s_log.debug("Done creating CMS Servce Package."); + } + + + private void loadContentCenterMapping(String mapFileName) throws ConfigError { + + final PageClassConfigHandler handler + = new PageClassConfigHandler(s_pageClasses, s_pageURLs); + + final ClassLoader loader = Thread.currentThread + ().getContextClassLoader(); + final InputStream input = loader.getResourceAsStream + (mapFileName.substring(1)); + + if (input == null) { + throw new IllegalStateException(mapFileName + " not found"); + } + + final InputSource source = new InputSource + (input); + + try { + final SAXParserFactory spf = SAXParserFactory.newInstance(); + final SAXParser parser = spf.newSAXParser(); + parser.parse(source, handler); + } catch (ParserConfigurationException e) { + throw new UncheckedWrapperException("error parsing dispatcher config", e); + } catch (SAXException e) { + throw new UncheckedWrapperException("error parsing dispatcher config", e); + } catch (IOException e) { + throw new UncheckedWrapperException("error parsing dispatcher config", e); + } + } + + + /** + * Parses XML file definition of content types and loads them to the + * database. 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. + * + * UDCT Copyright + *
+     * <ccm:content-types>
+     *   <ccm:content-type
+     *             name="Copyright"
+     *             label="UDCT Copyright"
+     *             parentType="com.arsdigita.cms.contenttypes.Address"
+     *             classname="com.arsdigita.cms.contenttypes.Address"
+     *             description="Copyright for storing copyright information"
+     *             objectType="com.arsdigita.cms.contentTypes.Address" >
+     *
+     *      <ccm:authoring-kit>
+     *      </ccm:authoring-kit>
+     *   </ccm:content-type>
+     * </ccm:content-types>
+     *
+ * + * @see XMLContentTypeHandler + */ + private void loadContentTypeDefinitions(List ctDefFiles) { + s_log.debug("Loading content type definitions ..."); + + if ( ctDefFiles != null) { + Iterator i = ctDefFiles.iterator(); + while (i.hasNext()) { + // TransactionContext txn = SessionManager.getSession() + // .getTransactionContext(); + // txn.beginTxn(); + + String xmlFile = (String)i.next(); + s_log.debug("Processing contentTypes in: " + xmlFile); + XML.parseResource(xmlFile, new XMLContentTypeHandler()); + + // txn.commitTxn(); + } + } + + s_log.debug("Done loading content type definitions."); + } + + + /** + * Creates the CMS privileges. + */ + private static void createPrivileges() { + s_log.debug("Creating Privileges..."); + + final String CMS_PRIVILEGES = "com.arsdigita.cms.getPrivileges"; + final String PRIVILEGE = "privilege"; + + DataQuery dq = SessionManager.getSession().retrieveQuery(CMS_PRIVILEGES); + try { + while ( dq.next() ) { + String privilege = (String) dq.get(PRIVILEGE); + if ( PrivilegeDescriptor.get(privilege) == null ) { + PrivilegeDescriptor.createPrivilege(privilege); + } + } + + } finally { + dq.close(); + } + s_log.debug("Done creating Privileges."); + } + + + /** + * Load an initial default content-section, specified in LoaderConfig. + * + * + */ + private void loadContentSection(String name) { + + s_log.info("Creating content section on /" + name); + + // Step 1: Creating content section application type first so that + // concrete content-section instance can be created. + ContentSectionSetup.setupContentSectionAppType(); + + + // Step 2: Validatge name for section + Util.validateURLParameter("name", name); + + + // Step 3: Create the installation default content section "name" + ContentSection section = ContentSection.create(name); + + // ContentSectionSetup is a convenient class for ContentSection.create() + ContentSectionSetup setup = new ContentSectionSetup(section); + + // ContentSection.create uses the following properties: + // Name, see above + // Root & template folder, set autonomously by ContentSection.create() + // Roles (staff group) used in 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 + + // registers a predefined standard recipient for alerts + setup.registerAlerts(); + // register a predefined one-phase lifecycle for items. + setup.registerPublicationCycles(); + // registers predefined "Authoring", "Approval", "Publishing' steps + setup.registerWorkflowTemplates(); + setup.registerContentTypes(s_conf.getContentSectionsContentTypes()); + + setup.registerResolvers(s_conf.getItemResolverClass(), + s_conf.getTemplateResolverClass() ); + // XML generator class, set autonomously by ContentSection.create() + + // 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()); + } + } + + section.save(); //persists any changes in the database (DomainObject) + //i.e. creates an object (instance) + + } + + + } diff --git a/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java b/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java index 3b18c1430..48fd8988f 100644 --- a/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java @@ -34,7 +34,7 @@ package com.arsdigita.cms; //import com.arsdigita.kernel.permissions.PrivilegeDescriptor; import com.arsdigita.runtime.AbstractConfig; 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.StringArrayParameter; import com.arsdigita.util.parameter.StringParameter; @@ -193,6 +193,28 @@ public final class LoaderConfig extends AbstractConfig { Parameter.REQUIRED, true); + /** + * List of content types to register in the given content-section. + * + * Example: + * { + * "com.arsdigita.cms.contenttypes.Address", + * "com.arsdigita.cms.contenttypes.Article", + * "com.arsdigita.cms.contenttypes.Contact" + * } + * + * Parameter name "TYPES" in the old initializer code, empty by default in + * the former enterprise.init file. + * When the list is empty and the first default content section is created, + * all installed content types will get registered. This behaviour should + * not be altered without very good reasons. + */ + private final Parameter + m_contentTypeList = new StringArrayParameter( + "com.arsdigita.cms.loader.ctypes_include_list", + Parameter.REQUIRED, + new String[] {} ); + // Page Resolver Class, set autonomously by ContentSection.create() method. // Item Resolver Class, configurable. @@ -241,30 +263,6 @@ public final class LoaderConfig extends AbstractConfig { // XML Generator Class, set autonomously by ContentSection.create() method. - // Additional Parameters - - /** - * List of content types to register in the given content-section. - * - * Example: - * { - * "com.arsdigita.cms.contenttypes.Address", - * "com.arsdigita.cms.contenttypes.Article", - * "com.arsdigita.cms.contenttypes.Contact" - * } - * - * Parameter name "TYPES" in the old initializer code, empty by default in - * the former enterprise.init file. - * When the list is empty and the first default content section is created, - * all installed content types will get registered. This behaviour should - * not be altered without very good reasons. - */ - private final Parameter - m_contentTypeList = new StringArrayParameter( - "com.arsdigita.cms.loader.ctypes_include_list", - Parameter.REQUIRED, - new String[] {} ); - /** * Determins weather to use section specific category tree(s). Defaults to * false, so standard navigation is used. @@ -297,86 +295,55 @@ public final class LoaderConfig extends AbstractConfig { // Collections.EMPTY_LIST); - /** - * A list of workflow tasks, and the associated events for which alerts - * have to be sent. - * Parameter name TASK_ALERTS in the old initializer system / enterprise.init - * Specifies 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. - * Example: - * (Note that the values below are based on the task labels, and as such are - * not globalized.) - *
-     * taskAlerts = {
-     *      { "Authoring",
-     *        { "enable", "finish", "rollback" }
-     *      },
-     *      { "Approval",
-     *        { "enable", "finish", "rollback" }
-     *      },
-     *      { "Deploy",
-     *        { "enable", "finish", "rollback" }
-     *      }
-     *  };
-     * 
- * - * Default value (site-wide) is handled via the parameter - *
com.arsdigita.cms.default_task_alerts
. - * Section-specific override can be added here. Only do so if you are - * changing for a good reason from the default for a specific content section. - */ - private final Parameter - m_taskAlerts = new StringArrayParameter( - "com.arsdigita.cms.loader.section_task_alerts", - Parameter.REQUIRED, - null ); - // new String[] {} ); + // /////////////////////////////////////////////////////////////////////// + // + // Parameters controlling Overdue Task alerts: + // + // There seems to be no functionality to store these parameters on a + // per section base of to store them in the database at all. So it is + // currently not a loader task and commented out here. + // /////////////////////////////////////////////////////////////////////// - // Parameters controlling Overdue Task alerts: +// /** +// * sendOverdueAlerts: Should we send alerts about overdue tasks at all? +// */ +// private final Parameter +// m_sendOverdueAlerts = new BooleanParameter( +// "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 +// * considered overdue (in HOURS) +// */ +// private final Parameter +// m_taskDuration = new IntegerParameter( +// "com.arsdigita.cms.loader.task_duration", +// Parameter.REQUIRED, +// new Integer(96) ); - /** - * sendOverdueAlerts: Should we send alerts about overdue tasks at all? - */ - private final Parameter - m_sendOverdueAlerts = new BooleanParameter( - "com.arsdigita.cms.loader.send_overdue_alerts", - Parameter.REQUIRED, - new Boolean(false) ); +// /** +// * alertInterval: The time to wait between sending successive alerts on +// * the same overdue task (in HOURS) +// */ +// private final Parameter +// m_overdueAlertInterval = new IntegerParameter( +// "com.arsdigita.cms.loader.overdue_alert_interval", +// Parameter.REQUIRED, +// new Integer(24) ); - /** - * taskDuration: The time between when a task is enabled (it is made - * available for completion) and when it is - * considered overdue (in HOURS) - */ - private final Parameter - m_taskDuration = new IntegerParameter( - "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) - */ - private final Parameter - m_overdueAlertInterval = new IntegerParameter( - "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 - */ - private final Parameter - m_maxAlerts = new IntegerParameter( - "com.arsdigita.cms.loader.mas_alerts", - Parameter.REQUIRED, - new Integer(5) ); +// /** +// * maxAlerts: The maximum number of alerts to send about any one +// * overdue task +// */ +// private final Parameter +// m_maxAlerts = new IntegerParameter( +// "com.arsdigita.cms.loader.mas_alerts", +// Parameter.REQUIRED, +// new Integer(5) ); /** * Standard Constructor. @@ -396,13 +363,14 @@ public final class LoaderConfig extends AbstractConfig { register(m_contentTypeList); register(m_useSectionCategories); register(m_categoryFileList); - register(m_taskAlerts); // Parameters controlling Overdue Task alerts: - register(m_sendOverdueAlerts); - register(m_taskDuration); - register(m_overdueAlertInterval); - register(m_maxAlerts); + // (Currently not a loader task) +// register(m_taskAlerts); no Loader task, moved to contentsection/Initializer +// register(m_sendOverdueAlerts); +// register(m_taskDuration); +// register(m_overdueAlertInterval); +// register(m_maxAlerts); @@ -455,7 +423,8 @@ public final class LoaderConfig extends AbstractConfig { * * In loading step a complete default configuration is persisted in database, * immutable at this point. - * See contentsection.ContentSectionSetup.registerRoles() + * See contentsection.ContentSectio +nSetup.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, @@ -586,48 +555,41 @@ public final class LoaderConfig extends AbstractConfig { return Arrays.asList(taskAlerts); } - /** - * Retrieve the list of workflow tasks and events for each tasks which - * should receive overdue notification alerts - */ - public List getTaskAlerts() { - String[] ctTypes = (String[]) get(m_contentTypeList); - return Arrays.asList(ctTypes); - } - // Parameters controlling Overdue Task alerts: + // Currently not a loader task, see above - /** - * getSendOverdueAlerts: Retrieve wether we should send alerts about - * overdue tasks at all? - */ - public final boolean getSendOverdueAlerts() { - return ((Boolean) get(m_sendOverdueAlerts)).booleanValue(); } +// /** +// * getSendOverdueAlerts: Retrieve wether we should send alerts about +// * overdue tasks at all? +// */ +// public final boolean getSendOverdueAlerts() { +// return ((Boolean) get(m_sendOverdueAlerts)).booleanValue(); } - /** - * getTaskDuration: Retrieve the time between when a task is enabled - * (it is made available for completion) and when it is considered - * overdue (in HOURS) - */ - public final Integer getTaskDuration() { - return ((Integer) get(m_taskDuration)); } +// /** +// * getTaskDuration: Retrieve the time between when a task is enabled +// * (it is made available for completion) and when it is considered +// * overdue (in HOURS) +// */ +// public final Integer getTaskDuration() { +// return ((Integer) get(m_taskDuration)); } - /** - * getAlertInterval: Retrieve the time to wait between sending successive - * alerts on the same overdue task (in HOURS) - */ - public final Integer getOverdueAlertInterval() { - return ((Integer) get(m_overdueAlertInterval)); } +// /** +// * getAlertInterval: Retrieve the time to wait between sending successive +// * alerts on the same overdue task (in HOURS) +// */ +// public final Integer getOverdueAlertInterval() { +// return ((Integer) get(m_overdueAlertInterval)); } - /** - * maxAlerts: Retrieve the maximum number of alerts to send about any one - * overdue task - */ - public final Integer getMaxAlerts() { - return ((Integer) get(m_maxAlerts)); } +// /** +// * maxAlerts: Retrieve the maximum number of alerts to send about any one +// * overdue task +// */ +// public final Integer getMaxAlerts() { +// return ((Integer) get(m_maxAlerts)); } + // End section task alerts // InputStream getTraversalAdapters() { // return (InputStream) get(m_adapters); diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java index d2e891d75..8f56f557e 100644 --- a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java @@ -26,15 +26,15 @@ 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.StringArrayParameter; import com.arsdigita.util.parameter.StringParameter; // import com.arsdigita.util.parameter.ResourceParameter; // import com.arsdigita.util.parameter.URLParameter; //import com.arsdigita.util.StringUtils; // import java.io.InputStream; -//import java.util.Arrays; -//import java.util.List; +import java.util.Arrays; +import java.util.List; //import java.util.ArrayList; import org.apache.log4j.Logger; @@ -53,32 +53,44 @@ public final class ContentSectionConfig extends AbstractConfig { Logger.getLogger(ContentSectionConfig.class); - -// /////////////////////////////////////////////////////// -// -// Set of parameters which specify a new content section -// to be created during next startup of the system. If -// the section already exists (created during previous -// startups) parameters are ignored and not processed. -// -// /////////////////////////////////////////////////////// - - /** - * The name of a new content section to be create during next boot of the - * system. During subsequent startups, when the section to be created - * already exists, the parameter is ignored and processing skipped. - * - * Empty by default so no processing will take place. - */ - private final Parameter - m_newContentSectionName = new StringParameter( - "com.arsdigita.cms.contentsection.new_section_name", - Parameter.REQUIRED, - null); - - // Parameters controlling Overdue Task alerts: + /** + * A list of workflow tasks, and the associated events for which alerts + * have to be sent. + * Parameter name TASK_ALERTS in the old initializer system / enterprise.init + * Specifies 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. + * Example: + * (Note that the values below are based on the task labels, and as such are + * not globalized.) + *
+     * taskAlerts = {
+     *      { "Authoring",
+     *        { "enable", "finish", "rollback" }
+     *      },
+     *      { "Approval",
+     *        { "enable", "finish", "rollback" }
+     *      },
+     *      { "Deploy",
+     *        { "enable", "finish", "rollback" }
+     *      }
+     *  };
+     * 
+ * + * Default value (site-wide) is handled via the parameter + *
com.arsdigita.cms.default_task_alerts
. + * Section-specific override can be added here. Only do so if you are + * changing for a good reason from the default for a specific content section. + */ + private final Parameter + m_taskAlerts = new StringArrayParameter( + "com.arsdigita.cms.loader.section_task_alerts", + Parameter.REQUIRED, + null ); + // new String[] {} ); /** * Should we send alerts about overdue tasks at all? @@ -137,48 +149,67 @@ public final class ContentSectionConfig extends AbstractConfig { new Integer(5) ); + +// /////////////////////////////////////////////////////// +// +// Set of parameters which specify a new content section +// to be created during next startup of the system. If +// the section already exists (created during previous +// startups) parameters are ignored and not processed. +// +// /////////////////////////////////////////////////////// + + /** + * The name of a new content section to be create during next boot of the + * system. During subsequent startups, when the section to be created + * already exists, the parameter is ignored and processing skipped. + * + * Empty by default so no processing will take place. + */ + private final Parameter + m_newContentSectionName = new StringParameter( + "com.arsdigita.cms.contentsection.new_section_name", + Parameter.REQUIRED, + null); + + /** * Constructor, do not instantiate this class directly! * * @see ContentSection#getConfig() - **/ + */ public ContentSectionConfig() { - - register(m_newContentSectionName); + // parameters for alerts (notifications) + register(m_taskAlerts); register(m_sendOverdueAlerts); register(m_taskDuration); register(m_alertInterval); register(m_maxAlerts); + + // parameters for creation of a new (additional) content section + register(m_newContentSectionName); } -// /////////////////////////////////////////////////////// +// ////////////////////////////////////////////////////////// // -// Processing of parameters which specify a new content -// section to be created during (next) startup of the -// system. The initializer has to check if it already -// exists and skip processing. +// Processing of parameters which handle overdue notification // -// /////////////////////////////////////////////////////// - +// ////////////////////////////////////////////////////////// /** - * Retrieve the name of a new content-section to create. + * Retrieve the list of workflow tasks and events for each tasks which + * should receive overdue notification alerts * - * The initializer has to check if it already exists and skip processing. + * XXX wrong implementation !! + * Should be moved to CMS or section initializer because may be modified + * each startup. Does not store anything in database so not a loader task! */ - public String getNewContentSectionName() { - return (String) get(m_newContentSectionName); - } - - -// /////////////////////////////////////////////////////// -// -// Processing of parameters which handle the timing -// of overdue notification -// -// /////////////////////////////////////////////////////// + public List getTaskAlerts() { +// String[] m_taskAlerts = (String[]) get(m_contentTypeList); + return Arrays.asList(m_taskAlerts); + } /** @@ -212,4 +243,25 @@ public final class ContentSectionConfig extends AbstractConfig { return (Integer) get(m_maxAlerts); } + + +// /////////////////////////////////////////////////////// +// +// Processing of parameters which specify a new content +// section to be created during (next) startup of the +// system. The initializer has to check if it already +// exists and skip processing. +// +// /////////////////////////////////////////////////////// + + + /** + * Retrieve the name of a new content-section to create. + * + * The initializer has to check if it already exists and skip processing. + */ + public String getNewContentSectionName() { + return (String) get(m_newContentSectionName); + } + } diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/Initializer.java b/ccm-cms/src/com/arsdigita/cms/contentsection/Initializer.java index 5808610f5..259ed258c 100644 --- a/ccm-cms/src/com/arsdigita/cms/contentsection/Initializer.java +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/Initializer.java @@ -25,13 +25,15 @@ import com.arsdigita.cms.LoaderConfig; import com.arsdigita.cms.installer.ContentSectionSetup; import com.arsdigita.cms.installer.Util; import com.arsdigita.cms.util.GlobalizationUtil; +import com.arsdigita.cms.workflow.UnfinishedTaskNotifier; import com.arsdigita.domain.DataObjectNotFoundException; -import com.arsdigita.kernel.SiteNode; import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.TransactionContext; import com.arsdigita.runtime.CompoundInitializer; import com.arsdigita.runtime.ConfigError; // import com.arsdigita.runtime.DataInitEvent; +import com.arsdigita.runtime.ContextInitEvent; +import com.arsdigita.runtime.ContextCloseEvent; import com.arsdigita.runtime.DomainInitEvent; import com.arsdigita.util.Assert; import com.arsdigita.web.Application; @@ -49,6 +51,9 @@ import org.apache.log4j.Logger; // changes as possible. // In a second step a restructure of the code will be done. +// Has to handle in future: +// -- configuration of alert tasks +// -- creation of additional content sections during restart /** * XXX Reformulate according to the code development! @@ -71,8 +76,8 @@ public class Initializer extends CompoundInitializer { /** Creates a s_logging category with name = to the full name of class */ private static Logger s_log = Logger.getLogger(Initializer.class); - /** Local configuration object LoaderConfig containing immutable parameters - after installation. */ + /** Local configuration object ContentSectionConfig containing parameters + which may be changed each system startup. */ // private static final LoaderConfig s_conf = LoaderConfig.getConfig(); private static final LoaderConfig s_conf = new LoaderConfig(); @@ -92,6 +97,7 @@ public class Initializer extends CompoundInitializer { // */ // public void init(DataInitEvent evt) { // } + /** * Initializes domain-coupling machinery, usually consisting of * registering object instantiators and observers. @@ -108,119 +114,96 @@ public class Initializer extends CompoundInitializer { // If super is not invoked, various other cms sub-initializer may not run. super.init(evt); - // Create and mount the demo content section if it does not exist. - // String name = (String) m_conf.getParameter(NAME); - String name = s_conf.getContentSectionName(); - TransactionContext txn = - SessionManager.getSession().getTransactionContext(); - txn.beginTxn(); - ContentSectionSetup.setupContentSectionAppType(); + /* + * loadAlertPrefs loads a list of workflow tasks and associated events + * from configuration file and fills a hashmap. No database operation. + * Not a loader task! + */ + // XXX Currently in ContenSectionSetup - has to be migrated !! + // setup.loadAlertPrefs((List) s_conf.getTaskAlerts()); - Util.validateURLParameter("name", name); - - String sitemapEntry = "/" + name + "/"; - if (Application.isInstalled(ContentSection.BASE_DATA_OBJECT_TYPE, - sitemapEntry)) { - s_log.info("skipping " + name + - " because it is already installed"); - } else { - s_log.info("Installing " + name + " at " + - sitemapEntry); - createSection(name); - } - - ContentSection section = retrieveContentSection(name); - Assert.exists(section, ContentSection.class); - ContentSectionSetup setup = new ContentSectionSetup(section); - - setup.loadAlertPrefs( s_conf.getTaskAlerts()); - - s_unfinishedTimer = setup.startNotifierTask - (s_conf.getSendOverdueAlerts(), - s_conf.getTaskDuration(), - s_conf.getOverdueAlertInterval(), - s_conf.getMaxAlerts()); - - txn.commitTxn(); s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) completed"); } - + /** + * Implementation of the {@link Initializer#init(ContextInitEvent)} + * method. * - * @param name + * Initializes the scheduler thread to fire all the events for the + * ...... that have just began or ended. + * + * A delay value of 0 inhibits start of processing. + * @param evt The context init event. + */ + public void init(ContextInitEvent evt) { + s_log.debug("content section ContextInitEvent started"); + + // XXX to be done yet! + // Currently we have only one timer, but notification is handled + // on a per section base. We have also only one set of timing parameters. + // So we have to configure all sections in the same way. +// s_unfinishedTimer = setup.startNotifierTask +// (s_conf.getSendOverdueAlerts(), +// s_conf.getTaskDuration(), +// s_conf.getOverdueAlertInterval(), +// s_conf.getMaxAlerts()); + + + s_log.debug("content section ContextInitEvent completed"); + } + + /** + * Implementation of the {@link Initializer#init(ContextCloseEvent)} + * method. + * + */ + public void close(ContextCloseEvent evt) { + s_log.debug("content section ContextCloseEvent started"); + if (s_unfinishedTimer != null) { + s_unfinishedTimer.cancel(); + s_unfinishedTimer = null; + } + s_log.debug("content section ContextCloseEvent completed"); + } + + + /** + * @param section content section for which notifier should be started + * @param sendOverdue + * @param duration + * @param alertInterval + * @param max * @return */ - private ContentSection retrieveContentSection(String name) { - BigDecimal rootNodeID = SiteNode.getRootSiteNode().getID(); - SiteNode node = null; - try { - node = SiteNode.getSiteNode("/" + name); - } catch (DataObjectNotFoundException ex) { - throw new ConfigError( - (String) GlobalizationUtil.globalize( - "cms.installer.root_site_node_missing").localize() + ex ); - } - ContentSection section = null; - if ( rootNodeID.equals(node.getID()) ) { - // This instance does not exist yet. - section = createSection(name); + private final Timer startNotifierTask( + ContentSection section, + Boolean sendOverdue, Integer duration, + Integer alertInterval, Integer max) { + Timer unfinished = null; + if (sendOverdue.booleanValue()) { + if (duration == null || alertInterval == null || max == null) { + s_log.info("Not sending overdue task alerts, " + + "required initialization parameters were not specified"); + return null; + } + // start the Timer as a daemon, so it doesn't keep the JVM from exiting + unfinished = new Timer(true); + UnfinishedTaskNotifier notifier = + new UnfinishedTaskNotifier( section, duration.intValue(), + alertInterval.intValue(), + max.intValue()); + // schedule the Task to start in 5 minutes, at 1 hour intervals + unfinished.schedule(notifier, 5L * 60 * 1000, 60L * 60 * 1000); + s_log.info("Sending overdue alerts for tasks greater than " + + duration + " hours old"); } else { - try { - section = ContentSection.getSectionFromNode(node); - } catch (DataObjectNotFoundException de) { - throw new ConfigError( - (String) GlobalizationUtil.globalize( - "cms.installer.could_not_load_section", - new Object[] {name}).localize() + de ); - } - } - return section; - } - /** - * Install the CMS Demo. - */ - private ContentSection createSection(String name) { - - s_log.info("Creating content section on /" + name); - - - ContentSection section = ContentSection.create(name); - - ContentSectionSetup setup = new ContentSectionSetup(section); - - // Setup the access controls - - // section specific categories, usually not used. - // During initial load at install time nor used at all! - if (ContentSection.getConfig().getUseSectionCategories()) { - // Iterator files = ((List) m_conf.getParameter(CATEGORIES)).iterator(); - Iterator files = s_conf.getCategoryFileList().iterator(); - while ( files.hasNext() ) { - setup.registerCategories((String) files.next()); - } + s_log.info("Not sending overdue task alerts"); } - // setup.registerRoles((List)m_conf.getParameter(ROLES)); - setup.registerRoles(s_conf.getStuffGroup()); - // setup.registerViewers((Boolean)m_conf.getParameter(PUBLIC)); - setup.registerViewers(s_conf.isPubliclyViewable()); - setup.registerAlerts(); - setup.registerPublicationCycles(); - setup.registerWorkflowTemplates(); - // setup.registerContentTypes((List)m_conf.getParameter(TYPES)); - setup.registerContentTypes(s_conf.getContentSectionsContentTypes()); - // setup.registerResolvers - // ((String) m_conf.getParameter(ITEM_RESOLVER_CLASS), - // (String) m_conf.getParameter(TEMPLATE_RESOLVER_CLASS)); - setup.registerResolvers - (s_conf.getItemResolverClass(), - s_conf.getTemplateResolverClass()); - section.save(); - - return section; + return unfinished; } } diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/enterprise.init b/ccm-cms/src/com/arsdigita/cms/contentsection/enterprise.init index 4d29ab737..01367fae8 100644 --- a/ccm-cms/src/com/arsdigita/cms/contentsection/enterprise.init +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/enterprise.init @@ -1,3 +1,4 @@ +// com/arsdigita/cms/contentsection/enterprise.init // CMS initialization file // // $Id: enterprise.init 2070 2010-01-28 08:47:41Z pboy $ diff --git a/ccm-cms/src/com/arsdigita/cms/installer/ContentCenterSetup.java b/ccm-cms/src/com/arsdigita/cms/installer/ContentCenterSetup.java index db427c5da..f4ff6c508 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/ContentCenterSetup.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/ContentCenterSetup.java @@ -119,22 +119,24 @@ public final class ContentCenterSetup { /** * Creates the CMS package type if it does not already exist. + * + * Actually: Creates the PackageType contentsection! */ private static void setupCMSPackage() { - if ( !PackageType.typeExists(Installer.PACKAGE_KEY) ) { + if ( !PackageType.typeExists(Installer.PACKAGE_KEY) ) { //key = content-section s_log.info("Creating the CMS package type..."); - PackageType type = PackageType.create - (PACKAGE_KEY, "Content Management System", "Content Management Systems", - "http://cms-java.arsdigita.com/"); - type.setDispatcherClass(DISPATCHER_CLASS); - //type.addListener(LISTENER_CLASS); +// PackageType type = PackageType.create +// (PACKAGE_KEY, "Content Management System", "Content Management Systems", +// "http://cms-java.arsdigita.com/"); +// type.setDispatcherClass(DISPATCHER_CLASS); +// //type.addListener(LISTENER_CLASS); // Register a stylesheets to the CMS package. - Stylesheet ss = Stylesheet.createStylesheet(STYLESHEET); - ss.save(); - type.addStylesheet(ss); - type.save(); +// Stylesheet ss = Stylesheet.createStylesheet(STYLESHEET); +// ss.save(); +// type.addStylesheet(ss); +// type.save(); createPrivileges(); @@ -186,7 +188,11 @@ public final class ContentCenterSetup { /** - * Creates the CMS privileges. + * Integrates the CMS privileges into the Core permision system. + * + * Skips through the CMS specific privileges and integrates those which are + * missing in core's acs_privileges into it, so the systems security system + * is aware of it. */ private static void createPrivileges() { diff --git a/ccm-cms/src/com/arsdigita/cms/installer/ContentSectionSetup.java b/ccm-cms/src/com/arsdigita/cms/installer/ContentSectionSetup.java index f998b3014..9da884cc5 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/ContentSectionSetup.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/ContentSectionSetup.java @@ -387,6 +387,10 @@ public final class ContentSectionSetup { return null; } + /** + * For the content section to be created create a role whose member will + * receive alerts. + */ public void registerAlerts() { Role alert = m_section.getStaffGroup().createRole("Alert Recipient"); alert.setDescription("Receive alerts regarding expiration of pubished content"); @@ -602,6 +606,10 @@ public final class ContentSectionSetup { } } + /** + * + * @param tasks + */ public void loadAlertPrefs(List tasks) { if (tasks == null) { // fallback to default com.arsdigita.cms.default_task_alerts registry parameter diff --git a/ccm-cms/src/com/arsdigita/cms/installer/Initializer.java b/ccm-cms/src/com/arsdigita/cms/installer/Initializer.java index 116659326..887ac5b6c 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/Initializer.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/Initializer.java @@ -55,21 +55,20 @@ public class Initializer extends CompoundInitializer { /** Creates a s_logging category with name = to the full name of class */ private static Logger s_log = Logger.getLogger(Initializer.class); - // private static PublishToFileConfig s_conf= PublishToFileConfig.getConfig(); private static final LoaderConfig s_conf = new LoaderConfig(); -// LoaderConfig conf = LoaderConfig.getConfig(); - -// As an example -// private static final ContentSectionConfig s_config = new ContentSectionConfig(); - -// static { -// s_config.load(); +// Verursacht aktuell eine Exception "no such contgext" +// static { // requirred to actually read the config file! +// s_conf.load(); // } + /** + * Constructor + */ public Initializer() { //final String url = RuntimeConfig.getConfig().getJDBCURL(); //final int database = DbHelper.getDatabaseFromURL(url); + s_log.debug("CMS.installer.Initializer.(Constructor) completed"); } // /** diff --git a/ccm-cms/src/com/arsdigita/cms/installer/LegacyInitializer.java b/ccm-cms/src/com/arsdigita/cms/installer/LegacyInitializer.java.nolongerInUse similarity index 100% rename from ccm-cms/src/com/arsdigita/cms/installer/LegacyInitializer.java rename to ccm-cms/src/com/arsdigita/cms/installer/LegacyInitializer.java.nolongerInUse diff --git a/ccm-cms/src/com/arsdigita/cms/installer/SectionLegacyInitializer.java b/ccm-cms/src/com/arsdigita/cms/installer/SectionLegacyInitializer.java.nolongerInUse similarity index 86% rename from ccm-cms/src/com/arsdigita/cms/installer/SectionLegacyInitializer.java rename to ccm-cms/src/com/arsdigita/cms/installer/SectionLegacyInitializer.java.nolongerInUse index fe0db4445..ef65da8b7 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/SectionLegacyInitializer.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/SectionLegacyInitializer.java.nolongerInUse @@ -36,6 +36,8 @@ import java.util.Iterator; // import java.util.List; import java.util.Timer; +// import org.apache.log4j.Logger; + /** *

Initializes a content section, registering a default * workflow, lifecycle & roles and adding the content types @@ -76,10 +78,6 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ // Temporär: Einbinden des neuen Parameter Systems private static final LoaderConfig s_conf = new LoaderConfig(); -// LoaderConfig conf = LoaderConfig.getConfig(); - -// As an example -// private static final ContentSectionConfig s_config = new ContentSectionConfig(); // Required to actually load the parameter file. // Aktuell: wenn man das aktiviert, gibt's einen Fehler: Kontext existiert @@ -92,6 +90,7 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ private static Timer s_unfinishedTimer; public SectionLegacyInitializer() throws InitializationException { + s_log.debug("CMS.installer.SectionLegacyInitializer.(Constructor) invoked"); // m_conf.initParameter(NAME, // "The name of the content section", // String.class); @@ -132,6 +131,7 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ // m_conf.initParameter(TEMPLATE_RESOLVER_CLASS, // "The TemplateResolver class to use for the section (defaults to DefaultTemplateResolver)", // String.class); + s_log.debug("CMS.installer.SectionLegacyInitializer.(Constructor) completed"); } // required by parent class. @@ -142,6 +142,7 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ protected void doStartup() { + s_log.debug("CMS.installer.SectionLegacyInitializer.doStartup() invoked"); // Create and mount the demo content section if it does not exist. // String name = (String) m_conf.getParameter(NAME); @@ -164,7 +165,9 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ } else { s_log.info("Installing " + name + " at " + sitemapEntry); - createSection(name); + createSection(name); // Create a content section, initial + // creation is a loader task, additional + // sections may be created during (re)start } ContentSection section = retrieveContentSection(name); @@ -172,20 +175,31 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ ContentSectionSetup setup = new ContentSectionSetup(section); // setup.loadAlertPrefs((List) m_conf.getParameter(TASK_ALERTS)); - setup.loadAlertPrefs( s_conf.getTaskAlerts()); + /* + * loadAlertPrefs loads a list of workflow tasks and associated events + * from configuration file and fills a hashmap. No database operation. + * Not a loader task! Moved to contentsection/Initializer + */ +// Moved from LoaderConfig to contentsection/ContentSectionConfig +// setup.loadAlertPrefs( s_conf.getTaskAlerts()); // s_unfinishedTimer = setup.startNotifierTask // ((Boolean) m_conf.getParameter(SEND_OVERDUE_ALERTS), // (Integer) m_conf.getParameter(TASK_DURATION), // (Integer) m_conf.getParameter(OVERDUE_ALERT_INTERVAL), // (Integer) m_conf.getParameter(MAX_ALERTS)); - s_unfinishedTimer = setup.startNotifierTask - (s_conf.getSendOverdueAlerts(), - s_conf.getTaskDuration(), - s_conf.getOverdueAlertInterval(), - s_conf.getMaxAlerts()); + +// Commented out in LoadereConfig because not a Loader task. So commented +// out here. If SectionLegacyInitializer should ever be used again, a +// defferent config file (section initializer config) should be used here + // s_unfinishedTimer = setup.startNotifierTask + // (s_conf.getSendOverdueAlerts(), + // s_conf.getTaskDuration(), + // s_conf.getOverdueAlertInterval(), + // s_conf.getMaxAlerts()); txn.commitTxn(); + s_log.debug("CMS.installer.SectionLegacyInitializer.doStartup() completed"); } /** @@ -193,6 +207,11 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ * @param name * @return */ + + // seems not to be requirred when using new web application functionality + // instead of old fashioned PackageType / SiteNode + // Not migrated to Loader nor to Initializer. + private ContentSection retrieveContentSection(String name) { BigDecimal rootNodeID = SiteNode.getRootSiteNode().getID(); SiteNode node = null; @@ -230,6 +249,9 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ /** * Install the CMS Demo. */ + + // Moved into Loader + private ContentSection createSection(String name) { s_log.info("Creating content section on /" + name); diff --git a/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java b/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java index 32b411f86..cc350c5e5 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java @@ -72,7 +72,8 @@ public class WorkspaceInstaller implements PackageEventListener { * * @return The Content Center package type */ - protected PackageType createPackageType() +// protected PackageType createPackageType() + public PackageType createPackageType() throws DataObjectNotFoundException { PackageType type = PackageType.create @@ -98,7 +99,8 @@ public class WorkspaceInstaller implements PackageEventListener { * * @return The Content Center package instance */ - protected PackageInstance createPackageInstance() +// protected PackageInstance createPackageInstance() + public PackageInstance createPackageInstance() throws DataObjectNotFoundException { PackageType type = @@ -117,7 +119,8 @@ public class WorkspaceInstaller implements PackageEventListener { * @param location The location of the Content Center * @return The SiteNode where the Content Center is mounted at */ - protected SiteNode mountPackageInstance(PackageInstance instance, +// protected SiteNode mountPackageInstance(PackageInstance instance, + public SiteNode mountPackageInstance(PackageInstance instance, String location) { SiteNode node = SiteNode.createSiteNode(location, SiteNode.getRootSiteNode()); diff --git a/ccm-cms/src/com/arsdigita/cms/installer/enterprise.init b/ccm-cms/src/com/arsdigita/cms/installer/enterprise.init.nolongerInUse similarity index 100% rename from ccm-cms/src/com/arsdigita/cms/installer/enterprise.init rename to ccm-cms/src/com/arsdigita/cms/installer/enterprise.init.nolongerInUse diff --git a/ccm-cms/src/com/arsdigita/cms/installer/portlet/Initializer.java b/ccm-cms/src/com/arsdigita/cms/installer/portlet.nolongerInUse/Initializer.java.nolongerInUse similarity index 95% rename from ccm-cms/src/com/arsdigita/cms/installer/portlet/Initializer.java rename to ccm-cms/src/com/arsdigita/cms/installer/portlet.nolongerInUse/Initializer.java.nolongerInUse index 66fd6a4c7..73fba0014 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/portlet/Initializer.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/portlet.nolongerInUse/Initializer.java.nolongerInUse @@ -41,6 +41,14 @@ import com.arsdigita.portal.PortletType; import org.apache.log4j.Logger; +// //////////////////////////////////////////////////////////////////////////// +// +// Migrated to new initializer system. +// code moved to c.ad.cms.loader and c.ad.cms.portlet.initializer +// +// //////////////////////////////////////////////////////////////////////////// + + public class Initializer extends BaseInitializer { diff --git a/ccm-cms/src/com/arsdigita/cms/installer/xml/ContentTypeLegacyInitializer.java b/ccm-cms/src/com/arsdigita/cms/installer/xml/ContentTypeLegacyInitializer.java.nolongerInUse similarity index 100% rename from ccm-cms/src/com/arsdigita/cms/installer/xml/ContentTypeLegacyInitializer.java rename to ccm-cms/src/com/arsdigita/cms/installer/xml/ContentTypeLegacyInitializer.java.nolongerInUse diff --git a/ccm-cms/src/com/arsdigita/cms/installer/xml/enterprise.init b/ccm-cms/src/com/arsdigita/cms/installer/xml/enterprise.init.nolongerInUse similarity index 100% rename from ccm-cms/src/com/arsdigita/cms/installer/xml/enterprise.init rename to ccm-cms/src/com/arsdigita/cms/installer/xml/enterprise.init.nolongerInUse diff --git a/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java b/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java index a2595a869..642e3beb3 100755 --- a/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java +++ b/ccm-cms/src/com/arsdigita/cms/search/IntermediaQueryEngine.java @@ -30,8 +30,8 @@ import java.util.List; import com.arsdigita.categorization.Category; import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentType; -import com.arsdigita.cms.search.ContentTypeFilterSpecification; -import com.arsdigita.cms.search.ContentTypeFilterType; +// import com.arsdigita.cms.search.ContentTypeFilterSpecification; +// import com.arsdigita.cms.search.ContentTypeFilterType; import com.arsdigita.kernel.PartyCollection; import com.arsdigita.persistence.DataQuery; import com.arsdigita.persistence.Filter; diff --git a/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java b/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java index f4e7b4aef..29883c4ed 100755 --- a/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java +++ b/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java @@ -365,7 +365,7 @@ public class CMSTask extends UserTask { typeLabel = typeLabel.trim(); operation = operation.trim(); // get the typeLabel -> list-of-operations map for this section - Map typeMap = (Map) s_alerts.get(section.getID()); + Map typeMap = (Map) s_alerts.get(section.getID()); //s_alerts: HashMap if (typeMap == null) { typeMap = new HashMap(5); s_alerts.put(section.getID(), typeMap); diff --git a/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java b/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java index 1377b3cac..edd954bc9 100755 --- a/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java +++ b/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java @@ -77,9 +77,9 @@ public class UnfinishedTaskNotifier extends TimerTask { m_maxNotifications = maxNotifications; s_log.debug("Created UnfinishedTaskNotifier for section " + section.getName()); s_log.debug("Sending notifications for tasks over " + m_unfinishedInterval + - " milliseconds old, with repeat notifications every " + m_notificationInterval + - " milliseconds, with a maxmimum of " + m_maxNotifications + " notifications going out for" + - " every task."); + " milliseconds old, with repeat notifications every " + + m_notificationInterval + " milliseconds, with a maxmimum of " + + m_maxNotifications + " notifications going out for every task."); } @@ -94,7 +94,8 @@ public class UnfinishedTaskNotifier extends TimerTask { } }.run(); } catch (Throwable t) { - s_log.error("Unexpeced error occured in UnfinishedTaskNotifier. Task has been disabled", t); + s_log.error("Unexpeced error occured in UnfinishedTaskNotifier." + + "Task has been disabled", t); throw new UncheckedWrapperException(t); } } @@ -116,7 +117,8 @@ public class UnfinishedTaskNotifier extends TimerTask { unfinishedTasks.setParameter("sectionID", m_sectionID); // we want to do the Date arithmetic in Java, since we set // the Date from Java initially - unfinishedTasks.setParameter("overdueDate", new Date(System.currentTimeMillis() - m_unfinishedInterval)); + unfinishedTasks.setParameter("overdueDate", + new Date(System.currentTimeMillis() - m_unfinishedInterval)); while (unfinishedTasks.next()) { CMSTask task = (CMSTask) DomainObjectFactory @@ -126,9 +128,11 @@ public class UnfinishedTaskNotifier extends TimerTask { Date lastSentDate = notification.getLastNotificationDate(); int numSent = notification.getNumNotifications(); if ((lastSentDate == null || - lastSentDate.before(new Date(System.currentTimeMillis() - m_notificationInterval))) + lastSentDate.before(new Date(System.currentTimeMillis() - + m_notificationInterval))) && m_maxNotifications > numSent) { - s_log.debug("Sending unfinished notification for " + task + ", started on " + task.getStartDate()); + s_log.debug("Sending unfinished notification for " + task + + ", started on " + task.getStartDate()); // make sure we record that we've sent this notification first notification.incrNumNotifications(); notification.save(); @@ -138,7 +142,8 @@ public class UnfinishedTaskNotifier extends TimerTask { txn.commitTxn(); committedTxn = true; - s_log.debug("UnfinishedTaskNotifier completed in " + (System.currentTimeMillis() - startTime) + "ms"); + s_log.debug("UnfinishedTaskNotifier completed in " + + (System.currentTimeMillis() - startTime) + "ms"); } finally { if (!committedTxn) { txn.abortTxn();