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
master
pb 2010-08-17 11:01:59 +00:00
parent ab8c22becf
commit 1dca0d0ebd
19 changed files with 951 additions and 380 deletions

View File

@ -23,6 +23,7 @@ import com.arsdigita.cms.dispatcher.AssetURLFinder;
import com.arsdigita.cms.dispatcher.ItemDelegatedURLPatternGenerator; import com.arsdigita.cms.dispatcher.ItemDelegatedURLPatternGenerator;
import com.arsdigita.cms.dispatcher.ItemTemplatePatternGenerator; import com.arsdigita.cms.dispatcher.ItemTemplatePatternGenerator;
import com.arsdigita.cms.dispatcher.ItemURLFinder; import com.arsdigita.cms.dispatcher.ItemURLFinder;
import com.arsdigita.cms.installer.WorkspaceInstaller;
import com.arsdigita.cms.publishToFile.PublishToFileListener; import com.arsdigita.cms.publishToFile.PublishToFileListener;
import com.arsdigita.cms.publishToFile.QueueManager; import com.arsdigita.cms.publishToFile.QueueManager;
import com.arsdigita.cms.search.AssetMetadataProvider; import com.arsdigita.cms.search.AssetMetadataProvider;
@ -48,6 +49,10 @@ import com.arsdigita.domain.DomainObjectInstantiator;
import com.arsdigita.domain.xml.TraversalHandler; import com.arsdigita.domain.xml.TraversalHandler;
import com.arsdigita.kernel.ACSObjectInstantiator; import com.arsdigita.kernel.ACSObjectInstantiator;
import com.arsdigita.kernel.NoValidURLException; 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.URLFinder;
import com.arsdigita.kernel.URLFinderNotFoundException; import com.arsdigita.kernel.URLFinderNotFoundException;
import com.arsdigita.kernel.URLService; 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.ManifestSource;
import com.arsdigita.persistence.pdl.NameFilter; import com.arsdigita.persistence.pdl.NameFilter;
import com.arsdigita.runtime.CompoundInitializer; import com.arsdigita.runtime.CompoundInitializer;
import com.arsdigita.runtime.ConfigError;
import com.arsdigita.runtime.DomainInitEvent; import com.arsdigita.runtime.DomainInitEvent;
import com.arsdigita.runtime.LegacyInitializer; import com.arsdigita.runtime.LegacyInitializer;
import com.arsdigita.runtime.PDLInitializer; import com.arsdigita.runtime.PDLInitializer;
@ -80,14 +86,23 @@ import com.arsdigita.templating.PatternStylesheetResolver;
import com.arsdigita.cms.util.LanguageUtil; import com.arsdigita.cms.util.LanguageUtil;
import com.arsdigita.kernel.Kernel; 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> * @author Justin Ross <jross@redhat.com>
* @version $Id: Initializer.java 2070 2010-01-28 08:47:41Z pboy $ * @version $Id: Initializer.java 2070 2010-01-28 08:47:41Z pboy $
*/ */
public class Initializer extends CompoundInitializer { 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 * Constructor
*/ */
@ -95,32 +110,58 @@ public class Initializer extends CompoundInitializer {
final String url = RuntimeConfig.getConfig().getJDBCURL(); final String url = RuntimeConfig.getConfig().getJDBCURL();
final int database = DbHelper.getDatabaseFromURL(url); final int database = DbHelper.getDatabaseFromURL(url);
s_log.debug("CMS.Initializer.(Constructor) invoked");
add(new PDLInitializer add(new PDLInitializer
(new ManifestSource (new ManifestSource
("ccm-cms.pdl.mf", ("ccm-cms.pdl.mf",
new NameFilter(DbHelper.getDatabaseSuffix(database), "pdl")))); 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()); add(new com.arsdigita.cms.installer.Initializer());
// Experimental: Moved into c.ad.cms.loader // Step 2:
add(new LegacyInitializer("com/arsdigita/cms/contentsection/enterprise.init")); // 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()); // 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()); 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()); 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 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 // Used to be step 5 in old enterprise.init
// add(new LegacyInitializer("com/arsdigita/cms/installer/xml/enterprise.init")); // Old type initializer "com.arsdigita.formbuilder.installer.Initializer"
// Used to initialize CMS forms using the forms in ccm-core
// now used to initialize the forms in ccm-core only!
// Can be replaced in ccm after ccm-core is migrated to new initializer. // Can be replaced in ccm after ccm-core is migrated to new initializer.
add(new LegacyInitializer("com/arsdigita/cms/enterprise.init")); 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 @Override
public void init(DomainInitEvent e) { public void init(DomainInitEvent e) {
s_log.debug("CMS.Initializer.init(DomainInitEvent) invoked");
super.init(e); super.init(e);
LanguageUtil.setSupportedLanguages( LanguageUtil.setSupportedLanguages(
Kernel.getConfig().getSupportedLanguages()); Kernel.getConfig().getSupportedLanguages());
@ -212,6 +255,11 @@ public class Initializer extends CompoundInitializer {
MetadataProviderRegistry.registerAdapter( MetadataProviderRegistry.registerAdapter(
FileAsset.BASE_DATA_OBJECT_TYPE, FileAsset.BASE_DATA_OBJECT_TYPE,
new AssetMetadataProvider()); new AssetMetadataProvider());
// Mount the content-center sidenode
s_log.debug("CMS.Initializer.init(DomainInitEvent) completed");
} // END init(DomainInitEvent e) } // END init(DomainInitEvent e)

View File

@ -18,29 +18,87 @@
*/ */
package com.arsdigita.cms; package com.arsdigita.cms;
import com.arsdigita.kernel.Kernel; import com.arsdigita.cms.installer.ContentSectionSetup;
import com.arsdigita.kernel.KernelExcursion; import com.arsdigita.cms.installer.PageClassConfigHandler;
import com.arsdigita.loader.PackageLoader; import com.arsdigita.cms.installer.Util;
import com.arsdigita.runtime.ScriptContext;
import com.arsdigita.cms.installer.ContentCenterSetup;
import com.arsdigita.cms.installer.xml.XMLContentTypeHandler; import com.arsdigita.cms.installer.xml.XMLContentTypeHandler;
import com.arsdigita.cms.installer.WorkspaceInstaller;
//import com.arsdigita.cms.portlet.ContentDirectoryPortlet; //import com.arsdigita.cms.portlet.ContentDirectoryPortlet;
import com.arsdigita.cms.portlet.ContentItemPortlet; import com.arsdigita.cms.portlet.ContentItemPortlet;
//import com.arsdigita.cms.portlet.ContentSectionsPortlet; //import com.arsdigita.cms.portlet.ContentSectionsPortlet;
import com.arsdigita.cms.portlet.TaskPortlet; import com.arsdigita.cms.portlet.TaskPortlet;
import com.arsdigita.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 com.arsdigita.xml.XML;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; 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; 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. * <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>
* *
* @author Justin Ross &lt;jross@redhat.com&gt; * <p>This class also optionally initializes user-defined content types. </p>
* @version $Id: Loader.java 2070 2010-01-28 08:47:41Z pboy $ * <p>Additional user-defined content sections can be loaded and initilized
* 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>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
* @version $Id: $
*/ */
public class Loader extends PackageLoader { public class Loader extends PackageLoader {
@ -50,59 +108,475 @@ public class Loader extends PackageLoader {
// Load main CMS configuration file // Load main CMS configuration file
private static final LoaderConfig s_conf = new LoaderConfig(); 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() { public Loader() {
s_log.debug("CMS.loader (Constructor) invoked");
s_log.debug("CMS.loader (Constructor) completed");
} }
public void run(final ScriptContext ctx) { public void run(final ScriptContext ctx) {
// XXX: Should move on demand initialization stuff here. // XXX: Should move on demand initialization stuff here.
s_log.debug("CMS.loader.run() invoked");
new KernelExcursion() { new KernelExcursion() {
public void excurse() { public void excurse() {
setEffectiveParty(Kernel.getSystemParty()); 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 // Loading content type definitions
// Used to be step 2 in former enterprise.init file // Used to be step 2 in former enterprise.init file
// Implemented by
// com.arsdigita.cms.installer.xml.ContentTypeInitializer
// //////////////////////////////// // ////////////////////////////////
List contentTypes = s_conf.getCTDefFiles(); loadContentTypeDefinitions(s_conf.getCTDefFiles() );
if ( contentTypes != null) {
Iterator i = contentTypes.iterator(); // ////////////////////////
while (i.hasNext()) { // 6) Load CMS (content section) package application instance
String xmlFile = (String)i.next(); // Loading content section application type and instance
s_log.debug("Processing contentTypes in: " + xmlFile); // Used to be step 4 in former enterprise.init file
XML.parseResource(xmlFile, new XMLContentTypeHandler()); // (step 3 being initialize publishToFile, not to handle in Loader)
} // Implemented by
} // com.arsdigita.cms.installer.SectionInitializer
// ////////////////////////////////
loadContentSection(s_conf.getContentSectionName());
// /////////////////////////////////////////////////////// // ///////////////////////////////////////////////////////
// Loading CMS portlets // 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(); //ContentDirectoryPortlet.loadPortletType();
ContentItemPortlet.loadPortletType(); ContentItemPortlet.loadPortletType();
//ContentSectionsPortlet.loadPortletType(); //ContentSectionsPortlet.loadPortletType();
TaskPortlet.loadPortletType(); TaskPortlet.loadPortletType();
} }
}.run(); }.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.
*
* <b>UDCT Copyright</b>
* <pre>
* &lt;ccm:content-types&gt;
* &lt;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" &gt;
*
* &lt;ccm:authoring-kit&gt;
* &lt;/ccm:authoring-kit&gt;
* &lt;/ccm:content-type&gt;
* &lt;/ccm:content-types&gt;
*</pre>
*
* @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)
}
} }

View File

@ -34,7 +34,7 @@ package com.arsdigita.cms;
//import com.arsdigita.kernel.permissions.PrivilegeDescriptor; //import com.arsdigita.kernel.permissions.PrivilegeDescriptor;
import com.arsdigita.runtime.AbstractConfig; import com.arsdigita.runtime.AbstractConfig;
import com.arsdigita.util.parameter.BooleanParameter; import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.IntegerParameter; // import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter; import com.arsdigita.util.parameter.Parameter;
import com.arsdigita.util.parameter.StringArrayParameter; import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter; import com.arsdigita.util.parameter.StringParameter;
@ -193,6 +193,28 @@ public final class LoaderConfig extends AbstractConfig {
Parameter.REQUIRED, Parameter.REQUIRED,
true); 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. // Page Resolver Class, set autonomously by ContentSection.create() method.
// Item Resolver Class, configurable. // Item Resolver Class, configurable.
@ -241,30 +263,6 @@ public final class LoaderConfig extends AbstractConfig {
// XML Generator Class, set autonomously by ContentSection.create() method. // 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 * Determins weather to use section specific category tree(s). Defaults to
* false, so standard navigation is used. * false, so standard navigation is used.
@ -297,86 +295,55 @@ public final class LoaderConfig extends AbstractConfig {
// Collections.EMPTY_LIST); // Collections.EMPTY_LIST);
/** // ///////////////////////////////////////////////////////////////////////
* A list of workflow tasks, and the associated events for which alerts //
* have to be sent. // Parameters controlling Overdue Task alerts:
* Parameter name TASK_ALERTS in the old initializer system / enterprise.init //
* Specifies when to generate email alerts: by default, generate email alerts // There seems to be no functionality to store these parameters on a
* on enable, finish, and rollback (happens on rejection) changes. // per section base of to store them in the database at all. So it is
* There are four action types for each task type: enable, disable, finish, // currently not a loader task and commented out here.
* and rollback. // ///////////////////////////////////////////////////////////////////////
* Example:
* (Note that the values below are based on the task labels, and as such are
* not globalized.)
* <pre>
* taskAlerts = {
* { "Authoring",
* { "enable", "finish", "rollback" }
* },
* { "Approval",
* { "enable", "finish", "rollback" }
* },
* { "Deploy",
* { "enable", "finish", "rollback" }
* }
* };
* </pre>
*
* Default value (site-wide) is handled via the parameter
* <pre>com.arsdigita.cms.default_task_alerts</pre>.
* 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: // /**
// * 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? // * alertInterval: The time to wait between sending successive alerts on
*/ // * the same overdue task (in HOURS)
private final Parameter // */
m_sendOverdueAlerts = new BooleanParameter( // private final Parameter
"com.arsdigita.cms.loader.send_overdue_alerts", // m_overdueAlertInterval = new IntegerParameter(
Parameter.REQUIRED, // "com.arsdigita.cms.loader.overdue_alert_interval",
new Boolean(false) ); // Parameter.REQUIRED,
// new Integer(24) );
/** // /**
* taskDuration: The time between when a task is enabled (it is made // * maxAlerts: The maximum number of alerts to send about any one
* available for completion) and when it is // * overdue task
* considered overdue (in HOURS) // */
*/ // private final Parameter
private final Parameter // m_maxAlerts = new IntegerParameter(
m_taskDuration = new IntegerParameter( // "com.arsdigita.cms.loader.mas_alerts",
"com.arsdigita.cms.loader.task_duration", // Parameter.REQUIRED,
Parameter.REQUIRED, // new Integer(5) );
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) );
/** /**
* Standard Constructor. * Standard Constructor.
@ -396,13 +363,14 @@ public final class LoaderConfig extends AbstractConfig {
register(m_contentTypeList); register(m_contentTypeList);
register(m_useSectionCategories); register(m_useSectionCategories);
register(m_categoryFileList); register(m_categoryFileList);
register(m_taskAlerts);
// Parameters controlling Overdue Task alerts: // Parameters controlling Overdue Task alerts:
register(m_sendOverdueAlerts); // (Currently not a loader task)
register(m_taskDuration); // register(m_taskAlerts); no Loader task, moved to contentsection/Initializer
register(m_overdueAlertInterval); // register(m_sendOverdueAlerts);
register(m_maxAlerts); // 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, * In loading step a complete default configuration is persisted in database,
* immutable at this point. * immutable at this point.
* See contentsection.ContentSectionSetup.registerRoles() * See contentsection.ContentSectio
nSetup.registerRoles()
* In enterprise.init: name roles, List of roles to create. * 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, * 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); 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: // Parameters controlling Overdue Task alerts:
// Currently not a loader task, see above
/** // /**
* getSendOverdueAlerts: Retrieve wether we should send alerts about // * getSendOverdueAlerts: Retrieve wether we should send alerts about
* overdue tasks at all? // * overdue tasks at all?
*/ // */
public final boolean getSendOverdueAlerts() { // public final boolean getSendOverdueAlerts() {
return ((Boolean) get(m_sendOverdueAlerts)).booleanValue(); } // return ((Boolean) get(m_sendOverdueAlerts)).booleanValue(); }
/** // /**
* getTaskDuration: Retrieve the time between when a task is enabled // * getTaskDuration: Retrieve the time between when a task is enabled
* (it is made available for completion) and when it is considered // * (it is made available for completion) and when it is considered
* overdue (in HOURS) // * overdue (in HOURS)
*/ // */
public final Integer getTaskDuration() { // public final Integer getTaskDuration() {
return ((Integer) get(m_taskDuration)); } // return ((Integer) get(m_taskDuration)); }
/** // /**
* getAlertInterval: Retrieve the time to wait between sending successive // * getAlertInterval: Retrieve the time to wait between sending successive
* alerts on the same overdue task (in HOURS) // * alerts on the same overdue task (in HOURS)
*/ // */
public final Integer getOverdueAlertInterval() { // public final Integer getOverdueAlertInterval() {
return ((Integer) get(m_overdueAlertInterval)); } // return ((Integer) get(m_overdueAlertInterval)); }
/** // /**
* maxAlerts: Retrieve the maximum number of alerts to send about any one // * maxAlerts: Retrieve the maximum number of alerts to send about any one
* overdue task // * overdue task
*/ // */
public final Integer getMaxAlerts() { // public final Integer getMaxAlerts() {
return ((Integer) get(m_maxAlerts)); } // return ((Integer) get(m_maxAlerts)); }
// End section task alerts
// InputStream getTraversalAdapters() { // InputStream getTraversalAdapters() {
// return (InputStream) get(m_adapters); // return (InputStream) get(m_adapters);

View File

@ -26,15 +26,15 @@ import com.arsdigita.util.parameter.BooleanParameter;
import com.arsdigita.util.parameter.IntegerParameter; import com.arsdigita.util.parameter.IntegerParameter;
import com.arsdigita.util.parameter.Parameter; import com.arsdigita.util.parameter.Parameter;
//import com.arsdigita.util.parameter.ParameterError; //import com.arsdigita.util.parameter.ParameterError;
//import com.arsdigita.util.parameter.StringArrayParameter; import com.arsdigita.util.parameter.StringArrayParameter;
import com.arsdigita.util.parameter.StringParameter; import com.arsdigita.util.parameter.StringParameter;
// import com.arsdigita.util.parameter.ResourceParameter; // import com.arsdigita.util.parameter.ResourceParameter;
// import com.arsdigita.util.parameter.URLParameter; // import com.arsdigita.util.parameter.URLParameter;
//import com.arsdigita.util.StringUtils; //import com.arsdigita.util.StringUtils;
// import java.io.InputStream; // import java.io.InputStream;
//import java.util.Arrays; import java.util.Arrays;
//import java.util.List; import java.util.List;
//import java.util.ArrayList; //import java.util.ArrayList;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -53,32 +53,44 @@ public final class ContentSectionConfig extends AbstractConfig {
Logger.getLogger(ContentSectionConfig.class); 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: // 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.)
* <pre>
* taskAlerts = {
* { "Authoring",
* { "enable", "finish", "rollback" }
* },
* { "Approval",
* { "enable", "finish", "rollback" }
* },
* { "Deploy",
* { "enable", "finish", "rollback" }
* }
* };
* </pre>
*
* Default value (site-wide) is handled via the parameter
* <pre>com.arsdigita.cms.default_task_alerts</pre>.
* 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? * Should we send alerts about overdue tasks at all?
@ -137,48 +149,67 @@ public final class ContentSectionConfig extends AbstractConfig {
new Integer(5) ); 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! * Constructor, do not instantiate this class directly!
* *
* @see ContentSection#getConfig() * @see ContentSection#getConfig()
**/ */
public ContentSectionConfig() { public ContentSectionConfig() {
register(m_newContentSectionName); // parameters for alerts (notifications)
register(m_taskAlerts);
register(m_sendOverdueAlerts); register(m_sendOverdueAlerts);
register(m_taskDuration); register(m_taskDuration);
register(m_alertInterval); register(m_alertInterval);
register(m_maxAlerts); register(m_maxAlerts);
// parameters for creation of a new (additional) content section
register(m_newContentSectionName);
} }
// /////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////
// //
// Processing of parameters which specify a new content // Processing of parameters which handle overdue notification
// 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. * 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() { public List getTaskAlerts() {
return (String) get(m_newContentSectionName); // String[] m_taskAlerts = (String[]) get(m_contentTypeList);
} return Arrays.asList(m_taskAlerts);
}
// ///////////////////////////////////////////////////////
//
// Processing of parameters which handle the timing
// of overdue notification
//
// ///////////////////////////////////////////////////////
/** /**
@ -212,4 +243,25 @@ public final class ContentSectionConfig extends AbstractConfig {
return (Integer) get(m_maxAlerts); 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);
}
} }

View File

@ -25,13 +25,15 @@ import com.arsdigita.cms.LoaderConfig;
import com.arsdigita.cms.installer.ContentSectionSetup; import com.arsdigita.cms.installer.ContentSectionSetup;
import com.arsdigita.cms.installer.Util; import com.arsdigita.cms.installer.Util;
import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.cms.workflow.UnfinishedTaskNotifier;
import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.kernel.SiteNode;
import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext; import com.arsdigita.persistence.TransactionContext;
import com.arsdigita.runtime.CompoundInitializer; import com.arsdigita.runtime.CompoundInitializer;
import com.arsdigita.runtime.ConfigError; import com.arsdigita.runtime.ConfigError;
// import com.arsdigita.runtime.DataInitEvent; // import com.arsdigita.runtime.DataInitEvent;
import com.arsdigita.runtime.ContextInitEvent;
import com.arsdigita.runtime.ContextCloseEvent;
import com.arsdigita.runtime.DomainInitEvent; import com.arsdigita.runtime.DomainInitEvent;
import com.arsdigita.util.Assert; import com.arsdigita.util.Assert;
import com.arsdigita.web.Application; import com.arsdigita.web.Application;
@ -49,6 +51,9 @@ import org.apache.log4j.Logger;
// changes as possible. // changes as possible.
// In a second step a restructure of the code will be done. // 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! * 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 */ /** Creates a s_logging category with name = to the full name of class */
private static Logger s_log = Logger.getLogger(Initializer.class); private static Logger s_log = Logger.getLogger(Initializer.class);
/** Local configuration object LoaderConfig containing immutable parameters /** Local configuration object ContentSectionConfig containing parameters
after installation. */ which may be changed each system startup. */
// private static final LoaderConfig s_conf = LoaderConfig.getConfig(); // private static final LoaderConfig s_conf = LoaderConfig.getConfig();
private static final LoaderConfig s_conf = new LoaderConfig(); private static final LoaderConfig s_conf = new LoaderConfig();
@ -92,6 +97,7 @@ public class Initializer extends CompoundInitializer {
// */ // */
// public void init(DataInitEvent evt) { // public void init(DataInitEvent evt) {
// } // }
/** /**
* Initializes domain-coupling machinery, usually consisting of * Initializes domain-coupling machinery, usually consisting of
* registering object instantiators and observers. * 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. // If super is not invoked, various other cms sub-initializer may not run.
super.init(evt); 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(); * loadAlertPrefs loads a list of workflow tasks and associated events
txn.beginTxn(); * from configuration file and fills a hashmap. No database operation.
ContentSectionSetup.setupContentSectionAppType(); * 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"); 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 * @return
*/ */
private ContentSection retrieveContentSection(String name) { private final Timer startNotifierTask(
BigDecimal rootNodeID = SiteNode.getRootSiteNode().getID(); ContentSection section,
SiteNode node = null; Boolean sendOverdue, Integer duration,
try { Integer alertInterval, Integer max) {
node = SiteNode.getSiteNode("/" + name); Timer unfinished = null;
} catch (DataObjectNotFoundException ex) { if (sendOverdue.booleanValue()) {
throw new ConfigError( if (duration == null || alertInterval == null || max == null) {
(String) GlobalizationUtil.globalize( s_log.info("Not sending overdue task alerts, " +
"cms.installer.root_site_node_missing").localize() + ex ); "required initialization parameters were not specified");
} return null;
ContentSection section = null; }
if ( rootNodeID.equals(node.getID()) ) { // start the Timer as a daemon, so it doesn't keep the JVM from exiting
// This instance does not exist yet. unfinished = new Timer(true);
section = createSection(name); 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 { } else {
try { s_log.info("Not sending overdue task alerts");
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());
}
} }
// setup.registerRoles((List)m_conf.getParameter(ROLES)); return unfinished;
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;
} }
} }

View File

@ -1,3 +1,4 @@
// com/arsdigita/cms/contentsection/enterprise.init
// CMS initialization file // CMS initialization file
// //
// $Id: enterprise.init 2070 2010-01-28 08:47:41Z pboy $ // $Id: enterprise.init 2070 2010-01-28 08:47:41Z pboy $

View File

@ -119,22 +119,24 @@ public final class ContentCenterSetup {
/** /**
* Creates the CMS package type if it does not already exist. * Creates the CMS package type if it does not already exist.
*
* Actually: Creates the PackageType contentsection!
*/ */
private static void setupCMSPackage() { 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..."); s_log.info("Creating the CMS package type...");
PackageType type = PackageType.create // PackageType type = PackageType.create
(PACKAGE_KEY, "Content Management System", "Content Management Systems", // (PACKAGE_KEY, "Content Management System", "Content Management Systems",
"http://cms-java.arsdigita.com/"); // "http://cms-java.arsdigita.com/");
type.setDispatcherClass(DISPATCHER_CLASS); // type.setDispatcherClass(DISPATCHER_CLASS);
//type.addListener(LISTENER_CLASS); // //type.addListener(LISTENER_CLASS);
// Register a stylesheets to the CMS package. // Register a stylesheets to the CMS package.
Stylesheet ss = Stylesheet.createStylesheet(STYLESHEET); // Stylesheet ss = Stylesheet.createStylesheet(STYLESHEET);
ss.save(); // ss.save();
type.addStylesheet(ss); // type.addStylesheet(ss);
type.save(); // type.save();
createPrivileges(); 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() { private static void createPrivileges() {

View File

@ -387,6 +387,10 @@ public final class ContentSectionSetup {
return null; return null;
} }
/**
* For the content section to be created create a role whose member will
* receive alerts.
*/
public void registerAlerts() { public void registerAlerts() {
Role alert = m_section.getStaffGroup().createRole("Alert Recipient"); Role alert = m_section.getStaffGroup().createRole("Alert Recipient");
alert.setDescription("Receive alerts regarding expiration of pubished content"); alert.setDescription("Receive alerts regarding expiration of pubished content");
@ -602,6 +606,10 @@ public final class ContentSectionSetup {
} }
} }
/**
*
* @param tasks
*/
public void loadAlertPrefs(List tasks) { public void loadAlertPrefs(List tasks) {
if (tasks == null) { if (tasks == null) {
// fallback to default com.arsdigita.cms.default_task_alerts registry parameter // fallback to default com.arsdigita.cms.default_task_alerts registry parameter

View File

@ -55,21 +55,20 @@ public class Initializer extends CompoundInitializer {
/** Creates a s_logging category with name = to the full name of class */ /** Creates a s_logging category with name = to the full name of class */
private static Logger s_log = Logger.getLogger(Initializer.class); private static Logger s_log = Logger.getLogger(Initializer.class);
// private static PublishToFileConfig s_conf= PublishToFileConfig.getConfig();
private static final LoaderConfig s_conf = new LoaderConfig(); private static final LoaderConfig s_conf = new LoaderConfig();
// LoaderConfig conf = LoaderConfig.getConfig(); // Verursacht aktuell eine Exception "no such contgext"
// static { // requirred to actually read the config file!
// As an example // s_conf.load();
// private static final ContentSectionConfig s_config = new ContentSectionConfig();
// static {
// s_config.load();
// } // }
/**
* Constructor
*/
public Initializer() { public Initializer() {
//final String url = RuntimeConfig.getConfig().getJDBCURL(); //final String url = RuntimeConfig.getConfig().getJDBCURL();
//final int database = DbHelper.getDatabaseFromURL(url); //final int database = DbHelper.getDatabaseFromURL(url);
s_log.debug("CMS.installer.Initializer.(Constructor) completed");
} }
// /** // /**

View File

@ -36,6 +36,8 @@ import java.util.Iterator;
// import java.util.List; // import java.util.List;
import java.util.Timer; import java.util.Timer;
// import org.apache.log4j.Logger;
/** /**
* <p>Initializes a content section, registering a default * <p>Initializes a content section, registering a default
* workflow, lifecycle & roles and adding the content types * 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 // Temporär: Einbinden des neuen Parameter Systems
private static final LoaderConfig s_conf = new LoaderConfig(); 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. // Required to actually load the parameter file.
// Aktuell: wenn man das aktiviert, gibt's einen Fehler: Kontext existiert // 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; private static Timer s_unfinishedTimer;
public SectionLegacyInitializer() throws InitializationException { public SectionLegacyInitializer() throws InitializationException {
s_log.debug("CMS.installer.SectionLegacyInitializer.(Constructor) invoked");
// m_conf.initParameter(NAME, // m_conf.initParameter(NAME,
// "The name of the content section", // "The name of the content section",
// String.class); // String.class);
@ -132,6 +131,7 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ
// m_conf.initParameter(TEMPLATE_RESOLVER_CLASS, // m_conf.initParameter(TEMPLATE_RESOLVER_CLASS,
// "The TemplateResolver class to use for the section (defaults to DefaultTemplateResolver)", // "The TemplateResolver class to use for the section (defaults to DefaultTemplateResolver)",
// String.class); // String.class);
s_log.debug("CMS.installer.SectionLegacyInitializer.(Constructor) completed");
} }
// required by parent class. // required by parent class.
@ -142,6 +142,7 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ
protected void doStartup() { protected void doStartup() {
s_log.debug("CMS.installer.SectionLegacyInitializer.doStartup() invoked");
// Create and mount the demo content section if it does not exist. // Create and mount the demo content section if it does not exist.
// String name = (String) m_conf.getParameter(NAME); // String name = (String) m_conf.getParameter(NAME);
@ -164,7 +165,9 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ
} else { } else {
s_log.info("Installing " + name + " at " + s_log.info("Installing " + name + " at " +
sitemapEntry); 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); ContentSection section = retrieveContentSection(name);
@ -172,20 +175,31 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ
ContentSectionSetup setup = new ContentSectionSetup(section); ContentSectionSetup setup = new ContentSectionSetup(section);
// setup.loadAlertPrefs((List) m_conf.getParameter(TASK_ALERTS)); // 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 // s_unfinishedTimer = setup.startNotifierTask
// ((Boolean) m_conf.getParameter(SEND_OVERDUE_ALERTS), // ((Boolean) m_conf.getParameter(SEND_OVERDUE_ALERTS),
// (Integer) m_conf.getParameter(TASK_DURATION), // (Integer) m_conf.getParameter(TASK_DURATION),
// (Integer) m_conf.getParameter(OVERDUE_ALERT_INTERVAL), // (Integer) m_conf.getParameter(OVERDUE_ALERT_INTERVAL),
// (Integer) m_conf.getParameter(MAX_ALERTS)); // (Integer) m_conf.getParameter(MAX_ALERTS));
s_unfinishedTimer = setup.startNotifierTask
(s_conf.getSendOverdueAlerts(), // Commented out in LoadereConfig because not a Loader task. So commented
s_conf.getTaskDuration(), // out here. If SectionLegacyInitializer should ever be used again, a
s_conf.getOverdueAlertInterval(), // defferent config file (section initializer config) should be used here
s_conf.getMaxAlerts()); // s_unfinishedTimer = setup.startNotifierTask
// (s_conf.getSendOverdueAlerts(),
// s_conf.getTaskDuration(),
// s_conf.getOverdueAlertInterval(),
// s_conf.getMaxAlerts());
txn.commitTxn(); txn.commitTxn();
s_log.debug("CMS.installer.SectionLegacyInitializer.doStartup() completed");
} }
/** /**
@ -193,6 +207,11 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ
* @param name * @param name
* @return * @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) { private ContentSection retrieveContentSection(String name) {
BigDecimal rootNodeID = SiteNode.getRootSiteNode().getID(); BigDecimal rootNodeID = SiteNode.getRootSiteNode().getID();
SiteNode node = null; SiteNode node = null;
@ -230,6 +249,9 @@ public class SectionLegacyInitializer extends com.arsdigita.kernel.BaseInitializ
/** /**
* Install the CMS Demo. * Install the CMS Demo.
*/ */
// Moved into Loader
private ContentSection createSection(String name) { private ContentSection createSection(String name) {
s_log.info("Creating content section on /" + name); s_log.info("Creating content section on /" + name);

View File

@ -72,7 +72,8 @@ public class WorkspaceInstaller implements PackageEventListener {
* *
* @return The Content Center package type * @return The Content Center package type
*/ */
protected PackageType createPackageType() // protected PackageType createPackageType()
public PackageType createPackageType()
throws DataObjectNotFoundException { throws DataObjectNotFoundException {
PackageType type = PackageType.create PackageType type = PackageType.create
@ -98,7 +99,8 @@ public class WorkspaceInstaller implements PackageEventListener {
* *
* @return The Content Center package instance * @return The Content Center package instance
*/ */
protected PackageInstance createPackageInstance() // protected PackageInstance createPackageInstance()
public PackageInstance createPackageInstance()
throws DataObjectNotFoundException { throws DataObjectNotFoundException {
PackageType type = PackageType type =
@ -117,7 +119,8 @@ public class WorkspaceInstaller implements PackageEventListener {
* @param location The location of the Content Center * @param location The location of the Content Center
* @return The SiteNode where the Content Center is mounted at * @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) { String location) {
SiteNode node = SiteNode node =
SiteNode.createSiteNode(location, SiteNode.getRootSiteNode()); SiteNode.createSiteNode(location, SiteNode.getRootSiteNode());

View File

@ -41,6 +41,14 @@ import com.arsdigita.portal.PortletType;
import org.apache.log4j.Logger; 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 public class Initializer
extends BaseInitializer { extends BaseInitializer {

View File

@ -30,8 +30,8 @@ import java.util.List;
import com.arsdigita.categorization.Category; import com.arsdigita.categorization.Category;
import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentType; import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.search.ContentTypeFilterSpecification; // import com.arsdigita.cms.search.ContentTypeFilterSpecification;
import com.arsdigita.cms.search.ContentTypeFilterType; // import com.arsdigita.cms.search.ContentTypeFilterType;
import com.arsdigita.kernel.PartyCollection; import com.arsdigita.kernel.PartyCollection;
import com.arsdigita.persistence.DataQuery; import com.arsdigita.persistence.DataQuery;
import com.arsdigita.persistence.Filter; import com.arsdigita.persistence.Filter;

View File

@ -365,7 +365,7 @@ public class CMSTask extends UserTask {
typeLabel = typeLabel.trim(); typeLabel = typeLabel.trim();
operation = operation.trim(); operation = operation.trim();
// get the typeLabel -> list-of-operations map for this section // 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) { if (typeMap == null) {
typeMap = new HashMap(5); typeMap = new HashMap(5);
s_alerts.put(section.getID(), typeMap); s_alerts.put(section.getID(), typeMap);

View File

@ -77,9 +77,9 @@ public class UnfinishedTaskNotifier extends TimerTask {
m_maxNotifications = maxNotifications; m_maxNotifications = maxNotifications;
s_log.debug("Created UnfinishedTaskNotifier for section " + section.getName()); s_log.debug("Created UnfinishedTaskNotifier for section " + section.getName());
s_log.debug("Sending notifications for tasks over " + m_unfinishedInterval + s_log.debug("Sending notifications for tasks over " + m_unfinishedInterval +
" milliseconds old, with repeat notifications every " + m_notificationInterval + " milliseconds old, with repeat notifications every " +
" milliseconds, with a maxmimum of " + m_maxNotifications + " notifications going out for" + m_notificationInterval + " milliseconds, with a maxmimum of " +
" every task."); m_maxNotifications + " notifications going out for every task.");
} }
@ -94,7 +94,8 @@ public class UnfinishedTaskNotifier extends TimerTask {
} }
}.run(); }.run();
} catch (Throwable t) { } 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); throw new UncheckedWrapperException(t);
} }
} }
@ -116,7 +117,8 @@ public class UnfinishedTaskNotifier extends TimerTask {
unfinishedTasks.setParameter("sectionID", m_sectionID); unfinishedTasks.setParameter("sectionID", m_sectionID);
// we want to do the Date arithmetic in Java, since we set // we want to do the Date arithmetic in Java, since we set
// the Date from Java initially // 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()) { while (unfinishedTasks.next()) {
CMSTask task = (CMSTask) DomainObjectFactory CMSTask task = (CMSTask) DomainObjectFactory
@ -126,9 +128,11 @@ public class UnfinishedTaskNotifier extends TimerTask {
Date lastSentDate = notification.getLastNotificationDate(); Date lastSentDate = notification.getLastNotificationDate();
int numSent = notification.getNumNotifications(); int numSent = notification.getNumNotifications();
if ((lastSentDate == null || if ((lastSentDate == null ||
lastSentDate.before(new Date(System.currentTimeMillis() - m_notificationInterval))) lastSentDate.before(new Date(System.currentTimeMillis() -
m_notificationInterval)))
&& m_maxNotifications > numSent) { && 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 // make sure we record that we've sent this notification first
notification.incrNumNotifications(); notification.incrNumNotifications();
notification.save(); notification.save();
@ -138,7 +142,8 @@ public class UnfinishedTaskNotifier extends TimerTask {
txn.commitTxn(); txn.commitTxn();
committedTxn = true; committedTxn = true;
s_log.debug("UnfinishedTaskNotifier completed in " + (System.currentTimeMillis() - startTime) + "ms"); s_log.debug("UnfinishedTaskNotifier completed in " +
(System.currentTimeMillis() - startTime) + "ms");
} finally { } finally {
if (!committedTxn) { if (!committedTxn) {
txn.abortTxn(); txn.abortTxn();