From 9b70cf801857affaea3bb03cea78da91088b9dd0 Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 22 Jul 2014 08:46:01 +0000 Subject: [PATCH] - The list of content types on the NewItemForm is now sorted by the localised names of the content types - The length of the description of (releated) link is now limited. The limit can be configured using the com.arsdigita.cms.link_description_max_length property in CMSConfig. The default value are 400 characters. git-svn-id: https://svn.libreccm.org/ccm/trunk@2769 8810af33-2d31-482b-a856-94f89814c4df --- .../ui/RelatedLinkPropertyForm.java | 89 +- ccm-cms/src/com/arsdigita/cms/CMSConfig.java | 2324 ++++++++--------- .../cms/CMSConfig_parameter.properties | 5 + .../cms/contenttypes/ui/LinkPropertyForm.java | 243 +- .../cms/ui/authoring/NewItemForm.java | 75 +- .../arsdigita/bebop/form/CheckboxGroup.java | 7 +- .../src/com/arsdigita/bebop/form/Option.java | 5 +- .../com/arsdigita/bebop/form/OptionGroup.java | 299 ++- .../com/arsdigita/bebop/form/RadioGroup.java | 7 +- .../src/com/arsdigita/bebop/form/Select.java | 19 +- .../arsdigita/bebop/form/SingleSelect.java | 60 +- .../ui/PublicationPropertyForm.java | 36 +- 12 files changed, 1653 insertions(+), 1516 deletions(-) diff --git a/ccm-cms-assets-relatedlink/src/com/arsdigita/cms/contentassets/ui/RelatedLinkPropertyForm.java b/ccm-cms-assets-relatedlink/src/com/arsdigita/cms/contentassets/ui/RelatedLinkPropertyForm.java index 7a63ca0d9..c27c57073 100755 --- a/ccm-cms-assets-relatedlink/src/com/arsdigita/cms/contentassets/ui/RelatedLinkPropertyForm.java +++ b/ccm-cms-assets-relatedlink/src/com/arsdigita/cms/contentassets/ui/RelatedLinkPropertyForm.java @@ -42,43 +42,41 @@ import com.arsdigita.util.Assert; import org.apache.log4j.Logger; /** - * Form to edit the basic properties of a RelatedLink. This form - * extends LinkPropertyForm in order to create items of the correct - * subclass and set the linkOwner property. Users have found the additional - * fields confusing at authoring time (resourceSize and resourceType) so we - * have added a configuration parameter that allows us to hide them on a - * site wide basis. + * Form to edit the basic properties of a RelatedLink. This form extends LinkPropertyForm in order + * to create items of the correct subclass and set the linkOwner property. Users have found the + * additional fields confusing at authoring time (resourceSize and resourceType) so we have added a + * configuration parameter that allows us to hide them on a site wide basis. + * * @version $Revision: #3 $ $Date: 2004/03/30 $ * @author Scott Seago (sseago@redhat.com) */ public class RelatedLinkPropertyForm extends LinkPropertyForm { private static final Logger logger = Logger.getLogger( - RelatedLinkPropertyForm.class); - private static boolean isHideNewTargetWindow = - RelatedLinkConfig.getInstance() - .isHideNewTargetWindow(); - private static boolean isHideAdditionalResourceFields = - RelatedLinkConfig.getInstance() - .isHideAdditionalResourceFields(); + RelatedLinkPropertyForm.class); + private static boolean isHideNewTargetWindow = RelatedLinkConfig.getInstance() + .isHideNewTargetWindow(); + private static boolean isHideAdditionalResourceFields = RelatedLinkConfig.getInstance() + .isHideAdditionalResourceFields(); private String m_linkListName; - + /** - * Creates a new form to edit the RelatedLink object specified - * by the item selection model passed in. - * @param itemModel The ItemSelectionModel to use to obtain the - * ContentItem to which this link is (or will be) attached - * @param link The LinkSelectionModel to use to obtain the - * Link to work on + * Creates a new form to edit the RelatedLink object specified by the item selection model + * passed in. + * + * @param itemModel The ItemSelectionModel to use to obtain the ContentItem to which this link + * is (or will be) attached + * @param link The LinkSelectionModel to use to obtain the Link to work on */ public RelatedLinkPropertyForm(ItemSelectionModel itemModel, - LinkSelectionModel link, String linkListName) { + LinkSelectionModel link, String linkListName) { this(itemModel, link, linkListName, null); } public RelatedLinkPropertyForm(ItemSelectionModel itemModel, - LinkSelectionModel link, String linkListName, ContentType contentType) { + LinkSelectionModel link, String linkListName, + ContentType contentType) { super(itemModel, link, contentType); logger.debug(String.format("linkListName = %s", linkListName)); @@ -105,32 +103,30 @@ public class RelatedLinkPropertyForm extends LinkPropertyForm { // m_URIOption.addOption(m_selectWindow); // add(m_URIOption, ColumnPanel.FULL_WIDTH); } - + if (isHideAdditionalResourceFields) { // Do nothing except protect the poor users from themselves. } else { add(new Label(RelatedLinkGlobalizationUtil.globalize( - "cms.contentassets.ui.related_link.resource_size"))); - TextField resSize = new TextField(new - StringParameter(RelatedLink.RESOURCE_SIZE)); + "cms.contentassets.ui.related_link.resource_size"))); + TextField resSize = new TextField(new StringParameter(RelatedLink.RESOURCE_SIZE)); add(resSize); add(new Label(RelatedLinkGlobalizationUtil.globalize( - "cms.contentassets.ui.related_link.resource_type"))); - SingleSelect resType = new SingleSelect(new - StringParameter(RelatedLink.RESOURCE_TYPE)); + "cms.contentassets.ui.related_link.resource_type"))); + SingleSelect resType = new SingleSelect(new StringParameter(RelatedLink.RESOURCE_TYPE)); addMimeOptions(resType); - add(resType); + add(resType); } Hidden linkListName = new Hidden(new StringParameter( - RelatedLink.LINK_LIST_NAME)); + RelatedLink.LINK_LIST_NAME)); add(linkListName); } /** - * Add mime-type options to the option group by loading all mime - * types which match a certain prefix from the database + * Add mime-type options to the option group by loading all mime types which match a certain + * prefix from the database * * @param w The mime type widget to which options should be added * @@ -144,11 +140,12 @@ public class RelatedLinkPropertyForm extends LinkPropertyForm { } } - /** - * Take care of basic RelatedLink creation steps. Creates the - * RelatedLink and sets the linkOwner property. + /** + * Take care of basic RelatedLink creation steps. Creates the RelatedLink and sets the linkOwner + * property. * * @param s the PageState + * * @return the newly-created RelatedLink */ @Override @@ -166,8 +163,8 @@ public class RelatedLinkPropertyForm extends LinkPropertyForm { } /** - * Over-ride super class method to initialize addtional fields specific - * to RelatedLink content asset. + * Over-ride super class method to initialize addtional fields specific to + * RelatedLink content asset. */ @Override public void init(FormSectionEvent fse) throws FormProcessException { @@ -183,7 +180,7 @@ public class RelatedLinkPropertyForm extends LinkPropertyForm { rl = (RelatedLink) getLinkSelectionModel().getSelectedLink(ps); data.put(RelatedLink.RESOURCE_SIZE, rl.getResourceSize()); if (rl.getResourceType() != null) { - data.put(RelatedLink.RESOURCE_TYPE, + data.put(RelatedLink.RESOURCE_TYPE, rl.getResourceType().getMimeType()); } data.put(RelatedLink.LINK_LIST_NAME, rl.getLinkListName()); @@ -196,9 +193,8 @@ public class RelatedLinkPropertyForm extends LinkPropertyForm { } } - /** - * over-ride super class method to set extended properties for - * RelatedLink. + /** + * over-ride super class method to set extended properties for RelatedLink. */ @Override protected void setLinkProperties(Link link, FormSectionEvent fse) { @@ -215,12 +211,13 @@ public class RelatedLinkPropertyForm extends LinkPropertyForm { rl.setResourceType(mType); } rl.setLinkListName((String) data.get(RelatedLink.LINK_LIST_NAME)); - + DataCollection links = RelatedLink.getRelatedLinks( - getContentItem(fse.getPageState()), - m_linkListName); + getContentItem(fse.getPageState()), + m_linkListName); rl.setOrder((int) links.size() + 1); - + super.setLinkProperties(link, fse); } + } diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java index d1a5bd370..2facea487 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSConfig.java +++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig.java @@ -51,8 +51,8 @@ import org.apache.log4j.Logger; /** * A record containing server-session scoped configuration properties. * - * Accessors of this class may return null. Developers should take care to trap - * null return values in their code. + * Accessors of this class may return null. Developers should take care to trap null return values + * in their code. * * @see ContentSection#getConfig() * @@ -61,1226 +61,1172 @@ import org.apache.log4j.Logger; */ public final class CMSConfig extends AbstractConfig { - /** - * Private Logger instance for debugging purpose. - */ - private static final Logger s_log = Logger.getLogger(CMSConfig.class); - /** - * Private Object to hold one's own instance to return to users. - */ - private static CMSConfig s_config; + /** + * Private Logger instance for debugging purpose. + */ + private static final Logger s_log = Logger.getLogger(CMSConfig.class); + /** + * Private Object to hold one's own instance to return to users. + */ + private static CMSConfig s_config; - /** - * Returns the singleton configuration record for the content section - * environment. - * - * @return The CMSConfig record; it cannot be null - */ - public static synchronized CMSConfig getInstanceOf() { - if (s_config == null) { - s_config = new CMSConfig(); - s_config.load(); - } + /** + * Returns the singleton configuration record for the content section environment. + * + * @return The CMSConfig record; it cannot be null + */ + public static synchronized CMSConfig getInstanceOf() { + if (s_config == null) { + s_config = new CMSConfig(); + 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; - /** - * Item category add form specifies 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); - /** - * 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 or the root folter for template folders. Path is relative to - * webapp root. Modify with care! Usually modified by developers only! - */ - private final Parameter m_templateRootPath = - new StringParameter( - "com.arsdigita.cms.template_root_path", - Parameter.REQUIRED, - "/templates/ccm-cms/content-section"); - // up to version 6.6.4 - // "/packages/content-section/templates"); - // URL resource: protocol handler removal: START - // remove: - // try { - // m_itemAdapters = new URLParameter - // ("com.arsdigita.cms.item_adapters", - // Parameter.REQUIRED, - // new URL("resource:WEB-INF/resources/cms-item-adapters.xml")); - // } catch (MalformedURLException ex) { - // 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 - /** - * 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, - Boolean.TRUE); - /** - * 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("Xinha.Config", - "/assets/xinha/CCMcmsXinhaConfig.js")); - // previous parameter definition: - // > DHTMLEditor.Config.STANDARD); < - // didn't work because of broken unmarshalling (cf. similiar problem - // with ResourceParameter and patch provided by Brad). It work for - // HTMLArea, because configuration was hard coded into xsl(!). - // Additionally, we would like to use a specific configuration for cms - // to include cms specific functions (like access to internal . - // content items for links and internal image assets, which may not - // be accessable by other modules which use DHTMLeditor. - // Would be bad style to configure a cms specific parameter in core. - /** - * 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); - /** - * 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); - /** - * Hide section admin tabs from users without administrative rights. - */ - private final Parameter m_hideAdminTabs = new BooleanParameter( - "com.arsdigita.cms.hide_admin_tabs", - Parameter.REQUIRED, - Boolean.FALSE); - /** - * Hide Folder Index Checkbox from folder view - */ - private final Parameter m_hideFolderIndexCheckbox = new BooleanParameter( - "com.arsdigita.cms.hide_folder_index_checkbox", - Parameter.REQUIRED, - Boolean.FALSE); - /** - * 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, - 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, - 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, - Boolean.FALSE); - /** - * 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, - 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, - Boolean.FALSE); - /** - * Hide User Defined Content Types UI - */ - private final Parameter m_hideUDCTUI = new BooleanParameter( - "com.arsdigita.cms.hide_udct_ui", - Parameter.REQUIRED, - 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()); - /** - * 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, - Boolean.FALSE); - /** - * 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, - Boolean.FALSE); - /** - * 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, - Boolean.TRUE); - /** - * 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(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(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, - Boolean.TRUE); - /** - * 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, - 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); - /** - * 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, - Boolean.TRUE); - /** - * 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); - /** - * 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)); - /** - * Limit the item search to current content section - */ - private final Parameter m_limitToContentSection = - new BooleanParameter( - "com.arsdigita.cms.search.limitToContentSection", - Parameter.OPTIONAL, - Boolean.TRUE); - /** - * 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 - */ - 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, - Boolean.FALSE); - /** - * 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, - Boolean.FALSE); - /** - * 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, - Boolean.FALSE); - /** - * 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 creation of a new Use Context in category tab of content - * sections. "Use Context" is the construct to constitute a category - * hierarchy implementet in core. It is superseded by the construct - * "Category Domain" in Terms (ccm-ldn-terms). Global parameter for all - * content sections. Default is false because all installation bundles - * use Terms. - */ - private final Parameter m_allowCategoryCreateUseContext = - new BooleanParameter( - "com.arsdigita.cms.allow_category_create_use_context", - Parameter.REQUIRED, - Boolean.FALSE); - /** - * Allow content creation in Workspace (content center) 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, - Boolean.TRUE); - /** - * Hide the legacy public site link in Workspace (content center) - * section listing. Legacy public site display is replaced by navigation - * based presentation (or by portlets) and should be hidden in the admin - * ui by default now. - */ - private final Parameter m_hideLegacyPublicSiteLink = - new BooleanParameter( - "com.arsdigita.cms.hide_legacy_public_site_link", - Parameter.REQUIRED, - Boolean.TRUE); - // /////////////////////////////////////////// - // 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, - Boolean.FALSE); - /** - * 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, - 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)); - /** - * 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, - 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 - // /////////////////////////////////////////// + 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; + /** + * Item category add form specifies 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); + /** + * 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 or the root folter for template folders. Path is relative to webapp root. Modify with + * care! Usually modified by developers only! + */ + private final Parameter m_templateRootPath = new StringParameter( + "com.arsdigita.cms.template_root_path", + Parameter.REQUIRED, + "/templates/ccm-cms/content-section"); + // up to version 6.6.4 + // "/packages/content-section/templates"); + // URL resource: protocol handler removal: START + // remove: + // try { + // m_itemAdapters = new URLParameter + // ("com.arsdigita.cms.item_adapters", + // Parameter.REQUIRED, + // new URL("resource:WEB-INF/resources/cms-item-adapters.xml")); + // } catch (MalformedURLException ex) { + // 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 + /** + * 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, + Boolean.TRUE); + /** + * 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("Xinha.Config", + "/assets/xinha/CCMcmsXinhaConfig.js")); + // previous parameter definition: + // > DHTMLEditor.Config.STANDARD); < + // didn't work because of broken unmarshalling (cf. similiar problem + // with ResourceParameter and patch provided by Brad). It work for + // HTMLArea, because configuration was hard coded into xsl(!). + // Additionally, we would like to use a specific configuration for cms + // to include cms specific functions (like access to internal . + // content items for links and internal image assets, which may not + // be accessable by other modules which use DHTMLeditor. + // Would be bad style to configure a cms specific parameter in core. + /** + * 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); + /** + * 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); + /** + * Hide section admin tabs from users without administrative rights. + */ + private final Parameter m_hideAdminTabs = new BooleanParameter( + "com.arsdigita.cms.hide_admin_tabs", + Parameter.REQUIRED, + Boolean.FALSE); + /** + * Hide Folder Index Checkbox from folder view + */ + private final Parameter m_hideFolderIndexCheckbox = new BooleanParameter( + "com.arsdigita.cms.hide_folder_index_checkbox", + Parameter.REQUIRED, + Boolean.FALSE); + /** + * 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, + 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, + 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, + Boolean.FALSE); + /** + * 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, + 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, + Boolean.FALSE); + /** + * Hide User Defined Content Types UI + */ + private final Parameter m_hideUDCTUI = new BooleanParameter( + "com.arsdigita.cms.hide_udct_ui", + Parameter.REQUIRED, + 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()); + /** + * 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, + Boolean.FALSE); + /** + * 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, + Boolean.FALSE); + /** + * 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, + Boolean.TRUE); + /** + * 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(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(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, + Boolean.TRUE); + /** + * 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, + 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); + /** + * 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, + Boolean.TRUE); + /** + * 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); + /** + * 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)); + /** + * Limit the item search to current content section + */ + private final Parameter m_limitToContentSection = new BooleanParameter( + "com.arsdigita.cms.search.limitToContentSection", + Parameter.OPTIONAL, + Boolean.TRUE); + /** + * 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 + */ + 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, + Boolean.FALSE); + /** + * 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, + Boolean.FALSE); + /** + * 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, + Boolean.FALSE); + /** + * 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 creation of a new Use Context in category tab of content sections. "Use Context" is the + * construct to constitute a category hierarchy implementet in core. It is superseded by the + * construct "Category Domain" in Terms (ccm-ldn-terms). Global parameter for all content + * sections. Default is false because all installation bundles use Terms. + */ + private final Parameter m_allowCategoryCreateUseContext = new BooleanParameter( + "com.arsdigita.cms.allow_category_create_use_context", + Parameter.REQUIRED, + Boolean.FALSE); + /** + * Allow content creation in Workspace (content center) 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, + Boolean.TRUE); + /** + * Hide the legacy public site link in Workspace (content center) section listing. Legacy public + * site display is replaced by navigation based presentation (or by portlets) and should be + * hidden in the admin ui by default now. + */ + private final Parameter m_hideLegacyPublicSiteLink = new BooleanParameter( + "com.arsdigita.cms.hide_legacy_public_site_link", + Parameter.REQUIRED, + Boolean.TRUE); + // /////////////////////////////////////////// + // 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, + Boolean.FALSE); + /** + * 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, + 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)); + /** + * 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, + 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 + // /////////////////////////////////////////// // Nolonger used, // replaced by c.ad.cms.ContentSection.getDefaultSection().getName() // 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); - ///////////////////////////////////////////// - // ItemSearchWidget - ///////////////////////////////////////////// - private final Parameter m_itemSearchDefaultTab = - new StringParameter( - "com.arsdigita.cms.item_search.default_tab", - Parameter.REQUIRED, "flatBrowse"); + // /////////////////////////////////////////// + // 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); + ///////////////////////////////////////////// + // ItemSearchWidget + ///////////////////////////////////////////// + private final Parameter m_itemSearchDefaultTab = new StringParameter( + "com.arsdigita.cms.item_search.default_tab", + Parameter.REQUIRED, "flatBrowse"); // private final Parameter m_itemSearchFlatBrowsePaneEnable = new BooleanParameter( // "com.arsdigita.cms.item_search.flat_browse_pane.enable", // Parameter.REQUIRED, // true); - private final Parameter m_itemSearchFlatBrowsePanePageSize = new IntegerParameter( - "com.arsdigita.cms.item_search.flat_browse_pane.page_size", - Parameter.REQUIRED, - 20); - ///////////////////////////////////////////// - // FolderBrowse - ///////////////////////////////////////////// - private final Parameter m_folderBrowseListSize = new IntegerParameter( - "com.arsdigita.cms.folder_browse_list_size", - Parameter.REQUIRED, - 20); - ///////////////////////////////////////////// - // Folder A to Z show limit: Display a A to Z filter bar when a folder has more than x items - ///////////////////////////////////////////// - private final Parameter m_folderAtoZShowLimit = new IntegerParameter( - "com.arsdigita.cms.folder_atoz_show_limit", - Parameter.REQUIRED, - 100); - ////////////////////////////////////////////// - //If set to true the old style ItemLifecycleItemPane (allows you to - //republish and withdraw items) is used. Otherwise the new style form is - //used, which is more secure against wrong clicks. - ////////////////////////////////////////////// - private final Parameter m_useOldStyleItemLifecycleItemPane = - new BooleanParameter( - "com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane", - Parameter.REQUIRED, - false); - //////////////////////////////////////////////// - //Actives threaded publishing. If active, the publish process for - //content items will run in a separate thread. May useful if you have - //large objects. - //////////////////////////////////////////////////// - private final Parameter m_threadPublishing = new BooleanParameter( - "com.arsdigita.cms.lifecycle.threaded_publishing", - Parameter.REQUIRED, - true); - private final Parameter m_publishingFailureSender = new StringParameter( - "cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from", - Parameter.REQUIRED, - ""); - private final Parameter m_publishingFailureReceiver = new StringParameter( - "cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to", - Parameter.REQUIRED, - ""); - ///////////////////////////////////////////////// - // ImageBrowser Parameter - ///////////////////////////////////////////////// - private final Parameter m_imageBrowserThumbnailMaxWidth = new IntegerParameter( - "com.arsdigita.cms.image_browser.thumbnail_max_width", - Parameter.REQUIRED, - 50); - private final Parameter m_imageBrowserThumbnailMaxHeight = new IntegerParameter( - "com.arsdigita.cms.image_browser.thumbnail_max_height", - Parameter.REQUIRED, - 50); - private final Parameter m_imageBrowserCaptionSize = new IntegerParameter( - "com.arsdigita.cms.image_browser.caption_size", - Parameter.REQUIRED, - 100); - private final Parameter m_imageBrowserDescriptionSize = new IntegerParameter( - "com.arsdigita.cms.image_browser.description_size", - Parameter.REQUIRED, - 400); - private final Parameter m_imageBrowserTitleSize = new IntegerParameter( - "com.arsdigita.cms.image_browser.title_size", - Parameter.REQUIRED, - 200); - ///////////////////////////////////////////////// - // ImageCache Parameter - ///////////////////////////////////////////////// - private final Parameter m_imageCacheEnabled = new BooleanParameter( - "com.arsdigita.cms.image_cache.enable", - Parameter.REQUIRED, - true); - private final Parameter m_imageCachePrefetchEnabled = new BooleanParameter( - "com.arsdigita.cms.image_cache.prefetch_enable", - Parameter.REQUIRED, - false); - private final Parameter m_imageCacheMaxSize = new IntegerParameter( - "com.arsdigita.cms.image_cache.max_size", - Parameter.REQUIRED, - 100); - private final Parameter m_imageCacheMaxAge = new IntegerParameter( - "com.arsdigita.cms.image_cache.max_age", - Parameter.REQUIRED, - 300); - /** - * Enable the PersonOrgaUnitsStep? - */ - private final Parameter m_attachPersonOrgaUnitsStep = new BooleanParameter( - "com.arsdigita.cms.contenttypes.genericperson.attach_person_orgaunits_step", - Parameter.REQUIRED, - Boolean.TRUE); - private final Parameter m_personOrgaUnitsStepSortKey = new BooleanParameter( - "com.arsdigita.cms.contenttypes.genericperson.person_orgaunits_step_sortkey", - Parameter.REQUIRED, - 20); - /** - * Enable or disable the XML cache in {@link SimpleXMLGenerator} - */ - private final Parameter m_enableXmlCache = new BooleanParameter( - "com.arsdigita.cms.xml.cache.enable", - Parameter.REQUIRED, - Boolean.FALSE); - /** - * Maximum number of items stored in the XML cache - * - */ - private final Parameter m_xmlCacheSize = new IntegerParameter( - "com.arsdigita.cms.xml.cache.size", - Parameter.REQUIRED, - 2500); - /** - * Maximum age of cache entry for the XML cache - * - */ - private final Parameter m_xmlCacheAge = new IntegerParameter( - "com.arsdigita.cms.xml.cache.age", - Parameter.REQUIRED, - 60 * 60 * 24); - - // /////////////////////////////////////////// - // publishToFile package related parameter - // /////////////////////////////////////////// - // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 - // private final Parameter m_disableItemPfs; - // private final Parameter m_publishToFileClass; - - + private final Parameter m_itemSearchFlatBrowsePanePageSize = new IntegerParameter( + "com.arsdigita.cms.item_search.flat_browse_pane.page_size", + Parameter.REQUIRED, + 20); + ///////////////////////////////////////////// + // FolderBrowse + ///////////////////////////////////////////// + private final Parameter m_folderBrowseListSize = new IntegerParameter( + "com.arsdigita.cms.folder_browse_list_size", + Parameter.REQUIRED, + 20); + ///////////////////////////////////////////// + // Folder A to Z show limit: Display a A to Z filter bar when a folder has more than x items + ///////////////////////////////////////////// + private final Parameter m_folderAtoZShowLimit = new IntegerParameter( + "com.arsdigita.cms.folder_atoz_show_limit", + Parameter.REQUIRED, + 100); + ////////////////////////////////////////////// + //If set to true the old style ItemLifecycleItemPane (allows you to + //republish and withdraw items) is used. Otherwise the new style form is + //used, which is more secure against wrong clicks. + ////////////////////////////////////////////// + private final Parameter m_useOldStyleItemLifecycleItemPane = new BooleanParameter( + "com.arsdigita.cms.lifecycle.use_old_style_item_lifecycle_item_pane", + Parameter.REQUIRED, + false); + //////////////////////////////////////////////// + //Actives threaded publishing. If active, the publish process for + //content items will run in a separate thread. May useful if you have + //large objects. + //////////////////////////////////////////////////// + private final Parameter m_threadPublishing = new BooleanParameter( + "com.arsdigita.cms.lifecycle.threaded_publishing", + Parameter.REQUIRED, + true); + private final Parameter m_publishingFailureSender = new StringParameter( + "cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.from", + Parameter.REQUIRED, + ""); + private final Parameter m_publishingFailureReceiver = new StringParameter( + "cms.arsdigita.cms.lifecycle.threaded_publishing.notify_on_error.to", + Parameter.REQUIRED, + ""); + ///////////////////////////////////////////////// + // ImageBrowser Parameter + ///////////////////////////////////////////////// + private final Parameter m_imageBrowserThumbnailMaxWidth = new IntegerParameter( + "com.arsdigita.cms.image_browser.thumbnail_max_width", + Parameter.REQUIRED, + 50); + private final Parameter m_imageBrowserThumbnailMaxHeight = new IntegerParameter( + "com.arsdigita.cms.image_browser.thumbnail_max_height", + Parameter.REQUIRED, + 50); + private final Parameter m_imageBrowserCaptionSize = new IntegerParameter( + "com.arsdigita.cms.image_browser.caption_size", + Parameter.REQUIRED, + 100); + private final Parameter m_imageBrowserDescriptionSize = new IntegerParameter( + "com.arsdigita.cms.image_browser.description_size", + Parameter.REQUIRED, + 400); + private final Parameter m_imageBrowserTitleSize = new IntegerParameter( + "com.arsdigita.cms.image_browser.title_size", + Parameter.REQUIRED, + 200); + ///////////////////////////////////////////////// + // ImageCache Parameter + ///////////////////////////////////////////////// + private final Parameter m_imageCacheEnabled = new BooleanParameter( + "com.arsdigita.cms.image_cache.enable", + Parameter.REQUIRED, + true); + private final Parameter m_imageCachePrefetchEnabled = new BooleanParameter( + "com.arsdigita.cms.image_cache.prefetch_enable", + Parameter.REQUIRED, + false); + private final Parameter m_imageCacheMaxSize = new IntegerParameter( + "com.arsdigita.cms.image_cache.max_size", + Parameter.REQUIRED, + 100); + private final Parameter m_imageCacheMaxAge = new IntegerParameter( + "com.arsdigita.cms.image_cache.max_age", + Parameter.REQUIRED, + 300); /** - * Constructor, but do NOT instantiate this class directly. - * - * @see ContentSection#getConfig() - * - */ - public CMSConfig() { + * Enable the PersonOrgaUnitsStep? + */ + private final Parameter m_attachPersonOrgaUnitsStep = new BooleanParameter( + "com.arsdigita.cms.contenttypes.genericperson.attach_person_orgaunits_step", + Parameter.REQUIRED, + Boolean.TRUE); + private final Parameter m_personOrgaUnitsStepSortKey = new BooleanParameter( + "com.arsdigita.cms.contenttypes.genericperson.person_orgaunits_step_sortkey", + Parameter.REQUIRED, + 20); + /** + * Enable or disable the XML cache in {@link SimpleXMLGenerator} + */ + private final Parameter m_enableXmlCache = new BooleanParameter( + "com.arsdigita.cms.xml.cache.enable", + Parameter.REQUIRED, + Boolean.FALSE); + /** + * Maximum number of items stored in the XML cache + * + */ + private final Parameter m_xmlCacheSize = new IntegerParameter( + "com.arsdigita.cms.xml.cache.size", + Parameter.REQUIRED, + 2500); + /** + * Maximum age of cache entry for the XML cache + * + */ + private final Parameter m_xmlCacheAge = new IntegerParameter( + "com.arsdigita.cms.xml.cache.age", + Parameter.REQUIRED, + 60 * 60 * 24); - // 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); + /** + * Max length of the description of a link (in database max length are 4000 characters) + */ + private final Parameter m_linkDescMaxLength = new IntegerParameter( + "com.arsdigita.cms.link_description_max_length", Parameter.REQUIRED, 400); + // /////////////////////////////////////////// + // 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() { - register(m_templateRootPath); - register(m_defaultItemTemplatePath); - register(m_defaultFolderTemplatePath); - register(m_categoryAuthoringAddForm); - register(m_itemAdapters); - register(m_useStreamlinedCreation); - register(m_dhtmlEditorConfig); - register(m_dhtmlEditorPlugins); - register(m_dhtmlEditorHiddenButtons); - register(m_hideTemplatesTab); - register(m_hideAdminTabs); - register(m_hideTimezone); - register(m_hideLaunchDate); - register(m_requireLaunchDate); - register(m_hideUDCTUI); - register(m_hideFolderIndexCheckbox); - register(m_defaultNotificationTime); - register(m_publishLifecycleListenerClass); - register(m_notifyAuthorOnLifecycle); - register(m_saveTextCleansWordTags); - register(m_disableFileAssetExtraction); - register(m_deleteWorkflowAfterPublication); - register(m_soonExpiredTimespanMonths); - register(m_soonExpiredTimespanDays); - register(m_unpublishedNotFound); - register(m_linksOnlyInSameSubsite); - register(m_categoryAuthoringExtension); - register(m_hideResetLifecycleLink); - register(m_keywordWeight); - register(m_limitToContentSection); - register(m_titleWeight); - register(m_scoreTitleAndKeywords); - register(m_skipAssetSteps); - register(m_mandatoryDescriptions); - register(m_deleteLifecycleWhenComplete); - register(m_deleteExpiryNotificationsWhenSent); - register(m_deleteWorkflowNotificationsWhenSent); - register(m_categoryTreeOrdering); - register(m_hasContactsAuthoringStep); - register(m_hideTextAssetUploadFile); - register(m_allowCategoryCreateUseContext); - register(m_allowContentCreateInSectionListing); - register(m_hideLegacyPublicSiteLink); + // 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); - // Content Center (Workspace) config related parameters - register(m_contentCenterMap); + register(m_templateRootPath); + register(m_defaultItemTemplatePath); + register(m_defaultFolderTemplatePath); + register(m_categoryAuthoringAddForm); + register(m_itemAdapters); + register(m_useStreamlinedCreation); + register(m_dhtmlEditorConfig); + register(m_dhtmlEditorPlugins); + register(m_dhtmlEditorHiddenButtons); + register(m_hideTemplatesTab); + register(m_hideAdminTabs); + register(m_hideTimezone); + register(m_hideLaunchDate); + register(m_requireLaunchDate); + register(m_hideUDCTUI); + register(m_hideFolderIndexCheckbox); + register(m_defaultNotificationTime); + register(m_publishLifecycleListenerClass); + register(m_notifyAuthorOnLifecycle); + register(m_saveTextCleansWordTags); + register(m_disableFileAssetExtraction); + register(m_deleteWorkflowAfterPublication); + register(m_soonExpiredTimespanMonths); + register(m_soonExpiredTimespanDays); + register(m_unpublishedNotFound); + register(m_linksOnlyInSameSubsite); + register(m_categoryAuthoringExtension); + register(m_hideResetLifecycleLink); + register(m_keywordWeight); + register(m_limitToContentSection); + register(m_titleWeight); + register(m_scoreTitleAndKeywords); + register(m_skipAssetSteps); + register(m_mandatoryDescriptions); + register(m_deleteLifecycleWhenComplete); + register(m_deleteExpiryNotificationsWhenSent); + register(m_deleteWorkflowNotificationsWhenSent); + register(m_categoryTreeOrdering); + register(m_hasContactsAuthoringStep); + register(m_hideTextAssetUploadFile); + register(m_allowCategoryCreateUseContext); + register(m_allowContentCreateInSectionListing); + register(m_hideLegacyPublicSiteLink); - // Content Section config related parameters - // register(m_defaultSection); + // Content Center (Workspace) config related parameters + register(m_contentCenterMap); - // Content Section creation parameters - register(m_defaultItemResolverClass); - register(m_defaultTemplateResolverClass); + // Content Section config related parameters + // register(m_defaultSection); + // Content Section creation parameters + register(m_defaultItemResolverClass); + register(m_defaultTemplateResolverClass); - register(m_itemSearchDefaultTab); + register(m_itemSearchDefaultTab); - register(m_folderBrowseListSize); - register(m_folderAtoZShowLimit); + register(m_folderBrowseListSize); + register(m_folderAtoZShowLimit); - register(m_useOldStyleItemLifecycleItemPane); - register(m_threadPublishing); - register(m_publishingFailureSender); - register(m_publishingFailureReceiver); + register(m_useOldStyleItemLifecycleItemPane); + register(m_threadPublishing); + register(m_publishingFailureSender); + register(m_publishingFailureReceiver); - // ImageBrowser - register(m_imageBrowserThumbnailMaxWidth); - register(m_imageBrowserThumbnailMaxHeight); - register(m_imageBrowserCaptionSize); - register(m_imageBrowserDescriptionSize); - register(m_imageBrowserTitleSize); + // ImageBrowser + register(m_imageBrowserThumbnailMaxWidth); + register(m_imageBrowserThumbnailMaxHeight); + register(m_imageBrowserCaptionSize); + register(m_imageBrowserDescriptionSize); + register(m_imageBrowserTitleSize); - // ImageCache Parameter - register(m_imageCacheEnabled); - register(m_imageCachePrefetchEnabled); - register(m_imageCacheMaxSize); - register(m_imageCacheMaxAge); - - // publishToFile package related parameter - // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 - // register(m_disableItemPfs); - // register(m_publishToFileClass); + // ImageCache Parameter + register(m_imageCacheEnabled); + register(m_imageCachePrefetchEnabled); + register(m_imageCacheMaxSize); + register(m_imageCacheMaxAge); + // publishToFile package related parameter + // Moved to publishToFile.PublishToFileConfig as of version 6.0.2 + // register(m_disableItemPfs); + // register(m_publishToFileClass); // register(m_itemSearchFlatBrowsePaneEnable); - register(m_itemSearchFlatBrowsePanePageSize); - - register(m_attachPersonOrgaUnitsStep); - register(m_personOrgaUnitsStepSortKey); - - register(m_enableXmlCache); - register(m_xmlCacheSize); - register(m_xmlCacheAge); - - loadInfo(); - } - - /** - * Retrieve path of the root folder for template folders. Path is - * relative to webapp root. - */ - public final String getTemplateRoot() { - return (String) get(m_templateRootPath); - } - - public final String getDefaultItemTemplatePath() { - return (String) get(m_defaultItemTemplatePath); - } - - public final String getDefaultFolderTemplatePath() { - return (String) get(m_defaultFolderTemplatePath); - } - - public final Class getDefaultItemResolverClass() { - return (Class) get(m_defaultItemResolverClass); - } - - public final Class getDefaultTemplateResolverClass() { - return (Class) get(m_defaultTemplateResolverClass); - } - - public final Class getCategoryAuthoringAddForm() { - return (Class) get(m_categoryAuthoringAddForm); - } - - public final InputStream getItemAdapters() { - // URL resource: protocol handler removal: START - // remove: - // try { - // return ((URL)get(m_itemAdapters)).openStream(); - // } catch (IOException ex) { - // throw new UncheckedWrapperException("Cannot read stream", ex); - // } - // ADD: - return (InputStream) get(m_itemAdapters); - } - - /** - * - * @deprecated use - * com.arsdigita.cms.ContentSection.getDefaultSection().getName() - * instead - */ - public final String getDefaultContentSection() { - // return (String) get(m_defaultSection); - return (String) ContentSection.getDefaultSection().getName(); - } - - public final boolean getUseStreamlinedCreation() { - return ((Boolean) get(m_useStreamlinedCreation)).booleanValue(); - } - - public final DHTMLEditor.Config getDHTMLEditorConfig() { - return (DHTMLEditor.Config) get(m_dhtmlEditorConfig); - } - - public final String[] getDHTMLEditorPlugins() { - return (String[]) get(m_dhtmlEditorPlugins); - } - - public final String[] getDHTMLEditorHiddenButtons() { - return (String[]) get(m_dhtmlEditorHiddenButtons); - } - - public final boolean getHideTemplatesTab() { - return ((Boolean) get(m_hideTemplatesTab)).booleanValue(); - } - - public final boolean getHideAdminTabs() { - return ((Boolean) get(m_hideAdminTabs)).booleanValue(); - } - - public final boolean getHideTimezone() { - return ((Boolean) get(m_hideTimezone)).booleanValue(); - } - - public final boolean getHideLaunchDate() { - return ((Boolean) get(m_hideLaunchDate)).booleanValue(); - } - - public final boolean getRequireLaunchDate() { - return ((Boolean) get(m_requireLaunchDate)).booleanValue(); - } - - public final boolean getHideUDCTUI() { - return ((Boolean) get(m_hideUDCTUI)).booleanValue(); - } - - public final boolean getHideFolderIndexCheckbox() { - return ((Boolean) get(m_hideFolderIndexCheckbox)).booleanValue(); - } - - public final int getDefaultNotificationTime() { - return ((Integer) get(m_defaultNotificationTime)).intValue(); - } - - public final String getPublishLifecycleListenerClass() { - return (String) get(m_publishLifecycleListenerClass); - } - - public final boolean getNotifyAuthorOnLifecycle() { - return ((Boolean) get(m_notifyAuthorOnLifecycle)).booleanValue(); - } - - public final boolean getSaveTextCleansWordTags() { - return ((Boolean) get(m_saveTextCleansWordTags)).booleanValue(); - } - - public final boolean getDisableFileAssetExtraction() { - return ((Boolean) get(m_disableFileAssetExtraction)).booleanValue(); - } - - public final boolean getDeleteWorkflowAfterPublication() { - return ((Boolean) get(m_deleteWorkflowAfterPublication)).booleanValue(); - } - - public final boolean getLinksOnlyInSameSubsite() { - return ((Boolean) get(m_linksOnlyInSameSubsite)).booleanValue(); - } - - public final int getSoonExpiredMonths() { - return ((Integer) get(m_soonExpiredTimespanMonths)).intValue(); - } - - public final int getSoonExpiredDays() { - return ((Integer) get(m_soonExpiredTimespanDays)).intValue(); - } - - public final boolean isUnpublishedNotFound() { - return ((Boolean) get(m_unpublishedNotFound)).booleanValue(); - } - - public final Class getCategoryAuthoringExtension() { - return (Class) get(m_categoryAuthoringExtension); - } - - // /////////////////////////////////////////// - // publishToFile package related configuration - // /////////////////////////////////////////// - // Moved to publishToFile.PublishToFileConfig! Temporarily retained here - // for backwards compatibility - public final boolean getDisableItemPfs() { - // return ((Boolean) get(m_disableItemPfs)).booleanValue(); - return PublishToFileConfig.getConfig().isItemPfsDisabled(); - } - - public final Class getPublishToFileClass() { - // return (Class) get(m_publishToFileClass); - return PublishToFileConfig.getConfig().getPublishListenerClass(); - } - - /** - * 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 - * creates a new DHMTLEditor Config object (internal class in - * DHTMLEditor). - * - * XXX Method unmarshal is broken and currently does not work correctly. - * It does not process default values provided by using - * DHTMLEditor.Config.Standard (see parameter m_dhtmlEditorConfig - * above). May be a similiar problem as with ResourceParameter and - * default value, see patch provided by pbrucha. Best solution may be to - * remove this special parameter class and use a string parameter - * instead to directly create a DHTMLEditor.Config object. (pboy, - * 2010-09-02) - */ - private class DHTMLEditorConfigParameter extends StringParameter { - - public DHTMLEditorConfigParameter(final String name, - final int multiplicity, - final Object defaultObj) { - super(name, multiplicity, defaultObj); - } - - /** - * WARNING: Does not correctly process default values, see - * above! - * - * @param value - * @param errors - * @return - */ - @Override - protected Object unmarshal(String value, ErrorList errors) { - return DHTMLEditor.Config.valueOf(value); - } - } - protected static HashMap extraXMLGenerators = new HashMap(); - - /** - * Add one ExtraXMLGenerator to the list. - */ - public static void registerExtraXMLGenerator(String type, - ExtraXMLGenerator gen) { - List gens = (List) extraXMLGenerators.get(type); - if (gens == null) { - gens = new LinkedList(); - extraXMLGenerators.put(type, gens); - } - // Store class reference so it can be recreated for each page. - // This requires a fix to all components using extraXMLGenerators, - // for example see the currently only one in core/cms: GreetingItemExtraXML - gens.add(gen.getClass()); // XXX assumes default ctor - } - - /** - * Get the iterator of ExtraXMLGenerators. - */ - public static Iterator getExtraXMLGeneratorsIterator() { - return extraXMLGenerators.entrySet().iterator(); - } - - public final boolean hideResetLifecycleLink() { - return ((Boolean) get(m_hideResetLifecycleLink)).booleanValue(); - } - - /** - * The relative weight given to the dcKeywords element within dublinCore - * element within cms:item element when ranking search results Only used - * by the interMedia query engine. - * - */ - public Integer getKeywordSearchWeight() { - return (Integer) get(m_keywordWeight); - } - - public final boolean limitToContentSection() { - return ((Boolean) get(m_limitToContentSection)).booleanValue(); - } - - /** - * The relative weight given to title element within cms:item element - * when ranking search results Only used by the interMedia query engine. - * - */ - public Integer getTitleSearchWeight() { - return (Integer) get(m_titleWeight); - } - - /** - * Whether to include INPATH operators to contains clause in intermedia - * search - * - * NB - if true, INDEX MUST BE CREATED WITH PATH_SECTION_GROUP - upgrade - * 6.5.0 - 6.5.1 - * - * @return - */ - public boolean scoreKeywordsAndTitle() { - return ((Boolean) get(m_scoreTitleAndKeywords)).booleanValue(); - } - - /** - * for the given content type, returns a collection of steps that are - * deemed irrelevant for the type. - * - * If no irrelevant steps, an empty set is returned. - * - * Steps are the names of the bebop step components that are used by the - * authoring kit wizard - * - * @param type - * @return - */ - public Collection getAssetStepsToSkip(ContentType type) { - s_log.debug("getting asset steps to skip for type " - + type.getClassName()); - if (s_skipAssetSteps == null) { - // populate static map once based on config parameter value - s_log.debug("loading skipsteps"); - s_skipAssetSteps = new HashMap(); - String[] skipSteps = (String[]) get(m_skipAssetSteps); - if (skipSteps != null) { - - s_log.debug(skipSteps.length + " entries in parameter"); - for (int i = 0; i < skipSteps.length; i++) { - String[] pair = StringUtils.split(skipSteps[i], ':'); - // 1st string is name of content type, 2nd string is name of asset step - s_log.debug("parameter read - type = " + pair[0] - + " - step = " + pair[1]); - Collection typeSteps = - (Collection) s_skipAssetSteps.get(pair[0]); - if (typeSteps == null) { - typeSteps = new HashSet(); - s_skipAssetSteps.put(pair[0], typeSteps); - - } - typeSteps.add(pair[1]); - - } - } - - } - Collection skipSteps = (Collection) s_skipAssetSteps.get(type. - getClassName()); - if (skipSteps == null) { - s_log.debug("no steps to skip"); - skipSteps = new HashSet(); - } - return skipSteps; - - } - - /** - * May be used by any content type creation form to decide whether to - * validate description field - * - */ - public boolean mandatoryDescriptions() { - return ((Boolean) get(m_mandatoryDescriptions)).booleanValue(); - } - - /** - * Used to decide whether lifecycles (and all asociated phases) should - * be deleted from the system when complete - * - * (Deleting lifecycle means that you lose a bit of historical - * information eg when was this item unpublished) - */ - public boolean deleteFinishedLifecycles() { - return ((Boolean) get(m_deleteLifecycleWhenComplete)).booleanValue(); - } - - /** - * Used to decide whether to delete old notification records for expiry - * notifications. - * - * If true, notifications and messages are deleted if the notification - * is successfully sent. Any send failures are retained - * - */ - public boolean deleteExpiryNotifications() { - return ((Boolean) get(m_deleteExpiryNotificationsWhenSent)).booleanValue(); - } - - /** - * Used to decide whether to delete old notification records for - * workflow notifications. - * - * If true, notifications and messages are deleted if the notification - * is successfully sent. Any send failures are retained - * - */ - public boolean deleteWorkflowNotifications() { - return ((Boolean) get(m_deleteWorkflowNotificationsWhenSent)). - booleanValue(); - } - - public String getCategoryTreeOrder() { - return (String) get(m_categoryTreeOrdering); - } - - /** - * I'am not sure for what this method is. I found it here when I tried - * figure out how add multiple parts to an ContentType, like - * ccm-cms-types-contact and the Multipart article do. I think this - * method should not be here because it is only needed by one specific - * contenttype. Because of this, I think that this method and the - * contact are violating many rules of modern software design. Jens - * Pelzetter, 2009-06-02. - * - * @return - */ - public boolean getHasContactsAuthoringStep() { - return ((Boolean) get(m_hasContactsAuthoringStep)).booleanValue(); - } - - public final boolean getHideTextAssetUploadFile() { - return ((Boolean) get(m_hideTextAssetUploadFile)).booleanValue(); - } - - /** - * Retrieve whether to allow creation of a new Use Context in category - * tab of content sections. "Use Context" is used to constitute a - * category hierarchy in core. It is superseded by the construct - * "Category Domain" in Terms (ccm-ldn-terms). Global parameter for all - * content sections. Default is false because all installation bundles - * use Terms. - * - * @return TRUE if creation is allowed, otherwise FALSE (default) - */ - public final boolean getAllowCategoryCreateUseContext() { - return ((Boolean) get(m_allowCategoryCreateUseContext)). - booleanValue(); - } - - public final boolean getAllowContentCreateInSectionListing() { - return ((Boolean) get(m_allowContentCreateInSectionListing)). - booleanValue(); - } - - /** - * Hide the (no longer used) legacy public site link in Workspace - * (content center) section listing, true by default. - */ - public final boolean getHideLegacyPublicSiteLink() { - return ((Boolean) get(m_hideLegacyPublicSiteLink)).booleanValue(); - } - - public String getItemSearchDefaultTab() { - return (String) get(m_itemSearchDefaultTab); - } - - public Integer getFolderBrowseListSize() { - return (Integer) get(m_folderBrowseListSize); - } - - public Integer getFolderAtoZShowLimit() { - return (Integer) get(m_folderAtoZShowLimit); - } - - public Boolean getUseOldStyleItemLifecycleItemPane() { - return (Boolean) get(m_useOldStyleItemLifecycleItemPane); - } - - public Boolean getThreadedPublishing() { - return (Boolean) get(m_threadPublishing); - } - - public String getPublicationFailureSender() { - return (String) get(m_publishingFailureSender); - } - - public String getPublicationFailureReceiver() { - return (String) get(m_publishingFailureReceiver); - } - - public Integer getImageBrowserThumbnailMaxWidth() { - return (Integer) get(m_imageBrowserThumbnailMaxWidth); - } - - public Integer getImageBrowserThumbnailMaxHeight() { - return (Integer) get(m_imageBrowserThumbnailMaxHeight); - } - - public int getImageBrowserCaptionSize() { - return Math.min(((Integer) get(m_imageBrowserCaptionSize)).intValue(), 100); - } - - public int getImageBrowserDescriptionSize() { - return Math.min(((Integer) get(m_imageBrowserDescriptionSize)).intValue(), 400); - } - - public int getImageBrowserTitleSize() { - return Math.min(((Integer) get(m_imageBrowserTitleSize)).intValue(), 200); - } - - public Boolean getImageCacheEnabled() { - return (Boolean) get(m_imageCacheEnabled); - } - - public Boolean getImageCachePrefetchEnabled() { - return (Boolean) get(m_imageCachePrefetchEnabled); - } - - public Integer getImageCacheMaxSize() { - return (Integer) get(m_imageCacheMaxSize); - } - - public Integer getImageCacheMaxAge() { - return (Integer) get(m_imageCacheMaxAge); - } + register(m_itemSearchFlatBrowsePanePageSize); + + register(m_attachPersonOrgaUnitsStep); + register(m_personOrgaUnitsStepSortKey); + + register(m_enableXmlCache); + register(m_xmlCacheSize); + register(m_xmlCacheAge); + + register(m_linkDescMaxLength); + + loadInfo(); + } + + /** + * Retrieve path of the root folder for template folders. Path is relative to webapp root. + */ + public final String getTemplateRoot() { + return (String) get(m_templateRootPath); + } + + public final String getDefaultItemTemplatePath() { + return (String) get(m_defaultItemTemplatePath); + } + + public final String getDefaultFolderTemplatePath() { + return (String) get(m_defaultFolderTemplatePath); + } + + public final Class getDefaultItemResolverClass() { + return (Class) get(m_defaultItemResolverClass); + } + + public final Class getDefaultTemplateResolverClass() { + return (Class) get(m_defaultTemplateResolverClass); + } + + public final Class getCategoryAuthoringAddForm() { + return (Class) get(m_categoryAuthoringAddForm); + } + + public final InputStream getItemAdapters() { + // URL resource: protocol handler removal: START + // remove: + // try { + // return ((URL)get(m_itemAdapters)).openStream(); + // } catch (IOException ex) { + // throw new UncheckedWrapperException("Cannot read stream", ex); + // } + // ADD: + return (InputStream) get(m_itemAdapters); + } + + /** + * + * @deprecated use com.arsdigita.cms.ContentSection.getDefaultSection().getName() instead + */ + public final String getDefaultContentSection() { + // return (String) get(m_defaultSection); + return (String) ContentSection.getDefaultSection().getName(); + } + + public final boolean getUseStreamlinedCreation() { + return ((Boolean) get(m_useStreamlinedCreation)).booleanValue(); + } + + public final DHTMLEditor.Config getDHTMLEditorConfig() { + return (DHTMLEditor.Config) get(m_dhtmlEditorConfig); + } + + public final String[] getDHTMLEditorPlugins() { + return (String[]) get(m_dhtmlEditorPlugins); + } + + public final String[] getDHTMLEditorHiddenButtons() { + return (String[]) get(m_dhtmlEditorHiddenButtons); + } + + public final boolean getHideTemplatesTab() { + return ((Boolean) get(m_hideTemplatesTab)).booleanValue(); + } + + public final boolean getHideAdminTabs() { + return ((Boolean) get(m_hideAdminTabs)).booleanValue(); + } + + public final boolean getHideTimezone() { + return ((Boolean) get(m_hideTimezone)).booleanValue(); + } + + public final boolean getHideLaunchDate() { + return ((Boolean) get(m_hideLaunchDate)).booleanValue(); + } + + public final boolean getRequireLaunchDate() { + return ((Boolean) get(m_requireLaunchDate)).booleanValue(); + } + + public final boolean getHideUDCTUI() { + return ((Boolean) get(m_hideUDCTUI)).booleanValue(); + } + + public final boolean getHideFolderIndexCheckbox() { + return ((Boolean) get(m_hideFolderIndexCheckbox)).booleanValue(); + } + + public final int getDefaultNotificationTime() { + return ((Integer) get(m_defaultNotificationTime)).intValue(); + } + + public final String getPublishLifecycleListenerClass() { + return (String) get(m_publishLifecycleListenerClass); + } + + public final boolean getNotifyAuthorOnLifecycle() { + return ((Boolean) get(m_notifyAuthorOnLifecycle)).booleanValue(); + } + + public final boolean getSaveTextCleansWordTags() { + return ((Boolean) get(m_saveTextCleansWordTags)).booleanValue(); + } + + public final boolean getDisableFileAssetExtraction() { + return ((Boolean) get(m_disableFileAssetExtraction)).booleanValue(); + } + + public final boolean getDeleteWorkflowAfterPublication() { + return ((Boolean) get(m_deleteWorkflowAfterPublication)).booleanValue(); + } + + public final boolean getLinksOnlyInSameSubsite() { + return ((Boolean) get(m_linksOnlyInSameSubsite)).booleanValue(); + } + + public final int getSoonExpiredMonths() { + return ((Integer) get(m_soonExpiredTimespanMonths)).intValue(); + } + + public final int getSoonExpiredDays() { + return ((Integer) get(m_soonExpiredTimespanDays)).intValue(); + } + + public final boolean isUnpublishedNotFound() { + return ((Boolean) get(m_unpublishedNotFound)).booleanValue(); + } + + public final Class getCategoryAuthoringExtension() { + return (Class) get(m_categoryAuthoringExtension); + } + + // /////////////////////////////////////////// + // publishToFile package related configuration + // /////////////////////////////////////////// + // Moved to publishToFile.PublishToFileConfig! Temporarily retained here + // for backwards compatibility + public final boolean getDisableItemPfs() { + // return ((Boolean) get(m_disableItemPfs)).booleanValue(); + return PublishToFileConfig.getConfig().isItemPfsDisabled(); + } + + public final Class getPublishToFileClass() { + // return (Class) get(m_publishToFileClass); + return PublishToFileConfig.getConfig().getPublishListenerClass(); + } + + /** + * 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 creates a new + * DHMTLEditor Config object (internal class in DHTMLEditor). + * + * XXX Method unmarshal is broken and currently does not work correctly. It does not process + * default values provided by using DHTMLEditor.Config.Standard (see parameter + * m_dhtmlEditorConfig above). May be a similiar problem as with ResourceParameter and default + * value, see patch provided by pbrucha. Best solution may be to remove this special parameter + * class and use a string parameter instead to directly create a DHTMLEditor.Config object. + * (pboy, 2010-09-02) + */ + private class DHTMLEditorConfigParameter extends StringParameter { + + public DHTMLEditorConfigParameter(final String name, + final int multiplicity, + final Object defaultObj) { + super(name, multiplicity, defaultObj); + } + + /** + * WARNING: Does not correctly process default values, see above! + * + * @param value + * @param errors + * + * @return + */ + @Override + protected Object unmarshal(String value, ErrorList errors) { + return DHTMLEditor.Config.valueOf(value); + } + + } + + protected static HashMap extraXMLGenerators = new HashMap(); + + /** + * Add one ExtraXMLGenerator to the list. + */ + public static void registerExtraXMLGenerator(String type, + ExtraXMLGenerator gen) { + List gens = (List) extraXMLGenerators.get(type); + if (gens == null) { + gens = new LinkedList(); + extraXMLGenerators.put(type, gens); + } + // Store class reference so it can be recreated for each page. + // This requires a fix to all components using extraXMLGenerators, + // for example see the currently only one in core/cms: GreetingItemExtraXML + gens.add(gen.getClass()); // XXX assumes default ctor + } + + /** + * Get the iterator of ExtraXMLGenerators. + */ + public static Iterator getExtraXMLGeneratorsIterator() { + return extraXMLGenerators.entrySet().iterator(); + } + + public final boolean hideResetLifecycleLink() { + return ((Boolean) get(m_hideResetLifecycleLink)).booleanValue(); + } + + /** + * The relative weight given to the dcKeywords element within dublinCore element within cms:item + * element when ranking search results Only used by the interMedia query engine. + * + */ + public Integer getKeywordSearchWeight() { + return (Integer) get(m_keywordWeight); + } + + public final boolean limitToContentSection() { + return ((Boolean) get(m_limitToContentSection)).booleanValue(); + } + + /** + * The relative weight given to title element within cms:item element when ranking search + * results Only used by the interMedia query engine. + * + */ + public Integer getTitleSearchWeight() { + return (Integer) get(m_titleWeight); + } + + /** + * Whether to include INPATH operators to contains clause in intermedia search + * + * NB - if true, INDEX MUST BE CREATED WITH PATH_SECTION_GROUP - upgrade 6.5.0 - 6.5.1 + * + * @return + */ + public boolean scoreKeywordsAndTitle() { + return ((Boolean) get(m_scoreTitleAndKeywords)).booleanValue(); + } + + /** + * for the given content type, returns a collection of steps that are deemed irrelevant for the + * type. + * + * If no irrelevant steps, an empty set is returned. + * + * Steps are the names of the bebop step components that are used by the authoring kit wizard + * + * @param type + * + * @return + */ + public Collection getAssetStepsToSkip(ContentType type) { + s_log.debug("getting asset steps to skip for type " + + type.getClassName()); + if (s_skipAssetSteps == null) { + // populate static map once based on config parameter value + s_log.debug("loading skipsteps"); + s_skipAssetSteps = new HashMap(); + String[] skipSteps = (String[]) get(m_skipAssetSteps); + if (skipSteps != null) { + + s_log.debug(skipSteps.length + " entries in parameter"); + for (int i = 0; i < skipSteps.length; i++) { + String[] pair = StringUtils.split(skipSteps[i], ':'); + // 1st string is name of content type, 2nd string is name of asset step + s_log.debug("parameter read - type = " + pair[0] + + " - step = " + pair[1]); + Collection typeSteps = (Collection) s_skipAssetSteps.get(pair[0]); + if (typeSteps == null) { + typeSteps = new HashSet(); + s_skipAssetSteps.put(pair[0], typeSteps); + + } + typeSteps.add(pair[1]); + + } + } + + } + Collection skipSteps = (Collection) s_skipAssetSteps.get(type. + getClassName()); + if (skipSteps == null) { + s_log.debug("no steps to skip"); + skipSteps = new HashSet(); + } + return skipSteps; + + } + + /** + * May be used by any content type creation form to decide whether to validate description field + * + */ + public boolean mandatoryDescriptions() { + return ((Boolean) get(m_mandatoryDescriptions)).booleanValue(); + } + + /** + * Used to decide whether lifecycles (and all asociated phases) should be deleted from the + * system when complete + * + * (Deleting lifecycle means that you lose a bit of historical information eg when was this item + * unpublished) + */ + public boolean deleteFinishedLifecycles() { + return ((Boolean) get(m_deleteLifecycleWhenComplete)).booleanValue(); + } + + /** + * Used to decide whether to delete old notification records for expiry notifications. + * + * If true, notifications and messages are deleted if the notification is successfully sent. Any + * send failures are retained + * + */ + public boolean deleteExpiryNotifications() { + return ((Boolean) get(m_deleteExpiryNotificationsWhenSent)).booleanValue(); + } + + /** + * Used to decide whether to delete old notification records for workflow notifications. + * + * If true, notifications and messages are deleted if the notification is successfully sent. Any + * send failures are retained + * + */ + public boolean deleteWorkflowNotifications() { + return ((Boolean) get(m_deleteWorkflowNotificationsWhenSent)). + booleanValue(); + } + + public String getCategoryTreeOrder() { + return (String) get(m_categoryTreeOrdering); + } + + /** + * I'am not sure for what this method is. I found it here when I tried figure out how add + * multiple parts to an ContentType, like ccm-cms-types-contact and the Multipart article do. I + * think this method should not be here because it is only needed by one specific contenttype. + * Because of this, I think that this method and the contact are violating many rules of modern + * software design. Jens Pelzetter, 2009-06-02. + * + * @return + */ + public boolean getHasContactsAuthoringStep() { + return ((Boolean) get(m_hasContactsAuthoringStep)).booleanValue(); + } + + public final boolean getHideTextAssetUploadFile() { + return ((Boolean) get(m_hideTextAssetUploadFile)).booleanValue(); + } + + /** + * Retrieve whether to allow creation of a new Use Context in category tab of content sections. + * "Use Context" is used to constitute a category hierarchy in core. It is superseded by the + * construct "Category Domain" in Terms (ccm-ldn-terms). Global parameter for all content + * sections. Default is false because all installation bundles use Terms. + * + * @return TRUE if creation is allowed, otherwise FALSE (default) + */ + public final boolean getAllowCategoryCreateUseContext() { + return ((Boolean) get(m_allowCategoryCreateUseContext)). + booleanValue(); + } + + public final boolean getAllowContentCreateInSectionListing() { + return ((Boolean) get(m_allowContentCreateInSectionListing)). + booleanValue(); + } + + /** + * Hide the (no longer used) legacy public site link in Workspace (content center) section + * listing, true by default. + */ + public final boolean getHideLegacyPublicSiteLink() { + return ((Boolean) get(m_hideLegacyPublicSiteLink)).booleanValue(); + } + + public String getItemSearchDefaultTab() { + return (String) get(m_itemSearchDefaultTab); + } + + public Integer getFolderBrowseListSize() { + return (Integer) get(m_folderBrowseListSize); + } + + public Integer getFolderAtoZShowLimit() { + return (Integer) get(m_folderAtoZShowLimit); + } + + public Boolean getUseOldStyleItemLifecycleItemPane() { + return (Boolean) get(m_useOldStyleItemLifecycleItemPane); + } + + public Boolean getThreadedPublishing() { + return (Boolean) get(m_threadPublishing); + } + + public String getPublicationFailureSender() { + return (String) get(m_publishingFailureSender); + } + + public String getPublicationFailureReceiver() { + return (String) get(m_publishingFailureReceiver); + } + + public Integer getImageBrowserThumbnailMaxWidth() { + return (Integer) get(m_imageBrowserThumbnailMaxWidth); + } + + public Integer getImageBrowserThumbnailMaxHeight() { + return (Integer) get(m_imageBrowserThumbnailMaxHeight); + } + + public int getImageBrowserCaptionSize() { + return Math.min(((Integer) get(m_imageBrowserCaptionSize)).intValue(), 100); + } + + public int getImageBrowserDescriptionSize() { + return Math.min(((Integer) get(m_imageBrowserDescriptionSize)).intValue(), 400); + } + + public int getImageBrowserTitleSize() { + return Math.min(((Integer) get(m_imageBrowserTitleSize)).intValue(), 200); + } + + public Boolean getImageCacheEnabled() { + return (Boolean) get(m_imageCacheEnabled); + } + + public Boolean getImageCachePrefetchEnabled() { + return (Boolean) get(m_imageCachePrefetchEnabled); + } + + public Integer getImageCacheMaxSize() { + return (Integer) get(m_imageCacheMaxSize); + } + + public Integer getImageCacheMaxAge() { + return (Integer) get(m_imageCacheMaxAge); + } // public Boolean getItemSearchFlatBrowsePaneEnable() { // return (Boolean) get(m_itemSearchFlatBrowsePaneEnable); // } - public Integer getItemSearchFlatBrowsePanePageSize() { - return (Integer) get(m_itemSearchFlatBrowsePanePageSize); - } + public Integer getItemSearchFlatBrowsePanePageSize() { + return (Integer) get(m_itemSearchFlatBrowsePanePageSize); + } - public Boolean getAttachPersonOrgaUnitsStep() { - return (Boolean) get(m_attachPersonOrgaUnitsStep); - } + public Boolean getAttachPersonOrgaUnitsStep() { + return (Boolean) get(m_attachPersonOrgaUnitsStep); + } - public Integer getPersonOrgaUnitsStepSortKey() { - return (Integer) get(m_personOrgaUnitsStepSortKey); - } + public Integer getPersonOrgaUnitsStepSortKey() { + return (Integer) get(m_personOrgaUnitsStepSortKey); + } - public Boolean getEnableXmlCache() { - return (Boolean) get(m_enableXmlCache); - } + public Boolean getEnableXmlCache() { + return (Boolean) get(m_enableXmlCache); + } - public Integer getXmlCacheSize() { - return (Integer) get(m_xmlCacheSize); - } + public Integer getXmlCacheSize() { + return (Integer) get(m_xmlCacheSize); + } + + public Integer getXmlCacheAge() { + return (Integer) get(m_xmlCacheAge); + } + + public Integer getLinkDescMaxLength() { + return (Integer) get(m_linkDescMaxLength); + } - public Integer getXmlCacheAge() { - return (Integer) get(m_xmlCacheAge); - } } diff --git a/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties b/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties index ee2706438..f067a811d 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSConfig_parameter.properties @@ -355,3 +355,8 @@ com.arsdigita.cms.xml.cache.age.title=Maximum age of an entry in the XML cache com.arsdigita.cms.xml.cache.age.purpose=Maximum age of an entry in the XML cache com.arsdigita.cms.xml.cache.age.example=60*60*24 com.arsdigita.cms.xml.cache.age.format=[integer] + +com.arsdigita.cms.link_description_max_length.title=Maximum length of the description of a link. +com.arsdigita.cms.link_description_max_length.purpose=Maximum length of the description of a link. +com.arsdigita.cms.link_description_max_length.example=400 +com.arsdigita.cms.link_description_max_length.format={Integer] \ No newline at end of file diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java index 35bea2f88..89c810ee4 100755 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/LinkPropertyForm.java @@ -41,6 +41,8 @@ import com.arsdigita.bebop.form.Fieldset; import com.arsdigita.bebop.form.TextArea; import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.StringLengthValidationListener; +import com.arsdigita.cms.CMSConfig; import com.arsdigita.cms.ContentBundle; import com.arsdigita.util.Assert; import com.arsdigita.util.UncheckedWrapperException; @@ -60,20 +62,22 @@ import java.net.URL; import org.apache.log4j.Logger; /** - * Form to edit the basic properties of an Link. This form can be extended to - * create forms for Link subclasses. + * Form to edit the basic properties of an Link. This form can be extended to create forms for Link + * subclasses. * * @version $Revision: #5 $ $Date: 2004/08/17 $ * @author Nobuko Asakai (nasakai@redhat.com) * @author Sören Bernstein */ public class LinkPropertyForm extends FormSection - implements FormInitListener, FormProcessListener, - FormValidationListener, FormSubmissionListener { - + implements FormInitListener, FormProcessListener, + FormValidationListener, FormSubmissionListener { + private static final Logger s_log = Logger.getLogger(LinkPropertyForm.class); - /** Name of this form */ + /** + * Name of this form + */ public static final String ID = "link_edit"; public static final String SSL_PROTOCOL = "https://"; public static final String HTTP_PROTOCOL = "http://"; @@ -90,46 +94,45 @@ public class LinkPropertyForm extends FormSection private ContentType m_contentType; protected final String ITEM_SEARCH = "contentItem"; - /** - * Constructor creates a new form to edit the Link object specified by the - * item selection model passed in. + * Constructor creates a new form to edit the Link object specified by the item selection model + * passed in. * - * @param itemModel The ItemSelectionModel to use to obtain the ContentItem - * to which this link is (or will be) attached - * @param link The LinkSelectionModel to use to obtain the Link to work on + * @param itemModel The ItemSelectionModel to use to obtain the ContentItem to which this link + * is (or will be) attached + * @param link The LinkSelectionModel to use to obtain the Link to work on */ public LinkPropertyForm(ItemSelectionModel itemModel, LinkSelectionModel link) { this(itemModel, link, null); } - + /** - * Constructor creates a new form to edit the Link object specified by the - * item selection model passed in. + * Constructor creates a new form to edit the Link object specified by the item selection model + * passed in. * * @param itemModel * @param link - * @param contentType + * @param contentType */ public LinkPropertyForm(ItemSelectionModel itemModel, - LinkSelectionModel link, + LinkSelectionModel link, ContentType contentType) { - + super(new ColumnPanel(2)); - + s_log.debug("property form constructor"); m_linkModel = link; m_itemModel = itemModel; m_contentType = contentType; - + addWidgets(); addSaveCancelSection(); - + addInitListener(this); - + addValidationListener(this); - + addProcessListener(this); addSubmissionListener(this); } @@ -149,13 +152,15 @@ public class LinkPropertyForm extends FormSection m_description = new TextArea("description"); m_description.setCols(40); m_description.setRows(5); + m_description.addValidationListener(new StringLengthValidationListener(CMSConfig + .getInstanceOf().getLinkDescMaxLength())); add(new Label(GlobalizationUtil.globalize( - "cms.contenttypes.ui.description"))); + "cms.contenttypes.ui.description"))); add(m_description); //add(new Label( add(new Embedded( - "\n", - false)); + false)); /* Sub-title external URL / internal URL (content item) */ add(new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.link_type_subtitle"), + "cms.contenttyes.link.ui.link_type_subtitle"), Label.BOLD), ColumnPanel.FULL_WIDTH); /* Option group to choose either external oder internal */ m_linkType = new RadioGroup("linkType"); - + Option m_external = new Option( - Link.EXTERNAL_LINK, - new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.option_group.link_type.external"))); + Link.EXTERNAL_LINK, + new Label(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.option_group.link_type.external"))); m_external.setOnClick("enableUrlFields()"); - + Option m_internal = new Option( - Link.INTERNAL_LINK, - new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.option_group.link_type.internal"))); + Link.INTERNAL_LINK, + new Label(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.option_group.link_type.internal"))); m_internal.setOnClick("enableItemFields()"); - + m_linkType.addOption(m_external); m_linkType.addOption(m_internal); m_linkType.setOptionSelected(m_internal); m_linkType.addValidationListener(new NotNullValidationListener()); add(new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.option_group.link_type.label"))); + "cms.contenttyes.link.ui.option_group.link_type.label"))); add(m_linkType); /* External target */ - Fieldset externalFieldset = new Fieldset(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_uri")); + Fieldset externalFieldset = new Fieldset(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.target_uri")); externalFieldset.setClassAttr("externalLink autoHide"); m_targetURI = new TextField("targetURI"); m_targetURI.setOnFocus("toggle_link_fields(false)"); m_targetURI.setHint(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_uri_hint")); + "cms.contenttyes.link.ui.target_uri_hint")); externalFieldset.add(new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_uri"))); + "cms.contenttyes.link.ui.target_uri"))); externalFieldset.add(m_targetURI); - add(externalFieldset); - + add(externalFieldset); + /* Internal target */ - Fieldset internalFieldset = new Fieldset(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_content_item")); + Fieldset internalFieldset = new Fieldset(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.target_content_item")); internalFieldset.setClassAttr("internalLink autoHide"); - internalFieldset.add(new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_content_item") )); + internalFieldset.add(new Label(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.target_content_item"))); m_itemSearch = new ItemSearchWidget(ITEM_SEARCH, m_contentType); m_itemSearch.getSearchButton().setOnFocus("toggle_link_fields(true)"); m_itemSearch.getClearButton().setOnFocus("toggle_link_fields(true)"); @@ -240,14 +245,14 @@ public class LinkPropertyForm extends FormSection /* Optional parameters for internal target */ internalFieldset.add(new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_parameters") )); + "cms.contenttyes.link.ui.target_parameters"))); m_itemParams = new TextField("itemParams"); m_itemParams.setOnFocus("toggle_link_fields(true)"); m_itemParams.setHint(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.target_parameters_hint") ); + "cms.contenttyes.link.ui.target_parameters_hint")); internalFieldset.add(m_itemParams); - add(internalFieldset); - + add(internalFieldset); + // TODO: // Move this option to contentasset related link for backwards compatibility // because this option is no longer compatible with current HTML @@ -255,17 +260,17 @@ public class LinkPropertyForm extends FormSection // cms_links to cms_related_links which shoud become ca_related_links /* Single option whether to open in new window, strongly discouraged!*/ Option m_selectWindow = new Option( - Link.TARGET_WINDOW, - new Label(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.option.new_window"))); - // "Open URL in new window"); + Link.TARGET_WINDOW, + new Label(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.option.new_window"))); + // "Open URL in new window"); m_URIOption = new CheckboxGroup("openOption"); m_URIOption.addOption(m_selectWindow); add(m_URIOption, ColumnPanel.FULL_WIDTH); //add(new Label( add(new Embedded( - "\n", - false), ColumnPanel.FULL_WIDTH); + false), ColumnPanel.FULL_WIDTH); } /** @@ -286,35 +291,37 @@ public class LinkPropertyForm extends FormSection m_saveCancelSection = new SaveCancelSection(); try { m_saveCancelSection.getCancelButton().addPrintListener( - new PrintListener() { - - @Override - public void prepare(PrintEvent e) { - Submit target = (Submit) e.getTarget(); - if (m_linkModel.isSelected(e.getPageState())) { - target.setButtonLabel(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.button_cancel")); - } else { - target.setButtonLabel(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.button_reset")); - } + new PrintListener() { + + @Override + public void prepare(PrintEvent e) { + Submit target = (Submit) e.getTarget(); + if (m_linkModel.isSelected(e.getPageState())) { + target.setButtonLabel(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.button_cancel")); + } else { + target.setButtonLabel(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.button_reset")); } - }); + } + + }); m_saveCancelSection.getSaveButton().addPrintListener( - new PrintListener() { - - @Override - public void prepare(PrintEvent e) { - Submit target = (Submit) e.getTarget(); - if (m_linkModel.isSelected(e.getPageState())) { - target.setButtonLabel(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.button_save")); - } else { - target.setButtonLabel(GlobalizationUtil.globalize( - "cms.contenttyes.link.ui.button_create")); - } + new PrintListener() { + + @Override + public void prepare(PrintEvent e) { + Submit target = (Submit) e.getTarget(); + if (m_linkModel.isSelected(e.getPageState())) { + target.setButtonLabel(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.button_save")); + } else { + target.setButtonLabel(GlobalizationUtil.globalize( + "cms.contenttyes.link.ui.button_create")); } - }); + } + + }); } catch (TooManyListenersException e) { throw new UncheckedWrapperException("this cannot happen", e); } @@ -323,6 +330,7 @@ public class LinkPropertyForm extends FormSection /** * Retrieves the saveCancelSection. + * * @return Save/Cencel section */ public SaveCancelSection getSaveCancelSection() { @@ -340,11 +348,12 @@ public class LinkPropertyForm extends FormSection * Submission listener. Handles cancel events. * * @param e the FormSectionEvent + * * @throws com.arsdigita.bebop.FormProcessException */ @Override public void submitted(FormSectionEvent e) - throws FormProcessException { + throws FormProcessException { if (m_saveCancelSection.getCancelButton().isSelected(e.getPageState())) { s_log.debug("cancel in submission listener"); m_linkModel.clearSelection(e.getPageState()); @@ -354,42 +363,42 @@ public class LinkPropertyForm extends FormSection } /** - * Validation listener. Ensures consistency of internal vs. external link - * data + * Validation listener. Ensures consistency of internal vs. external link data * * @param event the FormSectionEvent + * * @throws com.arsdigita.bebop.FormProcessException */ @Override public void validate(FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { PageState state = event.getPageState(); FormData data = event.getFormData(); - + if (Link.EXTERNAL_LINK.equals((String) m_linkType.getValue(state))) { // The link is external, the URL must be valid and not null String externalURI = (String) m_targetURI.getValue(state); if (externalURI == null || externalURI.length() == 0) { throw new FormProcessException( - "The URI field is required for an external link."); + "The URI field is required for an external link."); } - + String url = (String) m_targetURI.getValue(state); - + try { // See if it's a valid URL URL test = new URL(url); } catch (MalformedURLException ex) { boolean localLink = url.startsWith("/"); boolean hasProtocol = url.indexOf("://") != -1; - + String newURL; if (localLink) { // For a local link, see if it would be ok if we stuck // "http://servername" on the front newURL = HTTP_PROTOCOL + Web.getConfig().getHost() - + url; + + url; } else if (!hasProtocol) { // There's no protocol. See if it would be ok if we // put one on the beginning @@ -398,15 +407,14 @@ public class LinkPropertyForm extends FormSection } else { // No idea, just throw the error - throw new FormProcessException("URL is not valid: " + - ex.getMessage()); + throw new FormProcessException("URL is not valid: " + ex.getMessage()); } - + try { URL test = new URL(newURL); } catch (MalformedURLException ex2) { StringBuilder msg = new StringBuilder(); - + if (localLink) { // For local link, report the error after we put a // protocol and servername on it @@ -418,7 +426,7 @@ public class LinkPropertyForm extends FormSection msg.append("External URL is not valid: "); msg.append(ex.getMessage()); } - + throw new FormProcessException(msg.toString()); } @@ -427,21 +435,20 @@ public class LinkPropertyForm extends FormSection if (!localLink && !hasProtocol) { m_targetURI.setValue(state, newURL); throw new FormProcessException( - "A valid URL starts with a protocol, eg http://"); + "A valid URL starts with a protocol, eg http://"); } } } else if (Link.INTERNAL_LINK.equals((String) m_linkType.getValue( - state))) { + state))) { // The link is internal, the item selected must be not null if (data.get(ITEM_SEARCH) == null) { throw new FormProcessException( - "Item selection is required for internal link."); + "Item selection is required for internal link."); } // Quasimodo // The target of the link must not be the same as the owner - if(m_itemModel.getSelectedItem(state).getID().equals( - ((ContentItem) data.get(ITEM_SEARCH)).getID()) - ) { + if (m_itemModel.getSelectedItem(state).getID().equals( + ((ContentItem) data.get(ITEM_SEARCH)).getID())) { throw new FormProcessException("Link target is the same as this object."); } } @@ -451,6 +458,7 @@ public class LinkPropertyForm extends FormSection * Get the current ContentItem * * @param s the PageState + * * @return the ContentItem */ protected ContentItem getContentItem(PageState s) { @@ -461,6 +469,7 @@ public class LinkPropertyForm extends FormSection * Take care of basic Link creation steps * * @param s the PageState + * * @return the newly-created Link */ protected Link createLink(PageState s) { @@ -474,6 +483,7 @@ public class LinkPropertyForm extends FormSection * Init listener. For edit actions, fills the form with current data * * @param fse the FormSectionEvent + * * @throws com.arsdigita.bebop.FormProcessException */ @Override @@ -492,7 +502,7 @@ public class LinkPropertyForm extends FormSection if ((link.getTargetURI() != null) && link.getTargetURI().startsWith("&")) { m_itemParams.setValue(state, - link.getTargetURI().substring(1)); + link.getTargetURI().substring(1)); } else { m_targetURI.setValue(state, link.getTargetURI()); } @@ -505,7 +515,7 @@ public class LinkPropertyForm extends FormSection if (Link.INTERNAL_LINK.equals(link.getTargetType())) { data.put(ITEM_SEARCH, link.getTargetItem()); } - + } catch (IllegalStateException e) { s_log.error(e.getMessage()); throw e; @@ -526,6 +536,7 @@ public class LinkPropertyForm extends FormSection * Process listener. Saves/creates the new or modified Link * * @param fse the FormSectionEvent + * * @throws com.arsdigita.bebop.FormProcessException */ @Override @@ -538,9 +549,9 @@ public class LinkPropertyForm extends FormSection // cancel button is selected m_linkModel.clearSelection(state); s_log.debug("link save canceled"); - + } else { - + if (m_linkModel.isSelected(state)) { // Editing a link s_log.debug("processing link edit"); @@ -553,7 +564,7 @@ public class LinkPropertyForm extends FormSection //call to set various properties of Link. setLinkProperties(link, fse); s_log.debug("Created Link with ID: " + link.getOID().toString() - + "Title " + link.getTitle()); + + "Title " + link.getTitle()); } // XXX Initialize the form m_linkModel.clearSelection(state); @@ -561,8 +572,9 @@ public class LinkPropertyForm extends FormSection } /** - * Set various properties of the Link.Child clases can over-ride this method - * to add additional properties to Link. + * Set various properties of the Link.Child clases can over-ride this method to add additional + * properties to Link. + * * @param link * @param fse */ @@ -577,7 +589,7 @@ public class LinkPropertyForm extends FormSection // Process internal and external urls if (Link.EXTERNAL_LINK.equals(m_linkType.getValue(state))) { link.setTargetURI( - (String) m_targetURI.getValue(state)); + (String) m_targetURI.getValue(state)); link.setTargetItem(null); } else { // Internal @@ -585,7 +597,7 @@ public class LinkPropertyForm extends FormSection link.setTargetURI(null); } else { link.setTargetURI(String.format("&%s", m_itemParams.getValue( - state))); + state))); } // Quasimodo: BEGIN @@ -602,7 +614,7 @@ public class LinkPropertyForm extends FormSection // negotiate the language depending on browser settings ci = (ContentItem) ci.getParent(); } - + link.setTargetItem(ci); } // Process whether link is to be opened in new window @@ -618,7 +630,8 @@ public class LinkPropertyForm extends FormSection } else { link.setTargetWindow(""); } - + link.save(); } + } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/NewItemForm.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/NewItemForm.java index 6549f2beb..4682f9345 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/NewItemForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/NewItemForm.java @@ -49,22 +49,23 @@ import java.math.BigDecimal; import org.apache.log4j.Logger; /** - * A form element which displays a select box of all content types available - * under the given content section, and forwards to the item creation UI when - * the user selects a content type to instantiate. + * A form element which displays a select box of all content types available under the given content + * section, and forwards to the item creation UI when the user selects a content type to + * instantiate. * * @author Stanislav Freidin (sfreidin@arsdigtia.com) * @version $Revision: #12 $ $DateTime: 2004/08/17 23:15:09 $ - * @version $Id: NewItemForm.java 2161 2011-02-02 00:16:13Z pboy $ + * @version $Id: NewItemForm.java 2161 2011-02-02 00:16:13Z pboy $ */ public abstract class NewItemForm extends Form { - /** Internal logger instance to faciliate debugging. Enable logging output - * by editing /WEB-INF/conf/log4j.properties int hte runtime environment - * and set com.arsdigita.cms.ui.authoring.NewItemForm=DEBUG by uncommenting - * or adding the line. */ + /** + * Internal logger instance to faciliate debugging. Enable logging output by editing + * /WEB-INF/conf/log4j.properties int hte runtime environment and set + * com.arsdigita.cms.ui.authoring.NewItemForm=DEBUG by uncommenting or adding the line. + */ private static final Logger s_log = Logger.getLogger(NewItemForm.class); - + private final SingleSelect m_typeWidget; private final Submit m_submit; private final Label m_emptyLabel; @@ -72,8 +73,7 @@ public abstract class NewItemForm extends Form { public static final String TYPE_ID = "tid"; /** - * Construct a new NewItemForm. It sets a vertical BoxPanel as the component - * container. + * Construct a new NewItemForm. It sets a vertical BoxPanel as the component container. * * @param name the name attribute of the form. */ @@ -88,18 +88,19 @@ public abstract class NewItemForm extends Form { // create and add an "empty" component m_emptyLabel = new Label(GlobalizationUtil - .globalize("cms.ui.authoring.no_types_registered"), + .globalize("cms.ui.authoring.no_types_registered"), false); m_emptyLabel.setIdAttr("empty_label"); panel.add(m_emptyLabel); m_createLabel = new Label(GlobalizationUtil - .globalize("cms.ui.authoring.create_new"), + .globalize("cms.ui.authoring.create_new"), false); m_createLabel.setIdAttr("create_label"); panel.add(m_createLabel); - m_typeWidget = new SingleSelect(new BigDecimalParameter(TYPE_ID)); + m_typeWidget = new SingleSelect(new BigDecimalParameter(TYPE_ID), + OptionGroup.SortMode.ALPHABETICAL_ASCENDING); try { m_typeWidget.addPrintListener(new PrintListener() { @@ -113,10 +114,8 @@ public abstract class NewItemForm extends Form { ContentSection section = getContentSection(state); ContentType parentType = null; ContentTypeCollection typesCollection = null; - BigDecimal singleTypeID = (BigDecimal) - state.getValue(new - BigDecimalParameter( - ItemSearch.SINGLE_TYPE_PARAM)); + BigDecimal singleTypeID = (BigDecimal) state.getValue(new BigDecimalParameter( + ItemSearch.SINGLE_TYPE_PARAM)); if (singleTypeID != null) { try { @@ -125,7 +124,7 @@ public abstract class NewItemForm extends Form { parentType = null; } } - + if (parentType == null) { typesCollection = section.getCreatableContentTypes(); } else { @@ -141,7 +140,7 @@ public abstract class NewItemForm extends Form { ContentType type = typesCollection.getContentType(); if (PermissionService .getDirectGrantedPermissions(type.getOID()) - .size() > 0) { + .size() > 0) { // chris gilbert - allow restriction of some types // to certain users/groups. No interface to do // this, but group could be created and permission @@ -157,26 +156,25 @@ public abstract class NewItemForm extends Form { if (party == null) { party = Kernel.getPublicUser(); } - PermissionDescriptor create = - new PermissionDescriptor( - PrivilegeDescriptor - .get(SecurityManager - .CMS_NEW_ITEM), - type, - party); + PermissionDescriptor create = new PermissionDescriptor( + PrivilegeDescriptor + .get(SecurityManager.CMS_NEW_ITEM), + type, + party); list = PermissionService.checkPermission(create); } if (list) { - // o.addOption(new Option(type.getID().toString(), type.getName())); - o.addOption( new Option(type.getID().toString(), - new Label(type.getLabel())) ); + // o.addOption(new Option(type.getID().toString(), type.getName())); + o.addOption(new Option(type.getID().toString(), + new Label(type.getLabel()))); } } typesCollection.reset(); } } + }); } catch (java.util.TooManyListenersException e) { throw new UncheckedWrapperException("Too many listeners: " + e.getMessage(), e); @@ -185,26 +183,27 @@ public abstract class NewItemForm extends Form { panel.add(m_typeWidget); m_submit = new Submit("new", GlobalizationUtil.globalize( - "cms.ui.authoring.go")); + "cms.ui.authoring.go")); panel.add(m_submit); - + add(panel); } public abstract ContentSection getContentSection(PageState state); /** - * + * * @param state - * @return + * + * @return */ public BigDecimal getTypeID(PageState state) { return (BigDecimal) m_typeWidget.getValue(state); } /** - * - * @return + * + * @return */ public final SingleSelect getTypeSelect() { return m_typeWidget; @@ -212,8 +211,9 @@ public abstract class NewItemForm extends Form { /** * Generate XML - show/hide labels/widgets + * * @param state - * @param parent + * @param parent */ @Override public void generateXML(PageState state, Element parent) { @@ -233,4 +233,5 @@ public abstract class NewItemForm extends Form { super.generateXML(state, parent); } } + } diff --git a/ccm-core/src/com/arsdigita/bebop/form/CheckboxGroup.java b/ccm-core/src/com/arsdigita/bebop/form/CheckboxGroup.java index bbadbe4b1..68dc5cd2c 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/CheckboxGroup.java +++ b/ccm-core/src/com/arsdigita/bebop/form/CheckboxGroup.java @@ -43,7 +43,7 @@ public class CheckboxGroup extends OptionGroup implements BebopConstants { public CheckboxGroup(ArrayParameter param) { super(param); - m_xmlElement = BEBOP_CHECKBOX; + //m_xmlElement = BEBOP_CHECKBOX; } /** @@ -60,4 +60,9 @@ public class CheckboxGroup extends OptionGroup implements BebopConstants { protected String getElementTag() { return BEBOP_CHECKBOXGROUP; } + + @Override + public String getOptionXMLElement() { + return BEBOP_CHECKBOX; + } } diff --git a/ccm-core/src/com/arsdigita/bebop/form/Option.java b/ccm-core/src/com/arsdigita/bebop/form/Option.java index 7abe68bb4..85584d533 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/Option.java +++ b/ccm-core/src/com/arsdigita/bebop/form/Option.java @@ -133,8 +133,7 @@ public class Option extends DescriptiveComponent { Assert.isUnlocked(this); Assert.exists(group); m_group = group; - m_isSelectOption = - BebopConstants.BEBOP_OPTION.equals(m_group.m_xmlElement); + m_isSelectOption = BebopConstants.BEBOP_OPTION.equals(m_group.getOptionXMLElement()); } public final OptionGroup getGroup() { @@ -243,7 +242,7 @@ public class Option extends DescriptiveComponent { */ @Override public void generateXML(PageState s, Element e) { - Element option = e.newChildElement(m_group.m_xmlElement, BEBOP_XML_NS); + Element option = e.newChildElement(m_group.getOptionXMLElement(), BEBOP_XML_NS); if ( ! m_isSelectOption ) { option.addAttribute("name", getName()); } diff --git a/ccm-core/src/com/arsdigita/bebop/form/OptionGroup.java b/ccm-core/src/com/arsdigita/bebop/form/OptionGroup.java index 25f493d3d..40e73f9ab 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/OptionGroup.java +++ b/ccm-core/src/com/arsdigita/bebop/form/OptionGroup.java @@ -19,17 +19,23 @@ package com.arsdigita.bebop.form; import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.Label; import com.arsdigita.bebop.RequestLocal; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.parameters.ParameterData; import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.ParameterModelWrapper; import com.arsdigita.bebop.util.BebopConstants; +import com.arsdigita.globalization.GlobalizationHelper; import com.arsdigita.util.Assert; import com.arsdigita.xml.Element; +import java.text.Collator; import java.util.Iterator; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; @@ -45,71 +51,171 @@ import org.apache.log4j.Logger; * @author Michael Pih * @version $Id: OptionGroup.java 738 2005-09-01 12:36:52Z sskracic $ */ -public abstract class OptionGroup extends Widget - implements BebopConstants { +public abstract class OptionGroup extends Widget implements BebopConstants { - private static final Logger s_log = Logger.getLogger(OptionGroup.class); + private static final Logger LOGGER = Logger.getLogger(OptionGroup.class); /** * The XML element to be used by individual options belonging to this group. This variable has * to be initialized by every subclass of OptionGroup. LEGACY: An abstract method would be the * better design, but changing it would break the API. */ - protected String m_xmlElement; + //protected String m_xmlElement; // this only needs to be an ArrayList for multiple selection option groups - private ArrayList m_selected; - private ArrayList m_options; + private List m_selected; + private List