diff --git a/ccm-cms-types-mparticle/src/com/arsdigita/cms/contenttypes/ui/mparticle/MultiPartArticleForm.java b/ccm-cms-types-mparticle/src/com/arsdigita/cms/contenttypes/ui/mparticle/MultiPartArticleForm.java index c5534841a..3330be592 100755 --- a/ccm-cms-types-mparticle/src/com/arsdigita/cms/contenttypes/ui/mparticle/MultiPartArticleForm.java +++ b/ccm-cms-types-mparticle/src/com/arsdigita/cms/contenttypes/ui/mparticle/MultiPartArticleForm.java @@ -35,6 +35,7 @@ import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.DateParameter; import com.arsdigita.bebop.parameters.NotEmptyValidationListener; import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.URLTokenValidationListener; import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.TrimmedStringParameter; import com.arsdigita.cms.ContentItem; @@ -43,7 +44,6 @@ import com.arsdigita.cms.ContentSection; import com.arsdigita.cms.Folder; import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.contenttypes.MultiPartArticle; -import com.arsdigita.cms.ui.authoring.NameValidationListener; import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.cms.contenttypes.util.MPArticleGlobalizationUtil; import com.arsdigita.persistence.DataQuery; @@ -132,7 +132,8 @@ public abstract class MultiPartArticleForm extends FormSection add(new Label(GlobalizationUtil .globalize("cms.contenttypes.ui.name"))); TextField nameWidget = new TextField(new TrimmedStringParameter(NAME)); - nameWidget.addValidationListener(new NameValidationListener()); + nameWidget.addValidationListener(new NotNullValidationListener()); + nameWidget.addValidationListener(new URLTokenValidationListener()); nameWidget.setOnFocus("defaulting = false"); nameWidget.setOnBlur( "if (this.value == '') " + diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources.properties index 71f017eed..0e89cef97 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources.properties @@ -263,7 +263,7 @@ cms.ui.item_search.search=Search # Package com.arsdigita.cms.ui.authoring # ====================================== -cms.ui.authoring.an_item_with_this_name_already_exists=An item with this name already exists! +cms.ui.authoring.an_item_with_this_name_exists=An item with this name already exists! cms.ui.authoring.bad_getblob_datatype=Bad getBlob datatype cms.ui.authoring.bad_getclob_datatype=Bad getClob datatype cms.ui.authoring.body=Body: diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties index 2320e5e27..7d630a43a 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources_de.properties @@ -261,7 +261,7 @@ cms.ui.item_search.search=Suchen # Package com.arsdigita.cms.ui.authoring # ====================================== -cms.ui.authoring.an_item_with_this_name_already_exists=Ein Dokument mit diesem Namen existiert bereits! +cms.ui.authoring.an_item_with_this_name_exists=Ein Dokument mit diesem Namen existiert bereits! cms.ui.authoring.bad_getblob_datatype=Ung\u00fcltiger Datentyp getBlob cms.ui.authoring.bad_getclob_datatype=Ung\u00fcltiger Datentyp getClob cms.ui.authoring.body=Textbereich: diff --git a/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties b/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties index 3931826e6..384defec8 100755 --- a/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties +++ b/ccm-cms/src/com/arsdigita/cms/CMSResources_fr.properties @@ -157,7 +157,7 @@ cms.ui.no_items_matched_the_search=Pas d'\u00e9l\u00e9ment trouv\u00e9 dans la r # Package com.arsdigita.cms.ui.authoring # ====================================== -cms.ui.authoring.an_item_with_this_name_already_exists=Un \u00e9l\u00e9ment de ce nom existe d\u00e9j\u00e0! +cms.ui.authoring.an_item_with_this_name_exists=Un \u00e9l\u00e9ment de ce nom existe d\u00e9j\u00e0! cms.ui.authoring.bad_getblob_datatype=TRANSLATE THIS: Bad getBlob datatype (cms.ui.authoring.bad_getblob_datatype) cms.ui.authoring.bad_getclob_datatype=TRANSLATE THIS: Bad getClob datatype (cms.ui.authoring.bad_getclob_datatype) cms.ui.authoring.body=Corsp de la page diff --git a/ccm-cms/src/com/arsdigita/cms/ContentPage.java b/ccm-cms/src/com/arsdigita/cms/ContentPage.java index b2d58f86e..010251473 100755 --- a/ccm-cms/src/com/arsdigita/cms/ContentPage.java +++ b/ccm-cms/src/com/arsdigita/cms/ContentPage.java @@ -34,9 +34,15 @@ import java.util.Date; import org.apache.log4j.Logger; /** - * This class extends {@link com.arsdigita.cms.ContentItem content - * item} with the additional attributes name, title and description. The name attribute is used in - * generating the URL for this content page. + * This class extends {@link com.arsdigita.cms.ContentItem content item} with + * the additional attributes name, title and description. The name attribute is + * used in generating the URL for this content page. + * It is the base class for any document-type of content, i.e. content bearing a + * title, name and description/abstract (in con trast to assets or special + * content as Contact or internal type as folder). + * + * ContentPage is a bit of missleading, more adaquat would have been + * ContentDocument. * * @author Uday Mathur * @author Jack Chung diff --git a/ccm-cms/src/com/arsdigita/cms/ItemSelectionModel.java b/ccm-cms/src/com/arsdigita/cms/ItemSelectionModel.java index cecaba32f..58e7bbda5 100755 --- a/ccm-cms/src/com/arsdigita/cms/ItemSelectionModel.java +++ b/ccm-cms/src/com/arsdigita/cms/ItemSelectionModel.java @@ -59,7 +59,7 @@ public class ItemSelectionModel extends ACSObjectSelectionModel { * the {@link com.arsdigita.domain.DomainObjectFactory}. * * @param parameter The state parameter which should be used to store - * the object ID + * the object ID */ public ItemSelectionModel(BigDecimalParameter parameter) { this(null, null, parameter); @@ -72,7 +72,7 @@ public class ItemSelectionModel extends ACSObjectSelectionModel { * the {@link com.arsdigita.domain.DomainObjectFactory}. * * @param parameterName The name of the state parameter which will - * be used to store the object ID. + * be used to store the object ID. */ public ItemSelectionModel(String parameterName) { this(null, null, new BigDecimalParameter(parameterName)); @@ -216,7 +216,7 @@ public class ItemSelectionModel extends ACSObjectSelectionModel { * * @param s the current page state * @return the currently selected ContentItem, or null - * if no item was selected. + * if no item was selected. */ public final ContentItem getSelectedItem(PageState s) { return (ContentItem)getSelectedObject(s); @@ -253,9 +253,10 @@ public class ItemSelectionModel extends ACSObjectSelectionModel { } /** - * @return The content type of the items which are produced by - * this model, or null if the content type has not been specified - * in the constructor. + * + * @return The content type of the items which are produced by this model, + * or null if the content type has not been specified in the + * constructor. */ public ContentType getContentType() { diff --git a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java index 492a37da1..25dac8015 100755 --- a/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java +++ b/ccm-cms/src/com/arsdigita/cms/contenttypes/ui/GenericArticlePropertyForm.java @@ -35,6 +35,10 @@ import com.arsdigita.cms.ui.authoring.BasicPageForm; public class GenericArticlePropertyForm extends BasicPageForm implements FormProcessListener, FormInitListener, FormSubmissionListener { + /** 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.contenttypes.ui.GenericArticlePropertyForm=DEBUG + * by uncommenting or adding the line. */ private final static org.apache.log4j.Logger s_log = org.apache.log4j.Logger.getLogger(GenericArticlePropertyForm.class); private GenericArticlePropertiesStep m_step; diff --git a/ccm-cms/src/com/arsdigita/cms/ui/CategoryForm.java b/ccm-cms/src/com/arsdigita/cms/ui/CategoryForm.java index 42df2424a..e37ba9e63 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/CategoryForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/CategoryForm.java @@ -449,14 +449,14 @@ public abstract class CategoryForm extends Form if (query.size() > 0) { // we need to make sure that there is not an item ACSObject item = getObject(state); - Collection list = null; + Collection list; if (item instanceof ContentItem) { list = BasicItemForm.getAllVersionIDs((ContentItem) item); } else { list = new ArrayList(); list.add(item.getID()); } - BigDecimal itemID = null; + BigDecimal itemID; while (query.next()) { itemID = (BigDecimal) query.get("itemID"); if (!list.contains(itemID)) { diff --git a/ccm-cms/src/com/arsdigita/cms/ui/ItemPropertySheet.java b/ccm-cms/src/com/arsdigita/cms/ui/ItemPropertySheet.java index 3595abcec..88688d28a 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/ItemPropertySheet.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/ItemPropertySheet.java @@ -81,6 +81,7 @@ public class ItemPropertySheet extends PropertySheet { * @deprecated */ public ItemPropertySheet(ItemSelectionModel itemModel, boolean valueOutputEscape) { + super(new ItemModelBuilder(), valueOutputEscape); m_itemModel = itemModel; @@ -102,7 +103,7 @@ public class ItemPropertySheet extends PropertySheet { * @param label The label for the attribute * @param attribute The name for the attribute. Could be a simple name * or a compound path, such as "foo.bar.baz" - * @deprecated + * @deprecated use add(GlobalizedMessage label, String attribute) instead */ public void add(String label, String attribute) { add(GlobalizationUtil.globalize(label), attribute); @@ -110,8 +111,8 @@ public class ItemPropertySheet extends PropertySheet { /** - * Add a new property to the sheet. The sheet will automatically - * retrieve an attribute of the item and call toString() on it + * Add a new property to the sheet. The sheet will automatically retrieve + * an attribute of the item and call toString() on it * * @param label The label for the attribute * @param attribute The name for the attribute. Could be a simple name diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicItemForm.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicItemForm.java index 0dc274c00..658d99072 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicItemForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicItemForm.java @@ -33,7 +33,9 @@ import com.arsdigita.bebop.event.FormValidationListener; import com.arsdigita.bebop.form.Hidden; import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.ParameterData; import com.arsdigita.bebop.parameters.TrimmedStringParameter; +import com.arsdigita.bebop.parameters.URLTokenValidationListener; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentPage; import com.arsdigita.cms.Folder; @@ -85,6 +87,7 @@ public abstract class BasicItemForm extends FormSection * for loading the current item */ public BasicItemForm(String formName, ItemSelectionModel itemModel) { + super(new ColumnPanel(2)); m_widgetSection = new FormSection(new ColumnPanel(2, true)); @@ -196,8 +199,12 @@ public abstract class BasicItemForm extends FormSection final TextField nameWidget = new TextField(new TrimmedStringParameter(NAME)); nameWidget.setLabel(getNameLabel()); nameWidget.setHint(getNameHint()); + // We just check parameter specific properties here! Additionally, + // context properties as uniqueness in folder must be validated + // for the form es the whole (using the validate method required by + // implementing FormValidationListener in this form. nameWidget.addValidationListener(new NotNullValidationListener()); - nameWidget.addValidationListener(new NameValidationListener()); + nameWidget.addValidationListener(new URLTokenValidationListener()); nameWidget.setMaxLength(190); nameWidget.setOnFocus("defaulting = false"); nameWidget.setOnBlur( @@ -249,8 +256,9 @@ public abstract class BasicItemForm extends FormSection public abstract void process(FormSectionEvent e) throws FormProcessException; /** - * Validate the form. Children should override this method to provide - * custom form validation. + * Validate the form. Children have to override this method to provide + * context form validation, specifically name (url) uniqueness in a + * folder! * * @param e * @throws com.arsdigita.bebop.FormProcessException @@ -261,173 +269,6 @@ public abstract class BasicItemForm extends FormSection } - /** - * Ensure that the name of an item is unique within a folder. - * A "New item" form should call this method in the validation listener. - * - * @param parent the folder in which to check - * @param event the {@link FormSectionEvent} which was passed to the - * validation listener - * - * @throws FormProcessException if the folder already contains an item - * with the name the use provided on the input form. - */ - public void validateNameUniqueness(Folder parent, FormSectionEvent event) - throws FormProcessException { - - FormData data = event.getFormData(); - String newName = (String) data.get(NAME); - - validateNameUniqueness(parent, event, newName); - } - - /** - * - * @param parent - * @param event - * @param newName - * - * @throws FormProcessException - */ - public void validateNameUniqueness(Folder parent, - FormSectionEvent event, - String newName) - throws FormProcessException { - - if (newName != null) { - final String query = "com.arsdigita.cms.validateUniqueItemName"; - DataQuery dq = SessionManager.getSession().retrieveQuery(query); - dq.setParameter("parentId", parent.getID()); - dq.setParameter("name", newName.toUpperCase()); - FormData data = event.getFormData(); - - - if (dq.size() > 0) { - // we need to add all of the items that are - // different versions of this item to the list - // so that we do not throw an error if those - // are the only problems - BigDecimal itemID = null; - - ContentItem item = null; - if (getItemSelectionModel() != null) { - item = (ContentItem) getItemSelectionModel() - .getSelectedObject(event.getPageState()); - } - if (item == null) { - // this means it is a creation form - data.addError(globalize( - "cms.ui.authoring.an_item_with_this_name_already_exists")); - throw new FormProcessException( - "An item with this name already exists", - globalize("cms.ui.authoring.an_item_with_this_name_already_exists" - ) - ); - } - Collection list = getAllVersionIDs(item); - while (dq.next()) { - itemID = (BigDecimal) dq.get("itemID"); - if (!list.contains(itemID)) { - String[] itemObj=new String[1]; - itemObj[0]=itemID.toString(); - dq.close(); - data.addError(globalize( - "cms.ui.authoring.an_item_with_this_name_already_exists")); - throw new FormProcessException( - "An item with this name already exists", - globalize( - "cms.ui.authoring.items_with_this_name_already_exist", - itemObj) - ); - } - } - } - } - } - - /** - * Ensure that the name of an item is unique within a category. This should - * only be called from the validation listener of an "edit" form. - * - * @param event the {@link FormSectionEvent} which was passed to the - * validation listener - * @param id The id of the item that is being checked. This must no be null. - * - * @throws FormProcessException if the folder already contains an item with - * the name the user provided on the input form. - */ - public void validateNameUniquenessWithinCategory(FormSectionEvent event, - BigDecimal id) - throws FormProcessException { - if (id == null) { - s_log.warn("Trying to validation the name uniqueness without " - + " a valid item is invalid. This method should only " - + " be called in \"edit\" forms. The passed in id " - + " was null."); - return; - } - // now we check to make sure that the new name is valid - // within every category that the item is mapped to - // this is only necessary for category browsing - FormData data = event.getFormData(); - String url = (String) data.get(NAME); - if (url == null) { - return; - } - DataQuery query = SessionManager.getSession().retrieveQuery( - "com.arsdigita.categorization.getAllItemURLsForCategoryFromItem"); - query.setParameter("itemID", id); - query.addEqualsFilter("lower(url)", url.toLowerCase()); - if (query.size() > 0) { - // we need to make sure that the conflicting item is not a - // pending or live version of the same item - BigDecimal itemID = null; - - ContentItem item = (ContentItem)getItemSelectionModel() - .getSelectedObject(event.getPageState()); - Collection list = getAllVersionIDs(item); - try { - while (query.next()) { - itemID = (BigDecimal) query.get("itemID"); - if (!list.contains(itemID)) { - // StringBuffer buffer = new StringBuffer((String) GlobalizationUtil - // .globalize("cms.ui.authoring.error_conflicts_with_this_url") - // .localize()); - // buffer.append(url); - String[] urlObj=new String[1]; - urlObj[0]=url; - throw new FormProcessException( - "Error: Conflict with url: "+url, - globalize( - "cms.ui.authoring.error_conflicts_with_this_url", - urlObj) - ); - } - } - - } finally { - query.close(); - } - } - } - - public static Collection getAllVersionIDs(ContentItem item) { - // we need to add all of the items that are different versions - // of this item to the list so that we do not throw an error - // if those are the only problems - ArrayList list = new ArrayList(); - list.add(item.getID()); - ContentItem live = item.getLiveVersion(); - if (live != null) { - list.add(live.getID()); - } - ItemCollection collection = item.getPendingVersions(); - while (collection.next()) { - list.add(collection.getID()); - } - return list; - } - /** * Adds a component to this container. * @@ -500,4 +341,181 @@ public abstract class BasicItemForm extends FormSection return GlobalizationUtil.globalize("cms.contenttypes.ui.name_hint"); } + + // ////////////////////////////////////////////////////////////////////// + // + // VALIDATION helper methods + // + // ////////////////////////////////////////////////////////////////////// + + + /** + * Ensure that the name of an item is unique within a folder. + * A "New item" form should call this method in the validation listener. + * + * @param parent the folder in which to check + * @param event the {@link FormSectionEvent} which was passed to the + * validation listener + * + * @throws FormProcessException if the folder already contains an item + * with the name the use provided on the input form. + */ + public void validateNameUniqueness(Folder parent, FormSectionEvent event) { + + FormData data = event.getFormData(); + String newName = (String) data.get(NAME); + + validateNameUniqueness(parent, event, newName); + } + + /** + * + * @param parent + * @param event + * @param newName + * + * @throws FormProcessException + */ + public void validateNameUniqueness(Folder parent, + FormSectionEvent event, + String newName) { + + final String ERR_MSG = "cms.ui.authoring.an_item_with_this_name_exists"; + + if (newName != null) { + final String query = "com.arsdigita.cms.validateUniqueItemName"; + DataQuery dq = SessionManager.getSession().retrieveQuery(query); + dq.setParameter("parentId", parent.getID()); + dq.setParameter("name", newName.toUpperCase()); + FormData data = event.getFormData(); + ParameterData name = data.getParameter(NAME); + + + if (dq.size() > 0) { + // Try to get a currently selected content item + ContentItem item = null; + if (getItemSelectionModel() != null) { + item = (ContentItem) getItemSelectionModel() + .getSelectedObject(event.getPageState()); + } + if (item == null) { // The content item being null + // means it is a creation form. + // Therefore finding any item of the same name is a fault. + name.addError(globalize(ERR_MSG)); + return; + } else { + // means we are in a edit form. + // We need to add all of the items that are different + // versions of this item to the list so that we do not mark + // an error if those are the only problems. + BigDecimal itemID = null; + Collection list = getAllVersionIDs(item); + while (dq.next()) { + itemID = (BigDecimal) dq.get("itemID"); + if (!list.contains(itemID)) { + String[] itemObj=new String[1]; + itemObj[0]=itemID.toString(); + dq.close(); + name.addError(globalize(ERR_MSG)); + return; + } + } + } + } + } + } + + /** + * NOT USED ANYMORE. + * + * Ensure that the name of an item is unique within a category. This should + * only be called from the validation listener of an "edit" form. + * + * @param event the {@link FormSectionEvent} which was passed to the + * validation listener + * @param id The id of the item that is being checked. This must no be null. + * @return + * + * @throws FormProcessException if the folder already contains an item with + * the name the user provided on the input form. + * / + public void validateNameUniquenessWithinCategory(FormSectionEvent event, + BigDecimal id) + throws FormProcessException { + if (id == null) { + s_log.warn("Trying to validation the name uniqueness without " + + " a valid item is invalid. This method should only " + + " be called in \"edit\" forms. The passed in id " + + " was null."); + return; + } + // now we check to make sure that the new name is valid + // within every category that the item is mapped to + // this is only necessary for category browsing + FormData data = event.getFormData(); + String url = (String) data.get(NAME); + if (url == null) { + return; + } + DataQuery query = SessionManager.getSession().retrieveQuery( + "com.arsdigita.categorization.getAllItemURLsForCategoryFromItem"); + query.setParameter("itemID", id); + query.addEqualsFilter("lower(url)", url.toLowerCase()); + if (query.size() > 0) { + // we need to make sure that the conflicting item is not a + // pending or live version of the same item + BigDecimal itemID = null; + + ContentItem item = (ContentItem)getItemSelectionModel() + .getSelectedObject(event.getPageState()); + Collection list = getAllVersionIDs(item); + try { + while (query.next()) { + itemID = (BigDecimal) query.get("itemID"); + if (!list.contains(itemID)) { + // StringBuffer buffer = new StringBuffer((String) GlobalizationUtil + // .globalize("cms.ui.authoring.error_conflicts_with_this_url") + // .localize()); + // buffer.append(url); + String[] urlObj=new String[1]; + urlObj[0]=url; + throw new FormProcessException( + "Error: Conflict with url: "+url, + globalize( + "cms.ui.authoring.error_conflicts_with_this_url", + urlObj) + ); + } + } + + } finally { + query.close(); + } + } + } +*/ + + /** + * Helper Method for name uniqueness validation. + * + * @param item + * @return + */ + public static Collection getAllVersionIDs(ContentItem item) { + // we need to add all of the items that are different versions + // of this item to the list so that we do not throw an error + // if those are the only problems + ArrayList list = new ArrayList(); + list.add(item.getID()); + ContentItem live = item.getLiveVersion(); + if (live != null) { + list.add(live.getID()); + } + ItemCollection collection = item.getPendingVersions(); + while (collection.next()) { + list.add(collection.getID()); + } + return list; + } + } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicPageForm.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicPageForm.java index 6062c16c6..3efb6795b 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicPageForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/BasicPageForm.java @@ -44,11 +44,18 @@ import javax.servlet.ServletException; import java.util.Date; /** - * A form for editing subclasses of ContentPage. + * A form for editing basic properties of documents (that is subclasses of + * class ContentPage). + * + * Document specific classes inherit from this class which provides the basic + * widgets for title, name launch date to use by those classes. * * This is just a convenience class. It uses parent class to construct the form * including basic widgets (i.e. title and name/url as well as save/cancel - * buttons) and adds optional Lunchdate + * buttons) and adds optional Lunchdate. + * + * Note: It is for editing existing content (specifically due to its validation + * method). * * @author Stanislav Freidin (stas@arsdigita.com) * @version $Revision: #22 $ $DateTime: 2004/08/17 23:15:09 $ @@ -56,7 +63,13 @@ import java.util.Date; public abstract class BasicPageForm extends BasicItemForm { private FormSection m_widgetSection; -// public static final String DESCRIPTION = ContentPage.DESCRIPTION; + + // description / abstract has been delegated to document-specific classes + // propably to better adjust to specific needs, unfortunately to the + // expense of internal consistency (because any document should carry a + // description in constrast to items as folders of parts of a document, as + // a section in a multipart article). + // public static final String DESCRIPTION = ContentPage.DESCRIPTION; public static final String LAUNCH_DATE = ContentPage.LAUNCH_DATE; /** @@ -144,13 +157,16 @@ public abstract class BasicPageForm extends BasicItemForm { } /** + * Class specific implementation of FormValidationListener interface + * (inherited from BasicItemForm). * * @param fse * @throws FormProcessException */ @Override public void validate(final FormSectionEvent fse) throws FormProcessException { - super.validate(fse); + + super.validate(fse); //noop, BasicItemForm#validate does nothing final ContentItem item = getItemSelectionModel() .getSelectedItem(fse.getPageState()); @@ -165,7 +181,7 @@ public abstract class BasicPageForm extends BasicItemForm { Assert.exists(folder); final FormData data = fse.getFormData(); final String name = data.getString(NAME); - if (!item.getName().equals(name)) { + if (!item.getName().equals(name)) { // name modified? validateNameUniqueness(folder, fse); } } @@ -250,7 +266,6 @@ public abstract class BasicPageForm extends BasicItemForm { if (value == null) { data.addError("launch date is required"); - return; } } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/NameValidationListener.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/NameValidationListener.java deleted file mode 100755 index dc8d94248..000000000 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/NameValidationListener.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -package com.arsdigita.cms.ui.authoring; - -import com.arsdigita.bebop.event.ParameterEvent; -import com.arsdigita.bebop.event.ParameterListener; -import com.arsdigita.bebop.parameters.ParameterData; -import com.arsdigita.cms.util.GlobalizationUtil; - -import java.util.StringTokenizer; - -import org.apache.log4j.Logger; - -/** - * Verifies that the parameter is a valid filenamersp. URL stub, is not null, - * and contains no reserved characters. - * - * @author Justin Ross <jross@redhat.com> - * @author Peter Boy <pb@zes.uni-bremen.de> - * @version $Id: NameValidationListener.java 2090 2010-04-17 08:04:14Z pboy $ - */ -public class NameValidationListener implements ParameterListener { - - - /** 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.NameValidationListener=DEBUG - * by uncommenting or adding the line. */ - private static final Logger s_log = Logger.getLogger - (NameValidationListener.class); - - /** - * Default Constructor, creates a new NameValidationListener. - */ - public NameValidationListener() { - - } - - /** - * Constructs a new NameValidationListener. - * - * @param label the label for the error message - * @deprecated with no replacement. Does nothing anymore. - */ - public NameValidationListener(final String label) { - // Do nothing - } - - /** - * Validate the input field as passed in by ParameterEvent. - * - * @param e ParameterEvent containing input data. - */ - @Override - public void validate(final ParameterEvent e) { - final ParameterData data = e.getParameterData(); - final Object value = data.getValue(); - - if (value == null || value.toString().length() < 1) { - data.addError(GlobalizationUtil - .globalize("cms.ui.authoring.parameter_not_empty")); - return; - } - - final String text = value.toString(); - - final StringTokenizer tok = - new StringTokenizer(text, "*? /\\\'\"&$`~"); - - if (tok.hasMoreTokens()) { - final String token = tok.nextToken(); - - if (!token.equals(text)) { - data.addError(GlobalizationUtil.globalize( - "cms.ui.authoring.parameter_should_be_a_valid_filename")); - } - } - - if (text.indexOf(".") != -1) { - data.addError(GlobalizationUtil.globalize( - "cms.ui.authoring.parameter_should_be_a_valid_filename")); - } - } -} 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 d7f9a2880..6f3be4828 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/NewItemForm.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/NewItemForm.java @@ -94,6 +94,7 @@ public abstract class NewItemForm extends Form { m_typeWidget.addPrintListener(new PrintListener() { // Read the content section's content types and add them as options + @Override public void prepare(PrintEvent e) { OptionGroup o = (OptionGroup) e.getTarget(); PageState state = e.getPageState(); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageCreate.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageCreate.java index f43b3921f..721201478 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageCreate.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageCreate.java @@ -38,7 +38,8 @@ import java.util.Date; import org.apache.log4j.Logger; /** - * A form which will create a new ContentPage or one of its subclasses. + * A form which will create a new documnent (that is subclasses of class + * ContentPage). * * Used to create a new document / content item. Creates widgets to select the * workflow, and language. It displays the type of document as well. Super class @@ -54,12 +55,16 @@ import org.apache.log4j.Logger; public class PageCreate extends BasicPageForm implements FormSubmissionListener, CreationComponent { + /** 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.PageCreate=DEBUG + * by uncommenting or adding the line. */ + private final static org.apache.log4j.Logger s_log = + org.apache.log4j.Logger.getLogger(PageCreate.class); protected final CreationSelector m_parent; protected ApplyWorkflowFormSection m_workflowSection; - /** - * The state parameter which specifies the content section - */ + /** The state parameter which specifies the content section */ public static final String SECTION_ID = "sid"; /** @@ -154,6 +159,7 @@ public class PageCreate extends BasicPageForm * tries to access things which on existing yet. * * @param event + * @throws com.arsdigita.bebop.FormProcessException */ @Override public void validate(final FormSectionEvent event) throws FormProcessException { @@ -162,7 +168,14 @@ public class PageCreate extends BasicPageForm validateNameUniqueness(folder, event); } - // Process: save fields to the database + /** + * Class specific implementation if FormProcessListener (as inherited from + * BasicItemForm), saves fields to the database. + * + * @param e + * @throws FormProcessException + */ + @Override public void process(final FormSectionEvent e) throws FormProcessException { final FormData data = e.getFormData(); final PageState state = e.getPageState(); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEdit.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEdit.java index 7e6f3cfbd..d2544e6bc 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEdit.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEdit.java @@ -32,27 +32,27 @@ import com.arsdigita.cms.ui.ItemPropertySheet; import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess; import com.arsdigita.cms.util.GlobalizationUtil; import com.arsdigita.util.Assert; -import org.apache.log4j.Logger; import java.text.DateFormat; +import org.apache.log4j.Logger; + /** - * The article editing component. Consists of a display component - * which displays the form metadata, and a form which edits the - * metadata as well as text. + * The article editing component. Consists of a display component which + * displays the form metadata, and a form which edits the metadata as well + * as text. * * The {@link com.arsdigita.bebop.PropertySheet} class is often used * as the display component in the default authoring kit steps of * this class. * * @author Stanislav Freidin - * @version $Revision: #14 $ $DateTime: 2004/08/17 23:15:09 $ * @version $Id: PageEdit.java 2090 2010-04-17 08:04:14Z pboy $ */ public class PageEdit extends SimpleEditStep { - private static Logger s_log = + private static final Logger s_log = Logger.getLogger(PageEdit.class); //XD: The output escaping of the values of the label value pairs @@ -73,18 +73,23 @@ public class PageEdit extends SimpleEditStep { super(itemModel, parent); PageEditForm form = new PageEditForm(itemModel); - add("edit", "Edit", new WorkflowLockedComponentAccess(form, itemModel), + add("edit", + GlobalizationUtil.globalize("cms.ui.edit"), + new WorkflowLockedComponentAccess(form, itemModel), form.getSaveCancelSection().getCancelButton()); //DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel); ItemPropertySheet sheet = new ItemPropertySheet(itemModel, VALUE_OUTPUT_ESCAPE); - sheet.add((String) GlobalizationUtil.globalize("cms.ui.authoring.name").localize(), ContentPage.NAME); - sheet.add((String) GlobalizationUtil.globalize("cms.ui.authoring.title").localize(), ContentPage.TITLE); + sheet.add(GlobalizationUtil.globalize("cms.ui.authoring.name"), + ContentPage.NAME); + sheet.add(GlobalizationUtil.globalize("cms.ui.authoring.title"), + ContentPage.TITLE); if (!ContentSection.getConfig().getHideLaunchDate()) { sheet.add("Launch Date:", ContentPage.LAUNCH_DATE, new ItemPropertySheet.AttributeFormatter() { + @Override public String format(ContentItem item, String attribute, PageState state) { @@ -146,6 +151,11 @@ public class PageEdit extends SimpleEditStep { } } + /** + * + * @param event + * @throws FormProcessException + */ @Override public void validate(FormSectionEvent event) throws FormProcessException { super.validate(event); diff --git a/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEditDynamic.java b/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEditDynamic.java index 9de012f53..b50552f4a 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEditDynamic.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/authoring/PageEditDynamic.java @@ -38,6 +38,7 @@ import com.arsdigita.bebop.parameters.NotNullValidationListener; import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.parameters.TrimmedStringParameter; +import com.arsdigita.bebop.parameters.URLTokenValidationListener; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.ContentPage; import com.arsdigita.cms.ContentSection; @@ -286,7 +287,8 @@ public class PageEditDynamic extends SecurityPropertyEditor { add(new Label(GlobalizationUtil.globalize("cms.ui.authoring.name"))); add(new Label("")); TextField nameWidget = new TextField(new TrimmedStringParameter(NAME)); - nameWidget.addValidationListener(new NameValidationListener()); + nameWidget.addValidationListener(new NotNullValidationListener()); + nameWidget.addValidationListener(new URLTokenValidationListener()); add(nameWidget); add(new Label(GlobalizationUtil.globalize("cms.ui.authoring.title"))); @@ -295,14 +297,14 @@ public class PageEditDynamic extends SecurityPropertyEditor { titleWidget.addValidationListener(new NotNullValidationListener()); add(titleWidget); - add(new Label(GlobalizationUtil.globalize("cms.ui.authoring.page_launch_date"))); + add(new Label(GlobalizationUtil.globalize("cms.ui.authoring.page_launch_date"))); add(new Label("")); - ParameterModel launchDateParam = new DateParameter(LAUNCH_DATE); - launchDateParam - .addParameterListener(new NotNullValidationListener()); - com.arsdigita.bebop.form.Date launchDate - = new com.arsdigita.bebop.form.Date(launchDateParam); - add(launchDate); + ParameterModel launchDateParam = new DateParameter(LAUNCH_DATE); + launchDateParam + .addParameterListener(new NotNullValidationListener()); + com.arsdigita.bebop.form.Date launchDate + = new com.arsdigita.bebop.form.Date(launchDateParam); + add(launchDate); } } diff --git a/ccm-cms/src/com/arsdigita/cms/ui/templates/TemplateEdit.java b/ccm-cms/src/com/arsdigita/cms/ui/templates/TemplateEdit.java index 6e9146774..ee052868e 100755 --- a/ccm-cms/src/com/arsdigita/cms/ui/templates/TemplateEdit.java +++ b/ccm-cms/src/com/arsdigita/cms/ui/templates/TemplateEdit.java @@ -25,6 +25,7 @@ import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.form.TextField; import com.arsdigita.bebop.parameters.NotNullValidationListener; +import com.arsdigita.bebop.parameters.URLTokenValidationListener; import com.arsdigita.bebop.parameters.TrimmedStringParameter; import com.arsdigita.cms.ContentItem; import com.arsdigita.cms.Folder; @@ -32,7 +33,6 @@ import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.Template; import com.arsdigita.cms.ui.authoring.AuthoringKitWizard; import com.arsdigita.cms.ui.authoring.BasicPageForm; -import com.arsdigita.cms.ui.authoring.NameValidationListener; import com.arsdigita.cms.ui.authoring.SimpleEditStep; import com.arsdigita.cms.ui.workflow.WorkflowLockedComponentAccess; import com.arsdigita.cms.util.GlobalizationUtil; @@ -50,8 +50,11 @@ import org.apache.log4j.Logger; */ public class TemplateEdit extends SimpleEditStep { - private static Logger s_log = - Logger.getLogger(TemplateEdit.class); + /** 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.templates.TemplateEdit=DEBUG + * by uncommenting or adding the line. */ + private static final Logger s_log = Logger.getLogger(TemplateEdit.class); /** * Construct a new TemplateEdit component @@ -72,8 +75,10 @@ public class TemplateEdit extends SimpleEditStep { //DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel); DomainObjectPropertySheet sheet = new DomainObjectPropertySheet(itemModel, false); - sheet.add((String) GlobalizationUtil.globalize("cms.ui.templates.name").localize(), ContentItem.NAME); - sheet.add((String) GlobalizationUtil.globalize("cms.ui.templates.label").localize(), Template.LABEL); + sheet.add(GlobalizationUtil.globalize("cms.ui.templates.name"), + ContentItem.NAME); + sheet.add(GlobalizationUtil.globalize("cms.ui.templates.label"), + Template.LABEL); setDisplayComponent(sheet); } @@ -97,11 +102,13 @@ public class TemplateEdit extends SimpleEditStep { /** * Create the widgets for this form */ + @Override protected void addWidgets() { add(new Label(GlobalizationUtil.globalize("cms.ui.templates.name"))); TextField nameWidget = new TextField(new TrimmedStringParameter(NAME)); - nameWidget.addValidationListener(new NameValidationListener()); + nameWidget.addValidationListener(new NotNullValidationListener()); + nameWidget.addValidationListener(new URLTokenValidationListener()); add(nameWidget); add(new Label(GlobalizationUtil.globalize("cms.ui.templates.label"))); @@ -111,7 +118,13 @@ public class TemplateEdit extends SimpleEditStep { add(labelWidget); } - // Init: load the item and preset the widgets + /** + * Load the item and preset the widgets. + * + * @param e + * @throws FormProcessException + */ + @Override public void init(FormSectionEvent e) throws FormProcessException { FormData data = e.getFormData(); PageState state = e.getPageState(); @@ -121,7 +134,13 @@ public class TemplateEdit extends SimpleEditStep { data.put(Template.LABEL, t.getLabel()); } - // Process: save fields to the database + /** + * Save fields to the database. + * + * @param e + * @throws FormProcessException + */ + @Override public void process(FormSectionEvent e) throws FormProcessException { FormData data = e.getFormData(); PageState state = e.getPageState(); @@ -131,9 +150,15 @@ public class TemplateEdit extends SimpleEditStep { t.save(); } + /** + * + * @param event + * @throws FormProcessException + */ + @Override public void validate(FormSectionEvent event) throws FormProcessException { - //Calling super.validate(e) here causes an exception because the super method checks things which not available - //here. + // Calling super.validate(e) here causes an exception because the + // super method checks things which not available here. PageState state = event.getPageState(); FormData data = event.getFormData(); @@ -148,7 +173,12 @@ public class TemplateEdit extends SimpleEditStep { } } - // Get the current template + /** + * Get the current template. + * + * @param state + * @return + */ public Template getTemplate(PageState state) { Template t = (Template) getItemSelectionModel().getSelectedObject(state); diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java b/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java index 65acb2933..9c57852ef 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java @@ -56,7 +56,6 @@ public class NotEmptyValidationListener extends GlobalizedParameterListener { setError(new GlobalizedMessage(label, getBundleBaseName())); } - /** * Constructor taking a GlobalizedMessage as error message to display. * diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties index 33880025b..925495937 100644 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties @@ -7,3 +7,4 @@ file_empty_or_not_found=is empty or was not found. file_too_large=is too large uri_parameter_is_invalid=This parameter must be a URI formatted according to RFC2396 bebop.parameters.parameter_not_empty=This field must not be empty. +bebop.parameters.must_be_valid_part_of_url=Parameter must contain only alpha-numeric, hyphen, or underscore characters! diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_de.properties b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_de.properties index c015c3213..30a7da2db 100644 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_de.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_de.properties @@ -7,3 +7,4 @@ file_empty_or_not_found=ist leer oder wurde nicht gefunden. file_too_large=ist zu gro\u00df uri_parameter_is_invalid=Dieser Parameter muss ein URI sein, das entsprechend RFC2396 formatiert wird bebop.parameters.parameter_not_empty=Dieser Eintrag darf nicht leer sein! +bebop.parameters.must_be_valid_part_of_url=Dieser Parameter darf nur aus Buchstaben, Zahlen, Bindestrich und Unterstrich bestehen. diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_en.properties b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_en.properties index 33880025b..925495937 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_en.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_en.properties @@ -7,3 +7,4 @@ file_empty_or_not_found=is empty or was not found. file_too_large=is too large uri_parameter_is_invalid=This parameter must be a URI formatted according to RFC2396 bebop.parameters.parameter_not_empty=This field must not be empty. +bebop.parameters.must_be_valid_part_of_url=Parameter must contain only alpha-numeric, hyphen, or underscore characters! diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_es.properties b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_es.properties index cf09501af..b6309764e 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_es.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_es.properties @@ -2,3 +2,4 @@ bebop.parameters.parameter_is_required=Este par\u00e1metro es requerido string_in_range=Este par\u00e1metro no tiene entre {0} y {1} caracteres type_check={0} tiene que ser de clase {1} pero el objecto {2} es de clase {3} bebop.parameters.parameter_not_empty=This field must not be empty. +bebop.parameters.must_be_valid_part_of_url=Parameter must contain only alpha-numeric, hyphen, or underscore characters! diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_fr.properties b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_fr.properties index d8b1611fc..6946ea006 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_fr.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_fr.properties @@ -3,3 +3,4 @@ string_in_range=La longueur de ce param\u00e8tre n'est pas comprise entre {0} e type_check={0} doit \u00eatre de type {1} mais poss\u00e8de {2} de type {3} parameter.only.letters.digits=Ce param\u00e8tre ne doit contenir que des lettres ou des chiffres bebop.parameters.parameter_not_empty=This field must not be empty. +bebop.parameters.must_be_valid_part_of_url=Parameter must contain only alpha-numeric, hyphen, or underscore characters! diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/URLParameter.java b/ccm-core/src/com/arsdigita/bebop/parameters/URLParameter.java index eb8925b5c..f9a4107f2 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/URLParameter.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/URLParameter.java @@ -24,12 +24,12 @@ import java.net.URL; import javax.servlet.http.HttpServletRequest; /** - * A class that represents the model for URL form parameters. + * A class that represents the model for URL form parameters. * - * @author Karl Goldstein - * @author Uday Mathur - * @author Rory Solomon - * @version $Id: URLParameter.java 287 2005-02-22 00:29:02Z sskracic $ + * @author Karl Goldstein + * @author Uday Mathur + * @author Rory Solomon + * @version $Id: URLParameter.java 287 2005-02-22 00:29:02Z sskracic $ */ public class URLParameter extends StringParameter { @@ -37,8 +37,9 @@ public class URLParameter extends StringParameter { super(name); } + @Override public Object transformValue(HttpServletRequest request) - throws IllegalArgumentException { + throws IllegalArgumentException { String requestValue = Globalization.decodeParameter(request, getName()); if (requestValue==null) { diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/URLTokenValidationListener.java b/ccm-core/src/com/arsdigita/bebop/parameters/URLTokenValidationListener.java index 7e0afd4fb..3c95f5163 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/URLTokenValidationListener.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/URLTokenValidationListener.java @@ -18,37 +18,58 @@ */ package com.arsdigita.bebop.parameters; -import com.arsdigita.bebop.parameters.ParameterData; -import com.arsdigita.bebop.event.ParameterListener; import com.arsdigita.bebop.event.ParameterEvent; +import com.arsdigita.globalization.GlobalizedMessage; +//import com.arsdigita.bebop.parameters.ParameterData; import org.apache.oro.text.perl.Perl5Util; /** - * Verifies that the - * parameter's value is composed of only alpha-numeric, - * underscore, or hyphen characters. [a-zA-Z_0-9\-] + * Verifies that the parameter's value is composed only of character which are + * valid as part on an URL name (the token). + * That is only alpha-numeric, underscore, or hyphen characters. + * [a-zA-Z_0-9\-] * - * Note: An empty string will pass the validation tests. + * Note: An empty string will pass the validation tests. * - * @author Michael Pih - * @version $Id: URLTokenValidationListener.java 287 2005-02-22 00:29:02Z sskracic $ - **/ -public class URLTokenValidationListener implements ParameterListener { + * @author Michael Pih + * @version $Id: URLTokenValidationListener.java 287 2005-02-22 00:29:02Z sskracic $ + */ +public class URLTokenValidationListener extends GlobalizedParameterListener { - // match 1 or more instances of a non-alpha-numeric character + /** match 1 or more instances of a non-alpha-numeric character */ private static final String NON_KEYWORD_PATTERN = "/[^a-zA-Z_0-9\\-]+/"; - private String m_label; - - public URLTokenValidationListener(String label) { - m_label = label; - } - + /** + * Default Constructor setting a predefined label as error message. + */ public URLTokenValidationListener() { - this("This parameter"); + setError(new GlobalizedMessage("bebop.parameters.must_be_valid_part_of_url", + getBundleBaseName() ) + ); } + /** + * Constructor taking a label specified as key into a resource bundle to + * customize the error message. + * + * @param label key into the resource bundle + * @deprecated use URLTokenValidationListener(GlobalizedMessage error) + */ + public URLTokenValidationListener(String label) { + setError(new GlobalizedMessage(label, getBundleBaseName())); + } + + /** + * Constructor taking a GlobalizedMessage as error message to display. + * + * @param error GloblizedMessage taken as customized error message. + */ + public URLTokenValidationListener(GlobalizedMessage error) { + setError(error); + } + + /** * Validates the parameter by checking if the value is a valid keyword. * A keyword is defined as any combination of alph-numeric characters, @@ -58,6 +79,7 @@ public class URLTokenValidationListener implements ParameterListener { * * @param event The parameter event */ + @Override public void validate(ParameterEvent event) { ParameterData data = event.getParameterData(); Object value = data.getValue(); @@ -66,13 +88,6 @@ public class URLTokenValidationListener implements ParameterListener { if ( !util.match(NON_KEYWORD_PATTERN, value.toString()) ) { return; } - - // The error message - StringBuffer msg = new StringBuffer(128); - msg - .append(m_label) - .append( - " must contain only alpha-numeric, hyphen, or underscore characters"); - data.addError(msg.toString()); + data.addError(getError()); } } diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/URLValidationListener.java b/ccm-core/src/com/arsdigita/bebop/parameters/URLValidationListener.java index b7c03fe84..5cfcbf2b5 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/URLValidationListener.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/URLValidationListener.java @@ -21,14 +21,17 @@ package com.arsdigita.bebop.parameters; import com.arsdigita.bebop.event.ParameterEvent; import com.arsdigita.bebop.event.ParameterListener; import com.arsdigita.bebop.FormProcessException; -import com.arsdigita.bebop.parameters.ParameterData; +//import com.arsdigita.bebop.parameters.ParameterData; import java.net.MalformedURLException; import java.net.URL; - - +/** + * + * + */ public class URLValidationListener implements ParameterListener { + @Override public void validate(ParameterEvent e) throws FormProcessException { diff --git a/ccm-core/src/com/arsdigita/web/URL.java b/ccm-core/src/com/arsdigita/web/URL.java index 72ea2a064..f0e8cc683 100755 --- a/ccm-core/src/com/arsdigita/web/URL.java +++ b/ccm-core/src/com/arsdigita/web/URL.java @@ -103,10 +103,10 @@ import org.apache.log4j.Logger; * store the origin. This is used by LoginSignal and * ReturnSignal to implement UI excursions.

* - *

All static create methods taking an - * HttpServletRequest (1) preserve the request's scheme, - * server name, and port and (2) run parameter listeners if the URL's - * parameter map is not null.

+ *

All static create methods taking an HttpServletRequest + * (1) preserve the request's scheme, server name, and port and + * (2) run parameter listeners if the URL's parameter map is not null. + *

* *

Those methods not taking an HttpServletRequest use * the scheme, server name, and port defined in @@ -132,15 +132,12 @@ import org.apache.log4j.Logger; */ public class URL { + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int hte runtime environment + * and set com.arsdigita.web.URL=DEBUG + * by uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(URL.class); - /** - * The standard location for XSL files. - * No longer in use. - */ - // public static final String XSL_DIR = INTERNAL_DIR + "/xsl"; - - public static final String THEMES_DIR = "/themes"; /** Base direcotry for template files provided by packages. Each package diff --git a/ccm-sci-publications/src/com/arsdigita/cms/contenttypes/ui/JournalArticleAddForm.java b/ccm-sci-publications/src/com/arsdigita/cms/contenttypes/ui/JournalArticleAddForm.java index 3ceafc45d..6ff1561ee 100644 --- a/ccm-sci-publications/src/com/arsdigita/cms/contenttypes/ui/JournalArticleAddForm.java +++ b/ccm-sci-publications/src/com/arsdigita/cms/contenttypes/ui/JournalArticleAddForm.java @@ -26,7 +26,6 @@ import com.arsdigita.bebop.event.FormInitListener; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.cms.ContentType; -import com.arsdigita.cms.Folder; import com.arsdigita.cms.ItemSelectionModel; import com.arsdigita.cms.contenttypes.ArticleInJournal; import com.arsdigita.cms.contenttypes.ArticleInJournalCollection; @@ -35,7 +34,7 @@ import com.arsdigita.cms.contenttypes.PublicationsConfig; import com.arsdigita.cms.ui.ItemSearchWidget; import com.arsdigita.cms.ui.authoring.BasicItemForm; import com.arsdigita.kernel.Kernel; -import java.math.BigDecimal; + import org.apache.log4j.Logger; /** diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java index 4b7cece07..631a99359 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java @@ -82,10 +82,10 @@ public class ThemeDevelopmentFileManager extends ThemeFileManager { * This will not start up multiple threads...if there is already * a thread running, it will return that thread to you. * - * @param startupDelay number of seconds to wait before starting to - * process the file. A startupDelay of 0 means that this is a no-op - * @param pollDelay number of seconds to wait between checks if the file - * has any entries. + * @param startupDelay number of seconds to wait before starting to process + * the file. A startupDelay of 0 means that this is a no-op + * @param pollDelay number of seconds to wait between checks if the file + * has any entries. * @param baseDirectory * @return */ diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java index 6edf9348a..00d72af4f 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java @@ -40,8 +40,8 @@ public class ThemePublishedFileManager extends ThemeFileManager { * by editing /WEB-INF/conf/log4j.properties int hte runtime environment * and set com.arsdigita.themedirector.util.ThemePublishedFileManager=DEBUG * by uncommenting or adding the line. */ - private static Logger s_log = - Logger.getLogger(ThemePublishedFileManager.class); + private static Logger s_log = Logger.getLogger( + ThemePublishedFileManager.class); // The code in this class borrows heavily from // com.arsdigita.cms.publishToFile.FileManager @@ -74,9 +74,12 @@ public class ThemePublishedFileManager extends ThemeFileManager { * process the file. A startupDelay of 0 means that this is a no-op * @param pollDelay number of seconds to wait between checks if the file * has any entries. + * @param baseDirectory + * @return */ - public static ThemeFileManager startWatchingFiles - (int startupDelay, int pollDelay, String baseDirectory) { + public static ThemeFileManager startWatchingFiles(int startupDelay, + int pollDelay, + String baseDirectory) { if (s_manager == null) { s_log.info("Starting Theme File Manager Thread with the base " + "directory of " + baseDirectory); @@ -96,8 +99,10 @@ public class ThemePublishedFileManager extends ThemeFileManager { } /** - * This returns the current thread or null if the thread has not - * yet been started. + * This returns the current thread or null if the thread has not yet + * been started. + * + * @return */ public static ThemeFileManager getInstance() { return s_manager; @@ -105,19 +110,23 @@ public class ThemePublishedFileManager extends ThemeFileManager { /** - * this typically returns something like "getBaseDirectory() + PROD_DIR" + * This typically returns something like "getBaseDirectory() + PROD_DIR". + * + * @return */ + @Override protected String getManagerSpecificDirectory() { return getBaseDirectory() + PROD_THEMES_BASE_DIR; } /** - * This looks at all of the files in the db for the passed in theme - * and makes sure that this servers file system has all of the - * updated files. If the thread has run since the theme was - * last published then this is a no-op + * This looks at all of the files in the db for the passed in theme and + * makes sure that this servers file system has all of the updated files. + * If the thread has run since the theme was last published then this is + * a no-op */ + @Override protected void updateTheme(Theme theme) { if (getLastRunDate() == null || m_ignoreInterrupt || !(new File(getManagerSpecificDirectory() + theme.getURL())).exists() || @@ -132,9 +141,12 @@ public class ThemePublishedFileManager extends ThemeFileManager { /** - * This allows subclasses to filter the collection as appropriate. - * (e.g. only return "live" files or only "draft" files). + * This allows subclasses to filter the collection as appropriate. + * (e.g. only return "live" files or only "draft" files). + * + * @return */ + @Override protected ThemeFileCollection getThemeFilesCollection(Theme theme) { return theme.getPublishedThemeFiles(); }