Support for language extensions in ccm-navigation

git-svn-id: https://svn.libreccm.org/ccm/trunk@4912 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2017-08-20 10:57:17 +00:00
parent c3a9839ae5
commit e8775bb21e
7 changed files with 895 additions and 763 deletions

View File

@ -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()
*
@ -71,7 +71,8 @@ public final class CMSConfig extends AbstractConfig {
private static CMSConfig s_config;
/**
* Returns the singleton configuration record for the content section environment.
* Returns the singleton configuration record for the content section
* environment.
*
* @return The <code>CMSConfig</code> record; it cannot be null
*/
@ -85,36 +86,40 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Storage (map) for method getAssetStepsToSkip(ContentType type) to store mapping of steps that
* are deemed irrelevant for the passid in type.
* 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
* 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);
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.
* 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.
* 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!
* 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",
@ -134,8 +139,8 @@ public final class CMSConfig extends AbstractConfig {
// }
// ADD:
/**
* Item Adapters File, path to an XML resource containing adapter specifications. Path is
* relative to webapp root.
* 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",
@ -143,22 +148,23 @@ public final class CMSConfig extends AbstractConfig {
"/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
* 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.
* 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"));
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
@ -170,20 +176,22 @@ public final class CMSConfig extends AbstractConfig {
// be accessable by other modules which use DHTMLeditor.
// Would be bad style to configure a cms specific parameter in core.
/**
* Defines which plugins to use, e.g.TableOperations,CSS Format: [string,string,string]
* 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.
* 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);
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.
*/
@ -227,8 +235,8 @@ public final class CMSConfig extends AbstractConfig {
Parameter.REQUIRED,
Boolean.FALSE);
/**
* Hide timezone labels (if, for example, all users will be in the same timezone and such
* information would be unnecessary)
* 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",
@ -244,47 +252,54 @@ public final class CMSConfig extends AbstractConfig {
/**
* 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());
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'
* 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
* 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.
*
* jensp 2014-11-07: Default changed from true to false. Deleting the assigned workflow means
* that the authors have to reattach a workflow using the Workflow tab, which is complicated
* (for some users too complicated). Also deleting the workflow means that the new convenient
* Whether an item's workflow should be deleted, once the item has been
* (re)published.
*
* jensp 2014-11-07: Default changed from true to false. Deleting the
* assigned workflow means that the authors have to reattach a workflow
* using the Workflow tab, which is complicated (for some users too
* complicated). Also deleting the workflow means that the new convenient
* link to restart a workflow will not work.
*
*
*/
private final Parameter m_deleteWorkflowAfterPublication = new BooleanParameter(
"com.arsdigita.cms.delete_workflow_after_publication",
Parameter.REQUIRED,
Boolean.FALSE);
private final Parameter m_deleteWorkflowAfterPublication
= new BooleanParameter(
"com.arsdigita.cms.delete_workflow_after_publication",
Parameter.REQUIRED,
Boolean.FALSE);
/**
* Defines the number of days ahead that are covered in the 'Soon Expired' tab
* 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
* 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",
@ -298,47 +313,51 @@ public final class CMSConfig extends AbstractConfig {
Parameter.REQUIRED,
Boolean.TRUE);
/**
* Links created through browse interfaces should only be within the same subsite
* 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
* 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);
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.
* 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
* 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)
* 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)
* 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",
@ -352,74 +371,83 @@ public final class CMSConfig extends AbstractConfig {
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
* 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
* 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.
* 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);
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
* 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.
* 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.
* 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);
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.
*
* jensp 2014-11-07: Default changed to false. This feature isn't used by most users. Also
* it has some drawbacks, for example items creating using this way are put into the root
* folder.
* Allow content creation in Workspace (content center) section listing.
* Allows you to turn off the ability to create content in the section
* listing.
*
* jensp 2014-11-07: Default changed to false. This feature isn't used by
* most users. Also it has some drawbacks, for example items creating using
* this way are put into the root folder.
*/
private final Parameter m_allowContentCreateInSectionListing = new BooleanParameter(
"com.arsdigita.cms.allow_content_create_in_section_listing",
Parameter.REQUIRED,
Boolean.FALSE);
private final Parameter m_allowContentCreateInSectionListing
= new BooleanParameter(
"com.arsdigita.cms.allow_content_create_in_section_listing",
Parameter.REQUIRED,
Boolean.FALSE);
/**
* 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.
* 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",
@ -429,31 +457,34 @@ public final class CMSConfig extends AbstractConfig {
// Notification related parameters
// ///////////////////////////////////////////
/**
* Delete Sent Workflow Notifications. Decide whether successfully sent notifications and
* messages should be deleted from the system
* 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);
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
* 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);
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
* 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
* 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",
@ -463,7 +494,8 @@ public final class CMSConfig extends AbstractConfig {
// Content Center (Workspace) config related parameters
// ////////////////////////////////////////////////////
/**
* XML Mapping of the content center tabs to URLs, see {@link ContentCenterDispatcher}
* 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",
@ -485,16 +517,18 @@ public final class CMSConfig extends AbstractConfig {
// 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);
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
/////////////////////////////////////////////
@ -505,10 +539,11 @@ public final class CMSConfig extends AbstractConfig {
// "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);
private final Parameter m_itemSearchFlatBrowsePanePageSize
= new IntegerParameter(
"com.arsdigita.cms.item_search.flat_browse_pane.page_size",
Parameter.REQUIRED,
20);
/////////////////////////////////////////////
// FolderBrowse
/////////////////////////////////////////////
@ -528,10 +563,11 @@ public final class CMSConfig extends AbstractConfig {
//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);
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
@ -552,22 +588,25 @@ public final class CMSConfig extends AbstractConfig {
/////////////////////////////////////////////////
// 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_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_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,
@ -627,11 +666,18 @@ public final class CMSConfig extends AbstractConfig {
60 * 60 * 24);
/**
* Max length of the description of a link (in database max length are 4000 characters)
* 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);
/**
* Always use language extension?
*/
private final Parameter m_useLanguageExtension = new BooleanParameter(
"com.arsdigita.cms.use_language_extension", Parameter.REQUIRED, false);
// ///////////////////////////////////////////
// publishToFile package related parameter
// ///////////////////////////////////////////
@ -743,14 +789,17 @@ public final class CMSConfig extends AbstractConfig {
register(m_enableXmlCache);
register(m_xmlCacheSize);
register(m_xmlCacheAge);
register(m_linkDescMaxLength);
register(m_useLanguageExtension);
loadInfo();
}
/**
* Retrieve path of the root folder for template folders. Path is relative to webapp root.
* Retrieve path of the root folder for template folders. Path is relative
* to webapp root.
*/
public final String getTemplateRoot() {
return (String) get(m_templateRootPath);
@ -790,7 +839,8 @@ public final class CMSConfig extends AbstractConfig {
/**
*
* @deprecated use com.arsdigita.cms.ContentSection.getDefaultSection().getName() instead
* @deprecated use
* com.arsdigita.cms.ContentSection.getDefaultSection().getName() instead
*/
public final String getDefaultContentSection() {
// return (String) get(m_defaultSection);
@ -901,7 +951,8 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Fetch the file name contaning XML Mapping of the content center tabs to URLs
* Fetch the file name contaning XML Mapping of the content center tabs to
* URLs
*
* @return String containig file name including path component.
*/
@ -910,15 +961,16 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Internal class representing a DHTMLEditor configuration parameter. It creates a new
* DHMTLEditor Config object (internal class in DHTMLEditor).
* 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)
* 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 {
@ -973,8 +1025,9 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* 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.
* 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() {
@ -986,8 +1039,8 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* The relative weight given to title element within cms:item element when ranking search
* results Only used by the interMedia query engine.
* 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() {
@ -995,9 +1048,11 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Whether to include INPATH operators to contains clause in intermedia search
* 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
* NB - if true, INDEX MUST BE CREATED WITH PATH_SECTION_GROUP - upgrade
* 6.5.0 - 6.5.1
*
* @return
*/
@ -1006,12 +1061,13 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* for the given content type, returns a collection of steps that are deemed irrelevant for the
* type.
* 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
* Steps are the names of the bebop step components that are used by the
* authoring kit wizard
*
* @param type
*
@ -1033,7 +1089,8 @@ public final class CMSConfig extends AbstractConfig {
// 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]);
Collection typeSteps = (Collection) s_skipAssetSteps.get(
pair[0]);
if (typeSteps == null) {
typeSteps = new HashSet();
s_skipAssetSteps.put(pair[0], typeSteps);
@ -1056,7 +1113,8 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* May be used by any content type creation form to decide whether to validate description field
* May be used by any content type creation form to decide whether to
* validate description field
*
*/
public boolean mandatoryDescriptions() {
@ -1064,32 +1122,35 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Used to decide whether lifecycles (and all asociated phases) should be deleted from the
* system when complete
* 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)
* (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.
* 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
* 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();
return ((Boolean) get(m_deleteExpiryNotificationsWhenSent))
.booleanValue();
}
/**
* Used to decide whether to delete old notification records for workflow notifications.
* 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
* If true, notifications and messages are deleted if the notification is
* successfully sent. Any send failures are retained
*
*/
public boolean deleteWorkflowNotifications() {
@ -1102,11 +1163,12 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* 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.
* 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
*/
@ -1119,10 +1181,11 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* 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.
* 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)
*/
@ -1137,8 +1200,8 @@ public final class CMSConfig extends AbstractConfig {
}
/**
* Hide the (no longer used) legacy public site link in Workspace (content center) section
* listing, true by default.
* 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();
@ -1181,15 +1244,18 @@ public final class CMSConfig extends AbstractConfig {
}
public int getImageBrowserCaptionSize() {
return Math.min(((Integer) get(m_imageBrowserCaptionSize)).intValue(), 100);
return Math.min(((Integer) get(m_imageBrowserCaptionSize)).intValue(),
100);
}
public int getImageBrowserDescriptionSize() {
return Math.min(((Integer) get(m_imageBrowserDescriptionSize)).intValue(), 400);
return Math.min(((Integer) get(m_imageBrowserDescriptionSize))
.intValue(), 400);
}
public int getImageBrowserTitleSize() {
return Math.min(((Integer) get(m_imageBrowserTitleSize)).intValue(), 200);
return Math
.min(((Integer) get(m_imageBrowserTitleSize)).intValue(), 200);
}
public Boolean getImageCacheEnabled() {
@ -1234,9 +1300,13 @@ public final class CMSConfig extends AbstractConfig {
public Integer getXmlCacheAge() {
return (Integer) get(m_xmlCacheAge);
}
public Integer getLinkDescMaxLength() {
return (Integer) get(m_linkDescMaxLength);
}
public Boolean getUseLanguageExtension() {
return (Boolean) get(m_useLanguageExtension);
}
}

View File

@ -359,4 +359,9 @@ 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]
com.arsdigita.cms.link_description_max_length.format={Integer]
com.arsdigita.cms.use_language_extension.title=Add language extensions
com.arsdigita.cms.use_language_extension.purpose=Always add language extension to content item URLs
com.arsdigita.cms.use_language_extension.example=true
com.arsdigita.cms.use_language_extension.format=[Boolean]

View File

@ -123,6 +123,12 @@ public class GlobalizationHelper {
return selectedLocale;
}
public static void setSelectedLocale(final String language) {
final HttpServletRequest request = DispatcherHelper.getRequest();
request.getSession().setAttribute(LANG_PARAM, language);
}
/**
* Create a Locale from a browser provides language string
*

View File

@ -15,7 +15,6 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.arsdigita.navigation;
import com.arsdigita.bebop.PageState;
@ -51,28 +50,40 @@ import org.apache.log4j.Logger;
/**
* Configuration record for the navigation app
*
* @author Daniel Berrange
*/
public final class NavigationConfig extends AbstractConfig {
private static final Logger s_log = Logger.getLogger(NavigationConfig.class);
/** The cache lifetime for category index pages in seconds. Default 1 hour */
private final Parameter m_indexPageCacheLifetime = new IntegerParameter
("com.arsdigita.navigation.index_page_cache_lifetime",
Parameter.REQUIRED, new Integer(3600));
/** Generate full item URLs instead of going via search redirector. Default true */
private final Parameter m_generateItemURL = new BooleanParameter
("com.arsdigita.navigation.generate_item_url",
Parameter.REQUIRED, new Boolean(true));
/** The default category template. */
private final Parameter m_defaultTemplate = new StringParameter
("com.arsdigita.navigation.default_template",
Parameter.REQUIRED, "/templates/ccm-navigation/navigation/nav-default.jsp");
/** If no template for category, should it get template from parent, or
* fall back on default? Default: true */
/**
* The cache lifetime for category index pages in seconds. Default 1 hour
*/
private final Parameter m_indexPageCacheLifetime = new IntegerParameter(
"com.arsdigita.navigation.index_page_cache_lifetime",
Parameter.REQUIRED, new Integer(3600));
/**
* Generate full item URLs instead of going via search redirector. Default
* true
*/
private final Parameter m_generateItemURL = new BooleanParameter(
"com.arsdigita.navigation.generate_item_url",
Parameter.REQUIRED, new Boolean(true));
/**
* The default category template.
*/
private final Parameter m_defaultTemplate = new StringParameter(
"com.arsdigita.navigation.default_template",
Parameter.REQUIRED,
"/templates/ccm-navigation/navigation/nav-default.jsp");
/**
* If no template for category, should it get template from parent, or fall
* back on default? Default: true
*/
private final Parameter m_inheritTemplates;
// Removed, use content-section config directly instead!
// ContentSection.getConfig().getDefaultContentSection()
@ -92,19 +103,24 @@ public final class NavigationConfig extends AbstractConfig {
// Quasimodo: End
private final Parameter m_dateOrderCategories;
private final Parameter m_topLevelDateOrderCategories;
/** Class that provides categories included in menu for any categories that
* do not have an alternative provider registered */
private final Parameter m_defaultMenuCatProvider;
private final Parameter m_useLanguageExtension;
/**
* Class that provides categories included in menu for any categories that
* do not have an alternative provider registered
*/
private final Parameter m_defaultMenuCatProvider;
private static Set s_fixedDateOrderCats = null;
private Category m_defaultCategoryRoot = null;
// maybe 2 lookups in a single request so prevent double overhead
private RequestLocal m_allDateOrderCategories = new RequestLocal () {
public Object initialValue (PageState state) {
private RequestLocal m_allDateOrderCategories = new RequestLocal() {
public Object initialValue(PageState state) {
return getCurrentDateOrderCategories();
}
};
private NavigationModel m_defaultModel = null;
@ -112,54 +128,59 @@ public final class NavigationConfig extends AbstractConfig {
private TreeCatProvider m_treeCatProvider = null;
public NavigationConfig() {
// not desirable default value (IMHO) but retains existing behaviour
m_inheritTemplates = new BooleanParameter
("com.arsdigita.navigation.inherit_templates",
// not desirable default value (IMHO) but retains existing behaviour
m_inheritTemplates = new BooleanParameter(
"com.arsdigita.navigation.inherit_templates",
Parameter.REQUIRED, new Boolean(true));
m_relatedItemsContext = new StringParameter
("com.arsdigita.navigation.related_items_context",
Parameter.REQUIRED, "subject");
m_defaultModelClass = new StringParameter
("com.arsdigita.navigation.default_nav_model",
Parameter.REQUIRED, ApplicationNavigationModel.class.getName());
m_defaultCatRootPath = new StringParameter
("com.arsdigita.navigation.default_cat_root_path",
Parameter.REQUIRED, "/navigation/");
m_relatedItemsFactory = new ClassParameter
("com.arsdigita.navigation.related_items_factory",
Parameter.REQUIRED, RelatedItemsQueryFactoryImpl.class);
m_traversalAdapters = new ResourceParameter
("com.arsdigita.navigation.traversal_adapters",
Parameter.REQUIRED,
"/WEB-INF/resources/navigation-adapters.xml");
m_categoryMenuShowNephews = new BooleanParameter
("com.arsdigita.navigation.category_menu_show_nephews",
Parameter.OPTIONAL, new Boolean(false));
m_relatedItemsContext = new StringParameter(
"com.arsdigita.navigation.related_items_context",
Parameter.REQUIRED, "subject");
m_defaultModelClass = new StringParameter(
"com.arsdigita.navigation.default_nav_model",
Parameter.REQUIRED, ApplicationNavigationModel.class.getName());
m_defaultCatRootPath = new StringParameter(
"com.arsdigita.navigation.default_cat_root_path",
Parameter.REQUIRED, "/navigation/");
m_relatedItemsFactory = new ClassParameter(
"com.arsdigita.navigation.related_items_factory",
Parameter.REQUIRED, RelatedItemsQueryFactoryImpl.class);
m_traversalAdapters = new ResourceParameter(
"com.arsdigita.navigation.traversal_adapters",
Parameter.REQUIRED,
"/WEB-INF/resources/navigation-adapters.xml");
m_categoryMenuShowNephews = new BooleanParameter(
"com.arsdigita.navigation.category_menu_show_nephews",
Parameter.OPTIONAL, new Boolean(false));
// Quasimodo: Begin
m_categoryMenuShowGrandChildren = new StringParameter
("com.arsdigita.navigation.category_menu_show_grand_children",
Parameter.OPTIONAL, "false");
m_categoryMenuShowGrandChildrenMax = new IntegerParameter
("com.arsdigita.navigation.category_menu_show_grand_children_max",
Parameter.OPTIONAL, new Integer(0));
m_categoryMenuShowGrandChildrenMin = new IntegerParameter
("com.arsdigita.navigation.category_menu_show_grand_children_min",
Parameter.OPTIONAL, new Integer(1));
m_categoryMenuShowGrandChildrenLimit = new IntegerParameter
("com.arsdigita.navigation.category_menu_show_grand_children_limit",
Parameter.OPTIONAL, new Integer(1));
m_categoryMenuShowGrandChildren = new StringParameter(
"com.arsdigita.navigation.category_menu_show_grand_children",
Parameter.OPTIONAL, "false");
m_categoryMenuShowGrandChildrenMax = new IntegerParameter(
"com.arsdigita.navigation.category_menu_show_grand_children_max",
Parameter.OPTIONAL, new Integer(0));
m_categoryMenuShowGrandChildrenMin = new IntegerParameter(
"com.arsdigita.navigation.category_menu_show_grand_children_min",
Parameter.OPTIONAL, new Integer(1));
m_categoryMenuShowGrandChildrenLimit = new IntegerParameter(
"com.arsdigita.navigation.category_menu_show_grand_children_limit",
Parameter.OPTIONAL, new Integer(1));
// Quasimodo: End
m_dateOrderCategories = new StringArrayParameter
("com.arsdigita.navigation.date_order_categories",
Parameter.OPTIONAL, new String[0]);
m_topLevelDateOrderCategories = new StringArrayParameter
("com.arsdigita.navigation.top_level_date_order_categories",
m_dateOrderCategories = new StringArrayParameter(
"com.arsdigita.navigation.date_order_categories",
Parameter.OPTIONAL, new String[0]);
m_defaultMenuCatProvider = new ClassParameter
("com.arsdigita.navigation.default_menu_cat_provider",
m_topLevelDateOrderCategories = new StringArrayParameter(
"com.arsdigita.navigation.top_level_date_order_categories",
Parameter.OPTIONAL, new String[0]);
m_defaultMenuCatProvider = new ClassParameter(
"com.arsdigita.navigation.default_menu_cat_provider",
Parameter.OPTIONAL, null);
m_useLanguageExtension = new BooleanParameter(
"com.arsdigita.navigation.use_language_extension",
Parameter.OPTIONAL,
false);
register(m_indexPageCacheLifetime);
register(m_generateItemURL);
register(m_defaultTemplate);
@ -182,35 +203,38 @@ public final class NavigationConfig extends AbstractConfig {
register(m_dateOrderCategories);
register(m_topLevelDateOrderCategories);
register(m_defaultMenuCatProvider);
register(m_useLanguageExtension);
loadInfo();
// Quasimodo: Begin
// Checking Paramter
String param = new String((String)get(m_categoryMenuShowGrandChildren));
if( param.equals("false") || param.equals("adaptive") || param.equals("true")) {
String param = new String((String) get(m_categoryMenuShowGrandChildren));
if (param.equals("false") || param.equals("adaptive") || param.equals(
"true")) {
set(m_categoryMenuShowGrandChildren, param);
} else {
s_log.error("com.arsdigita.navigation.category_menu_show_grand_children: "+
"Invalid setting " + param + ". Falling back to false.");
set(m_categoryMenuShowGrandChildren, "false");
s_log.error(
"com.arsdigita.navigation.category_menu_show_grand_children: "
+ "Invalid setting " + param + ". Falling back to false.");
set(m_categoryMenuShowGrandChildren, "false");
}
// Quasimodo: End
}
public final long getIndexPageCacheLifetime() {
return ((Integer)get(m_indexPageCacheLifetime)).longValue();
return ((Integer) get(m_indexPageCacheLifetime)).longValue();
}
public final boolean getGenerateItemURL() {
return ((Boolean)get(m_generateItemURL)).booleanValue();
return ((Boolean) get(m_generateItemURL)).booleanValue();
}
public final String getDefaultTemplate() {
return (String)get(m_defaultTemplate);
return (String) get(m_defaultTemplate);
}
public final boolean inheritTemplates() {
return ((Boolean) get(m_inheritTemplates)).booleanValue();
return ((Boolean) get(m_inheritTemplates)).booleanValue();
}
// Removed, use content-section config directly instead!
@ -218,17 +242,16 @@ public final class NavigationConfig extends AbstractConfig {
// public final String getDefaultContentSectionURL() {
// return (String)get(m_defaultContentSectionURL);
// }
public final String getRelatedItemsContext() {
return (String)get(m_relatedItemsContext);
return (String) get(m_relatedItemsContext);
}
public final String getDefaultCategoryRootPath() {
return (String)get(m_defaultCatRootPath);
return (String) get(m_defaultCatRootPath);
}
public final Class getRelatedItemsFactory() {
return (Class)get(m_relatedItemsFactory);
return (Class) get(m_relatedItemsFactory);
}
public final synchronized NavigationModel getDefaultModel() {
@ -236,29 +259,27 @@ public final class NavigationConfig extends AbstractConfig {
return m_defaultModel;
}
String defaultModelClassName = (String)get(m_defaultModelClass);
String defaultModelClassName = (String) get(m_defaultModelClass);
try {
Class defaultModelClass = Class.forName(defaultModelClassName);
Constructor cons = defaultModelClass.getConstructor
( new Class[]{} );
m_defaultModel = (NavigationModel) cons.newInstance
( new Object[]{} );
Constructor cons = defaultModelClass.getConstructor(new Class[]{});
m_defaultModel = (NavigationModel) cons.newInstance(new Object[]{});
} catch (Exception ex) {
throw new UncheckedWrapperException( ex );
throw new UncheckedWrapperException(ex);
}
return m_defaultModel;
}
public final synchronized Category getDefaultCategoryRoot() {
if (null != m_defaultCategoryRoot) {
if (null != m_defaultCategoryRoot) {
return m_defaultCategoryRoot;
}
String defaultCatRootPath = (String)get(m_defaultCatRootPath);
String defaultCatRootPath = (String) get(m_defaultCatRootPath);
Application app =
Application.retrieveApplicationForPath(defaultCatRootPath);
Application app = Application.retrieveApplicationForPath(
defaultCatRootPath);
Assert.exists(app, Application.class);
Category m_defaultCategoryRoot = Category.getRootForObject(app);
@ -268,33 +289,37 @@ public final class NavigationConfig extends AbstractConfig {
}
InputStream getTraversalAdapters() {
return (InputStream)get(m_traversalAdapters);
return (InputStream) get(m_traversalAdapters);
}
public final boolean getCategoryMenuShowNephews() {
return ((Boolean)get(m_categoryMenuShowNephews)).booleanValue();
}
return ((Boolean) get(m_categoryMenuShowNephews)).booleanValue();
}
// Quasimodo: Begin
public final String getCategoryMenuShowGrandChildren() {
return (String)get(m_categoryMenuShowGrandChildren);
}
public final long getCategoryMenuShowGrandChildrenMax() {
return ((Integer)get(m_categoryMenuShowGrandChildrenMax)).longValue();
}
public final long getCategoryMenuShowGrandChildrenMin() {
return ((Integer)get(m_categoryMenuShowGrandChildrenMin)).longValue();
}
public final long getCategoryMenuShowGrandChildrenLimit() {
return ((Integer)get(m_categoryMenuShowGrandChildrenLimit)).longValue();
}
return (String) get(m_categoryMenuShowGrandChildren);
}
public final long getCategoryMenuShowGrandChildrenMax() {
return ((Integer) get(m_categoryMenuShowGrandChildrenMax)).longValue();
}
public final long getCategoryMenuShowGrandChildrenMin() {
return ((Integer) get(m_categoryMenuShowGrandChildrenMin)).longValue();
}
public final long getCategoryMenuShowGrandChildrenLimit() {
return ((Integer) get(m_categoryMenuShowGrandChildrenLimit)).longValue();
}
// Quasimodo: End
/**
* retrieve a collection of categories to order by date. Collection includes
* categories directly specified as date ordered and also all subcategories of
* categories specified as being top level date ordered categories
* in config
* retrieve a collection of categories to order by date. Collection includes
* categories directly specified as date ordered and also all subcategories
* of categories specified as being top level date ordered categories in
* config
*
* @return
*/
public Collection getDateOrderedCategories(PageState state) {
@ -302,56 +327,57 @@ public final class NavigationConfig extends AbstractConfig {
if (state == null) {
categories = getCurrentDateOrderCategories();
} else {
categories = (Collection)m_allDateOrderCategories.get(state);
categories = (Collection) m_allDateOrderCategories.get(state);
}
return categories;
}
public boolean isDateOrderedCategory (Category cat, PageState state) {
public boolean isDateOrderedCategory(Category cat, PageState state) {
return getDateOrderedCategories(state).contains(cat.getID().toString());
}
private Collection getCurrentDateOrderCategories () {
if (s_fixedDateOrderCats == null) {
populateFixedDateOrderCats();
}
private Collection getCurrentDateOrderCategories() {
if (s_fixedDateOrderCats == null) {
populateFixedDateOrderCats();
}
String[] topLevelCats = (String[]) get(m_topLevelDateOrderCategories);
Set allCats = new HashSet();
allCats.addAll(s_fixedDateOrderCats);
for (int i = 0; i < topLevelCats.length; i++) {
try {
String[] categoryArray = StringUtils.split(topLevelCats[i], ':');
String order = "";
if (categoryArray.length > 1) {
order = ":" + categoryArray[1];
}
Category topLevelCat = new Category(new BigDecimal(categoryArray[0]));
s_log.debug("retrieved top level category " + topLevelCat);
Set childCats = new HashSet();
CategoryCollection children = topLevelCat.getDescendants();
while (children.next()) {
BigDecimal id = children.getCategory().getID();
childCats.add(id.toString() + order);
}
String[] topLevelCats = (String[]) get(m_topLevelDateOrderCategories);
Set allCats = new HashSet();
allCats.addAll(s_fixedDateOrderCats);
for (int i = 0; i < topLevelCats.length; i++) {
try {
String[] categoryArray = StringUtils.split(topLevelCats[i], ':');
String order = "";
if (categoryArray.length > 1) {
order = ":" + categoryArray[1];
}
Category topLevelCat = new Category(new BigDecimal(
categoryArray[0]));
s_log.debug("retrieved top level category " + topLevelCat);
Set childCats = new HashSet();
CategoryCollection children = topLevelCat.getDescendants();
while (children.next()) {
BigDecimal id = children.getCategory().getID();
childCats.add(id.toString() + order);
}
allCats.addAll(childCats);
} catch (DataObjectNotFoundException e) {
// non existent category id specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + topLevelCats[i] +
" specified in configuration as a top level date order category, " +
"but the category does not exist");
} catch (NumberFormatException e) {
// non number specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + topLevelCats[i] +
" specified in configuration as a top level date order category, "+
"but this is not a valid number");
}
allCats.addAll(childCats);
} catch (DataObjectNotFoundException e) {
// non existent category id specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + topLevelCats[i]
+ " specified in configuration as a top level date order category, "
+ "but the category does not exist");
} catch (NumberFormatException e) {
// non number specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + topLevelCats[i]
+ " specified in configuration as a top level date order category, "
+ "but this is not a valid number");
}
}
return allCats;
}
return allCats;
}
@ -360,49 +386,54 @@ public final class NavigationConfig extends AbstractConfig {
// concurrently first time after server restart
private synchronized void populateFixedDateOrderCats() {
String[] catArray = (String[]) get(m_dateOrderCategories);
s_fixedDateOrderCats = new HashSet();
for (int i = 0; i < catArray.length; i++) {
try {
// don't need to do this, as including invalid or non existent
// ids will not have any adverse effects, but this gives us a chance to
// provide some warning to the users when they find that a category
// they expected to be date ordered isn't because they mistyped etc.
// This only occurs once, first time navigation page is accessed after
// server restart
String[] category = StringUtils.split(catArray[i], ':');
Category cat = new Category(new BigDecimal(category[0]));
} catch (DataObjectNotFoundException e) {
// non existent category id specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + catArray[i] +
" specified in configuration as a date ordered category, but the category" +
"does not exist");
} catch (NumberFormatException e) {
// non number specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + catArray[i] +
" specified in configuration as a date ordered category, "+
"but this is not a valid number");
}
s_fixedDateOrderCats.add(catArray[i]);
}
String[] catArray = (String[]) get(m_dateOrderCategories);
s_fixedDateOrderCats = new HashSet();
for (int i = 0; i < catArray.length; i++) {
try {
// don't need to do this, as including invalid or non existent
// ids will not have any adverse effects, but this gives us a chance to
// provide some warning to the users when they find that a category
// they expected to be date ordered isn't because they mistyped etc.
// This only occurs once, first time navigation page is accessed after
// server restart
String[] category = StringUtils.split(catArray[i], ':');
Category cat = new Category(new BigDecimal(category[0]));
} catch (DataObjectNotFoundException e) {
// non existent category id specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + catArray[i]
+ " specified in configuration as a date ordered category, but the category"
+ "does not exist");
} catch (NumberFormatException e) {
// non number specified in configuration. Output warning to
// logs and continue
s_log.warn("Category with id " + catArray[i]
+ " specified in configuration as a date ordered category, "
+ "but this is not a valid number");
}
s_fixedDateOrderCats.add(catArray[i]);
}
}
public final TreeCatProvider getDefaultMenuCatProvider() {
if (null == m_treeCatProvider) {
try {
Class providerClass = (Class) get(m_defaultMenuCatProvider);
if (providerClass == null) {
m_treeCatProvider = new Menu();
} else {
m_treeCatProvider = (TreeCatProvider) providerClass.newInstance();
}
} catch (Exception ex) {
throw new UncheckedWrapperException(ex);
}
}
return m_treeCatProvider;
if (null == m_treeCatProvider) {
try {
Class providerClass = (Class) get(m_defaultMenuCatProvider);
if (providerClass == null) {
m_treeCatProvider = new Menu();
} else {
m_treeCatProvider = (TreeCatProvider) providerClass
.newInstance();
}
} catch (Exception ex) {
throw new UncheckedWrapperException(ex);
}
}
return m_treeCatProvider;
}
public Boolean getUseLanguageExtension() {
return (Boolean) get(m_useLanguageExtension);
}
}

View File

@ -82,3 +82,8 @@ com.arsdigita.navigation.default_menu_cat_provider.title=Default Menu Category P
com.arsdigita.navigation.default_menu_cat_provider.purpose=Class that provides categories included in menu for any categories that do not have an alternative provider registered
com.arsdigita.navigation.default_menu_cat_provider.example=com.arsdigita.navigation.ui.category.TreeCatProviderImpl
com.arsdigita.navigation.default_menu_cat_provider.format=[class]
com.arsdigita.navigation.use_language_extension.title=Use language extension
com.arsdigita.navigation.use_language_extension.purpose=Use language extension to distiguish language version.
com.arsdigita.navigation.use_language_extension.example=true
com.arsdigita.navigation.use_language_extension.format=[Boolean]

View File

@ -43,16 +43,18 @@ import com.arsdigita.web.Application;
import com.arsdigita.web.DefaultApplicationFileResolver;
import com.arsdigita.web.Web;
import com.arsdigita.globalization.GlobalizationHelper;
/**
* Manages the processing of URLs in the Navigation application.
*
*/
public class NavigationFileResolver extends DefaultApplicationFileResolver {
private static final Logger s_log =
Logger.getLogger(NavigationFileResolver.class);
private static final String CATEGORY_PATH_ATTR =
NavigationFileResolver.class + ".categoryPath";
private static final Logger s_log = Logger.getLogger(
NavigationFileResolver.class);
private static final String CATEGORY_PATH_ATTR
= NavigationFileResolver.class + ".categoryPath";
// path is set in a cookie, which navigation models may use if they wish
public static final String PATH_COOKIE_NAME = "ad_path";
public static final char PATH_COOKIE_SEPARATOR = '|';
@ -71,6 +73,14 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
s_log.debug("Resolving " + path);
}
if (Navigation.getConfig().getUseLanguageExtension()
&& path.matches("(.*)/index\\.[a-zA-Z]{2}")) {
final String lang = path.substring(path.length() - 2);
path = path.substring(0, path.length() - "index.$$".length());
GlobalizationHelper.setSelectedLocale(lang);
}
if (path.equals("/category.jsp")) {
Navigation nav = (Navigation) Web.getWebContext().getApplication();
@ -105,14 +115,16 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
// check that the category is in the tree of categories
Category root = null;
DataCollection objs = SessionManager.getSession()
.retrieve(Domain.BASE_DATA_OBJECT_TYPE);
objs.addEqualsFilter("model.ownerUseContext.categoryOwner.id", nav.getID());
.retrieve(Domain.BASE_DATA_OBJECT_TYPE);
objs.addEqualsFilter("model.ownerUseContext.categoryOwner.id", nav
.getID());
String dispatcherContext = null;
TemplateContext tc = Navigation.getContext().getTemplateContext();
if (tc != null) {
dispatcherContext = tc.getContext();
}
objs.addEqualsFilter("model.ownerUseContext.useContext", dispatcherContext);
objs.addEqualsFilter("model.ownerUseContext.useContext",
dispatcherContext);
DomainCollection domains = new DomainCollection(objs);
if (domains.next()) {
root = ((Domain) domains.getDomainObject()).getModel();
@ -141,7 +153,8 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
cats.add(parents.getCategory());
}
Category[] catsArray = (Category[]) cats.toArray(new Category[cats.size()]);
Category[] catsArray = (Category[]) cats.toArray(new Category[cats
.size()]);
sreq.setAttribute(CATEGORY_PATH_ATTR,
catsArray);
@ -206,9 +219,8 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
// be used if a navigation model retains the cookie. If we link to
// another application, it's navigation model may use this when
// deciding whether to trust the given path.
path.append(PATH_COOKIE_SEPARATOR +
Kernel.getContext().getResource().getID().toString());
path.append(PATH_COOKIE_SEPARATOR + Kernel.getContext().getResource()
.getID().toString());
for (int i = 0; i < catsArray.length; i++) {
Category cat = catsArray[i];
path.append(PATH_COOKIE_SEPARATOR + cat.getID().toString());
@ -223,7 +235,6 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
}
resp.addCookie(cookie);
}
public static Category[] getCategoryPath(HttpServletRequest req) {
@ -240,10 +251,11 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
}
/**
*
*
* @param cat
* @param useContext
* @return
*
* @return
*/
private RequestDispatcher resolveTemplate(Category cat, String useContext) {
Template template = null;
@ -258,9 +270,9 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
}
// If there's an explicit use context which doesn't exist, give a 404
if (!Template.DEFAULT_USE_CONTEXT.equals(useContext) && null == template) {
s_log.debug("No template found in context " + getTemplateContext() +
" for category " + cat.getID()
+ " with use context " + useContext);
s_log.debug("No template found in context " + getTemplateContext()
+ " for category " + cat.getID()
+ " with use context " + useContext);
return null;
}
@ -316,12 +328,13 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
/**
*
* category resolution retained as an instance method to allow it to be
* overridden. Default functionality contained in static resolveCategory
* category resolution retained as an instance method to allow it to be
* overridden. Default functionality contained in static resolveCategory
* method.
*
* @param root
* @param path
*
* @return
*/
protected Category[] resolvePath(Category root, String path) {
@ -329,13 +342,13 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
}
/**
* Match a URL with the category tree and return the requested category
* if exists.
* Match a URL with the category tree and return the requested category if
* exists.
*
* Quasimodo: Originally addEqualsFilter has been used to filter the
* appropriate category directly inside the SQL query. This isn't possible
* anymore due to the localised URLs of the new localised categories
* (or at least: not found it). Therefore we do the filtering in Java now.
* Quasimodo: Originally addEqualsFilter has been used to filter the
* appropriate category directly inside the SQL query. This isn't possible
* anymore due to the localised URLs of the new localised categories (or at
* least: not found it). Therefore we do the filtering in Java now.
*
*/
public static Category[] resolveCategory(Category root,
@ -382,4 +395,5 @@ public class NavigationFileResolver extends DefaultApplicationFileResolver {
return (Category[]) cats.toArray(new Category[cats.size()]);
}
}