From efa88c40a7e340001027891bb243b08dc23a4ba1 Mon Sep 17 00:00:00 2001 From: pb Date: Wed, 27 Oct 2010 23:28:15 +0000 Subject: [PATCH] =?UTF-8?q?Weiterer=20Schritt=20Ausbau=20alter=20Initialis?= =?UTF-8?q?ierungscode=20aus=20ccm-cms:=20Umgestellt=20auf=20content-secti?= =?UTF-8?q?on=20Initializer,=20alten=20Code=20entfernt,=20Starten=20und=20?= =?UTF-8?q?Stopppen=20des=20Background=20Thread=20eingebaut.=20Es=20fehlt?= =?UTF-8?q?=20noch:=20Erstellen=20einer=20zus=C3=A4tzlichen=20content=20se?= =?UTF-8?q?ction.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.libreccm.org/ccm/trunk@587 8810af33-2d31-482b-a856-94f89814c4df --- ccm-cms/src/ccm-cms.config | 4 + ccm-cms/src/com/arsdigita/cms/CMS.java | 38 +- ccm-cms/src/com/arsdigita/cms/CMSConfig.java | 643 ++++++++++------ .../cms/CMSConfig_parameter.properties | 30 +- .../src/com/arsdigita/cms/ContentSection.java | 258 ++++--- .../src/com/arsdigita/cms/Initializer.java | 43 +- ccm-cms/src/com/arsdigita/cms/Loader.java | 205 ++++-- .../src/com/arsdigita/cms/LoaderConfig.java | 147 ++-- .../cms/LoaderConfig_parameter.properties | 25 + .../src/com/arsdigita/cms/WorkspaceSetup.java | 140 ++++ .../contentsection/ContentSectionConfig.java | 356 ++++++++- .../contentsection/ContentSectionSetup.java | 696 ++++++++++++++++++ .../cms/contentsection/Initializer.java | 218 +++--- .../dispatcher/ContentCenterDispatcher.java | 25 +- .../arsdigita/cms/dispatcher/Utilities.java | 20 +- ... => ContentCenterSetup.java.nolongerInUse} | 6 + ...=> ContentSectionSetup.java.nolongerInUse} | 5 +- ...er.java => Initializer.java.nolongerInUse} | 11 + ...ller.java => Installer.java.nolongerInUse} | 10 + ...va => ServiceInstaller.java.nolongerInUse} | 11 + ... => VersioningUpgrader.java.nolongerInUse} | 0 ... => WorkspaceInstaller.java.nolongerInUse} | 11 + .../cms/lifecycle/LifecycleDefinition.java | 1 + .../cms/ui/authoring/ItemCategoryForm.java | 5 + .../cms/ui/authoring/ItemCategoryStep.java | 6 +- .../PageClassConfigHandler.java | 2 +- .../cms/{installer => util}/Util.java | 2 +- .../com/arsdigita/cms/workflow/CMSTask.java | 7 +- .../cms/workflow/UnfinishedTaskNotifier.java | 3 + 29 files changed, 2263 insertions(+), 665 deletions(-) create mode 100644 ccm-cms/src/com/arsdigita/cms/WorkspaceSetup.java create mode 100644 ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java rename ccm-cms/src/com/arsdigita/cms/installer/{ContentCenterSetup.java => ContentCenterSetup.java.nolongerInUse} (97%) rename ccm-cms/src/com/arsdigita/cms/installer/{ContentSectionSetup.java => ContentSectionSetup.java.nolongerInUse} (99%) rename ccm-cms/src/com/arsdigita/cms/installer/{Initializer.java => Initializer.java.nolongerInUse} (92%) rename ccm-cms/src/com/arsdigita/cms/installer/{Installer.java => Installer.java.nolongerInUse} (95%) rename ccm-cms/src/com/arsdigita/cms/installer/{ServiceInstaller.java => ServiceInstaller.java.nolongerInUse} (91%) rename ccm-cms/src/com/arsdigita/cms/installer/{VersioningUpgrader.java => VersioningUpgrader.java.nolongerInUse} (100%) rename ccm-cms/src/com/arsdigita/cms/installer/{WorkspaceInstaller.java => WorkspaceInstaller.java.nolongerInUse} (93%) rename ccm-cms/src/com/arsdigita/cms/{installer => util}/PageClassConfigHandler.java (98%) rename ccm-cms/src/com/arsdigita/cms/{installer => util}/Util.java (97%) diff --git a/ccm-cms/src/ccm-cms.config b/ccm-cms/src/ccm-cms.config index 6a9c17e5c..48dfa584d 100755 --- a/ccm-cms/src/ccm-cms.config +++ b/ccm-cms/src/ccm-cms.config @@ -2,6 +2,10 @@ + + ContentSectionConfig record; it cannot be null + */ + public static final synchronized CMSConfig getInstance() { + if (s_config == null) { + s_config = new CMSConfig(); + // deprecated + // s_config.require("ccm-core/runtime.properties"); + // use instead: + // read values from the persistent storage + s_config.load(); + } + + return s_config; + } + + /** + * Storage (map) for method getAssetStepsToSkip(ContentType type) to store + * mapping of steps that are deemed irrelevant for the passid in type. + */ private static Map s_skipAssetSteps = null; - private final Parameter m_templateRootPath; - private final Parameter m_categoryAuthoringAddForm; - private final Parameter m_defaultItemTemplatePath; - private final Parameter m_defaultFolderTemplatePath; - private final Parameter m_defaultSection; - private final Parameter m_defaultItemResolverClass; - private final Parameter m_defaultTemplateResolverClass; - private final Parameter m_useSectionCategories; - private final Parameter m_itemAdapters; - private final Parameter m_useStreamlinedCreation; - private final Parameter m_dhtmlEditorConfig; - private final Parameter m_dhtmlEditorPlugins; - private final Parameter m_dhtmlEditorHiddenButtons; - private final Parameter m_hideTemplatesTab; - private final Parameter m_hideAdminTabs; - private final Parameter m_hideTimezone; - private final Parameter m_hideLaunchDate; - private final Parameter m_hideUDCTUI; - private final Parameter m_hideFolderIndexCheckbox; - private final Parameter m_defaultNotificationTime; - private final Parameter m_notifyAuthorOnLifecycle; - private final Parameter m_publishLifecycleListenerClass; - private final Parameter m_requireLaunchDate; - private final Parameter m_saveTextCleansWordTags; - private final Parameter m_hideAdditionalResourceFields; - private final Parameter m_disableFileAssetExtraction; - private final Parameter m_deleteWorkflowAfterPublication; - private final Parameter m_soonExpiredTimespanMonths; - private final Parameter m_soonExpiredTimespanDays; - private final Parameter m_defaultTaskAlerts; - private final Parameter m_unpublishedNotFound; - private final Parameter m_linksOnlyInSameSubsite; - private final Parameter m_categoryAuthoringExtension; - private final Parameter m_hideResetLifecycleLink; - private final Parameter m_scoreTitleAndKeywords; - private final Parameter m_titleWeight; - private final Parameter m_keywordWeight; - private final Parameter m_skipAssetSteps; - private final Parameter m_mandatoryDescriptions; - private final Parameter m_deleteLifecycleWhenComplete; - private final Parameter m_deleteExpiryNotificationsWhenSent; - private final Parameter m_deleteWorkflowNotificationsWhenSent; - private final Parameter m_hasContactsAuthoringStep; - private final Parameter m_categoryTreeOrdering; - private final Parameter m_hideTextAssetUploadFile; - private final Parameter m_allowContentCreateInSectionListing; - - // /////////////////////////////////////////// - // publishToFile package related parameter - // /////////////////////////////////////////// - - // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 - // private final Parameter m_disableItemPfs; - // private final Parameter m_publishToFileClass; - /** - * Do not instantiate this class directly. - * - * @see ContentSection#getConfig() - **/ - public CMSConfig() { - - m_defaultItemTemplatePath = new StringParameter - ("com.arsdigita.cms.default_item_template_path", - Parameter.REQUIRED, "/default/item.jsp"); - m_defaultFolderTemplatePath = new StringParameter - ("com.arsdigita.cms.default_folder_template_path", - Parameter.REQUIRED, "/default/folder.jsp"); - - m_linksOnlyInSameSubsite = new BooleanParameter - ("com.arsdigita.cms.browse_links_in_same_subsite_only", - Parameter.REQUIRED, new Boolean(false)); - - m_defaultTaskAlerts = new StringArrayParameter - ("com.arsdigita.cms.default_task_alerts", - Parameter.REQUIRED, new String[] { - "Authoring:enable:finish:rollback", - "Approval:enable:finish:rollback", - "Deploy:enable:finish:rollback" } - ); - - // XXX these are probably temporary parameters, as the - // item/template resolvers will be determined by the successor - // to SectionInitializer. However, it still may be useful to - // keep these for the default values. - m_defaultItemResolverClass = new SpecificClassParameter - ("com.arsdigita.cms.default_item_resolver_class", - Parameter.REQUIRED, - MultilingualItemResolver.class, - ItemResolver.class); - m_defaultTemplateResolverClass = new SpecificClassParameter - ("com.arsdigita.cms.default_template_resolver_class", - Parameter.REQUIRED, - DefaultTemplateResolver.class, - TemplateResolver.class); - - m_categoryAuthoringAddForm = new SpecificClassParameter + * Item category add form speciofies Subclass of ItemCategoryForm + * to use for the assign categories step. + * Used in c.ad.cms.ui.authoring.ItemCategoryStep + */ + private final Parameter + m_categoryAuthoringAddForm = new SpecificClassParameter ("com.arsdigita.cms.category_authoring_add_form", Parameter.REQUIRED, ItemCategoryForm.class, SimpleComponent.class); - m_templateRootPath = new StringParameter + /** + * Path for the default item template. Path is relative to the + * Template Root path. + */ + private final Parameter + m_defaultItemTemplatePath = new StringParameter + ("com.arsdigita.cms.default_item_template_path", + Parameter.REQUIRED, "/default/item.jsp"); + + /** + * Path for the default folder template. Path is relative to the + * Template Root path. + */ + private final Parameter + m_defaultFolderTemplatePath = new StringParameter + ("com.arsdigita.cms.default_folder_template_path", + Parameter.REQUIRED, "/default/folder.jsp"); + /** + * Path for the default template folder. Path is relative to webapp root + */ + private final Parameter + m_templateRootPath = new StringParameter ("com.arsdigita.cms.template_root_path", Parameter.REQUIRED, "/packages/content-section/templates"); - // XXX: temporary parameter. will be removed when - // SectionInitializer is replaced with a separate Section - // loader app. - m_useSectionCategories = new BooleanParameter - ("com.arsdigita.cms.use_section_categories", - Parameter.REQUIRED, new Boolean(true)); - - // URL resource: protocol handler removal: START + + // URL resource: protocol handler removal: START // remove: // try { // m_itemAdapters = new URLParameter @@ -223,21 +173,32 @@ public final class CMSConfig extends AbstractConfig { // throw new UncheckedWrapperException("Cannot parse URL", ex); // } // ADD: + /** + * Item Adapters File, path to an XML resource containing adapter + * specifications. Path is relative to webapp root. + */ + private final Parameter m_itemAdapters = new ResourceParameter ("com.arsdigita.cms.item_adapters", Parameter.REQUIRED, "/WEB-INF/resources/cms-item-adapters.xml"); // URL resource: protocol handler removal: END - - m_defaultSection = new StringParameter - ("com.arsdigita.cms.default_content_section", - Parameter.REQUIRED, "content"); - m_useStreamlinedCreation = new BooleanParameter + /** + * Use streamlined content creation: upon item creation, + * automatically open authoring steps and forward to the next step + */ + private final Parameter + m_useStreamlinedCreation = new BooleanParameter ("com.arsdigita.cms.use_streamlined_creation", - Parameter.REQUIRED, new Boolean(false)); + Parameter.REQUIRED, new Boolean(true)); - m_dhtmlEditorConfig = new DHTMLEditorConfigParameter + /** + * DHTML Editor Configuration for use in CMS module, lists the + * config object name and Javascript source location for its definition. + */ + private final Parameter + m_dhtmlEditorConfig = new DHTMLEditorConfigParameter ("com.arsdigita.cms.dhtml_editor_config", Parameter.REQUIRED, new DHTMLEditor.Config( "XinhaConfig", @@ -253,190 +214,397 @@ public final class CMSConfig extends AbstractConfig { // be accessable by other modules which use DHTMLeditor. // Would be bad style to configure a cms specific parameter in core. - m_dhtmlEditorPlugins = new StringArrayParameter + /** + * Defines which plugins to use, e.g.TableOperations,CSS + * Format: [string,string,string] + */ + private final Parameter + m_dhtmlEditorPlugins = new StringArrayParameter ("com.arsdigita.cms.dhtml_editor_plugins", Parameter.OPTIONAL, null); - m_dhtmlEditorHiddenButtons = new StringArrayParameter + /** + * Prevent undesirable functions from being made available, + * eg images should only be added through the cms methods. + */ + private final Parameter + m_dhtmlEditorHiddenButtons = new StringArrayParameter ("com.arsdigita.cms.dhtml_editor_hidden_buttons", Parameter.OPTIONAL, null); - - m_hideTemplatesTab = new BooleanParameter - ("com.arsdigita.cms.hide_templates_tab", - Parameter.REQUIRED, new Boolean(false)); - m_hideAdminTabs = new BooleanParameter + /** + * Hide section admin tabs from users without administrative rights. + */ + private final Parameter + m_hideAdminTabs = new BooleanParameter ("com.arsdigita.cms.hide_admin_tabs", Parameter.REQUIRED, new Boolean(false)); - m_hideTimezone = new BooleanParameter - ("com.arsdigita.cms.hide_timezone", - Parameter.REQUIRED, new Boolean(false)); - - m_hideLaunchDate = new BooleanParameter - ("com.arsdigita.cms.hide_launch_date", - Parameter.REQUIRED, new Boolean(true)); - - m_requireLaunchDate = new BooleanParameter - ("com.arsdigita.cms.require_launch_date", - Parameter.REQUIRED, new Boolean(false)); - - m_hideUDCTUI = new BooleanParameter - ("com.arsdigita.cms.hide_udct_ui", - Parameter.REQUIRED, new Boolean(false)); - - m_hideFolderIndexCheckbox = new BooleanParameter + /** + * Hide Folder Index Checkbox from folder view + */ + private final Parameter + m_hideFolderIndexCheckbox = new BooleanParameter ("com.arsdigita.cms.hide_folder_index_checkbox", Parameter.REQUIRED, new Boolean(false)); - m_defaultNotificationTime = new IntegerParameter - ("com.arsdigita.cms.default_notification_time", - Parameter.REQUIRED, new Integer(0)); + /** + * Hide launch date parameter on all forms and displays where it's used. + */ + private final Parameter + m_hideLaunchDate = new BooleanParameter + ("com.arsdigita.cms.hide_launch_date", + Parameter.REQUIRED, new Boolean(true)); + /** + * Require the launch date parameter to be set by the content author. + */ + private final Parameter + m_requireLaunchDate = new BooleanParameter + ("com.arsdigita.cms.require_launch_date", + Parameter.REQUIRED, new Boolean(false)); + /** + * Hide the templates tab on the item admin page. + */ + private final Parameter + m_hideTemplatesTab = new BooleanParameter + ("com.arsdigita.cms.hide_templates_tab", + Parameter.REQUIRED, new Boolean(false)); - m_publishLifecycleListenerClass = new StringParameter + /** + * Hide the upload file link in the editing of a text asset. + */ + private final Parameter + m_hideTextAssetUploadFile = new BooleanParameter + ("com.arsdigita.cms.hide_text_asset_upload_file", + Parameter.REQUIRED, + new Boolean(false)); + + /** + * Hide timezone labels (if, for example, all users will be in the + * same timezone and such information would be unnecessary) + */ + private final Parameter + m_hideTimezone = new BooleanParameter + ("com.arsdigita.cms.hide_timezone", + Parameter.REQUIRED, new Boolean(false)); + + /** + * Hide User Defined Content Types UI + */ + private final Parameter + m_hideUDCTUI = new BooleanParameter + ("com.arsdigita.cms.hide_udct_ui", + Parameter.REQUIRED, new Boolean(false)); + + + /** + * Specifies the name of the class to use as a PublishLifecycleListener + */ + private final Parameter + m_publishLifecycleListenerClass = new StringParameter ("com.arsdigita.cms.publish_lifecycle_listener_class", Parameter.OPTIONAL, PublishLifecycleListener.class.getName()); - m_notifyAuthorOnLifecycle = new BooleanParameter - ("com.arsdigita.cms.notify_author_on_lifecycle", - Parameter.OPTIONAL, new Boolean(true)); - m_saveTextCleansWordTags = new BooleanParameter + /** + * Wether the Wysiwyg editor should clear the text of MSWord tags, + * everytime the user clicks on 'Save' + */ + private final Parameter + m_saveTextCleansWordTags = new BooleanParameter ("com.arsdigita.cms.save_text_cleans_word_tags", Parameter.OPTIONAL, new Boolean(false)); - m_hideAdditionalResourceFields = new BooleanParameter + /** + * Hide Additional Resource Fields on RelatedLinkPropertyForm + */ + private final Parameter + m_hideAdditionalResourceFields = new BooleanParameter ("com.arsdigita.cms.contentassets.ui."+ "RelatedLinkPropertyForm.hideAdditionalResourceFields", Parameter.REQUIRED, new Boolean(false)); - m_disableFileAssetExtraction = new BooleanParameter + /** + * Get the search indexing not to process FileAssets, + * eg to avoid PDF slowdowns + */ + private final Parameter + m_disableFileAssetExtraction = new BooleanParameter ("com.arsdigita.cms.search.disableFileAssetExtraction", Parameter.REQUIRED, new Boolean(false)); - m_deleteWorkflowAfterPublication = new BooleanParameter + /** + * Whether an item's workflow should be deleted, once the item + * has been (re)published + */ + private final Parameter + m_deleteWorkflowAfterPublication = new BooleanParameter ("com.arsdigita.cms.delete_workflow_after_publication", Parameter.REQUIRED, new Boolean(true)); - m_soonExpiredTimespanDays = new IntegerParameter + /** + * Defines the number of days ahead that are covered in the + * 'Soon Expired' tab + */ + private final Parameter + m_soonExpiredTimespanDays = new IntegerParameter ("com.arsdigita.cms.soon_expired_timespan_days", - Parameter.REQUIRED, new Integer(1)); - - m_soonExpiredTimespanMonths = new IntegerParameter + Parameter.REQUIRED, new Integer(14)); + + /** + * Defines the number of months ahead that are covered in the + * 'Soon Expired' tab + */ + private final Parameter + m_soonExpiredTimespanMonths = new IntegerParameter ("com.arsdigita.cms.soon_expired_timespan_months", - Parameter.REQUIRED, new Integer(0)); - - m_unpublishedNotFound = new BooleanParameter + Parameter.REQUIRED, new Integer(1)); + + /** + * Does a redirect to the unpublished item generate not found error? + */ + private final Parameter + m_unpublishedNotFound = new BooleanParameter ("com.arsdigita.cms.unpublished_not_found", Parameter.REQUIRED, new Boolean(true)); - m_categoryAuthoringExtension = new SpecificClassParameter + /** + * Links created through browse interfaces should only be within the + * same subsite + */ + private final Parameter + m_linksOnlyInSameSubsite = new BooleanParameter + ("com.arsdigita.cms.browse_links_in_same_subsite_only", + Parameter.REQUIRED, new Boolean(false)); + + /** + * Item category step extension hook: Subclass of ItemCategoryExtension + * which adds extension actions for the category authoring step + */ + private final Parameter + m_categoryAuthoringExtension = new SpecificClassParameter ("com.arsdigita.cms.category_authoring_extension", Parameter.REQUIRED, ItemCategoryExtension.class, ItemCategoryExtension.class); - m_hideResetLifecycleLink = new BooleanParameter + /** + * Link available to reset lifecycle on republish. If false don't display + * the link otherwise display. + */ + private final Parameter + m_hideResetLifecycleLink = new BooleanParameter ("com.arsdigita.cms.hide_reset_lifecycle_link", Parameter.OPTIONAL, new Boolean(true)); - m_keywordWeight = new IntegerParameter - ("com.arsdigita.cms.search.intermedia.keyword_weight", - Parameter.OPTIONAL, - new Integer(1)); - - m_titleWeight = new IntegerParameter - ("com.arsdigita.cms.search.intermedia.title_weight", - Parameter.OPTIONAL, - new Integer(1)); - - m_scoreTitleAndKeywords = new BooleanParameter + /** + * Whether to include INPATH operators to contains clause in intermedia search + */ + private final Parameter + m_scoreTitleAndKeywords = new BooleanParameter ("com.arsdigita.cms.search.score_title_and_keywords", Parameter.OPTIONAL, Boolean.FALSE); /** - * each entry in the list is a : separated pair. The first string - * is the className for the type (refer to classname column in contenttypes table - * eg com.arsdigita.cms.contenttypes.MultiPartArticle + * Title Weight, the relative weight given to title element within + * cms:item when ranking search results (only used by interMedia) + */ + private final Parameter + m_titleWeight = new IntegerParameter + ("com.arsdigita.cms.search.intermedia.title_weight", + Parameter.OPTIONAL, + new Integer(1)); + + /** + * Keyword Weight, the relative weight given to the dcKeywords element + * within dublinCore element within cms:item element when ranking + * search results (only used by interMedia) + */ + private final Parameter + m_keywordWeight = new IntegerParameter + ("com.arsdigita.cms.search.intermedia.keyword_weight", + Parameter.OPTIONAL, + new Integer(1)); + + /** + * Asset steps to skip, specify asset steps that are not relevant for + * specific content types. + * Each entry in the list is a : separated pair. The first string + * is the className for the type (refer to classname column in contenttypes + * table eg com.arsdigita.cms.contenttypes.MultiPartArticle * Second string is the name of the bebop step component * eg com.arsdigita.cms.contenttypes.ui.ImageStep */ - m_skipAssetSteps = new StringArrayParameter - ("com.arsdigita.cms.skip_asset_steps", - Parameter.OPTIONAL, - null); - - m_mandatoryDescriptions = new BooleanParameter + private final Parameter + m_skipAssetSteps = new StringArrayParameter + ("com.arsdigita.cms.skip_asset_steps", + Parameter.OPTIONAL, + null); + /** + * Mandatory Descriptions Content types may refer to this to decide + * whether to validate against empty descriptions + */ + private final Parameter + m_mandatoryDescriptions = new BooleanParameter ("com.arsdigita.cms.mandatory_descriptions", Parameter.OPTIONAL, new Boolean(false)); - - m_deleteExpiryNotificationsWhenSent = new BooleanParameter - ("com.arsdigita.cms.delete_expiry_notification_when_sent", + + /** + * Delete Finished Lifecycles. Decide whether lifecycles and their phases + * should be deleted from the system when finished. + */ + private final Parameter + m_deleteLifecycleWhenComplete = new BooleanParameter + ("com.arsdigita.cms.delete_lifecycle_when_complete", Parameter.OPTIONAL, new Boolean(false)); - m_deleteWorkflowNotificationsWhenSent = new BooleanParameter - ("com.arsdigita.cms.delete_workflow_notification_when_sent", - Parameter.OPTIONAL, new Boolean(false)); - - m_categoryTreeOrdering = new EnumerationParameter - ("com.arsdigita.cms.category_tree_order", - Parameter.OPTIONAL, Category.SORT_KEY ); - - // 2 valid values at the moment - enumeration used rather than boolean - // in case other possible orders are deemed valid - ((EnumerationParameter)m_categoryTreeOrdering).put("SortKey", Category.SORT_KEY ); - ((EnumerationParameter)m_categoryTreeOrdering).put("Alphabetical", Category.NAME); - - m_hasContactsAuthoringStep = new BooleanParameter + /** + * Contacts for content items. Allows you to add a Contact authoring step + * to all items + */ + private final Parameter + m_hasContactsAuthoringStep = new BooleanParameter ("com.arsdigita.cms.has_contacts_authoring_step", Parameter.REQUIRED, new Boolean(false)); - - m_hideTextAssetUploadFile = new BooleanParameter - ("com.arsdigita.cms.hide_text_asset_upload_file", - Parameter.REQUIRED, - new Boolean(false)); - - m_allowContentCreateInSectionListing = new BooleanParameter + + /** + * Ordering for nodes in assign category tree. Decide whether entries + * should be ordered alphabetically or according to sort key + * (maintained in category admin tab in content centre) + * SortKey|Alphabetical is initialized in constructor! See below. + */ + private final Parameter + m_categoryTreeOrdering = new EnumerationParameter + ("com.arsdigita.cms.category_tree_order", + Parameter.OPTIONAL, Category.SORT_KEY ); + + + /** + * Allow content creation in section listing. Allows you to turn off + * the ability to create content in the section listing + */ + private final Parameter + m_allowContentCreateInSectionListing = new BooleanParameter ("com.arsdigita.cms.allow_content_create_in_section_listing", Parameter.REQUIRED, new Boolean(true)); - // Lifecycle package - m_deleteLifecycleWhenComplete = new BooleanParameter - ("com.arsdigita.cms.delete_lifecycle_when_complete", + // /////////////////////////////////////////// + // Notification related parameters + // /////////////////////////////////////////// + + /** + * Delete Sent Workflow Notifications. Decide whether successfully sent + * notifications and messages should be deleted from the system + */ + private final Parameter + m_deleteWorkflowNotificationsWhenSent = new BooleanParameter + ("com.arsdigita.cms.delete_workflow_notification_when_sent", Parameter.OPTIONAL, new Boolean(false)); - // /////////////////////////////////////////// - // publishToFile package related parameter - // /////////////////////////////////////////// + /** + * Decide whether successfully sent notifications and messages + * should be deleted from the system + */ + private final Parameter + m_deleteExpiryNotificationsWhenSent = new BooleanParameter + ("com.arsdigita.cms.delete_expiry_notification_when_sent", + Parameter.OPTIONAL, new Boolean(false)); + /** + * Amount of time (in hours) before the expiration of a content item + * that users in the Alert Recipient role are alerted via email + */ + private final Parameter + m_defaultNotificationTime = new IntegerParameter + ("com.arsdigita.cms.default_notification_time", + Parameter.REQUIRED, new Integer(0)); - // XXX: temporary parameter. will be removed when MapParameter - // works and the p2fs initializer is converted away from the - // legacy init - // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 - // m_disableItemPfs = new BooleanParameter - // ("com.arsdigita.cms.disable_item_pfs", - // Parameter.REQUIRED, new Boolean(false)); - // - // m_publishToFileClass = new SpecificClassParameter - // ("com.arsdigita.cms.publish_to_file_class", - // Parameter.REQUIRED, - // PublishToFile.class, - // PublishToFileListener.class); + /** + * Wether a content item's author should be notified + * by the item's LifecycleListener; defaults to true + */ + private final Parameter + m_notifyAuthorOnLifecycle = new BooleanParameter + ("com.arsdigita.cms.notify_author_on_lifecycle", + Parameter.OPTIONAL, new Boolean(true)); + + // //////////////////////////////////////////////////// + // Content Center (Workspace) config related parameters + // //////////////////////////////////////////////////// + /** + * XML Mapping of the content center tabs to URLs, see + * {@link ContentCenterDispatcher} + */ + private final StringParameter + m_contentCenterMap = new StringParameter( + "com.arsdigita.cms.loader.content_center_map", + Parameter.REQUIRED, + "/WEB-INF/resources/content-center-map.xml"); + + + // /////////////////////////////////////////// + // Content Section config related parameters + // /////////////////////////////////////////// + private final Parameter + m_defaultSection = new StringParameter + ("com.arsdigita.cms.default_content_section", + Parameter.REQUIRED, "content"); + + // /////////////////////////////////////////// + // Content Section creation parameters + // XXX these are probably temporary parameters, as the + // item/template resolvers will be determined by the successor + // to SectionInitializer. However, it still may be useful to + // keep these for the default values. + // /////////////////////////////////////////// + private final Parameter + m_defaultItemResolverClass = new SpecificClassParameter + ("com.arsdigita.cms.default_item_resolver_class", + Parameter.REQUIRED, + MultilingualItemResolver.class, + ItemResolver.class); + + private final Parameter + m_defaultTemplateResolverClass = new SpecificClassParameter + ("com.arsdigita.cms.default_template_resolver_class", + Parameter.REQUIRED, + DefaultTemplateResolver.class, + TemplateResolver.class); + + + // /////////////////////////////////////////// + // publishToFile package related parameter + // /////////////////////////////////////////// + + // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 + // private final Parameter m_disableItemPfs; + // private final Parameter m_publishToFileClass; + + + /** + * Constructor, but do NOT instantiate this class directly. + * + * @see ContentSection#getConfig() + **/ + public CMSConfig() { + + // Initialize m_categoryTreeOrdering parameter here! + // 2 valid values at the moment - enumeration used rather than boolean + // in case other possible orders are deemed valid + ((EnumerationParameter)m_categoryTreeOrdering).put("SortKey", Category.SORT_KEY ); + ((EnumerationParameter)m_categoryTreeOrdering).put("Alphabetical", Category.NAME); + + register(m_templateRootPath); register(m_defaultItemTemplatePath); register(m_defaultFolderTemplatePath); - register(m_defaultItemResolverClass); - register(m_defaultTemplateResolverClass); register(m_categoryAuthoringAddForm); - register(m_useSectionCategories); register(m_itemAdapters); - register(m_defaultSection); register(m_useStreamlinedCreation); register(m_dhtmlEditorConfig); register(m_dhtmlEditorPlugins); @@ -457,7 +625,6 @@ public final class CMSConfig extends AbstractConfig { register(m_deleteWorkflowAfterPublication); register(m_soonExpiredTimespanMonths); register(m_soonExpiredTimespanDays); - register(m_defaultTaskAlerts); register(m_unpublishedNotFound); register(m_linksOnlyInSameSubsite); register(m_categoryAuthoringExtension); @@ -475,6 +642,17 @@ public final class CMSConfig extends AbstractConfig { register(m_hideTextAssetUploadFile); register(m_allowContentCreateInSectionListing); + // Content Center (Workspace) config related parameters + register(m_contentCenterMap); + + // Content Section config related parameters + register(m_defaultSection); + + // Content Section creation parameters + register(m_defaultItemResolverClass); + register(m_defaultTemplateResolverClass); + + // publishToFile package related parameter // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 // register(m_disableItemPfs); // register(m_publishToFileClass); @@ -506,10 +684,6 @@ public final class CMSConfig extends AbstractConfig { return (Class) get(m_categoryAuthoringAddForm); } - public final boolean getUseSectionCategories() { - return ((Boolean) get(m_useSectionCategories)).booleanValue(); - } - public final InputStream getItemAdapters() { // URL resource: protocol handler removal: START // remove: @@ -609,10 +783,6 @@ public final class CMSConfig extends AbstractConfig { public final int getSoonExpiredDays() { return ((Integer) get(m_soonExpiredTimespanDays)).intValue(); } - - public final String[] getDefaultTaskAlerts() { - return (String[]) get(m_defaultTaskAlerts); - } public final boolean isUnpublishedNotFound() { return ((Boolean) get(m_unpublishedNotFound)).booleanValue(); @@ -639,6 +809,15 @@ public final class CMSConfig extends AbstractConfig { } + /** + * Fetch the file name contaning XML Mapping of the content center tabs + * to URLs + * @return String containig file name including path component. + */ + public String getContentCenterMap() { + return (String) get(m_contentCenterMap); + } + /** * Internal class representing a DHTMLEditor configuration parameter. It diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties b/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties index 8ac397827..513014e85 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties @@ -1,8 +1,3 @@ -com.arsdigita.cms.template_root_path.title=Template Root Path -com.arsdigita.cms.template_root_path.purpose=Path for the default template folder. Path is relative to webapp root -com.arsdigita.cms.template_root_path.example=/packages/content-section/templates -com.arsdigita.cms.template_root_path.format=[string] - com.arsdigita.cms.default_item_template_path.title=Default Item Template Path com.arsdigita.cms.default_item_template_path.purpose=Path for the default item template. Path is relative to the Template Root path. com.arsdigita.cms.default_item_template_path.example=/default/item.jsp @@ -13,6 +8,11 @@ com.arsdigita.cms.default_folder_template_path.purpose=Path for the default fold com.arsdigita.cms.default_folder_template_path.example=/default/folder.jsp com.arsdigita.cms.default_folder_template_path.format=[string] +com.arsdigita.cms.template_root_path.title=Template Root Path +com.arsdigita.cms.template_root_path.purpose=Path for the default template folder. Path is relative to webapp root +com.arsdigita.cms.template_root_path.example=/packages/content-section/templates +com.arsdigita.cms.template_root_path.format=[string] + com.arsdigita.cms.default_item_resolver_class.title=Item resolver class com.arsdigita.cms.default_item_resolver_class.purpose=Default item resolver class will be used for any content section which does not override in SectionInitializer enterprise.init section. This class must implement com.arsdigita.cms.dispatcher.ItemResolver. com.arsdigita.cms.default_item_resolver_class.example=com.arsdigita.cms.dispatcher.MultilingualItemResolver @@ -48,16 +48,21 @@ com.arsdigita.cms.use_streamlined_creation.purpose=Use streamlined content creat com.arsdigita.cms.use_streamlined_creation.example=false com.arsdigita.cms.use_streamlined_creation.format=[boolean] -com.arsdigita.cms.hide_templates_tab.title=Hide Templates Tab -com.arsdigita.cms.hide_templates_tab.purpose=Hide the templates tab on the item admin page. -com.arsdigita.cms.hide_templates_tab.example=false -com.arsdigita.cms.hide_templates_tab.format=[boolean] - com.arsdigita.cms.hide_admin_tabs.title=Hide Admin Tabs com.arsdigita.cms.hide_admin_tabs.purpose=Hide section admin tabs from users without administrative rights. com.arsdigita.cms.hide_admin_tabs.example=false com.arsdigita.cms.hide_admin_tabs.format=[boolean] +com.arsdigita.cms.hide_folder_index_checkbox.title=Hide Folder Index Checkbox +com.arsdigita.cms.hide_folder_index_checkbox.purpose=Hide Folder Index Checkbox from folder view +com.arsdigita.cms.hide_folder_index_checkbox.example=false +com.arsdigita.cms.hide_folder_index_checkbox.format=[boolean] + +com.arsdigita.cms.hide_templates_tab.title=Hide Templates Tab +com.arsdigita.cms.hide_templates_tab.purpose=Hide the templates tab on the item admin page. +com.arsdigita.cms.hide_templates_tab.example=false +com.arsdigita.cms.hide_templates_tab.format=[boolean] + com.arsdigita.cms.hide_timezone.title=Hide timezone labels com.arsdigita.cms.hide_timezone.purpose=Hide timezone labels (if, for example, all users will be in the same timezone and such information would be unnecessary) com.arsdigita.cms.hide_timezone.example=false @@ -78,11 +83,6 @@ com.arsdigita.cms.hide_udct_ui.purpose=Hide User Defined Content Types UI com.arsdigita.cms.hide_udct_ui.example=false com.arsdigita.cms.hide_udct_ui.format=[boolean] -com.arsdigita.cms.hide_folder_index_checkbox.title=Hide Folder Index Checkbox -com.arsdigita.cms.hide_folder_index_checkbox.purpose=Hide Folder Index Checkbox from folder view -com.arsdigita.cms.hide_folder_index_checkbox.example=false -com.arsdigita.cms.hide_folder_index_checkbox.format=[boolean] - com.arsdigita.cms.dhtml_editor_config.title=DHTML Editor Configuration com.arsdigita.cms.dhtml_editor_config.purpose=LIsts the config object name and Javascript source location for its definition com.arsdigita.cms.dhtml_editor_config.example=HTMLArea.Config.CMSStyled,/assets/htmlarea/config/Styled.js diff --git a/ccm-cms/src/com/arsdigita/cms/ContentSection.java b/ccm-cms/src/com/arsdigita/cms/ContentSection.java index fe00ddde1..cde00e365 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentSection.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentSection.java @@ -144,27 +144,44 @@ public class ContentSection extends Application { // super(BASE_DATA_OBJECT_TYPE); // } // -// public ContentSection(String type) { -// super(type); -// } + /** + * Constructor re-creating a content section object by retrieving its data + * object by OID + * + * @param oid + * @throws DataObjectNotFoundException + */ public ContentSection(OID oid) throws DataObjectNotFoundException { super(oid); } + /** + * Constructor re-creating a content section object from its data object. + * + * @param oid + * @throws DataObjectNotFoundException + */ public ContentSection(DataObject obj) { super(obj); } + /** + * Constructor re-creating a content section object by retrieving its data + * Object by ID + * + * @param oid + * @throws DataObjectNotFoundException + */ public ContentSection(BigDecimal id) throws DataObjectNotFoundException { super(new OID(BASE_DATA_OBJECT_TYPE, id)); } + public static CMSConfig getConfig() { return s_config; } - /** * @return the base PDL object type for this section. Child classes should * override this method to return the correct value @@ -234,38 +251,42 @@ public class ContentSection extends Application { set(NAME, name); } - /** - * Get the package instance for this content section. Each section is - * associated with exactly one package instance. - * - * @return the package instance associated with this content section. - * @post return != null - */ +// Left-over from content section as old-style application based on kernel +// PackageType and Sitenode instead on new style web.Application. +// Retained for reference purpose until the packages Workspace and Service are +// migrated to new style application as well. +// /** +// * Get the package instance for this content section. Each section is +// * associated with exactly one package instance. +// * +// * @return the package instance associated with this content section. +// * @post return != null +// */ // public PackageInstance getPackageInstance() { // DataObject pkg = (DataObject) get(PACKAGE); // Assert.exists(pkg, "package instance"); // return new PackageInstance(pkg); // } - - /** - * Set the package instance for this content section. - * - * @param pkg The package instance - * @pre ( pkg != null ) - */ +// +// /** +// * Set the package instance for this content section. +// * +// * @param pkg The package instance +// * @pre ( pkg != null ) +// */ // protected void setPackageInstance(PackageInstance pkg) { // Assert.exists(pkg, "package instance"); // setAssociation(PACKAGE, pkg); // } - - /** - * Fetch the site node on which the content section is mounted. - * A content section should be mounted on exactly one site node. If it - * is mounted on more than one site node, only the first site node will - * be returned. - * - * @return The site node - */ +// +// /** +// * Fetch the site node on which the content section is mounted. +// * A content section should be mounted on exactly one site node. If it +// * is mounted on more than one site node, only the first site node will +// * be returned. +// * +// * @return The site node +// */ // public SiteNode getSiteNode() { // return getPackageInstance().getDefaultMountPoint(); // } @@ -306,6 +327,7 @@ public class ContentSection extends Application { return URL.getDispatcherPath() + getPath(); } +// Left over, see above // public final String getPath() { // final String path = getSiteNode().getURL(); // @@ -467,7 +489,7 @@ public class ContentSection extends Application { * @return The class name * @post ( return != null ) */ - public String getPageResolverClass() { + public String getPageResolverClassName() { String prc = (String) get(PAGE_RESOLVER_CLASS); Assert.exists(prc, "Page Resolver class"); return prc; @@ -489,7 +511,7 @@ public class ContentSection extends Application { } try { - final Class prc = Class.forName(getPageResolverClass()); + final Class prc = Class.forName(getPageResolverClassName()); m_pageResolver = (PageResolver) prc.newInstance(); m_pageResolver.setContentSectionID(getID()); } catch (ClassNotFoundException cnfe) { @@ -513,7 +535,7 @@ public class ContentSection extends Application { * * @param className The class name */ - public void setPageResolverClass(String className) { + public void setPageResolverClassName(String className) { set(PAGE_RESOLVER_CLASS, className); m_pageResolver = null; } @@ -524,7 +546,7 @@ public class ContentSection extends Application { * @return The class name * @post ( return != null ) */ - public String getItemResolverClass() { + public String getItemResolverClassName() { String irc = (String) get(ITEM_RESOLVER_CLASS); Assert.exists(irc, "Content Item Resolver class"); s_log.debug("Content Item Resolver Class is " + irc); @@ -541,7 +563,7 @@ public class ContentSection extends Application { public ItemResolver getItemResolver() { if (m_itemResolver == null) { try { - final Class irc = Class.forName(getItemResolverClass()); + final Class irc = Class.forName(getItemResolverClassName()); m_itemResolver = (ItemResolver) irc.newInstance(); } catch (ClassNotFoundException cnfe) { throw new UncheckedWrapperException(cnfe); @@ -571,7 +593,7 @@ public class ContentSection extends Application { * @return The class name * @post ( return != null ) */ - public String getTemplateResolverClass() { + public String getTemplateResolverClassName() { String trc = (String) get(TEMPLATE_RESOLVER_CLASS); Assert.exists(trc, "Template Resolver class"); return trc; @@ -586,7 +608,7 @@ public class ContentSection extends Application { public TemplateResolver getTemplateResolver() { if (m_templateResolver == null) { try { - Class trc = Class.forName(getTemplateResolverClass()); + Class trc = Class.forName(getTemplateResolverClassName()); m_templateResolver = (TemplateResolver) trc.newInstance(); } catch (ClassNotFoundException cnfe) { throw new UncheckedWrapperException(cnfe); @@ -616,7 +638,7 @@ public class ContentSection extends Application { * * @return The class name */ - public String getXMLGeneratorClass() { + public String getXMLGeneratorClassName() { String xgc = (String) get(XML_GENERATOR_CLASS); Assert.exists(xgc, "XML Generator class"); return xgc; @@ -631,7 +653,7 @@ public class ContentSection extends Application { public XMLGenerator getXMLGenerator() { if (m_xmlGenerator == null) { try { - Class xgc = Class.forName(getXMLGeneratorClass()); + Class xgc = Class.forName(getXMLGeneratorClassName()); m_xmlGenerator = (XMLGenerator) xgc.newInstance(); } catch (ClassNotFoundException cnfe) { throw new UncheckedWrapperException(cnfe); @@ -940,14 +962,14 @@ public class ContentSection extends Application { // return getSectionFromPackage(pkg); } - /** - * Looks up the section given the PackageInstance. - * - * @param pkg The package instance - * @return The content section ID - * @pre ( pkg != null ) - * @post ( return != null ) - */ +// /** +// * Looks up the section given the PackageInstance. +// * +// * @param pkg The package instance +// * @return The content section ID +// * @pre ( pkg != null ) +// * @post ( return != null ) +// */ // public static ContentSection getSectionFromPackage(PackageInstance pkg) // throws DataObjectNotFoundException { // @@ -964,8 +986,8 @@ public class ContentSection extends Application { // dq.close(); // } else { // throw new DataObjectNotFoundException( -// "Failed to fetch a content section for the current package " + -// "instance. [package_id =" + pkg.getID().toString() + "]"); +// "Failed to fetch a content section for the current package " + +// "instance. [package_id =" + pkg.getID().toString() + "]"); // } // return section; // } @@ -1014,6 +1036,48 @@ public class ContentSection extends Application { + /** + * Creates a content section of the given name using default values and + * returns it. + * + * @param name Name of the content section + * @return ContentSection + */ + public static ContentSection create(final String name) { + + Folder folder = createRootFolder(name); + Category category = createRootCategory(name); + Group staff = createStaffGroup(name); + + // Some default classes for a content section. + String prc = "com.arsdigita.cms.dispatcher.SimplePageResolver"; + String irc = "com.arsdigita.cms.dispatcher.MultilingualItemResolver"; + String xgc = "com.arsdigita.cms.dispatcher.SimpleXMLGenerator"; + String trc = "com.arsdigita.cms.dispatcher.DefaultTemplateResolver"; + + ContentSection section = ContentSection.create( name, + folder, + category, + staff, + prc, + irc, + xgc, + trc); + + // Set the default context on the root folder to + // the content section + PermissionService.setContext(folder.getOID(), section.getOID()); + createDefaultResources(section); + +// Left over, see above +// } +// }; +// rootExcursion.run(); +// +// //now retrieve the created content section and return it +// return (ContentSection) Application.retrieveApplicationForPath("/" + name + "/"); + return section; + } /** * Create a new content section. This method is called automatically when a @@ -1086,62 +1150,21 @@ public class ContentSection extends Application { //create and initialize the content section application ContentSection section = (ContentSection) Application.createApplication (BASE_DATA_OBJECT_TYPE, name, name, null ); - section.initialize( - name, - folder, - category, - staff, - prc, - irc, - xgc, - trc, - templates, - viewers); + section.initialize( name, + folder, + category, + staff, + prc, + irc, + xgc, + trc, + templates, + viewers); return section; } - /** - * Method create. Creates a default content section and returns it - * @param name Name of the content section - * @return ContentSection - */ - public static ContentSection create(final String name) { - - Group staff = createStaffGroup(name); - Folder folder = createRootFolder(name); - Category category = createRootCategory(name); - - // Some default classes for a content section. - String prc = "com.arsdigita.cms.dispatcher.SimplePageResolver"; - String irc = "com.arsdigita.cms.dispatcher.MultilingualItemResolver"; - String xgc = "com.arsdigita.cms.dispatcher.SimpleXMLGenerator"; - String trc = "com.arsdigita.cms.dispatcher.DefaultTemplateResolver"; - - ContentSection section = ContentSection.create( - name, - folder, - category, - staff, - prc, - irc, - xgc, - trc); - - // Set the default context on the root folder to - // the content section - PermissionService.setContext(folder.getOID(), section.getOID()); - createDefaultResources(section); -// } -// }; -// rootExcursion.run(); - - //now retrieve the created content section and return it -// return (ContentSection) Application.retrieveApplicationForPath("/" + name + "/"); - return section; - } - /** * Creates and maps default resources to the content section. * @@ -1155,8 +1178,7 @@ public class ContentSection extends Application { // XML resources ResourceType rt = ResourceType.findResourceType("xml"); - Resource r = - rt.createInstance("com.arsdigita.cms.ui.ContentSectionPage"); + Resource r = rt.createInstance("com.arsdigita.cms.ui.ContentSectionPage"); r.save(); ResourceMapping rm = r.createInstance(section, "admin"); rm.save(); @@ -1176,20 +1198,6 @@ public class ContentSection extends Application { } - /** - * Creates default staff group and associated default roles for a - * content section. - * - * @param name The name of the content section - * @return The staff group - */ - private static Group createStaffGroup(String name) { - Group staff = new Group(); - staff.setName(name + " Administration"); - staff.save(); - return staff; - } - /** * Creates the root folder for a content section. * @@ -1217,6 +1225,20 @@ public class ContentSection extends Application { return root; } + /** + * Creates default staff group and associated default roles for a + * content section. + * + * @param name The name of the content section + * @return The staff group + */ + private static Group createStaffGroup(String name) { + Group staff = new Group(); + staff.setName(name + " Administration"); + staff.save(); + return staff; + } + /** * Initialize a newly created content section. @@ -1245,15 +1267,15 @@ public class ContentSection extends Application { setName(name); //setPackageInstance(pkg); - setStaffGroup(staff); - setViewersGroup(viewers); setRootFolder(folder); setRootCategory(category); - setPageResolverClass(prc); + setStaffGroup(staff); + setPageResolverClassName(prc); setItemResolverClass(irc); setXMLGeneratorClass(xgc); - setTemplatesFolder(templates); setTemplateResolverClass(trc); + setTemplatesFolder(templates); + setViewersGroup(viewers); save(); return this; @@ -1273,10 +1295,12 @@ public class ContentSection extends Application { return new Folder.ItemCollection(dq); } + @Override public String getServletPath() { return URL.SERVLET_DIR + "/content-section"; } + @Override public String getStylesheetPath() { return STYLESHEET; } diff --git a/ccm-cms/src/com/arsdigita/cms/Initializer.java b/ccm-cms/src/com/arsdigita/cms/Initializer.java index 0a4e7a6e8..2ddfe25d3 100755 --- a/ccm-cms/src/com/arsdigita/cms/Initializer.java +++ b/ccm-cms/src/com/arsdigita/cms/Initializer.java @@ -23,7 +23,8 @@ 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.installer.WorkspaceInstaller; +// import com.arsdigita.cms.installer.ContentCenterSetup; import com.arsdigita.cms.publishToFile.PublishToFileListener; import com.arsdigita.cms.publishToFile.QueueManager; import com.arsdigita.cms.search.AssetMetadataProvider; @@ -49,10 +50,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.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; @@ -62,7 +63,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.ConfigError; import com.arsdigita.runtime.DomainInitEvent; import com.arsdigita.runtime.LegacyInitializer; import com.arsdigita.runtime.PDLInitializer; @@ -87,14 +88,15 @@ import com.arsdigita.cms.util.LanguageUtil; import com.arsdigita.kernel.Kernel; // For Id. -import java.math.BigDecimal; +// import java.math.BigDecimal; import org.apache.log4j.Logger; /** - * The main CMS initializer. + * The main CMS initializer, executed recurringly at each system startup. * * @author Justin Ross <jross@redhat.com> + * @author Peter Boy <pboy@barkhof.uni-bremen.de> * @version $Id: Initializer.java 2070 2010-01-28 08:47:41Z pboy $ */ public class Initializer extends CompoundInitializer { @@ -103,8 +105,17 @@ 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); + /** Configuration object for the CMS module */ + private static final CMSConfig s_conf = CMSConfig.getInstance(); +// Verursacht aktuell eine Exception "no such context" +// Vermutliche Lösung: in config.xml eintragen. +// static { // requirred to actually read the config file! +// s_conf.load(); +// } + /** - * Constructor + * Constructor, adds db connection information and various sub-initializers + * for subpackages in the CMS module. */ public Initializer() { final String url = RuntimeConfig.getConfig().getJDBCURL(); @@ -127,7 +138,7 @@ public class Initializer extends CompoundInitializer { // // 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()); // Step 2: // Old type initializer "com.arsdigita.cms.installer.xml.ContentTypeInitializer" @@ -145,7 +156,7 @@ public class Initializer extends CompoundInitializer { // Initializer for content section, needed when LegacyInitializer in step 4 // 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()); @@ -231,9 +242,15 @@ public class Initializer extends CompoundInitializer { registerPatternGenerators(); // cg - register Task Retrieval engine - Engine.registerEngine(CMSEngine.CMS_ENGINE_TYPE, new CMSEngine()); + // Setup Workspace tab to URL mapping + final String workspaceURL = CMS.WORKSPACE_PACKAGE_KEY; + final String contentCenterMap = s_conf.getContentCenterMap(); + WorkspaceSetup workspaceSetup = new WorkspaceSetup( workspaceURL, + contentCenterMap); + workspaceSetup.run(); + // register item adapters XML.parse(ContentSection.getConfig().getItemAdapters(), new TraversalHandler()); @@ -316,6 +333,7 @@ public class Initializer extends CompoundInitializer { f.registerInstantiator (WorkflowTemplate.BASE_DATA_OBJECT_TYPE, new ACSObjectInstantiator() { + @Override public DomainObject doNewInstance(DataObject dataObject) { return new WorkflowTemplate(dataObject); } @@ -327,6 +345,7 @@ public class Initializer extends CompoundInitializer { public DomainObject doNewInstance(DataObject dataObject) { return new TemplateContext(dataObject); } + @Override public DomainObjectInstantiator resolveInstantiator(DataObject obj) { return this; diff --git a/ccm-cms/src/com/arsdigita/cms/Loader.java b/ccm-cms/src/com/arsdigita/cms/Loader.java index 400e82a13..9e3314584 100755 --- a/ccm-cms/src/com/arsdigita/cms/Loader.java +++ b/ccm-cms/src/com/arsdigita/cms/Loader.java @@ -18,11 +18,13 @@ */ package com.arsdigita.cms; -import com.arsdigita.cms.installer.ContentSectionSetup; +// import com.arsdigita.cms.CMS; +// import com.arsdigita.cms.installer.ContentSectionSetup; +import com.arsdigita.cms.contentsection.ContentSectionSetup; // import com.arsdigita.cms.installer.PageClassConfigHandler; -import com.arsdigita.cms.installer.Util; +import com.arsdigita.cms.util.Util; import com.arsdigita.cms.installer.xml.XMLContentTypeHandler; -import com.arsdigita.cms.installer.WorkspaceInstaller; +// import com.arsdigita.cms.installer.WorkspaceInstaller; //import com.arsdigita.cms.portlet.ContentDirectoryPortlet; import com.arsdigita.cms.portlet.ContentItemPortlet; //import com.arsdigita.cms.portlet.ContentSectionsPortlet; @@ -38,7 +40,7 @@ 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.Stylesheet; import com.arsdigita.kernel.permissions.PrivilegeDescriptor; import com.arsdigita.loader.PackageLoader; import com.arsdigita.persistence.DataObject; @@ -138,11 +140,11 @@ public class Loader extends PackageLoader { 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"; +// /** +// * 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 @@ -163,11 +165,11 @@ public class Loader extends PackageLoader { * 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"; +// /** +// * Constant string used as key for creating service package as a +// * legacy application. +// */ +// public final static String SERVICE_PACKAGE_KEY = "cms-service"; @@ -235,40 +237,43 @@ public class Loader extends PackageLoader { }.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. - * createPrivileges might be included in load, but has te be executed at - * each startup to take modifications into accout. So it has to be an - * initializer task anyway. - */ - 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" +// Migration Status: +// Method completely replaced by loadContentSection() +// Code kept for reference purpose untill the complete migration will be done. +// +// /** +// * 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. +// * createPrivileges might be included in load, but has te be executed at +// * each startup to take modifications into accout. So it has to be an +// * initializer task anyway. +// */ +// 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. +// //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 @@ -280,12 +285,12 @@ public class Loader extends PackageLoader { // // 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."); - } +// +// +// createPrivileges(); +// +// s_log.debug("Done creating the CMS package type."); +// } /** @@ -296,29 +301,42 @@ public class Loader extends PackageLoader { private void loadWorkspacePackage() { s_log.debug("Creating CMS Workspace..."); - WorkspaceInstaller workspaceInstaller = new WorkspaceInstaller(); - try { - workspaceInstaller.createPackageType(); - // type.setDispatcherClass(WORKSPACE_DISPATCHER_CLASS); + // from WorkspaceInstaller workspaceInstaller = new WorkspaceInstaller(); + try { + // workspaceInstaller.createPackageType(); + PackageType type = PackageType.create(CMS.WORKSPACE_PACKAGE_KEY, + "Content Center", + "Content Centers", + "http://cms-workspace.arsdigita.com/"); + 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(); + // Register a stylesheet to the Content Center package. + Stylesheet ss = + Stylesheet.createStylesheet(WORKSPACE_STYLESHEET); + ss.save(); + type.addStylesheet(ss); - // workspaceInstaller.mountPackageInstance(instance, m_workspaceURL); - // Does the following: - // SiteNode node = SiteNode.createSiteNode( - // s_conf.getWorkspaceURL(), - // SiteNode.getRootSiteNode()); - // node.mountPackage(instance); - // node.save(); + type.save(); + + // from PackageInstance instance = workspaceInstaller.createPackageInstance(); + // Does the following: + type = PackageType.findByKey(CMS.WORKSPACE_PACKAGE_KEY); + PackageInstance instance = type.createInstance(WORKSPACE_INSTANCE_NAME); + instance.save(); + + // from: workspaceInstaller.mountPackageInstance(instance, m_workspaceURL); + // Does the following: + // We really don't want it configurable. + // SiteNode node = SiteNode.createSiteNode(CMS.WORKSPACE_PACKAGE_KEY, + // SiteNode.getRootSiteNode()); + SiteNode node = SiteNode.createSiteNode(CMS.WORKSPACE_PACKAGE_KEY, + SiteNode.getRootSiteNode()); + node.mountPackage(instance); + node.save(); // m_workspaceURL == WORKSPACE_PACKAGE_KEY // workspaceInstaller.mountPackageInstance(instance, m_workspaceURL); - workspaceInstaller.mountPackageInstance(instance, WORKSPACE_PACKAGE_KEY); + // workspaceInstaller.mountPackageInstance(instance, CMS.WORKSPACE_PACKAGE_KEY); } catch (DataObjectNotFoundException e) { throw new ConfigError( @@ -387,7 +405,7 @@ public class Loader extends PackageLoader { try { // from ServiceInstaller.createPackageType(); PackageType type = PackageType.create - (SERVICE_PACKAGE_KEY, + (CMS.SERVICE_PACKAGE_KEY, "Content Management System Services", "Content Management System Services", "http://cms-service.arsdigita.com/"); @@ -396,8 +414,8 @@ public class Loader extends PackageLoader { type.save(); // from PackageInstance instance = ServiceInstaller.createPackageInstance(); - type = PackageType.findByKey(SERVICE_PACKAGE_KEY); - PackageInstance instance = type.createInstance(SERVICE_PACKAGE_KEY); + type = PackageType.findByKey(CMS.SERVICE_PACKAGE_KEY); + PackageInstance instance = type.createInstance(CMS.SERVICE_PACKAGE_KEY); instance.save(); // from ServiceInstaller.mountPackageInstance(instance, url); @@ -472,48 +490,68 @@ public class Loader extends PackageLoader { 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(); - - createPrivileges(); - - // Step 2: Validatge name for section + // Step 1: Validate name for section Util.validateURLParameter("name", name); - // Step 3: Create the installation default content section "name" - ContentSection section = ContentSection.create(name); + // Step 2: Creating content section application type first so that + // concrete content-section instance can be created. + // from: ContentSectionSetup.setupContentSectionAppType(); + // Install application type using new application classes + ApplicationSetup appType = new ApplicationSetup(s_log); + appType.setApplicationObjectType(ContentSection.BASE_DATA_OBJECT_TYPE); + appType.setKey(ContentSection.PACKAGE_TYPE); // by default: content-section + appType.setTitle("CMS Content Section"); + appType.setDescription("A CMS Content Section"); + appType.setPortalApplication(false); + //setup.setDispatcherClass(ContentItemDispatcher.class.getName()); + appType.setStylesheet(CMS_STYLESHEET); // by default: /pack./c-s/xml/cms.xml + // contains the xsl to generate the page + appType.setInstantiator(new ACSObjectInstantiator() { + @Override + public DomainObject doNewInstance(DataObject dataObject) { + return new ContentSection(dataObject); + } + }); + appType.run(); - // ContentSectionSetup is a convenient class for ContentSection.create() + // Step 3: + createPrivileges(); + + // Step 4: Create the installation default content section "name" + // ContentSection.create creates a section with several default values + // which have to be adopted for a concrete installation. + ContentSection section = ContentSection.create(name); + // ContentSectionSetup is a convenient class to adopt a section created + // by 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. + setup.registerContentTypes(s_conf.getContentSectionsContentTypes()); + // 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()) { @@ -523,6 +561,13 @@ public class Loader extends PackageLoader { } } + // registers a predefined standard recipient for alerts + setup.registerAlerts(); + + // Load a list of cms tasks and associated alert events + // Currently no functionality to persist them. Not a loader task yet + // setup.loadTaskAlerts(s_conf.getTaskAlerts()); + section.save(); //persists any changes in the database (DomainObject) //i.e. creates an object (instance) diff --git a/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java b/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java index 2568cbdd2..8c39deb6f 100644 --- a/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/LoaderConfig.java @@ -17,18 +17,6 @@ */ -// ***************************************************************************** - -// Stand: -// Alle Parameter aus SectionInitializer und enterprise.init hierhin übertragen. -// Noch zu klären, welche gehören tatsächlich hier hin? -// In Loader gehören nur solche, die in der Datenbank eingetragen werden (persisted). -// Alles, was zur Laufzeit eingestellt wird, muss in Initializer configuration. - -// ***************************************************************************** - - - package com.arsdigita.cms; //import com.arsdigita.kernel.permissions.PrivilegeDescriptor; @@ -60,32 +48,36 @@ public final class LoaderConfig extends AbstractConfig { private static final Logger s_log = Logger.getLogger(LoaderConfig.class); - // //////////////////////////////////////////////// - // The following two (three) parameters are used by - // com.arsdigita.cms.installer.Initializer - // //////////////////////////////////////////////// +// /** +// * The name of the workspace package instance, i.e. URL of the workspace, +// * where authors, editors and publishers are working and from which they +// * can select a content-section to create and edit documents. +// * Usually you won't modify it! +// * +// * NOTE Version 6.6.1 /2010-10-27) +// * This parameter is not used in Loader. Perhaps we will make it configurable +// * a migrating Workspace to new application style so it is retained here +// * for the time being. +// */ +// private StringParameter +// m_workspaceURL = new StringParameter( +// "com.arsdigita.cms.loader.workspace_url", +// Parameter.REQUIRED, +// "content-center"); - /** - * The name of the workspace package instance, i.e. URL of the workspace, - * where authors, editors and publishers are working and from which they - * can select a content-section to create and edit documents. - * Usually you won't modify it! - */ - private StringParameter - m_workspaceURL = new StringParameter( - "com.arsdigita.cms.loader.workspace_url", - Parameter.REQUIRED, - "content-center"); - - /** - * XML Mapping of the content center tabs to URLs, see - * {@link ContentCenterDispatcher} - */ - private final StringParameter - m_contentCenterMap = new StringParameter( - "com.arsdigita.cms.loader.content_center_map", - Parameter.REQUIRED, - "/WEB-INF/resources/content-center-map.xml"); +// /** +// * XML Mapping of the content center tabs to URLs, see +// * {@link ContentCenterDispatcher} +// * NOTE Version 6.6.1 /2010-10-27) +// * Currently not used in Loader because it will not be persisted. Retained +// * here for reference in case we will add persisting while migrating to +// * new style application. +// */ +// private final StringParameter +// m_contentCenterMap = new StringParameter( +// "com.arsdigita.cms.loader.content_center_map", +// Parameter.REQUIRED, +// "/WEB-INF/resources/content-center-map.xml"); // Update master object if upgrading from old versioning // XXX: shouldn't we just gut this section (and @@ -127,12 +119,12 @@ public final class LoaderConfig extends AbstractConfig { m_ctDefFiles = new StringArrayParameter( "com.arsdigita.cms.loader.contenttype_definition_files", Parameter.REQUIRED, - // Generic*.xml added by Quasi in enterprise.init fot + // Generic*.xml added by Quasi in enterprise.init for // new generic Basetypes in addition to article new String[] {"/WEB-INF/content-types/GenericAddress.xml", "/WEB-INF/content-types/GenericArticle.xml", "/WEB-INF/content-types/GenericContact.xml", - "/WEB-INF/content-types/GenericOrganizationalUnit.xml", + "/WEB-INF/content-types/GenericOrganizationalUnit.xml", "/WEB-INF/content-types/GenericPerson.xml", "/WEB-INF/content-types/Template.xml"} ); @@ -153,7 +145,7 @@ public final class LoaderConfig extends AbstractConfig { */ private final Parameter m_contentSectionName = new StringParameter( - "com.arsdigita.cms.loader.content_section_name", + "com.arsdigita.cms.loader.section_name", Parameter.REQUIRED, "content"); //"public"); @@ -172,7 +164,7 @@ public final class LoaderConfig extends AbstractConfig { * Not implemented yet! We need a new parameter type "list" which must have * multidimensional capabilities. */ -// private final StringParameter +// private final Parameter // m_staffGroup = new StringParameter( // "com.arsdigita.cms.loader.section_staff_group", // Parameter.REQUIRED, @@ -212,7 +204,7 @@ public final class LoaderConfig extends AbstractConfig { */ private final Parameter m_contentTypeList = new StringArrayParameter( - "com.arsdigita.cms.loader.ctypes_include_list", + "com.arsdigita.cms.loader.section_ctypes_list", Parameter.REQUIRED, new String[] {} ); @@ -287,13 +279,24 @@ public final class LoaderConfig extends AbstractConfig { Parameter.REQUIRED, new String[] {"/WEB-INF/resources/article-categories.xml", "/WEB-INF/resources/navigation-categories.xml"} ); - // Category tree to load - // categories = { "/WEB-INF/resources/article-categories.xml", - // "/WEB-INF/resources/navigation-categories.xml" }; - // m_conf.initParameter(CATEGORIES, - // "XML file containing the category tree", - // List.class, - // Collections.EMPTY_LIST); + + +// Currently not a Loader task. There is no way to persist tasks preferences +// on a per section base. +// /** +// * When to generate email alerts: by default, generate email alerts +// * on enable, finish, and rollback (happens on rejection) changes. +// * There are four action types for each task type: enable, +// * disable, finish, and rollback. Note that the values below are +// * based on the task labels, and as such are not globalized. +// */ +// private final Parameter +// m_taskAlerts = new StringArrayParameter( +// "com.arsdigita.cms.task_alerts", +// Parameter.REQUIRED, new String[] { +// "Authoring:enable:finish:rollback", +// "Approval:enable:finish:rollback", +// "Deploy:enable:finish:rollback" } ); // /////////////////////////////////////////////////////////////////////// @@ -351,8 +354,8 @@ public final class LoaderConfig extends AbstractConfig { */ public LoaderConfig() { - register(m_workspaceURL); - register(m_contentCenterMap); +// register(m_workspaceURL); +// register(m_contentCenterMap); register(m_ctDefFiles); // Parameters for creating a content section @@ -365,9 +368,10 @@ public final class LoaderConfig extends AbstractConfig { register(m_useSectionCategories); register(m_categoryFileList); + // (Currently not a loader task) +// register(m_taskAlerts); // Parameters controlling Overdue Task alerts: // (Currently not a loader task) -// register(m_taskAlerts); no Loader task, moved to contentsection/Initializer // register(m_sendOverdueAlerts); // register(m_taskDuration); // register(m_overdueAlertInterval); @@ -386,22 +390,24 @@ public final class LoaderConfig extends AbstractConfig { // // ////////////////////////// - /** - * Fetch name (URL) of the workspace package instance, e.g. content-center - * @return (URL) of the workspace package instance - */ - public String getWorkspaceURL() { - return (String) get(m_workspaceURL); - } +// Not used as long as we use old style application (seee above) +// /** +// * Fetch name (URL) of the workspace package instance, e.g. content-center +// * @return (URL) of the workspace package instance +// */ +// public String getWorkspaceURL() { +// return (String) get(m_workspaceURL); +// } - /** - * Fetch the file name contaning XML Mapping of the content center tabs - * to URLs - * @return String containig file name including path component. - */ - public String getContentCenterMap() { - return (String) get(m_contentCenterMap); - } +// Moved to CMSConfig as long as it is not a Loader task. (see above) +// /** +// * Fetch the file name contaning XML Mapping of the content center tabs +// * to URLs +// * @return String containig file name including path component. +// */ +// public String getContentCenterMap() { +// return (String) get(m_contentCenterMap); +// } public List getCTDefFiles() { String[] ctDefFiles = (String[]) get(m_ctDefFiles); @@ -424,8 +430,7 @@ public final class LoaderConfig extends AbstractConfig { * * In loading step a complete default configuration is persisted in database, * immutable at this point. - * See contentsection.ContentSectio -nSetup.registerRoles() + * See contentsection.ContentSectionSetup.registerRoles() * In enterprise.init: name roles, List of roles to create. * * Set consists of a set of roles, for each role first field is the role name, @@ -557,6 +562,10 @@ nSetup.registerRoles() } +// public final String[] getTaskAlerts() { +// return (String[]) get(m_taskAlerts); +// } + // Parameters controlling Overdue Task alerts: // Currently not a loader task, see above diff --git a/ccm-cms/src/com/arsdigita/cms/LoaderConfig_parameter.properties b/ccm-cms/src/com/arsdigita/cms/LoaderConfig_parameter.properties index 254b59cf1..42a3c4564 100644 --- a/ccm-cms/src/com/arsdigita/cms/LoaderConfig_parameter.properties +++ b/ccm-cms/src/com/arsdigita/cms/LoaderConfig_parameter.properties @@ -7,3 +7,28 @@ com.arsdigita.cms.loader.content_center_map.title=Frequency com.arsdigita.cms.loader.content_center_map.purpose=How often (in seconds) does the system look for pending items to make them live and live items to expire. com.arsdigita.cms.loader.content_center_map.example=600 com.arsdigita.cms.loader.content_center_map.format=[integer] + +com.arsdigita.cms.loader.contenttype_definition_files.title= +com.arsdigita.cms.loader.contenttype_definition_files.purpose= +com.arsdigita.cms.loader.contenttype_definition_files.example= +com.arsdigita.cms.loader.contenttype_definition_files.format=[StringArray] + +com.arsdigita.cms.loader.section_name.title= +com.arsdigita.cms.loader.section_name.purpose= +com.arsdigita.cms.loader.section_name.example= +com.arsdigita.cms.loader.section_name.format=[StringArray] + +com.arsdigita.cms.loader.section_staff_group.title= +com.arsdigita.cms.loader.section_staff_group.purpose= +com.arsdigita.cms.loader.section_staff_group.example= +com.arsdigita.cms.loader.section_staff_group.format=[StringArray] + +com.arsdigita.cms.loader.section_is_public.title= +com.arsdigita.cms.loader.section_is_public.purpose= +com.arsdigita.cms.loader.section_is_public.example= +com.arsdigita.cms.loader.section_is_public.format=[StringArray] + +com.arsdigita.cms.loader.section_ctypes_list.title= +com.arsdigita.cms.loader.section_ctypes_list.purpose= +com.arsdigita.cms.loader.section_ctypes_list.example= +com.arsdigita.cms.loader.section_ctypes_list.format=[ boolean] diff --git a/ccm-cms/src/com/arsdigita/cms/WorkspaceSetup.java b/ccm-cms/src/com/arsdigita/cms/WorkspaceSetup.java new file mode 100644 index 000000000..55442681d --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/WorkspaceSetup.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2010 Peter Boy All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms; + +import com.arsdigita.cms.util.PageClassConfigHandler; +// import com.arsdigita.domain.DataObjectNotFoundException; +import com.arsdigita.runtime.ConfigError; +import com.arsdigita.initializer.InitializationException; +// import com.arsdigita.kernel.PackageInstance; +// import com.arsdigita.kernel.PackageType; +// import com.arsdigita.kernel.Stylesheet; +// import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +// import com.arsdigita.persistence.DataQuery; +// import com.arsdigita.persistence.SessionManager; +import com.arsdigita.util.UncheckedWrapperException; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.apache.log4j.Logger; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + + +/** + * Sets up the CMS package. + * + * @author Peter Boy + * @version $Id: $ + */ +public final class WorkspaceSetup { + + private static Logger s_log = Logger.getLogger(WorkspaceSetup.class); + + /** URL to access the CMS Workspace, by default content-center */ + final String m_workspaceURL; + + /** Map of URL stubs and resource handler classes for ContentCenterDispatcher + * to use */ + final String m_contentCenterMap; + + /** Contains mapping of URL (key) to resource handler*/ + private static HashMap s_pageClasses = new HashMap(); + + /** Contains mapping of resource(key) to resource handler */ + private static HashMap s_pageURLs = new HashMap(); + + + /** + * Constructor + * + * @param workspaceURL + * @param contentCenterMap + */ + public WorkspaceSetup( String workspaceURL, + String contentCenterMap) { + + m_workspaceURL = workspaceURL; + m_contentCenterMap = contentCenterMap; + + } + + /** Gives you a mapping of URL (key) to resource handler + * Use the returned map like so: map.get("search"); + */ + public static HashMap getURLToClassMap() { + return s_pageClasses; + } + + /** Gives you a mapping of resource(key) to resource handler + * Use the returned map like so: map.get("com.arsdigita.cms.ui.WorkspacePage"); + */ + public static HashMap getClassToURLMap() { + return s_pageURLs; + } + + public void run() { + + // Load the content-center page mappings. + // Has to be executed at each system startup and is an + // Initializer task. + setupContentCenter(); + + } + + + /** + * Load the content center page mappings. + * Mapping stored in hashMaps, must be run during each system startup, so + * it is an initializer task. + * @throws InitializationException + */ + private void setupContentCenter() throws ConfigError { + + final PageClassConfigHandler handler + = new PageClassConfigHandler(s_pageClasses, s_pageURLs); + + final ClassLoader loader = Thread.currentThread() + .getContextClassLoader(); + final InputStream input = loader.getResourceAsStream + (m_contentCenterMap.substring(1)); + + if (input == null) { + throw new IllegalStateException(m_contentCenterMap + " 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); + } + } + +} diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java index 8f56f557e..de72f273b 100644 --- a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionConfig.java @@ -35,7 +35,7 @@ import com.arsdigita.util.parameter.StringParameter; // import java.io.InputStream; import java.util.Arrays; import java.util.List; -//import java.util.ArrayList; +import java.util.ArrayList; import org.apache.log4j.Logger; @@ -52,8 +52,37 @@ public final class ContentSectionConfig extends AbstractConfig { private static final Logger s_log = Logger.getLogger(ContentSectionConfig.class); + /** Private Object to hold one's own instance to return to users. */ + private static ContentSectionConfig s_config; - // Parameters controlling Overdue Task alerts: + /** + * Returns the singleton configuration record for the content section + * environment. + * + * @return The ContentSectionConfig record; it cannot be null + */ + public static final synchronized ContentSectionConfig getInstance() { + if (s_config == null) { + s_config = new ContentSectionConfig(); + // deprecated + // s_config.require("ccm-core/runtime.properties"); + // use instead: + // read values from the persistent storage + s_config.load(); + } + + return s_config; + } + + +// ///////////////////////////////////////////////////////////////////////////// +// +// Set of parameters controlling Overdue Task alerts: +// Currently there is no way to persist it nor to persist on a per section base. +// Therefore Initializer has to create overdue task alert mechanism using a +// configuration applied to every content section. +// +// ///////////////////////////////////////////////////////////////////////////// /** * A list of workflow tasks, and the associated events for which alerts @@ -80,17 +109,23 @@ public final class ContentSectionConfig extends AbstractConfig { * }; * * - * 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. + * In the new Initializer system we use a specifically formatted String Array + * because we have no List parameter. Format: + * - A string for each task to handle, possible values: Authoring, Approval, + * Depploy + * - Each String: [taskName]:[alert_1]:...:[alert_n] + * Currently there is no way to persist taskAlerts section specific. So all + * sections have to treated equally. + * Default values are provided here. */ private final Parameter m_taskAlerts = new StringArrayParameter( - "com.arsdigita.cms.loader.section_task_alerts", - Parameter.REQUIRED, - null ); - // new String[] {} ); + "com.arsdigita.cms.section.task_alerts", + Parameter.REQUIRED, new String[] { + "Authoring:enable:finish:rollback", + "Approval:enable:finish:rollback", + "Deploy:enable:finish:rollback" } + ); /** * Should we send alerts about overdue tasks at all? @@ -100,7 +135,7 @@ public final class ContentSectionConfig extends AbstractConfig { */ private final Parameter m_sendOverdueAlerts = new BooleanParameter( - "com.arsdigita.cms.contentsection.send_overdue_alerts", + "com.arsdigita.cms.section.send_overdue_alerts", Parameter.REQUIRED, false ); @@ -117,7 +152,7 @@ public final class ContentSectionConfig extends AbstractConfig { // considered overdue (in hours) private final Parameter m_taskDuration = new IntegerParameter( - "com.arsdigita.cms.contentsection.task_duration", + "com.arsdigita.cms.section.task_duration", Parameter.REQUIRED, new Integer(96) ); @@ -131,7 +166,7 @@ public final class ContentSectionConfig extends AbstractConfig { */ private final Parameter m_alertInterval = new IntegerParameter( - "com.arsdigita.cms.contentsection.alert_interval", + "com.arsdigita.cms.section.alert_interval", Parameter.REQUIRED, new Integer(24) ); @@ -144,7 +179,7 @@ public final class ContentSectionConfig extends AbstractConfig { */ private final Parameter m_maxAlerts = new IntegerParameter( - "com.arsdigita.cms.contentsection.max_alerts", + "com.arsdigita.cms.section.max_alerts", Parameter.REQUIRED, new Integer(5) ); @@ -168,9 +203,141 @@ public final class ContentSectionConfig extends AbstractConfig { */ private final Parameter m_newContentSectionName = new StringParameter( - "com.arsdigita.cms.contentsection.new_section_name", - Parameter.REQUIRED, + "com.arsdigita.cms.section.new_section_name", + Parameter.OPTIONAL, null); + /** + * Staff Group + * Contains roles and associated privileges. In loading step a complete + * default configuration is persisted in database, immutable at this point. + * See contentsection.ContentSectionSetup.registerRoles() + * In enterprise.init: name roles, List of roles to create. + * + * Not implemented yet! We need a new parameter type "list" which must have + * multidimensional capabilities. + */ +// private final StringParameter +// m_staffGroup = new StringParameter( +// "com.arsdigita.cms.loader.section_staff_group", +// Parameter.REQUIRED, +// null); + private List m_staffGroup; + + + // Viewer group, set autonomously by ContentSection.create() method. We can + // here specify, whether the first ( probalby only) content section should + // have a public viewer, i.e. without registration and login. + /** + * Whether to make content viewable to 'The Public', ie non-registered users. + * + * Parameter name in the old initializer code: PUBLIC. Default true. + */ + private final BooleanParameter + m_isPublic = new BooleanParameter( + "com.arsdigita.cms.section.is_public", + 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.section.ctypes_list", + Parameter.REQUIRED, + new String[] {} ); + + // Page Resolver Class, set autonomously by ContentSection.create() method. + + // Item Resolver Class, configurable. + /** + * Name of the item resolver class to use for the section (defaults to + *
com.arsdigita.cms.dispatcher.MultilingualItemResolver
). + * + * Default value (site-wide) is handled via the parameter + *
com.arsdigita.cms.default_item_resolver_class
. + * Section-specific override can be added here. Only do so if you are + * changing from the default for a specific content section. The class + * must implement
com.arsdigita.cms.dispatcher.ItemResolver
. + * + * Parameter name ITEM_RESOLVER_CLASS in the old initializer system. + * Description: The ItemResolver class to use for the section + * (defaults to MultilingualItemResolver) + */ + private final Parameter + m_itemResolverClass = new StringParameter( + "com.arsdigita.cms.section.item_resolver_class", + Parameter.OPTIONAL, null ); + // , "com.arsdigita.cms.dispatcher.MultilingualItemResolver" + + + // Template Resolver Class, configurable. + /** + * Name of the template resolver class to use for the section + * (defaults to
com.arsdigita.cms.dispatcher.DefaultTemplateResolver
) + * + * Default value (site-wide) is handled via the parameter + *
com.arsdigita.cms.default_template_resolver_class
. + * Section-specific override can be added here. Only do so if you are + * changing from the default for a specific content section. The class + * must implement
com.arsdigita.cms.dispatcher.TemplateResolver
. + * + * Parameter name TEMPLATE_RESOLVER_CLASS in the old initializer system. + */ + private final Parameter + m_templateResolverClass = new StringParameter( + "com.arsdigita.cms.section.template_resolver_class", + Parameter.OPTIONAL, + null ); + // "com.arsdigita.cms.dispatcher.DefaultTemplateResolver" ); + + + // XML Generator Class, set autonomously by ContentSection.create() method. + + + /** + * Determins weather to use section specific category tree(s). Defaults to + * false, so standard navigation is used. + * If set to true loader loads the categories from file(s) specified in the + * next parameter ( m_categoryFileList ) + */ + private final Parameter + m_useSectionCategories = new BooleanParameter + ("com.arsdigita.cms.section.use_section_categories", + Parameter.REQUIRED, new Boolean(false)); + + /** + * XML file containing the category tree to load for this content section. + * Usually not loaded {@see m_useSectionCategories). The files listed as + * default values are demo material and must be replaced in a production + * environment. + */ + private final Parameter + m_categoryFileList = new StringArrayParameter( + "com.arsdigita.cms.section.categories_toload", + Parameter.REQUIRED, + new String[] {"/WEB-INF/resources/article-categories.xml", + "/WEB-INF/resources/navigation-categories.xml"} ); + // Category tree to load + // categories = { "/WEB-INF/resources/article-categories.xml", + // "/WEB-INF/resources/navigation-categories.xml" }; + // m_conf.initParameter(CATEGORIES, + // "XML file containing the category tree", + // List.class, + // Collections.EMPTY_LIST); /** @@ -189,6 +356,14 @@ public final class ContentSectionConfig extends AbstractConfig { // parameters for creation of a new (additional) content section register(m_newContentSectionName); + // register(m_staffGroup); NOT IMPLEMENTED yet + register(m_isPublic); + register(m_itemResolverClass); + register(m_templateResolverClass); + register(m_contentTypeList); + register(m_useSectionCategories); + register(m_categoryFileList); + } @@ -201,14 +376,9 @@ public final class ContentSectionConfig extends AbstractConfig { /** * Retrieve the list of workflow tasks and events for each tasks which * should receive overdue notification alerts - * - * 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 List getTaskAlerts() { -// String[] m_taskAlerts = (String[]) get(m_contentTypeList); - return Arrays.asList(m_taskAlerts); + public final String[] getTaskAlerts() { + return (String[]) get(m_taskAlerts); } @@ -264,4 +434,144 @@ public final class ContentSectionConfig extends AbstractConfig { return (String) get(m_newContentSectionName); } + /** + * Retrieve the STAFF GROUP, i.e. a set of roles (author, editor, publisher, + * manager) and associated privileges for the content section to be created + * (m_contentSectionName). + * + * In loading step a complete default configuration is persisted in database, + * immutable at this point. + * See contentsection.ContentSectionSetup.registerRoles() + * In enterprise.init: name roles, List of roles to create. + * + * Set consists of a set of roles, for each role first field is the role name, + * second is the description, third is a list of privileges, and (optional) + * fourth is the workflow task to assign to. + * + * The set of roles constructed here is a complete set which reflects all + * functions of CMS and forms a necessary base for operations. When the first + * content section is created and loaded into database (during installation) + * this set is created, immutable by installer / administrator. Additional + * content section may be created using a subset. For a very special purpose + * a developer may alter the set. + * + * This method is typically used to construct the initial content section + * during installation. + * + * Not really implemented yet! We need a new parameter type "list" which + * must have multidimensional capabilities. + * + * As a temporary measure a constant list is retrieved. Until now the list + * was burried in enterprise.init and not user available for configuration. + * So it may turn into a permanent solution. + */ + public List getStuffGroup() { + + final List AUTH_PRIVS = Arrays.asList( + "new_item","read_item", "preview_item", "edit_item", + "categorize_items"); + final List EDIT_PRIVS = Arrays.asList( + "new_item","read_item", "preview_item", "edit_item", + "categorize_items", "delete_item", "approve_item" ); + final List PUBL_PRIVS = Arrays.asList( + "new_item","read_item", "preview_item", "edit_item", + "categorize_items", "delete_item", "approve_item", + "publish"); + final List MNGR_PRIVS = Arrays.asList( + "new_item","read_item", "preview_item", "edit_item", + "categorize_items", "delete_item", "approve_item", + "publish", + "staff_admin", "content_type_admin", "lifecycle_admin", + "workflow_admin", "category_admin"); + + m_staffGroup = new ArrayList(); + + m_staffGroup.add + ( new ArrayList() {{ add("Author"); + add("Creates new content"); + add(AUTH_PRIVS); + add("Authoring"); + }} + ); + m_staffGroup.add + ( new ArrayList() {{ add("Editor"); + add("Reviews and approves the author's work"); + add(EDIT_PRIVS); + add("Approval"); + }} + ); + m_staffGroup.add + ( new ArrayList() {{ add("Publisher"); + add("Deploys the content to the web site"); + add(PUBL_PRIVS); + add("Publishing"); + }} + ); + m_staffGroup.add + ( new ArrayList() {{ add("Manager"); + add("Manages the overall content section"); + add(MNGR_PRIVS); + // NB, manager doesn't have any assigned + // task for workflow - (as usual) + }} + ); + + return (List) m_staffGroup ; + + } + + /** + * Retrieve whether the content-section is publicly viewable (i.e. without + * registration and login) + */ + public Boolean isPubliclyViewable() { + return ((Boolean) get(m_isPublic)).booleanValue(); + } + + /** + * Retrieve the item resolver class + */ + public String getItemResolverClass() { + return (String) get(m_itemResolverClass); + } + + /** + * Retrieve the template resolver class + */ + public String getTemplateResolverClass() { + return (String) get(m_templateResolverClass); + } + + + /** + * Retrieve weather to use section specific categories. If true they are + * loaded using the next parameters file list {@see getUseSectionCategories()} + * + * Default value is false, so standard navigation is used. + * @return + */ + public final boolean getUseSectionCategories() { + return ((Boolean) get(m_useSectionCategories)).booleanValue(); + } + + /** + * Retrieve the list of files containing categories to load. + * In old Initialiser: Parameter name: CATEGORIES + * Deskr. "XML file containing the category tree" + */ + public List getCategoryFileList() { + String[] catFiles = (String[]) get(m_categoryFileList); + return Arrays.asList(catFiles); + } + + /** + * Retrieve the + */ + public List getContentSectionsContentTypes() { + String[] taskAlerts = (String[]) get(m_contentTypeList); + return Arrays.asList(taskAlerts); + } + + + } diff --git a/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java new file mode 100644 index 000000000..db1e7391e --- /dev/null +++ b/ccm-cms/src/com/arsdigita/cms/contentsection/ContentSectionSetup.java @@ -0,0 +1,696 @@ +/* + * Copyright (C) 2010 Peter Boy All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.contentsection; + +import com.arsdigita.categorization.Category; +import com.arsdigita.categorization.RootCategoryCollection; +import com.arsdigita.cms.ContentSection; +import com.arsdigita.cms.ContentType; +import com.arsdigita.cms.ContentTypeLifecycleDefinition; +import com.arsdigita.cms.ContentTypeWorkflowTemplate; +import com.arsdigita.cms.SecurityManager; +import com.arsdigita.cms.Template; +import com.arsdigita.cms.TemplateManagerFactory; +import com.arsdigita.cms.lifecycle.LifecycleDefinition; +import com.arsdigita.cms.lifecycle.PhaseDefinition; +import com.arsdigita.cms.util.GlobalizationUtil; +import com.arsdigita.cms.workflow.CMSTask; +import com.arsdigita.cms.workflow.CMSTaskType; +import com.arsdigita.domain.DataObjectNotFoundException; +// import com.arsdigita.domain.DomainObject; +import com.arsdigita.initializer.InitializationException; +// import com.arsdigita.kernel.ACSObjectInstantiator; +import com.arsdigita.kernel.Party; +import com.arsdigita.kernel.PartyCollection; +import com.arsdigita.kernel.Role; +import com.arsdigita.kernel.permissions.PermissionService; +import com.arsdigita.kernel.permissions.PrivilegeDescriptor; +// import com.arsdigita.persistence.DataObject; +// import com.arsdigita.runtime.AbstractConfig; +import com.arsdigita.cms.LoaderConfig; +import com.arsdigita.util.Assert; +import com.arsdigita.util.UncheckedWrapperException; +// import com.arsdigita.web.ApplicationSetup; +import com.arsdigita.workflow.simple.WorkflowTemplate; +import com.arsdigita.xml.XML; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Date; +import java.util.EmptyStackException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +// import java.util.NoSuchElementException; +import java.util.Stack; + +import org.apache.log4j.Logger; +import org.xml.sax.Attributes; +import org.xml.sax.helpers.DefaultHandler; + +/** + * Helper class to setup (configure) a newly created content section instance. + * It handles those properties of a content section, which are to be persisted + * into the database. + * + * @author Peter Boy (pboy@barkhof.uni-bremen.de) + * @author Jon Orris (jorris@redhat.com) + * @version $Id: $ + */ +public final class ContentSectionSetup { + + private static Logger s_log = Logger.getLogger(ContentSectionSetup.class); + + private final static String STYLESHEET = "/packages/content-section/xsl/cms.xsl"; + private HashMap m_tasks = new HashMap(); + private LifecycleDefinition m_lcd; + private WorkflowTemplate m_wf; + final ContentSection m_section; + + // Load main CMS configuration file + private static final LoaderConfig s_conf = new LoaderConfig(); + + + /** + * Constructor. Using this constructor the content section has to be + * already created using ContentSection.create(name) + * + * @param section name of a content section previously created by + * ContentSection.create + */ + public ContentSectionSetup(ContentSection section) { + Assert.exists(section, ContentSection.class); + m_section = section; + } + + + /** + * Wrapper class to create and configure a content section instance + * in one step. + * + */ + public static void setupContentSectionAppInstance(String name, + List staffGroup, + Boolean isPubliclyViewable, + String itemResolverClassName, + String templateResolverClassName, + List sectionContentTypes, + Boolean useSectionCategories, + List categoryFileList + ) { + s_log.info("Creating content section on /" + name); + + ContentSection section = ContentSection.create(name); + ContentSectionSetup setup = new ContentSectionSetup(section); + + // Setup the access controls + setup.registerRoles(staffGroup); + setup.registerViewers(isPubliclyViewable); + setup.registerPublicationCycles(); + setup.registerWorkflowTemplates(); + setup.registerResolvers( itemResolverClassName,templateResolverClassName ); + + // setup.registerContentTypes((List)m_conf.getParameter(TYPES)); + setup.registerContentTypes(sectionContentTypes); + + // section specific categories, usually not used. + if (useSectionCategories) { + // Iterator files = ((List) m_conf.getParameter(CATEGORIES)).iterator(); + // Iterator files = s_conf.getCategoryFileList().iterator(); + Iterator files = categoryFileList.iterator(); + while ( files.hasNext() ) { + setup.registerCategories((String) files.next()); + } + } + setup.registerAlerts(); + + section.save(); + + // return section; + + } + + + + /** + * Steps through a list of roles which are part of a staff group and + * delegates processing of each role. + * + * @param roles + */ + public void registerRoles(List roles) { + + Iterator i = roles.iterator(); + while (i.hasNext()) { + List role = (List)i.next(); + + String name = (String)role.get(0); + String desc = (String)role.get(1); + List privileges = (List)role.get(2); + String task = (role.size() > 3 ? (String)role.get(3) : null); + + s_log.info("Creating role " + name); + + + Role group = registerRole( + name, + desc, + privileges); + + if (task != null) + m_tasks.put(task, group); + } + + } + + /** + * Takes the characteristics of a role and persists them in the database. + * + * @param name Name of the role + * @param desc Description of role + * @param privileges set (list) of privileges associated with the role + * @return + */ + private Role registerRole(String name, String desc, List privileges) { + + Role role = m_section.getStaffGroup().createRole(name); + role.setDescription(desc); + role.save(); + + Iterator i = privileges.iterator(); + while (i.hasNext()) { + String priv = (String)i.next(); + s_log.info("Granting privilege cms_" + priv); + + role.grantPermission(m_section, + PrivilegeDescriptor.get("cms_" + priv)); + + if (priv.equals(SecurityManager.CATEGORY_ADMIN) || + priv.equals(SecurityManager.CATEGORIZE_ITEMS)) { + RootCategoryCollection coll = Category.getRootCategories(m_section); + while (coll.next()) { + if (priv.equals(SecurityManager.CATEGORY_ADMIN)) { + role.grantPermission(coll.getCategory(), + PrivilegeDescriptor.ADMIN); + } else { + role.grantPermission(coll.getCategory(), + Category.MAP_DESCRIPTOR); + } + } + } + } + + return role; + } + + /** + * Creates a public user role and adds permission to read published pages. + * + * @param pub Boolean wether published pages are accessible by the public + * (i.e. without login). + */ + public void registerViewers(Boolean pub) { + + // XXX Obviously the pub parameter does not determine public access or + // not! + Role viewers = m_section.getViewersGroup().createRole("Content Reader"); + viewers.setDescription("Can view published pages within this section"); + viewers.save(); + + // XXX Shouldn't read permission granted depending on pub=true? + viewers.grantPermission(m_section, + PrivilegeDescriptor.get("cms_read_item")); + + String email = Boolean.TRUE.equals(pub) ? "public@nullhost" + : "registered@nullhost"; + + Party viewer = retrieveParty(email); + if (viewer == null) + throw new InitializationException( + (String) GlobalizationUtil.globalize( + "cms.installer.cannot_find_group_for_email").localize() + email); + + s_log.info("Adding " + email + " to viewers role"); + viewers.getGroup().addMemberOrSubgroup(viewer); + viewers.save(); + } + + /** + * Retrieves a party by eimail as part of the viewers registration process. + * + * @param email + * @return + */ + private Party retrieveParty(String email) { + PartyCollection parties = Party.retrieveAllParties(); + parties.filter(email); + if (parties.next()) { + Party party = parties.getParty(); + parties.close(); + return party; + } + return null; + } + + /** + * Checks for specific item resolver and template resolver classes probably + * specified in parameters, otherwise uses system wide default parameters + * specified in CMS global configuration file. Delegates persistence task + * to ContentSection. + * + * @param itemResolverClassName + * @param templateResolverClassName + */ + public void registerResolvers(String itemResolverClassName, + String templateResolverClassName) { + + if (itemResolverClassName != null && itemResolverClassName.length()>0) { + m_section.setItemResolverClass(itemResolverClassName); + s_log.info("Registering " + itemResolverClassName + + " as the item resolver class"); + } else { + m_section.setItemResolverClass(ContentSection.getConfig() + .getDefaultItemResolverClass() + .getName()); + s_log.info("Registering " + itemResolverClassName + + " as the item resolver class"); + } + if (templateResolverClassName != null && templateResolverClassName.length()>0) { + m_section.setTemplateResolverClass(templateResolverClassName); + s_log.info("Registering " + templateResolverClassName + + " as the template resolver class"); + } else { + m_section.setTemplateResolverClass(ContentSection.getConfig() + .getDefaultTemplateResolverClass() + .getName()); + s_log.info("Registering " + templateResolverClassName + + " as the template resolver class"); + } + + m_section.save(); + } + + /** + * Create a (default) publication cycle and store it in the datavbase + * (delegated to package com.arsdigita.cms.lifecycle) + * + * @throws InitializationException + */ + public void registerPublicationCycles() + throws InitializationException { + + // The feature lifecycle. + LifecycleDefinition lcd = new LifecycleDefinition(); + lcd.setLabel( (String) GlobalizationUtil.globalize( + "cms.installer.simple_publication").localize()); + lcd.setDescription("A one-phase lifecycle for items."); + lcd.save(); + + PhaseDefinition pd = lcd.addPhaseDefinition( + "Live", "The first phase. It lasts forever.", + new Integer(0), null, null); + pd.save(); + + lcd.save(); + + m_lcd = lcd; + // Save the created life cycle for the section to be set up. + m_section.addLifecycleDefinition(lcd); + m_section.save(); + } + + /** + * Defines a (default for section) workflow which gets persisted in tne + * database. + * + * @throws InitializationException + */ + public void registerWorkflowTemplates() + throws InitializationException { + + // The 3-step production workflow. + WorkflowTemplate wf = new WorkflowTemplate(); + wf.setLabel( (String) GlobalizationUtil.globalize( + "cms.installer.production_workflow").localize()); + wf.setDescription("A process that involves creating and approving content."); + wf.save(); + + CMSTask authoring = new CMSTask(); + authoring.setLabel((String) GlobalizationUtil.globalize( + "cms.installer.authoring").localize()); + authoring.setDescription("Create content."); + authoring.save(); + + + Role author = (Role)m_tasks.get("Authoring"); + if (author != null) + authoring.assignGroup(author.getGroup()); + + authoring.setTaskType(CMSTaskType.retrieve(CMSTaskType.AUTHOR)); + authoring.save(); + + CMSTask approval = new CMSTask(); + approval.setLabel( (String) GlobalizationUtil.globalize( + "cms.installer.approval").localize()); + approval.setDescription("Approve content."); + approval.save(); + approval.addDependency(authoring); + approval.save(); + + Role approver = (Role)m_tasks.get("Approval"); + if (approver != null) + approval.assignGroup(approver.getGroup()); + + approval.setTaskType(CMSTaskType.retrieve(CMSTaskType.EDIT)); + approval.save(); + + + CMSTask deploy = new CMSTask(); + deploy.setLabel((String) GlobalizationUtil.globalize( + "cms.installer.deploy").localize()); + deploy.setDescription("Deploy content."); + deploy.save(); + deploy.addDependency(approval); + deploy.save(); + + Role publisher = (Role)m_tasks.get("Publishing"); + if (publisher != null) + deploy.assignGroup(publisher.getGroup()); + + deploy.setTaskType(CMSTaskType.retrieve(CMSTaskType.DEPLOY)); + deploy.save(); + + wf.addTask(authoring); + wf.addTask(approval); + wf.addTask(deploy); + wf.save(); + + m_section.addWorkflowTemplate(wf); + m_section.save(); + + m_wf = wf; + } + + /** + * Steps through a list of congtent types to be available for this content + * section and delegates processing of each type. + * + * @param types list of content types to be available for this content section + */ + public void registerContentTypes(List types) { + + Iterator i = types.iterator(); + + while (i.hasNext()) { + Object obj = i.next(); + if (obj instanceof String) { + registerContentType((String)obj); + } else { + List list = (List)obj; + String name = (String)list.get(0); + String file = (String)list.get(1); + + ContentType type = registerContentType(name); + registerTemplate(type, file); + } + } + } + + /** + * Process one content type and registers it with the current content section. + * + * @param name + * @return + */ + ContentType registerContentType(String name) { + ContentType type = null; + try { + type = ContentType.findByAssociatedObjectType(name); + } catch (DataObjectNotFoundException ex) { + throw new UncheckedWrapperException( + (String) GlobalizationUtil.globalize( + "cms.installer.cannot_find_content_type").localize() + name, ex); + } + + s_log.info("Adding type " + name + " to " + m_section.getDisplayName()); + m_section.addContentType(type); + + s_log.info("Setting the default lifecycle for " + + name + " to " + m_lcd.getLabel()); + ContentTypeLifecycleDefinition. + updateLifecycleDefinition(m_section, type, m_lcd); + m_lcd.save(); + + s_log.info("Setting the default workflow template for " + name + + " to " + m_wf.getLabel()); + ContentTypeWorkflowTemplate.updateWorkflowTemplate(m_section, type, m_wf); + m_wf.save(); + + return type; + } + + void registerTemplate(ContentType type, String filename) { + // Use the base of the file name (ie without path & extension) + // as the template name + int pos1 = filename.lastIndexOf("/"); + int pos2 = filename.lastIndexOf("."); + + if (pos2 == -1) + pos2 = filename.length(); + + String label = filename.substring(pos1+1,pos2); + + String typename = type.getClassName(); + int pos3 = typename.lastIndexOf("."); + String name = typename.substring(pos3+1, typename.length()) + "-" + label; + + Template temp = new Template(); + temp.setContentSection(m_section); + temp.setName(name); + temp.setLabel(label); + temp.setParent(m_section.getTemplatesFolder()); + + final ClassLoader loader = Thread.currentThread + ().getContextClassLoader(); + final InputStream stream = loader.getResourceAsStream + (filename.substring(1)); + + if (stream == null) { + throw new IllegalStateException + ((String) GlobalizationUtil.globalize + ("cms.installer.cannot_find_file").localize() + filename); + } + + final BufferedReader input = new BufferedReader + (new InputStreamReader(stream)); + + StringBuffer body = new StringBuffer(); + String line; + for (;;) { + try { + line = input.readLine(); + } catch (IOException ex) { + throw new UncheckedWrapperException( + (String) GlobalizationUtil.globalize( + "cms.installer.cannot_read_line_of_data").localize(), ex); + } + if (line == null) + break; + + body.append(line); + body.append("\n"); + } + + temp.setText(body.toString()); + + temp.save(); + + TemplateManagerFactory.getInstance() + .addTemplate(m_section, type, temp, "public"); + + temp.publish(m_lcd, new Date()); + // Dan said to comment this out + // temp.getLifecycle().start(); + } + + /** + * + * @param filename + */ + public void registerCategories(String filename) { + + if (filename == null) { + s_log.info("not loading any categories"); + return; + } + + s_log.info("loading categories from " + filename); + + XML.parseResource(filename, new CategoryHandler(m_section)); + } + + /** + * 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"); + alert.save(); + } + + +// // Currently there is no way to persists alert preferemces, therefore +// // currently not a loader or setup task. +// /** +// * Steps through a string array of tasks and associated alert events +// * creating section specific CMStasks. +// * +// * @param tasks +// */ +// public void loadTaskAlerts(String[] taskAlerts) { +// +// if (taskAlerts != null) { +// for (int i=0,n=taskAlerts.length; iInitializes a content section, registering a default workflow, lifecycle & - * roles and adding the content types. + * Initializes the content section sub-package of the CMS package (module). + * + * XXX Reformulate according to the code development! + * Currently: + * - creation of additional content sections during restart (comming soon) + * - initializes alert preferences for each content section + * - initializes overdue alerts for each content section + * In the (hopefully) near future: + * Content section specific tasks of cms.Initializer will be moved into this + * Initializer. * - *

The initialization process takes several configuration - * parameters. The name is the name of the content - * section, the types is a list of content types - * to register * * @author Daniel Berrange (berrange@redhat.com) * @author Michael Pih - * @author pb + * @author pboy (pb@zes.uni-bremen.de) * @version $Id: $ */ public class Initializer extends CompoundInitializer { @@ -78,11 +75,10 @@ public class Initializer extends CompoundInitializer { /** 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(); + private static final ContentSectionConfig s_conf = ContentSectionConfig.getInstance(); /** The Timer used to send Unfinished notifications */ - private static Timer s_unfinishedTimer; + private static Vector s_unfinishedTimers = new Vector(); public Initializer() { @@ -90,6 +86,7 @@ public class Initializer extends CompoundInitializer { //final int database = DbHelper.getDatabaseFromURL(url); } +// Currently nothing to do here. Will be changed in the ongoing migration process // /** // * An empty implementation of {@link Initializer#init(DataInitEvent)}. // * @@ -98,42 +95,35 @@ public class Initializer extends CompoundInitializer { // public void init(DataInitEvent evt) { // } - /** - * Initializes domain-coupling machinery, usually consisting of - * registering object instantiators and observers. - * - */ - public void init(DomainInitEvent evt) { - s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) invoked"); - - // Recursive invokation of init, is it really necessary?? - // On the other hand: - // An empty implementations prevents this initializer from being executed. - // A missing implementations causes the super class method to be executed, - // which invokes the above added LegacyInitializer. - // If super is not invoked, various other cms sub-initializer may not run. - super.init(evt); - - - /* - * 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()); - - - s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) completed"); - } +// Currently nothing to do here. Will be changed in the ongoing migration process +// /** +// * Initializes domain-coupling machinery, usually consisting of +// * registering object instantiators and observers. +// * +// */ +// public void init(DomainInitEvent evt) { +// s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) invoked"); +// +// // Recursive invokation of init, is it really necessary?? +// // On the other hand: +// // An empty implementations prevents this initializer from being executed. +// // A missing implementations causes the super class method to be executed, +// // which invokes the above added LegacyInitializer. +// // If super is not invoked, various other cms sub-initializer may not run. +// super.init(evt); +// +// +// s_log.debug("CMS.installer.Initializer.init(DomainInitEvent) completed"); +// } /** * Implementation of the {@link Initializer#init(ContextInitEvent)} * method. * - * Initializes the scheduler thread to fire all the events for the - * ...... that have just began or ended. + * Steps through all installed content sections and for each section + * - initializes the allert preferences + * - initializes the scheduler background thread to fire all all alert events. * * A delay value of 0 inhibits start of processing. * @param evt The context init event. @@ -141,16 +131,33 @@ public class Initializer extends CompoundInitializer { 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()); + super.init(evt); + // Currently we have only one set of both alert preference configuration + // and timer configuration. Notification is handled on a per section + // base, so we have to configure all sections in the same way. + // TODO: Store alerts prefs as well as timer configuration for each + // content section and make it configurable in the UI. + // For now we step through all sections and configure them the same way. + ContentSectionCollection sections=ContentSection.getAllSections(); + while( sections.next() ) { + ContentSection section = sections.getContentSection(); + + // Initialize workflow tasks and associated events from configuration + // file filling a hashmap. + initializeTaskAlerts(section, s_conf.getTaskAlerts() ); + + Timer unfinishedTimer = startNotifierTask( + section, + s_conf.getSendOverdueAlerts(), + s_conf.getTaskDuration(), + s_conf.getAlertInterval(), + s_conf.getMaxAlerts() + ); + if ( unfinishedTimer != null) { + s_unfinishedTimers.addElement(unfinishedTimer); + } + } s_log.debug("content section ContextInitEvent completed"); } @@ -160,16 +167,56 @@ public class Initializer extends CompoundInitializer { * method. * */ + @Override public void close(ContextCloseEvent evt) { s_log.debug("content section ContextCloseEvent started"); - if (s_unfinishedTimer != null) { - s_unfinishedTimer.cancel(); - s_unfinishedTimer = null; + + Timer unfinishedTimer = null; + if (s_unfinishedTimers.size() > 0) { + for (Enumeration el=s_unfinishedTimers.elements(); el.hasMoreElements(); ) { + unfinishedTimer = (Timer) el.nextElement(); + if(unfinishedTimer != null) unfinishedTimer.cancel(); + unfinishedTimer = null; + // s_unfinishedTimer = null; + } + } s_log.debug("content section ContextCloseEvent completed"); } + /** + * Steps through a string array of tasks and associated alert events + * creating section specific CMStasks from configuration file. + * + * Note: Tasks are created on a per section base, but we have currently no + * way to store different values for each section. So all sections are + * configured equal. + * + * @param section A section object + * @param taskAlerts An array of tasks and associated events + */ + public void initializeTaskAlerts(ContentSection section, + String[] taskAlerts) { + + if (taskAlerts != null) { + for (int i=0,n=taskAlerts.length; icreate Workspace package type and instance *

  • create CMS Service package type and instance
  • * + * + * All these tasks are migrated to Loader (2010-10-15). */ diff --git a/ccm-cms/src/com/arsdigita/cms/installer/Installer.java b/ccm-cms/src/com/arsdigita/cms/installer/Installer.java.nolongerInUse similarity index 95% rename from ccm-cms/src/com/arsdigita/cms/installer/Installer.java rename to ccm-cms/src/com/arsdigita/cms/installer/Installer.java.nolongerInUse index e3a5cb3dd..e36c08634 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/Installer.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/Installer.java.nolongerInUse @@ -16,6 +16,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ + + +// ///////////////////////////////////////////////////////////////////////////// +// Migration Status +// All tasks this class used to perform are migrated to cms.Loader +// File is kept in trunk for reference purpose until the whole migration process +// will be completed. (2010-20-18) +// ///////////////////////////////////////////////////////////////////////////// + + package com.arsdigita.cms.installer; diff --git a/ccm-cms/src/com/arsdigita/cms/installer/ServiceInstaller.java b/ccm-cms/src/com/arsdigita/cms/installer/ServiceInstaller.java.nolongerInUse similarity index 91% rename from ccm-cms/src/com/arsdigita/cms/installer/ServiceInstaller.java rename to ccm-cms/src/com/arsdigita/cms/installer/ServiceInstaller.java.nolongerInUse index 800b0e461..95cf1140e 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/ServiceInstaller.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/ServiceInstaller.java.nolongerInUse @@ -16,6 +16,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ + + +// ///////////////////////////////////////////////////////////////////////////// +// Migration Status +// All tasks this class used to perform are migrated to either cms.Loader or +// cms.CMS. +// File is kept in trunk for reference purpose until the whole migration process +// will be completed. (2010-20-18) +// ///////////////////////////////////////////////////////////////////////////// + + package com.arsdigita.cms.installer; import com.arsdigita.domain.DataObjectNotFoundException; diff --git a/ccm-cms/src/com/arsdigita/cms/installer/VersioningUpgrader.java b/ccm-cms/src/com/arsdigita/cms/installer/VersioningUpgrader.java.nolongerInUse similarity index 100% rename from ccm-cms/src/com/arsdigita/cms/installer/VersioningUpgrader.java rename to ccm-cms/src/com/arsdigita/cms/installer/VersioningUpgrader.java.nolongerInUse diff --git a/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java b/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java.nolongerInUse similarity index 93% rename from ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java rename to ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java.nolongerInUse index d71e82e22..b62bf5191 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java +++ b/ccm-cms/src/com/arsdigita/cms/installer/WorkspaceInstaller.java.nolongerInUse @@ -16,6 +16,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ + + +// ///////////////////////////////////////////////////////////////////////////// +// Migration Status +// All tasks this class used to perform are migrated to either cms.Loader or +// cms.CMS. +// File is kept in trunk for reference purpose until the whole migration process +// will be completed. (2010-20-18) +// ///////////////////////////////////////////////////////////////////////////// + + package com.arsdigita.cms.installer; import com.arsdigita.domain.DataObjectNotFoundException; diff --git a/ccm-cms/src/com/arsdigita/cms/lifecycle/LifecycleDefinition.java b/ccm-cms/src/com/arsdigita/cms/lifecycle/LifecycleDefinition.java index 0ee44b841..12b3eb77c 100755 --- a/ccm-cms/src/com/arsdigita/cms/lifecycle/LifecycleDefinition.java +++ b/ccm-cms/src/com/arsdigita/cms/lifecycle/LifecycleDefinition.java @@ -98,6 +98,7 @@ public class LifecycleDefinition extends ACSObject { * @return the base PDL object type for this definition. Child classes should * override this method to return the correct value */ + @Override public String getBaseDataObjectType() { return BASE_DATA_OBJECT_TYPE; } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryForm.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryForm.java index 231bb1098..d1b0d73ee 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryForm.java @@ -29,6 +29,11 @@ import com.arsdigita.cms.CMS; import com.arsdigita.cms.ContentItem; import com.arsdigita.kernel.ACSObject; +/** + * (No description available yet). + * + * Usage of this class is configured in parameter c.ad.cms.category_authoring_add_form + */ public class ItemCategoryForm extends ACSObjectCategoryForm { private static Logger s_log = Logger.getLogger(ItemCategoryForm.class); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryStep.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryStep.java index 0bf80d138..9eed99aa7 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryStep.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/ItemCategoryStep.java @@ -33,13 +33,17 @@ import com.arsdigita.web.RedirectSignal; import com.arsdigita.cms.CMS; import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.ItemSelectionModel; -import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; +// import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; import com.arsdigita.util.Assert; import com.arsdigita.util.Classes; import java.math.BigDecimal; import org.apache.log4j.Logger; +/** + * + * + */ public class ItemCategoryStep extends SimpleContainer implements Resettable{ diff --git a/ccm-cms/src/com/arsdigita/cms/installer/PageClassConfigHandler.java b/ccm-cms/src/com/arsdigita/cms/util/PageClassConfigHandler.java similarity index 98% rename from ccm-cms/src/com/arsdigita/cms/installer/PageClassConfigHandler.java rename to ccm-cms/src/com/arsdigita/cms/util/PageClassConfigHandler.java index 4c008cd1f..31ef078e7 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/PageClassConfigHandler.java +++ b/ccm-cms/src/com/arsdigita/cms/util/PageClassConfigHandler.java @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -package com.arsdigita.cms.installer; +package com.arsdigita.cms.util; import org.xml.sax.helpers.DefaultHandler; diff --git a/ccm-cms/src/com/arsdigita/cms/installer/Util.java b/ccm-cms/src/com/arsdigita/cms/util/Util.java similarity index 97% rename from ccm-cms/src/com/arsdigita/cms/installer/Util.java rename to ccm-cms/src/com/arsdigita/cms/util/Util.java index e5276f21f..668b687a1 100755 --- a/ccm-cms/src/com/arsdigita/cms/installer/Util.java +++ b/ccm-cms/src/com/arsdigita/cms/util/Util.java @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -package com.arsdigita.cms.installer; +package com.arsdigita.cms.util; import com.arsdigita.initializer.InitializationException; import org.apache.oro.text.perl.Perl5Util; diff --git a/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java b/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java index 29883c4ed..4313fd20f 100755 --- a/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java +++ b/ccm-cms/src/com/arsdigita/cms/workflow/CMSTask.java @@ -20,7 +20,7 @@ package com.arsdigita.cms.workflow; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentSection; -import com.arsdigita.cms.SecurityManager; +// import com.arsdigita.cms.SecurityManager; import com.arsdigita.cms.ui.ContentItemPage; import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.domain.DataObjectNotFoundException; @@ -43,7 +43,6 @@ import com.arsdigita.persistence.Session; import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.metadata.ObjectType; import com.arsdigita.util.Assert; -import com.arsdigita.util.StringUtils; import com.arsdigita.versioning.TagCollection; import com.arsdigita.versioning.Transaction; import com.arsdigita.versioning.TransactionCollection; @@ -303,6 +302,7 @@ public class CMSTask extends UserTask { * Creates a deep copy of this task and stores a persistent copy. * TODO: refactor this method in this class, and its parents * */ + @Override public Object clone() { CMSTask taskClone = new CMSTask(); copyAttributes(taskClone); @@ -444,6 +444,7 @@ public class CMSTask extends UserTask { return send; } + @Override protected boolean sendAlerts(String operation) { ContentSection section = getContentSection(); String label = getLabel(); @@ -466,6 +467,7 @@ public class CMSTask extends UserTask { * @see com.arsdigita.messaging.Message * @see #filterUsersAndSendMessage */ + @Override protected void sendMessageToAssignees(Message msg) { if (m_authorOnly) { ContentItem item = getItem(); @@ -619,6 +621,7 @@ public class CMSTask extends UserTask { } } + @Override public void finish() throws TaskException { super.finish(); Integer type = getTaskType().getID(); diff --git a/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java b/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java index edd954bc9..7eda4911d 100755 --- a/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java +++ b/ccm-cms/src/com/arsdigita/cms/workflow/UnfinishedTaskNotifier.java @@ -83,6 +83,9 @@ public class UnfinishedTaskNotifier extends TimerTask { } + /** + * The action to be performed by this timer Task. + */ public void run() { Thread.currentThread().setName("unfinished-notifier"); try {