diff --git a/ccm-cms-types-decisiontree/src/com/arsdigita/cms/contenttypes/ui/DecisionTreeTargetEditForm.java b/ccm-cms-types-decisiontree/src/com/arsdigita/cms/contenttypes/ui/DecisionTreeTargetEditForm.java index 7b2496ee7..b8e0017e5 100644 --- a/ccm-cms-types-decisiontree/src/com/arsdigita/cms/contenttypes/ui/DecisionTreeTargetEditForm.java +++ b/ccm-cms-types-decisiontree/src/com/arsdigita/cms/contenttypes/ui/DecisionTreeTargetEditForm.java @@ -94,7 +94,7 @@ public class DecisionTreeTargetEditForm extends Form /** * Constructor. * - * @param selArticle the current article + * @param selTree * @param selTarget the current section * @param container container which this form is added to */ @@ -138,6 +138,7 @@ public class DecisionTreeTargetEditForm extends Form /** * Returns the save/cancel section from this form. + * @return */ public SaveCancelSection getSaveCancelSection() { return m_saveCancelSection; @@ -213,7 +214,9 @@ public class DecisionTreeTargetEditForm extends Form } /** Form initialisation hook. Sets the options for select widgets. + * @param fse */ + @Override public void init(FormSectionEvent fse) { PageState state = fse.getPageState(); FormData data = fse.getFormData(); @@ -276,6 +279,7 @@ public class DecisionTreeTargetEditForm extends Form try { m_targetSectionWidget.addPrintListener(new PrintListener() { + @Override public void prepare(PrintEvent e) { initTargetOptions(e); } @@ -287,6 +291,7 @@ public class DecisionTreeTargetEditForm extends Form add(m_targetSectionWidget); addValidationListener(new FormValidationListener() { + @Override public final void validate(final FormSectionEvent event) throws FormProcessException { final PageState state = event.getPageState(); @@ -312,7 +317,10 @@ public class DecisionTreeTargetEditForm extends Form /** * Called on form submission. Check to see if the user clicked the * cancel button. If they did, don't continue with the form. + * @param event + * @throws com.arsdigita.bebop.FormProcessException */ + @Override public void submitted(FormSectionEvent event) throws FormProcessException { PageState state = event.getPageState(); @@ -332,7 +340,10 @@ public class DecisionTreeTargetEditForm extends Form /** * Called after form has been validated. Create the new * DecisionTreeOptionTarget and assign it to the current DecisionTree. + * @param event + * @throws com.arsdigita.bebop.FormProcessException */ + @Override public void process(FormSectionEvent event) throws FormProcessException { PageState state = event.getPageState(); FormData data = event.getFormData(); diff --git a/ccm-core/src/com/arsdigita/bebop/Form.java b/ccm-core/src/com/arsdigita/bebop/Form.java index f0da30a02..f5e2e9664 100755 --- a/ccm-core/src/com/arsdigita/bebop/Form.java +++ b/ccm-core/src/com/arsdigita/bebop/Form.java @@ -238,32 +238,43 @@ public class Form extends FormSection implements BebopConstants { return form; } + /** + * + * @param ps + * @param parent + */ protected void generateErrors(PageState ps, Element parent) { + for (Iterator it = getFormData(ps).getErrors(); it.hasNext(); ) { Element errors = parent.newChildElement(BEBOP_FORMERRORS, BEBOP_XML_NS); - errors.addAttribute - ("message", - (String) ((GlobalizedMessage) it.next()).localize - (ps.getRequest())); + errors.addAttribute("message", + (String)((GlobalizedMessage) it.next()).localize + (ps.getRequest()) + ); errors.addAttribute("id", getName()); } + } /** *
Determine whether or not this Form will redirect after its * process listeners are fired.
+ * + * @return */ public boolean isRedirecting() { return m_isRedirecting; } /** - *Setting the redirecting flag will cause the Form to clear - * the control event and redirect back to the current URL, after - * firing all process listeners. Doing so means that a user - * reload will not cause the form to be resubmitted. The default - * value for this flag is false.
+ * Setting the redirecting flag will cause the Form to clear the + * control event and redirect back to the current URL, after + * firing all process listeners. Doing so means that a user reload + * will not cause the form to be resubmitted. The default value for + * this flag is false. + * + * @param isRedirecting */ public void setRedirecting(boolean isRedirecting) { Assert.isUnlocked(this); @@ -273,10 +284,12 @@ public class Form extends FormSection implements BebopConstants { /** * Responds to the request by processing this form with the HTTP request * given instate.
+ * @see #process process(...)
*
* @param state represents the current request
- * @see #process process(...)
+ * @throws javax.servlet.ServletException
*/
+ @Override
public void respond(PageState state) throws ServletException {
final FormData data = process(state);
@@ -420,15 +433,16 @@ public class Form extends FormSection implements BebopConstants {
* right set of init, validation, and process listeners, depending on
* whether this is an initial request to the form and whether the form
* submission was valid. Submission listeners are always run.
- *
- * @param state represents the current request
- *
- * @return the values extracted from the HTTP request contained
- * in state.
* @see #getFormData
+ *
+ * @param state represents the current request
+ * @return the values extracted from the HTTP request contained
+ * in state.
+ * @throws com.arsdigita.bebop.FormProcessException
* @pre state != null
* @post return != null
*/
+ @Override
public FormData process(PageState state) throws FormProcessException {
Assert.exists(state, "PageState");
FormData result = new FormData(getModel(), state.getRequest());
@@ -476,6 +490,7 @@ public class Form extends FormSection implements BebopConstants {
*/
protected void traverse() {
Traversal formRegistrar = new Traversal() {
+ @Override
protected void act(Component c) {
if ( c == Form.this ) {
return;
@@ -497,6 +512,7 @@ public class Form extends FormSection implements BebopConstants {
*
* @param p page in which to register this form
*/
+ @Override
public void register(Page p) {
traverse();
p.addComponent(this);
@@ -504,6 +520,7 @@ public class Form extends FormSection implements BebopConstants {
/**
* TODO
+ * @param model
*/
public void excludeParameterFromExport(ParameterModel model) {
getModel().excludeFormParameterFromExport(model);
@@ -516,6 +533,7 @@ public class Form extends FormSection implements BebopConstants {
*/
private void initFormData() {
m_formData = new RequestLocal() {
+ @Override
protected Object initialValue(PageState s) {
// TODO: We need to come up with the right strategy for
// how we deal with FormProcessExceptions. Are they fatal
@@ -524,7 +542,8 @@ public class Form extends FormSection implements BebopConstants {
return process(s);
} catch (FormProcessException e) {
s_log.error("Form Process exception", e);
- throw new UncheckedWrapperException("Form Process error: " + e.getMessage(), e);
+ throw new UncheckedWrapperException("Form Process error: "
+ + e.getMessage(), e);
}
}
};
@@ -535,6 +554,7 @@ public class Form extends FormSection implements BebopConstants {
*
* @return a human-readable representation of this.
*/
+ @Override
public String toString() {
return super.toString() + " " +
"[" + getName() + "," + getAction() + "," + getMethod() + "," +
@@ -542,10 +562,13 @@ public class Form extends FormSection implements BebopConstants {
}
/**
- * Protected access to set the formdata request local
+ * Protected access to set the formdata request local.
+ * This method is required if a subclass wishes to override the
+ * process method.
+ *
+ * @param state
+ * @param data
*/
- // this method is required if a subclass wishes to override
- // the process method
protected void setFormData(PageState state, FormData data) {
m_formData.set(state, data);
}
diff --git a/ccm-core/src/com/arsdigita/bebop/FormData.java b/ccm-core/src/com/arsdigita/bebop/FormData.java
index 20489a6f5..0a1ccc694 100755
--- a/ccm-core/src/com/arsdigita/bebop/FormData.java
+++ b/ccm-core/src/com/arsdigita/bebop/FormData.java
@@ -36,9 +36,8 @@ import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.URLRewriter;
/**
- * Manages the data associated with forms and
- * other remote sources.
- *
+ * Manages the data associated with forms and other remote sources.
+
* The basic task of a FormData object is to transform
* a set of key-value string pairs into a validated set of Java data
* objects for use in subsequent processing. In most cases the original
@@ -81,8 +80,8 @@ public class FormData implements Map, Cloneable {
private boolean m_isSubmission;
/**
- * Ensure that no one can create this object from outside the
- * package without supplying meaningful parameters
+ * Ensure that no one can create this object from outside the package
+ * without supplying meaningful parameters
*/
private FormData() {}
@@ -277,9 +276,8 @@ public class FormData implements Map, Cloneable {
}
/**
- * Validates this FormData object according to its
- * form model. If the FormData is already valid,
- * does nothing.
+ * Validates this FormData object according to its form model.
+ * If the FormData is already valid, does nothing.
*
* @param state describes the current page state
* @pre state != null
@@ -300,9 +298,8 @@ public class FormData implements Map, Cloneable {
}
/**
- * Validates this FormData object against its
- * form model, regardless of whether the object is currently
- * valid.
+ * Validates this FormData object against its form model,
+ * regardless of whether the object is currently valid.
*
* @param state describes the current page state
* @pre state != null
@@ -324,7 +321,8 @@ public class FormData implements Map, Cloneable {
}
/**
- * Reports a validation error on the form as a whole.
+ * Reports a validation error on the form as a whole.
+ * Uses a GlobalizedMessage for inklusion
*
* @param message the error message
* @pre message != null
diff --git a/ccm-core/src/com/arsdigita/bebop/Page.java b/ccm-core/src/com/arsdigita/bebop/Page.java
index cd2ea31a9..631e5a06f 100755
--- a/ccm-core/src/com/arsdigita/bebop/Page.java
+++ b/ccm-core/src/com/arsdigita/bebop/Page.java
@@ -52,16 +52,17 @@ import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
/**
- *
- * The top-level container for all Bebop components and containers.
+ * The top-level container for all Bebop components and containers. * - *+ *
Page may be created as follows: null * Page p = new Page("Hello World"); * p.add(new Label("Hello World"); @@ -114,9 +115,10 @@ public class Page extends BlockStylable implements Container { */ static final String INVISIBLE = INTERNAL + "i"; /** - * Map of stateful components (id --> Component) SortedMap used because component based hash for - * page is based on concatenation of component ids, and so need to guarantee that they are - * returned in the same order for the same page - cg. + * Map of stateful components (id --> Component) SortedMap used because + * component based hash for page is based on concatenation of component ids, + * and so need to guarantee that they are returned in the same order for + * the same page - cg. */ private SortedMap m_componentMap; private List m_components; @@ -132,13 +134,14 @@ public class Page extends BlockStylable implements Container { private List m_actionListeners; private List m_requestListeners; /** - * The title of the page to be added in the head of HTML output. The title is wrapped in a Label - * to allow developers to add PrintListeners to dynamically change the value of the title. + * The title of the page to be added in the head of HTML output. The title + * is wrapped in a Label to allow developers to add PrintListeners to + * dynamically change the value of the title. */ private Label m_title; /** - * Stores the actual title for the current request. The title may be generated with a - * PrintListener of the m_title Label. + * Stores the actual title for the current request. The title may be + * generated with a PrintListener of the m_title Label. */ private RequestLocal m_currentTitle; /** @@ -172,54 +175,58 @@ public class Page extends BlockStylable implements Container { private boolean m_useHttpSession = false; /** - * Returnstrueif this page should export state through the HttpSession instead of - * the URL query string. + * Returnstrueif this page should export state through the + * HttpSession instead of the URL query string. *- * If this returns
true, then PageState.stateAsURL() will only export the control - * event as a URL query string. If this returnsfalse, then stateAsURL() will - * export the entire page state. - * - * + * If this returnstrue, then PageState.stateAsURL() will only + * export the control event as a URL query string. If this returns + *false, then stateAsURL() will export the entire page state. * @see PageState#stateAsURL * - * @returntrueif this page should export state through the HttpSession; - *falseif it should export using the URL query string. + * @returntrueif this page should export state through the + * HttpSession; + *falseif it should export using the URL query + * string. */ public boolean isUsingHttpSession() { return m_useHttpSession; } /** - * Indicates to this page whether it should export its entire state to subsequent requests - * through the URL query string, or if it should use the HttpSession instead and only use the - * URL query string for the control event. + * Indicates to this page whether it should export its entire state to + * subsequent requests through the URL query string, or if it should use the + * HttpSession instead and only use the URL query string for the control + * event. * * @see PageState#stateAsURL * - * @param btrueif PageState.stateAsURL() will export only the control event as a - * URL query string.falseif stateAsURL() will export the entire page - * state. + * @param btrueif PageState.stateAsURL() will export only the + * control event as a URL query string.falseif stateAsURL() + * will export the entire page state. */ public void setUsingHttpSession(boolean b) { m_useHttpSession = b; } + // //////////////////////////////////////////////////////////////////////// + // Constructor Section + // //////////////////////////////////////////////////////////////////////// + /** - * Creates an empty page with the specified title and panel. + * Constructor, creates an empty page with the specified title and panel. * * @param title title for this page - * * @param panel container for this page + * @deprecated use Page(Lab el, Container) instead. */ public Page(String title, Container panel) { this(new Label(title), panel); } /** - * Creates an empty page with the specified title and panel. - * - * @param title title for this page + * Constructor, creates an empty page with the specified title and panel. * + * @param title title for this page as (globalized) Label * @param panel container for this page */ public Page(Label title, Container panel) { @@ -231,7 +238,7 @@ public class Page extends BlockStylable implements Container { m_components = new ArrayList(); m_componentMap = new TreeMap(); setErrorDisplay(new PageErrorDisplay()); - setTitle(title); + m_title = title; // Initialize the RequestLocal where the title for the current // request will be kept @@ -270,7 +277,8 @@ public class Page extends BlockStylable implements Container { } /** - * Creates an empty page with the specified title and implicit BoxPanel container. + * Creates an empty page with the specified title and implicit BoxPanel + * container. * * @param title title for this page */ @@ -281,7 +289,8 @@ public class Page extends BlockStylable implements Container { } /** - * Creates an empty page with the specified title and implicit BoxPanel container. + * Creates an empty page with the specified title and implicit BoxPanel + * container. * * @param title title for this page */ @@ -301,13 +310,13 @@ public class Page extends BlockStylable implements Container { } /** - * Adds a component with the specified layout constraints to this container. Layout constraints - * are defined in each layout container as static ints. To specify multiple constraints, use - * bitwise OR. + * Adds a component with the specified layout constraints to this container. + * Layout constraints are defined in each layout container as static ints. + * To specify multiple constraints, use bitwise OR. * * @param c component to add to this container - * - * @param constraints layout constraints (a bitwise OR of static ints in the particular layout) + * @param constraints layout constraints (a bitwise OR of static ints in the + * particular layout) */ @Override public void add(Component c, int constraints) { @@ -315,17 +324,20 @@ public class Page extends BlockStylable implements Container { } /** - * Returnstrueif this list contains the specified element. More formally, returns - *trueif and only if this list contains at least one element e such that (o==null - * ? e==null : o.equals(e)). + * Returnstrueif this list contains the specified element. + * More formally, returnstrueif and only if this list + * contains at least one element e such that (o==null ? e==null : + * o.equals(e)). *- * This method returns
trueonly if the component has been directly added to this - * container. If this container contains another container that contains this component, this - * method returnsfalse. + * This method returnstrueonly if the component has been + * directly added to this container. If this container contains another + * container that contains this component, this method returns + *false. * * @param o element whose presence in this container is to be tested * - * @returntrueif this Container contains the specified component directly; + * @returntrueif this Container contains the specified + * component directly; *falseotherwise. */ @Override @@ -334,12 +346,12 @@ public class Page extends BlockStylable implements Container { } /** - * Returns the component at the specified position. Each call to the add method increments the - * index. Since the user has no control over the index of added components (other than counting - * each call to add), this method should be used in conjunction with indexOf. + * Returns the component at the specified position. Each call to the add + * method increments the index. Since the user has no control over the index + * of added components (other than counting each call to add), this method + * should be used in conjunction with indexOf. * * @param index the index of the item to be retrieved from this Container - * * @return the component at the specified position in this container. */ @Override @@ -351,14 +363,12 @@ public class Page extends BlockStylable implements Container { * Gets the index of a component. * * @param c component to search for - * - * @return the index in this list of the first occurrence of the specified element, or -1 if - * this list does not contain this element. + * @return the index in this list of the first occurrence of the specified + * element, or -1 if this list does not contain this element. * * @pre c != null * @post contains(c) implies (return >= 0) && (return < size()) - * @pos - * t !contains(c) implies return == -1 + * @post !contains(c) implies return == -1 */ @Override public int indexOf(Component c) { @@ -368,8 +378,8 @@ public class Page extends BlockStylable implements Container { /** * Returnstrueif the container contains no components. * - * @returntrueif this container contains no * * components;false- * otherwise. + * @returntrueif this container contains no components; + *falseotherwise. */ @Override public boolean isEmpty() { @@ -377,8 +387,9 @@ public class Page extends BlockStylable implements Container { } /** - * Returns the number of elements in this container. This does not recursively count the - * components that are indirectly contained in this container. + * Returns the number of elements in this container. This does not + * recursively count the components that are indirectly contained in this + * container. * * @return the number of components directly in this container. */ @@ -393,7 +404,8 @@ public class Page extends BlockStylable implements Container { } /** - * Returns the panel that thePageuses for rendering its components. + * Returns the panel that thePageuses for rendering its + * components. * * @return the panel. */ @@ -402,9 +414,11 @@ public class Page extends BlockStylable implements Container { } /** - * Set the Container used for rendering components on this page. Caution should be used with - * this function, as the existing container is simply overwritten. + * Set the Container used for rendering components on this page. Caution + * should be used with this function, as the existing container is simply + * overwritten. * + * @param c * @author Matthew Booth (mbooth@redhat.com) */ public void setPanel(Container c) { @@ -412,8 +426,7 @@ public class Page extends BlockStylable implements Container { } /** - *- * Retrieves the title of this page.
+ * Retrieves the title of this page. * * @return the static title of this page. */ @@ -425,7 +438,6 @@ public class Page extends BlockStylable implements Container { * Retrieves the title of this page as a Bebop label component. * * @param state the state of the current request - * * @return the title of the page for the current request. */ public final Label getTitle(PageState state) { @@ -453,12 +465,13 @@ public class Page extends BlockStylable implements Container { } /** - * Sets the {@link Component} that will display the validation errors in the current - * {@link PageState}. Any validation error in thePageStatewill cause the - *Pageto completely ignore all other components and render only the error display - * component. + * Sets the {@link Component} that will display the validation errors in the + * current {@link PageState}. Any validation error in the + *PageStatewill cause thePageto completely + * ignore all other components and render only the error display component. *- * By default, a {@link PageErrorDisplay} component is used to display the validation errors. + * By default, a {@link PageErrorDisplay} component is used to display the + * validation errors. * * @param c the component that will display the validation errors in the current *
PageState@@ -469,12 +482,13 @@ public class Page extends BlockStylable implements Container { } /** - * Gets the {@link Component} that will display the validation errors in the current - * {@link PageState}. Any validation error in thePageStatewill cause the - *Pageto completely ignore all other components and render only the error display - * component. + * Gets the {@link Component} that will display the validation errors in the + * current {@link PageState}. Any validation error in the + *PageStatewill cause thePageto completely + * ignore all other components and render only the error display component. *- * By default, a {@link PageErrorDisplay} component is used to display the validation errors. + * By default, a {@link PageErrorDisplay} component is used to display the + * validation errors. * * @return the component that will display the validation errors in the current *
PageState. @@ -484,21 +498,23 @@ public class Page extends BlockStylable implements Container { } /** - * Adds a client-side stylesheet that should be used in HTML output. Arbitrarily many - * client-side stylesheets can be added with this method. To use a CSS stylesheet, call - * something likesetStyleSheet("style.css", "text/css"). + * Adds a client-side stylesheet that should be used in HTML output. + * Arbitrarily many client-side stylesheets can be added with this method. + * To use a CSS stylesheet, call something like + *setStyleSheet("style.css", "text/css"). * ** These values will ultimately wind up in a <link> * tag in the head of the HTML page. * *
- * Note that the stylesheet set with this call has nothing to do with the XSLT stylesheet - * (transformer) that is applied to the XML generated from this page! + * Note that the stylesheet set with this call has nothing to do with the + * XSLT stylesheet (transformer) that is applied to the XML generated from + * this page! * * @param styleSheetURI the location of the stylesheet * @param mimeType the MIME type of the stylesheet, usually - * text/css + * text/css * * @pre ! isLocked() */ @@ -507,19 +523,17 @@ public class Page extends BlockStylable implements Container { } /** - * Adds a global state parameter to this page. Global parameters are values that need to be - * preserved between requests, but that have no special connection to any of the components on - * the page. For a page that displays details about an item, a global parameter would be used to - * identify the item. - * - *
- * If the parameter was previously added as a component state parameter, its name is unmangled - * and stays unmangled. - * - * @param p the global parameter to add + * Adds a global state parameter to this page. Global parameters are values + * that need to be preserved between requests, but that have no special + * connection to any of the components on the page. For a page that displays + * details about an item, a global parameter would be used to identify the + * item. * + * If the parameter was previously added as a component state parameter, its + * name is unmangled and stays unmangled. * @see #addComponentStateParam * + * @param p the global parameter to add * @pre ! isLocked() * @pre parameter != null */ @@ -530,8 +544,8 @@ public class Page extends BlockStylable implements Container { } /** - * Constructs the top nodes of the DOM or JDOM tree. Used by generateXML(PageState, Document) - * below. + * Constructs the top nodes of the DOM or JDOM tree. Used by + * generateXML(PageState, Document) below. *
* Generates DOM fragment: *
@@ -541,12 +555,13 @@ public class Page extends BlockStylable implements Container { * ... page content gnerated by children ... * </bebop:page>The content of the <title> * element can be set by calling {@link #setTitle setTitle}. The - * <stylesheet> element will only be present if a stylesheet has been set with {@link + * <stylesheet> element will only be present if a stylesheet + * has been set with {@link * #setStyleSheet setStyleSheet}. * * @param ps the page state for the current page * @param parent the DOM node for the whole Document - * + * @return * @pre isLocked() */ protected Element generateXMLHelper(PageState ps, Document parent) { @@ -569,8 +584,9 @@ public class Page extends BlockStylable implements Container { } /** - * Constructs a DOM or JDOM tree with all components on the page. The tree represents the page - * that results from the {@link javax.servlet.http.HttpServletRequest} kept in the + * Constructs a DOM or JDOM tree with all components on the page. The tree + * represents the page that results from the + * {@link javax.servlet.http.HttpServletRequest} kept in the *state. * * @param state the page state produced by {@link #process} @@ -611,19 +627,25 @@ public class Page extends BlockStylable implements Container { /** * Do nothing. Top-level add nodes is meaningless. + * + * @param elt */ @Override public void generateXML(PageState state, Element elt) { } /** - * Creates a PageState object and processes it by calling the respond method on the selected - * component. Processes a request by notifying the component from which the process originated - * and {@link #fireActionEvent - * broadcasts} an {@link ActionEvent} to all the listeners that registered with - * {@link #addActionListener addActionListener}. - * + * Creates a PageState object and processes it by calling the respond method + * on the selected component. Processes a request by notifying the component + * from which the process originated and {@link #fireActionEvent + * broadcasts} an {@link ActionEvent} to all the listeners that registered + * with {@link #addActionListener addActionListener}. * @see #generateXML(PageState,Document) generateXML + * + * @param request + * @param response + * @return + * @throws javax.servlet.ServletException * @pre isLocked() * @pre request != null * @pre response != null @@ -675,26 +697,14 @@ public class Page extends BlockStylable implements Container { } } -// /** -// * Does all the servicing of a request except output generation. -// * This includes most of the common duties of buildDocument and print. -// * -// * @deprecated Use {@link -// * #process(HttpServletRequest,HttpServletResponse)} instead. -// */ -// protected PageState prepare(HttpServletRequest req, HttpServletResponse res) -// throws ServletException { -// Assert.isLocked(this); -// PageState state = process(req, res); -// return state; -// } /** - * Builds a DOM Document from the current request state by doing a depth-first tree walk on the - * current set of components in this Page, calling generateXML on each. Does NOT do the - * rendering. If the HTTP response has already been committed, does not build the XML document. - * - * @return a DOM ready for rendering, or null if the response has already been committed. + * Builds a DOM Document from the current request state by doing a + * depth-first tree walk on the current set of components in this Page, + * calling generateXML on each. Does NOT do the rendering. If the HTTP + * response has already been committed, does not build the XML document. * + * @return a DOM ready for rendering, or null if the response has already + * been committed. * @post res.isCommitted() == (return == null) */ public Document buildDocument(HttpServletRequest req, diff --git a/ccm-core/src/com/arsdigita/bebop/event/FormSectionEvent.java b/ccm-core/src/com/arsdigita/bebop/event/FormSectionEvent.java index ae7f1eaa3..41538edb0 100755 --- a/ccm-core/src/com/arsdigita/bebop/event/FormSectionEvent.java +++ b/ccm-core/src/com/arsdigita/bebop/event/FormSectionEvent.java @@ -55,7 +55,8 @@ public class FormSectionEvent extends PageEvent { * @param state the state of the enclosing page * @param formData the form data constructed so far */ - public FormSectionEvent(Object source, PageState state, + public FormSectionEvent(Object source, + PageState state, FormData formData) { super(source, state); _formData = formData; diff --git a/ccm-core/src/com/arsdigita/bebop/event/FormValidationListener.java b/ccm-core/src/com/arsdigita/bebop/event/FormValidationListener.java index 6fe2cabdb..fc4828e47 100755 --- a/ccm-core/src/com/arsdigita/bebop/event/FormValidationListener.java +++ b/ccm-core/src/com/arsdigita/bebop/event/FormValidationListener.java @@ -29,7 +29,6 @@ import java.util.EventListener; * @author Uday Mathur * @version $Id: FormValidationListener.java 287 2005-02-22 00:29:02Z sskracic $ */ - public interface FormValidationListener extends EventListener { /** @@ -49,23 +48,14 @@ public interface FormValidationListener extends EventListener { * be handled internally, or if they are unrecoverable may be * rethrown as instances ofFormProcessException. * - * @param model The form model describing the structure and properties - * of the form data included with this request. The validation procedure - * may require knowledge of form or parameter properties to complete. + * @param e FormSectionEvent containing the FormData as well as the + * PageState. + * Clients may access the PageState by executing something like + * PageState state = fse.getPageState(); + * Method getFormData() allows access to the Form's data. * - * @param data The container for all data objects associated with - * the request. All parameters specified in the form model are - * converted to data objects and stored in this container before - * any form validation procedures are called. - * - * @param request The HTTP request information from which the form - * data was extracted. Note that the request object is supplied - * only in case the validation procedure involves contextual - * information (information extracted from cookies or the peer - * address, for example). - * - * @exception FormProcessException If the data does not pass the - * check. */ + * @exception FormProcessException ff the data does not pass the check. + */ void validate(FormSectionEvent e) throws FormProcessException; diff --git a/ccm-core/src/com/arsdigita/bebop/event/ParameterListener.java b/ccm-core/src/com/arsdigita/bebop/event/ParameterListener.java index af5e259a8..983ad8c55 100755 --- a/ccm-core/src/com/arsdigita/bebop/event/ParameterListener.java +++ b/ccm-core/src/com/arsdigita/bebop/event/ParameterListener.java @@ -22,8 +22,8 @@ import com.arsdigita.bebop.FormProcessException; import java.util.EventListener; /** - * Defines the interface - * for a class that validates the values of a single parameter. + * Defines the interface for a class that validates the values of a + * single parameter. * * @author Karl Goldstein * @author Uday Mathur diff --git a/ccm-core/src/com/arsdigita/bebop/form/SearchAndSelect.java b/ccm-core/src/com/arsdigita/bebop/form/SearchAndSelect.java index e71dd3aae..966ad73b6 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/SearchAndSelect.java +++ b/ccm-core/src/com/arsdigita/bebop/form/SearchAndSelect.java @@ -18,7 +18,6 @@ */ package com.arsdigita.bebop.form; - import com.arsdigita.bebop.event.PageEvent; import com.arsdigita.bebop.event.PrintEvent; import com.arsdigita.bebop.event.PrintListener; @@ -41,25 +40,25 @@ import java.util.TooManyListenersException; import org.apache.log4j.Logger; /** - * Search and select Bebop widget. This widget is used to allow a user to - * search for a particular item over a potentially very large set. Depending - * on the size of the dataset, the user will either see a search box or a - * selection box (with all valid items). The search box will then change to - * a selection box once the user submits the form, allowing them then to - * choose the items they desire. + * Search and select Bebop widget. This widget is used to allow a user to search + * for a particular item over a potentially very large set. Depending on the + * size of the dataset, the user will either see a search box or a selection box + * (with all valid items). The search box will then change to a selection box + * once the user submits the form, allowing them then to choose the items they + * desire. ** The datasource for SearchAndSelect is provided by an implentation of the - * SearchAndSelectModel interface. SAMPLE IMPLEMENTATION GOES HERE + * SearchAndSelectModel interface. SAMPLE IMPLEMENTATION GOES HERE * * @author Patrick McNeill * @version $Id: SearchAndSelect.java 287 2005-02-22 00:29:02Z sskracic $ * @since 4.5 */ public class SearchAndSelect extends FormSection - implements BebopConstants, PrintListener { + implements BebopConstants, PrintListener { - private static final Logger s_cat = - Logger.getLogger(SearchAndSelect.class); + private static final Logger s_cat + = Logger.getLogger(SearchAndSelect.class); protected String m_name; // name of this super-widget @@ -92,7 +91,7 @@ public class SearchAndSelect extends FormSection protected Object m_this = this; // so "this" will work in my anonymous inner classes - protected TextField m_outputTextWidget; + protected TextField m_outputTextWidget; protected Widget m_outputSelectWidget; // internal widgets used render either a text box, a checkbox, or a select @@ -109,19 +108,19 @@ public class SearchAndSelect extends FormSection /* * Creates the output widgets and adds them all to the form */ - private void initializeOutputWidget () { + private void initializeOutputWidget() { m_oldValueWidget = new Hidden(getName() + ".oldvalue"); add(m_oldValueWidget); m_outputTextWidget = new TextField(getName() + ".text"); add(m_outputTextWidget); - if ( m_isMultiple ) { - if ( m_useCheckboxes ) { + if (m_isMultiple) { + if (m_useCheckboxes) { m_outputSelectWidget = new CheckboxGroup(getName() + ".select"); } else { - m_outputSelectWidget = - new MultipleSelect(getName() + ".select"); + m_outputSelectWidget + = new MultipleSelect(getName() + ".select"); } } else { m_outputSelectWidget = new SingleSelect(getName() + ".select"); @@ -138,31 +137,31 @@ public class SearchAndSelect extends FormSection } public void prepare(PrintEvent e) { - if ( m_results == null ) { + if (m_results == null) { m_results = m_listener.getModel(new PageEvent(this, e.getPageState())); } - if ( m_results == null ) { + if (m_results == null) { return; } - m_results.setQuery ( m_query ); + m_results.setQuery(m_query); - if ( m_isSearchLocked || - ( ( ( ! m_oldValue.equals("") && - m_oldValue.equals(m_value) ) || - ( m_maxViewableResults >= m_results.resultsCount() ) ) && - ( m_results.resultsCount() > 0 ) ) ) { + if (m_isSearchLocked + || (((!m_oldValue.equals("") + && m_oldValue.equals(m_value)) + || (m_maxViewableResults >= m_results.resultsCount())) + && (m_results.resultsCount() > 0))) { - OptionGroup outputWidget = (OptionGroup)e.getTarget(); + OptionGroup outputWidget = (OptionGroup) e.getTarget(); - if ( m_isOptional && ! m_isMultiple ) { - outputWidget.addOption( new Option ( "", "None" ) ); + if (m_isOptional && !m_isMultiple) { + outputWidget.addOption(new Option("", "None")); } - for ( int i = 0; i < m_results.resultsCount(); i++ ) { + for (int i = 0; i < m_results.resultsCount(); i++) { outputWidget.addOption( - new Option ( m_results.getID(i), m_results.getLabel(i) ) ); + new Option(m_results.getID(i), m_results.getLabel(i))); s_cat.debug(" " + m_results.getID(i)); } @@ -174,8 +173,8 @@ public class SearchAndSelect extends FormSection * * @param name the name of the widget */ - public SearchAndSelect ( String name ) { - this( name, false, false ); + public SearchAndSelect(String name) { + this(name, false, false); } /** @@ -186,9 +185,9 @@ public class SearchAndSelect extends FormSection * @param isMultiple whether or not the widget accepts multiple values * @param useCheckboxes use checkboxes or a multiselect */ - public SearchAndSelect ( String name, - boolean isMultiple ) { - this( name, isMultiple, false ); + public SearchAndSelect(String name, + boolean isMultiple) { + this(name, isMultiple, false); } /** @@ -199,9 +198,9 @@ public class SearchAndSelect extends FormSection * @param isMultiple whether or not the widget accepts multiple values * @param useCheckboxes use checkboxes or a multiselect */ - public SearchAndSelect ( String name, - boolean isMultiple, - boolean useCheckboxes ) { + public SearchAndSelect(String name, + boolean isMultiple, + boolean useCheckboxes) { super(new SimpleContainer()); @@ -218,103 +217,103 @@ public class SearchAndSelect extends FormSection * that the error messages generated here are not displayed to the * user as the error field is also used as a help field. */ - super.addValidationListener ( new FormValidationListener() { - public void validate ( FormSectionEvent e ) { - FormData data = e.getFormData(); + super.addValidationListener(new FormValidationListener() { + @Override + public void validate(FormSectionEvent e) { + FormData data = e.getFormData(); - m_results = m_listener.getModel( - new PageEvent(m_this, e.getPageState())); + m_results = m_listener.getModel( + new PageEvent(m_this, e.getPageState())); - if ( m_results == null ) { - return; - } - - m_oldValue = data.getString( getName() + ".oldvalue"); - - m_value = data.getString( getName() + ".text"); - - /* - * Determine what stage in the process we're at. If .text - * is null, then check what the select/checkbox shows. - */ - if ( m_value == null ) { - m_isSearchLocked = true; - m_query = m_oldValue; - - if ( m_isMultiple ) { - String[] tmpArray = (String[])data - .get( getName() + ".select" ); - if ( tmpArray == null ) { - m_value = ""; - } else { - m_value = tmpArray[0]; - } - } else { - m_value = data.getString( getName() + ".select"); - } - } else { - m_query = m_value; - } - - /* - * If optional and nothing selected, we're done - */ - if ( m_value.equals("") && m_isOptional ) { - return; - } - - String oldQuery = m_results.getQuery(); - - m_results.setQuery(m_query); - - /* - * If search returns only one hit and is a non-optional single - * select, it's done. - */ - if ( ! m_isOptional && - ! m_isMultiple && - ( m_results.resultsCount() == 1 ) ) { - m_isSearchLocked = true; - m_value = m_results.getID(0); - } - - /* - * If we're in the results phase, determine what the user - * chose - */ - if ( m_isSearchLocked ) { - if ( !m_isMultiple ) { - StringParameter param = - new StringParameter( getName() ); - - data.setParameter( getName(), - new ParameterData(param, m_value) ); - } else { - ArrayParameter param = - new ArrayParameter( getName() ); - String[] tmpArray = (String[])data - .get( getName() + ".select" ); - - if ( tmpArray == null ) { - tmpArray = new String[0]; - } - - data.setParameter( getName(), - new ParameterData(param, tmpArray )); - } - - return; - } else { - data.addError("Search not complete yet."); - } - - m_results.setQuery(oldQuery); + if (m_results == null) { + return; } - }); + + m_oldValue = data.getString(getName() + ".oldvalue"); + + m_value = data.getString(getName() + ".text"); + + /* + * Determine what stage in the process we're at. If .text + * is null, then check what the select/checkbox shows. + */ + if (m_value == null) { + m_isSearchLocked = true; + m_query = m_oldValue; + + if (m_isMultiple) { + String[] tmpArray = (String[]) data + .get(getName() + ".select"); + if (tmpArray == null) { + m_value = ""; + } else { + m_value = tmpArray[0]; + } + } else { + m_value = data.getString(getName() + ".select"); + } + } else { + m_query = m_value; + } + + /* + * If optional and nothing selected, we're done + */ + if (m_value.equals("") && m_isOptional) { + return; + } + + String oldQuery = m_results.getQuery(); + + m_results.setQuery(m_query); + + /* + * If search returns only one hit and is a non-optional single + * select, it's done. + */ + if (!m_isOptional + && !m_isMultiple + && (m_results.resultsCount() == 1)) { + m_isSearchLocked = true; + m_value = m_results.getID(0); + } + + /* + * If we're in the results phase, determine what the user + * chose + */ + if (m_isSearchLocked) { + if (!m_isMultiple) { + StringParameter param + = new StringParameter(getName()); + + data.setParameter(getName(), + new ParameterData(param, m_value)); + } else { + ArrayParameter param + = new ArrayParameter(getName()); + String[] tmpArray = (String[]) data + .get(getName() + ".select"); + + if (tmpArray == null) { + tmpArray = new String[0]; + } + + data.setParameter(getName(), + new ParameterData(param, tmpArray)); + } + + return; + } else { + data.addError("Search not complete yet."); + } + + m_results.setQuery(oldQuery); + } + }); } - public final void setSearchAndSelectListener - (SearchAndSelectListener listener) { + public final void setSearchAndSelectListener(SearchAndSelectListener listener) { m_listener = listener; } @@ -323,38 +322,38 @@ public class SearchAndSelect extends FormSection * * @return the name of the widget */ - public final String getName () { + public final String getName() { return m_name; } /* * Internal function to retrieve a single text value for the widget. */ - private String getTextValue ( PageState state ) { - if ( m_value != null ) { + private String getTextValue(PageState state) { + if (m_value != null) { return m_value; } - if ( m_isSearchLocked ) { - if ( m_isMultiple ) { - return ((String[])m_outputSelectWidget.getValue(state))[0]; + if (m_isSearchLocked) { + if (m_isMultiple) { + return ((String[]) m_outputSelectWidget.getValue(state))[0]; } else { - return (String)m_outputSelectWidget.getValue(state); + return (String) m_outputSelectWidget.getValue(state); } } else { - return (String)m_outputTextWidget.getValue(state); + return (String) m_outputTextWidget.getValue(state); } } /** - * Determine the type of HTML form element to create. - * This will not necessarily be accurate until generateWidget is called - * as the query will be unavailable until that point. + * Determine the type of HTML form element to create. This will not + * necessarily be accurate until generateWidget is called as the query will + * be unavailable until that point. * * @return "text" or "select" depending on the result size */ - public String getType () { - if ( m_isSearchLocked ) { + public String getType() { + if (m_isSearchLocked) { return m_outputSelectWidget.getType(); } else { return "text"; @@ -366,7 +365,7 @@ public class SearchAndSelect extends FormSection * * @return boolean -- true for multiple, false for single */ - public final boolean isMultiple () { + public final boolean isMultiple() { return m_isMultiple; } @@ -375,7 +374,7 @@ public class SearchAndSelect extends FormSection * * @return true for optional, false otherwise */ - public final boolean isOptional () { + public final boolean isOptional() { return m_isOptional; } @@ -384,96 +383,96 @@ public class SearchAndSelect extends FormSection * * @param isOptional true for optional, false for required */ - public SearchAndSelect setOptional ( boolean isOptional ) { + public SearchAndSelect setOptional(boolean isOptional) { m_isOptional = isOptional; return this; } /** - * Indicates if the widget is composed of multiple HTML elements. - * Always returns true, as the widget makes use of a hidden element and - * another element. + * Indicates if the widget is composed of multiple HTML elements. Always + * returns true, as the widget makes use of a hidden element and another + * element. * * @return true */ - public boolean isCompound () { + public boolean isCompound() { return true; } /** - * Generates the XML datastructure for this widget. Adds a hidden, - * a textbox, checkbox group, or select, and possibly some number of + * Generates the XML datastructure for this widget. Adds a hidden, a + * textbox, checkbox group, or select, and possibly some number of * formErrors. * * @param state the state of the page * @param parent the parent widget */ - public void generateXML( PageState state, Element parent ) { - if ( m_results == null ) { + public void generateXML(PageState state, Element parent) { + if (m_results == null) { m_results = m_listener.getModel(new PageEvent(this, state)); } - if ( m_results == null ) { + if (m_results == null) { return; } - if ( m_isSearchLocked || - ( ( ( ! m_oldValue.equals("") && - m_oldValue.equals(m_value) ) || - ( m_maxViewableResults >= m_results.resultsCount() ) ) && - ( m_results.resultsCount() > 0 ) ) ) { - m_outputSelectWidget.generateXML ( state, parent ); + if (m_isSearchLocked + || (((!m_oldValue.equals("") + && m_oldValue.equals(m_value)) + || (m_maxViewableResults >= m_results.resultsCount())) + && (m_results.resultsCount() > 0))) { + m_outputSelectWidget.generateXML(state, parent); } else { - m_outputTextWidget.generateXML ( state, parent ); + m_outputTextWidget.generateXML(state, parent); } - m_oldValueWidget.setValue ( state, m_query ); + m_oldValueWidget.setValue(state, m_query); - m_oldValueWidget.generateXML ( state, parent ); + m_oldValueWidget.generateXML(state, parent); - generateErrors ( state, parent ); + generateErrors(state, parent); } /** - * Generate the error messages for this widget. This widget has some - * specialized error messages, so it is necessary to override the - * default error generator. Basically, the m_results field won't be - * available outside this class, so this needs to be internal. + * Generate the error messages for this widget. This widget has some + * specialized error messages, so it is necessary to override the default + * error generator. Basically, the m_results field won't be available + * outside this class, so this needs to be internal. * * @param state the state of the page * @param parent the parent widget */ - protected void generateErrors ( PageState state, Element parent ) { + protected void generateErrors(PageState state, Element parent) { String curValue = getTextValue(state); - if ( m_results == null ) { + if (m_results == null) { return; } - if ( m_results.resultsCount() > m_maxViewableResults ) { + if (m_results.resultsCount() > m_maxViewableResults) { Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS); - if ( ( curValue == null ) || ( curValue.equals("") ) ) { + if ((curValue == null) || (curValue.equals(""))) { error.addAttribute("message", - "Please enter a comma-delimited search"); - } else if ( ( ! m_oldValue.equals( curValue ) ) && - ! m_isSearchLocked ) { + "Please enter a comma-delimited search"); + } else if ((!m_oldValue.equals(curValue)) + && !m_isSearchLocked) { error.addAttribute("message", - "Your search returned " + - m_results.resultsCount() +" matches. " + - "Please refine your search or leave the " + - "search as it is to see all results."); + "Your search returned " + + m_results.resultsCount() + " matches. " + + "Please refine your search or leave the " + + "search as it is to see all results."); } } - if ( m_results.resultsCount() == 0 ) { - if ( !curValue.equals("") ) { + if (m_results.resultsCount() == 0) { + if (!curValue.equals("")) { Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS); error.addAttribute("message", - "Your search returned no matches. Please " + - "try again"); + "Your search returned no matches. Please " + + "try again"); } else { Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS); error.addAttribute("message", "WARNING -- NO DATA FOUND"); diff --git a/ccm-core/src/com/arsdigita/bebop/form/Widget.java b/ccm-core/src/com/arsdigita/bebop/form/Widget.java index d18ec6d67..0578745da 100755 --- a/ccm-core/src/com/arsdigita/bebop/form/Widget.java +++ b/ccm-core/src/com/arsdigita/bebop/form/Widget.java @@ -42,7 +42,7 @@ import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.util.BebopConstants; import com.arsdigita.globalization.GlobalizedMessage; -import com.arsdigita.kernel.Kernel; +// import com.arsdigita.kernel.Kernel; import com.arsdigita.util.Assert; import com.arsdigita.xml.Element; diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/GlobalizedParameterListener.java b/ccm-core/src/com/arsdigita/bebop/parameters/GlobalizedParameterListener.java index 1f28ba46e..7e2f19843 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/GlobalizedParameterListener.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/GlobalizedParameterListener.java @@ -47,7 +47,6 @@ public abstract class GlobalizedParameterListener return BUNDLE_NAME; } - /** * Set the error message for this parameter. * @@ -56,6 +55,7 @@ public abstract class GlobalizedParameterListener protected void setError(GlobalizedMessage error) { m_error = error; } + /** * Get the error message for this parameter. * diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java b/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java index 7bcabdec6..65acb2933 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/NotEmptyValidationListener.java @@ -24,39 +24,61 @@ import com.arsdigita.bebop.event.ParameterEvent; import com.arsdigita.globalization.GlobalizedMessage; /** - * Verifies that the parameter's value is non-empty. - * A value is considererd non-empty if it exists in the page state, - * and it contains some data besides whitespace. + * Verifies that the parameter's value is non-empty. + * A value is considererd non-empty if it exists in the page state, + * and it contains some data besides whitespace. * - * @author Karl Goldstein - * @author Uday Mathur - * @author Stas Freidin - * @author Rory Solomon - * @author Bill Schneider + * @author Karl Goldstein + * @author Uday Mathur + * @author Stas Freidin + * @author Rory Solomon + * @author Bill Schneider * @version $Id: NotEmptyValidationListener.java 1502 2007-03-20 11:38:53Z chrisgilbert23 $ */ public class NotEmptyValidationListener extends GlobalizedParameterListener { + /** + * Default Constructor setting a predefined label as error message. + */ + public NotEmptyValidationListener() { + setError(new GlobalizedMessage("bebop.parameters.parameter_not_empty", + getBundleBaseName() ) + ); + } + + /** + * Constructor taking a label specified as key into a resource bundle to + * customize the error message. + * + * @param label key into the resource bundle + */ public NotEmptyValidationListener(String label) { setError(new GlobalizedMessage(label, getBundleBaseName())); } - public NotEmptyValidationListener() { - setError(new GlobalizedMessage( - "parameter_is_required", getBundleBaseName() - )); - } + /** + * Constructor taking a GlobalizedMessage as error message to display. + * + * @param error GloblizedMessage taken as customized error message. + */ public NotEmptyValidationListener(GlobalizedMessage error) { setError(error); } + /** + * Validate Method required and used to validate input. + * + * @param e ParameterEvent containing the data + */ + @Override public void validate (ParameterEvent e) { + ParameterData data = e.getParameterData(); Object value = data.getValue(); if (value != null) { - // all these are possible: + // all these are possible values: // " " // " " // " " @@ -68,13 +90,12 @@ public class NotEmptyValidationListener extends GlobalizedParameterListener { valueString = StringUtils.strip(valueString, Character.toString('\u00A0')); valueString = StringUtils.strip(valueString, Character.toString('\u2007')); if (valueString.length() > 0) { - return; + // non-empty value, just return + return; + } } - } - - - + // Empty or null value, add error message to parameter data object. data.addError(getError()); } } diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/NotWhiteSpaceValidationListener.java b/ccm-core/src/com/arsdigita/bebop/parameters/NotWhiteSpaceValidationListener.java index aaee97809..1f91b1a3b 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/NotWhiteSpaceValidationListener.java +++ b/ccm-core/src/com/arsdigita/bebop/parameters/NotWhiteSpaceValidationListener.java @@ -16,14 +16,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -package com.arsdigita.bebop.parameters; +// package com.arsdigita.bebop.parameters; -import com.arsdigita.globalization.GlobalizedMessage; +// import com.arsdigita.globalization.GlobalizedMessage; /** - * @deprecated Use {@link NotEmptyValidationListener}. + * @ deprecated Use {@link NotEmptyValidationListener}. */ - +/* public class NotWhiteSpaceValidationListener extends NotEmptyValidationListener { public NotWhiteSpaceValidationListener(String title) { @@ -32,10 +32,11 @@ public class NotWhiteSpaceValidationListener extends NotEmptyValidationListener public NotWhiteSpaceValidationListener() { setError(new GlobalizedMessage - ("parameter_is_required", getBundleBaseName())); + ("bebop.parameters.parameter_is_required", getBundleBaseName())); } public NotWhiteSpaceValidationListener(GlobalizedMessage error) { setError(error); } } +*/ \ No newline at end of file diff --git a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties index 3f10de225..33880025b 100644 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources.properties @@ -6,3 +6,4 @@ parameter.only.letters.digits=This parameter can only contain letters and/or dig 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. 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 60fbc7408..c015c3213 100644 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_de.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_de.properties @@ -6,3 +6,4 @@ parameter.only.letters.digits=Dieser Parameter darf nur Buchstaben und/oder Zahl 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! 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 3f10de225..33880025b 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_en.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_en.properties @@ -6,3 +6,4 @@ parameter.only.letters.digits=This parameter can only contain letters and/or dig 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. 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 b896311f4..cf09501af 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_es.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_es.properties @@ -1,3 +1,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. 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 8f4ed9ccd..d8b1611fc 100755 --- a/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_fr.properties +++ b/ccm-core/src/com/arsdigita/bebop/parameters/ParameterResources_fr.properties @@ -2,3 +2,4 @@ bebop.parameters.parameter_is_required=Ce param\u00e8tre est obligatoire string_in_range=La longueur de ce param\u00e8tre n'est pas comprise entre {0} et {1} 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. diff --git a/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java b/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java index be90460f0..cb57b2648 100755 --- a/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java +++ b/ccm-core/src/com/arsdigita/globalization/GlobalizedMessage.java @@ -108,7 +108,9 @@ public class GlobalizedMessage { * @param args An Object[] of arguments to interpolate into the retrieved * message. */ - public GlobalizedMessage(final String key, final String bundleName, final Object[] args) { + public GlobalizedMessage(final String key, + final String bundleName, + final Object[] args) { this(key, bundleName); setArgs(args); } @@ -176,7 +178,8 @@ public class GlobalizedMessage { * GlobalizedObject? */ public Object localize() { - return localize(com.arsdigita.globalization.GlobalizationHelper.getNegotiatedLocale()); + return localize(com.arsdigita.globalization.GlobalizationHelper + .getNegotiatedLocale()); } /** @@ -201,7 +204,8 @@ public class GlobalizedMessage { * GlobalizedObject? */ public Object localize(final HttpServletRequest request) { - return localize(com.arsdigita.globalization.GlobalizationHelper.getNegotiatedLocale()); + return localize(com.arsdigita.globalization.GlobalizationHelper + .getNegotiatedLocale()); } /** @@ -293,7 +297,7 @@ public class GlobalizedMessage { } /** - *
For debugging, not for localizing!
+ * For debugging, not for localizing. * * If you need a String, use an additional localize() to get an object * and cast it to String. e.g. diff --git a/ccm-core/src/com/arsdigita/ui/admin/UserForm.java b/ccm-core/src/com/arsdigita/ui/admin/UserForm.java index 30e9dc15f..d06f195ce 100755 --- a/ccm-core/src/com/arsdigita/ui/admin/UserForm.java +++ b/ccm-core/src/com/arsdigita/ui/admin/UserForm.java @@ -65,9 +65,9 @@ class UserForm extends Form implements FormValidationListener, AdminConstants { protected TextField m_url; protected TextField m_screenName; protected EmailList m_emailList; - private PasswordValidationListener m_pwListener; - private NotEmptyValidationListener m_notNullListener; - private SecurityConfig securityConfig = SecurityConfig.getConfig(); + private final PasswordValidationListener m_pwListener; + private final NotEmptyValidationListener m_notNullListener; + private final SecurityConfig securityConfig = SecurityConfig.getConfig(); public UserForm(String formName) { super(formName); @@ -184,6 +184,7 @@ class UserForm extends Form implements FormValidationListener, AdminConstants { * password-confirm field. Also verifies that primary email * address and screen name are unique amoung all users. */ + @Override public void validate(FormSectionEvent event) throws FormProcessException { PageState ps = event.getPageState(); diff --git a/ccm-core/src/com/arsdigita/web/Web.java b/ccm-core/src/com/arsdigita/web/Web.java index 3f24d3d92..6721a89a4 100755 --- a/ccm-core/src/com/arsdigita/web/Web.java +++ b/ccm-core/src/com/arsdigita/web/Web.java @@ -170,7 +170,7 @@ public class Web { /** * Processes an URL String trying to identify a corresponding recource * which is mapped to the given path String. The method ensures that the - * resource defiunitely exists (using the URL returned) or definitely not + * resource definitely exists (using the URL returned) or definitely not * (returning null). * * The resourcePath may be stored at various sources (file system, jar file, diff --git a/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/admin/PropertiesForm.java b/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/admin/PropertiesForm.java index a9dbebc6c..654aacc09 100755 --- a/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/admin/PropertiesForm.java +++ b/ccm-simplesurvey/src/com/arsdigita/simplesurvey/ui/admin/PropertiesForm.java @@ -18,12 +18,10 @@ */ package com.arsdigita.simplesurvey.ui.admin; - - import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormInitListener; -import com.arsdigita.bebop.parameters.NotWhiteSpaceValidationListener; +import com.arsdigita.bebop.parameters.NotEmptyValidationListener; import com.arsdigita.bebop.Form; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.PageState; @@ -42,22 +40,20 @@ import com.arsdigita.simplesurvey.Survey; import com.arsdigita.simplesurvey.Poll; // import com.arsdigita.simplesurvey.SimpleSurveyUtil; import com.arsdigita.simplesurvey.ui.SurveySelectionModel; -import com.arsdigita.simplesurvey.util.GlobalizationUtil ; +import com.arsdigita.simplesurvey.util.GlobalizationUtil; import java.util.Calendar; import java.util.GregorianCalendar; - /** - * - * + * + * */ public class PropertiesForm extends Form { - + private SurveySelectionModel m_survey; private Class m_type; - private TextField m_surveyName; private TextArea m_description; private Date m_startDate; @@ -65,26 +61,31 @@ public class PropertiesForm extends Form { private RadioGroup m_responsesPublic; private RadioGroup m_quizType; + /** + * Constructor. + * + * @param survey + * @param type + */ public PropertiesForm(SurveySelectionModel survey, - Class type) { + Class type) { - super("properties" + type.getName()); - - m_survey = survey; - m_type = type; + super("properties" + type.getName()); + + m_survey = survey; + m_type = type; m_surveyName = new TextField("surveyName"); - m_surveyName.addValidationListener(new NotWhiteSpaceValidationListener()); + m_surveyName.addValidationListener(new NotEmptyValidationListener()); m_description = new TextArea("description"); - m_startDate = new Date("startDate"); m_endDate = new Date("endDate"); add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.name"))); add(m_surveyName); - - add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.description"))); + + add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.description"))); m_description.setRows(20); m_description.setCols(60); add(m_description); @@ -95,44 +96,40 @@ public class PropertiesForm extends Form { add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.end_date"))); add(m_endDate); - - - add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.should_quiz_responses_be_public"))); - m_responsesPublic = new RadioGroup("responsesPublic"); - Option o1 = new Option("true", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.Yes"))); + add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.should_quiz_responses_be_public"))); + m_responsesPublic = new RadioGroup("responsesPublic"); + Option o1 = new Option("true", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.Yes"))); Option o2 = new Option("false", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.No"))); - m_responsesPublic.addOption(o1); - m_responsesPublic.addOption(o2); - add(m_responsesPublic); - - // There can be 2 kinds of quizzes: the knowledge test kind of quiz and the personality assessment kind - add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.what_type_of_quiz_is_this"))); - m_quizType = new RadioGroup("quizType"); - Option o3 = new Option("knowledge_test", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.knowledge_test_quiz"))); - Option o4 = new Option("personal_assessment", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.personal_assessment_quiz"))); - m_quizType.addOption(o3); - m_quizType.addOption(o4); - add(m_quizType); + m_responsesPublic.addOption(o1); + m_responsesPublic.addOption(o2); + add(m_responsesPublic); - add(new Submit("submit"), BlockStylable.CENTER); + // There can be 2 kinds of quizzes: the knowledge test kind of quiz and the personality assessment kind + add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.what_type_of_quiz_is_this"))); + m_quizType = new RadioGroup("quizType"); + Option o3 = new Option("knowledge_test", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.knowledge_test_quiz"))); + Option o4 = new Option("personal_assessment", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.personal_assessment_quiz"))); + m_quizType.addOption(o3); + m_quizType.addOption(o4); + add(m_quizType); + + add(new Submit("submit"), BlockStylable.CENTER); addInitListener(new SurveyInitListener()); addProcessListener(new PropertiesFormProcessListener()); } - - /** - * + * */ private class SurveyInitListener implements FormInitListener { /** - * + * * @param e - * @throws FormProcessException + * @throws FormProcessException */ - public void init(FormSectionEvent e) throws FormProcessException { + public void init(FormSectionEvent e) throws FormProcessException { PageState state = e.getPageState(); @@ -145,10 +142,10 @@ public class PropertiesForm extends Form { m_startDate.setValue(state, survey.getStartDate()); m_endDate.setValue(state, survey.getEndDate()); m_quizType.setValue(state, survey.getQuizType()); - if ( survey.responsesArePublic() ) { + if (survey.responsesArePublic()) { m_responsesPublic.setValue(state, "true"); } else { - m_responsesPublic.setValue(state,"false"); + m_responsesPublic.setValue(state, "false"); } } else { @@ -158,7 +155,7 @@ public class PropertiesForm extends Form { Calendar startCalendar = new GregorianCalendar(); startCalendar.add(Calendar.DATE, 0); java.util.Date startDate = startCalendar.getTime(); - Calendar endCalendar = new GregorianCalendar(); + Calendar endCalendar = new GregorianCalendar(); endCalendar.add(Calendar.DATE, 15); java.util.Date endDate = endCalendar.getTime(); @@ -170,17 +167,15 @@ public class PropertiesForm extends Form { } } - - /** - * + * */ private class PropertiesFormProcessListener implements FormProcessListener { /** - * + * * @param e - * @throws FormProcessException + * @throws FormProcessException */ public void process(FormSectionEvent e) throws FormProcessException { @@ -188,7 +183,7 @@ public class PropertiesForm extends Form { Survey survey; PersistentForm form; - + if (m_survey.isSelected(state)) { survey = m_survey.getSelectedSurvey(state); form = survey.getForm(); @@ -197,27 +192,26 @@ public class PropertiesForm extends Form { // PackageInstance is old style application, no longer used. // survey.setPackageInstance(SimpleSurveyUtil.getPackageInstance(state)); - form = new PersistentForm(); survey.setForm(form); } - - form.setAdminName((String)m_surveyName.getValue(state)); - form.setHTMLName(getHTMLName((String)m_surveyName.getValue(state))); - form.setDescription((String)m_description.getValue(state)); + + form.setAdminName((String) m_surveyName.getValue(state)); + form.setHTMLName(getHTMLName((String) m_surveyName.getValue(state))); + form.setDescription((String) m_description.getValue(state)); form.save(); - survey.setStartDate((java.util.Date)m_startDate.getValue(state)); - survey.setEndDate((java.util.Date)m_endDate.getValue(state)); + survey.setStartDate((java.util.Date) m_startDate.getValue(state)); + survey.setEndDate((java.util.Date) m_endDate.getValue(state)); survey.setResponsesPublic(new Boolean((String) m_responsesPublic.getValue(state))); survey.setQuizType((String) m_quizType.getValue(state)); survey.save(); } /** - * + * * @param surveyName - * @return + * @return */ private String getHTMLName(String surveyName) { String htmlName = surveyName.trim().toLowerCase(); diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java index 05f7c9d5b..6c33bb7a9 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorConfig.java @@ -235,7 +235,7 @@ public class ThemeDirectorConfig extends AbstractConfig { "defaultThemeURLAttribute"; /** - * Purpose uncodumented. + * Purpose undocumented. * * @return */ diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources.properties b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources.properties index 42831555a..be68896c7 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources.properties +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources.properties @@ -38,3 +38,5 @@ theme.url_hint=Enter the LAST part of the url for the theme, eg 'holiday'. Shoul theme.save_button_hint=Save the details in the form theme.cancel_button_hint=Abort changes & reset the form. theme.cancel_button_pressed_msg=cancel pressed +theme.form.url_can_contain_only_characters=The URL can only contain A-Z, a-z, 0-9, _, and -. +theme.form.url_already_exists=A theme with this url already exists. diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_de.properties b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_de.properties index db835f2f1..d27f27197 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_de.properties +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_de.properties @@ -38,3 +38,5 @@ theme.url_hint=Geben Sie den LETZTEN Teil der URL ein, z.B. 'ferien'. Der Eintra theme.save_button_hint=Speichern der Angaben in dem Formular. theme.cancel_button_hint=Verwerfen der Eintragungen und R\u00fccksetzen des Formulars. theme.cancel_button_pressed_msg=Vorgang abgebrochen +theme.form.url_can_contain_only_characters=Die URL darf nur die Zeichen A-Z, a-z, 0-9, _ und - enthalten. +theme.form.url_already_exists=Ein Theme mit dieser URL existiert bereits. diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_en.properties b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_en.properties index d04943938..21b381b5c 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_en.properties +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_en.properties @@ -38,3 +38,5 @@ theme.url_hint=Enter the LAST part of tht url for the theme, eg 'holiday'. Shou theme.save_button_hint=Save the details in the form theme.cancel_button_hint=Abort changes & reset the form. theme.cancel_button_pressed_msg=cancel pressed +theme.form.url_can_contain_only_characters=The URL can only contain A-Z, a-z, 0-9, _, and -. +theme.form.url_already_exists=A theme with this url already exists. diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_fr.properties b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_fr.properties index d04943938..21b381b5c 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_fr.properties +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ThemeDirectorResources_fr.properties @@ -38,3 +38,5 @@ theme.url_hint=Enter the LAST part of tht url for the theme, eg 'holiday'. Shou theme.save_button_hint=Save the details in the form theme.cancel_button_hint=Abort changes & reset the form. theme.cancel_button_pressed_msg=cancel pressed +theme.form.url_can_contain_only_characters=The URL can only contain A-Z, a-z, 0-9, _, and -. +theme.form.url_already_exists=A theme with this url already exists. diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java b/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java index 9eca078b5..34b413ed7 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/dispatcher/InternalThemePrefixerServlet.java @@ -44,7 +44,7 @@ public class InternalThemePrefixerServlet extends InternalPrefixerServlet { * by editing /WEB-INF/conf/log4j.properties int the runtime environment * and set * com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet=DEBUG - * by uncommenting or adding the line. */ + * by uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(InternalPrefixerServlet.class); @@ -105,7 +105,7 @@ public class InternalThemePrefixerServlet extends InternalPrefixerServlet { } } - String prefix = pathInfo; + String prefix; if (path != null) { String themeName = pathInfo.substring(0, pathInfo.indexOf(path)); prefix = m_prefix + themeName; diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeContainer.java b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeContainer.java index db223ccb2..f561ad94e 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeContainer.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeContainer.java @@ -49,9 +49,13 @@ import org.apache.log4j.Logger; * * @author Randy Graebner <randyg@redhat.com> */ -public class ThemeContainer extends SimpleContainer implements ThemeDirectorConstants { +public class ThemeContainer extends SimpleContainer + implements ThemeDirectorConstants { - /** A logger instance. */ + /** Internal logger instance to faciliate debugging. Enable logging output + * by editing /WEB-INF/conf/log4j.properties int the runtime environment + * and set com.arsdigita.themedirector.ui.ThemeContainer=DEBUG + * by uncommenting or adding the line. */ private static final Logger s_log = Logger.getLogger(ThemeContainer.class); @@ -61,7 +65,8 @@ public class ThemeContainer extends SimpleContainer implements ThemeDirectorCons private SimpleContainer m_mainPanel; /** - * Constructor. + * Constructor. + * * @param model * @param parent */ @@ -228,6 +233,11 @@ public class ThemeContainer extends SimpleContainer implements ThemeDirectorCons * */ private class ProductionFilesDownloadLink extends Link { + + /** + * Constructor + * @param model + */ ProductionFilesDownloadLink(final ThemeSelectionModel model) { super(new Label(GlobalizationUtil.globalize ("theme.download_prod_theme_files")), @@ -245,6 +255,11 @@ public class ThemeContainer extends SimpleContainer implements ThemeDirectorCons }); } + /** + * + * @param state + * @return + */ @Override public boolean isVisible(PageState state) { return super.isVisible(state) && diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java index 3e23330e7..90d5c56cc 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeControlPanel.java @@ -52,18 +52,20 @@ import java.util.TooManyListenersException; import org.apache.log4j.Logger; /** - * This is the base page for controlling themes in the system. It - * contains a list of the themes on the left side and it manages the state - * to show the correct forms/containers on the left + * This is the base page for controlling themes in the system. It contains + * a list of the themes on the left side and it manages the state to show the + * correct forms/containers on the right */ -public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorConstants { +public class ThemeControlPanel extends SelectionPanel + implements ThemeDirectorConstants { /** Internal logger instance to faciliate debugging. Enable logging output * by editing /WEB-INF/conf/log4j.properties int the runtime environment - * and set com.arsdigita.templating.ui.ThemeControlPanel=DEBUG - * by uncommenting or adding the line. */ + * and set com.arsdigita.themedirector.ui.ThemeControlPanel=DEBUG + * by uncommenting or adding the line. */ private static final Logger LOGGER = Logger.getLogger(ThemeControlPanel.class); private final ThemeSelectionModel selectionModel; + /** Stored the theme form object, which shopws widget / data for a theme. */ private final Form themeForm; private final BigDecimalParameter defaultThemeParam = new BigDecimalParameter("defaultTheme"); @@ -121,19 +123,28 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo addAction(defaultThemeForm); } + /** + * + * @return + */ private Form createDefaultThemeForm() { - final Form defaultThemeForm = new Form("defaultThemeForm", new SimpleContainer()); - defaultThemeForm.add(new Label(GlobalizationUtil.globalize("theme.set_default_theme"))); + final Form defaultThemeForm = new Form("defaultThemeForm", + new SimpleContainer()); + defaultThemeForm.add(new Label(GlobalizationUtil.globalize( + "theme.set_default_theme"))); final SingleSelect themes = new SingleSelect(defaultThemeParam); - themes.addOption(new Option(null, new Label(GlobalizationUtil.globalize("theme.none")))); + themes.addOption(new Option(null, new Label(GlobalizationUtil.globalize( + "theme.none")))); try { themes.addPrintListener(new PrintListener() { @Override public void prepare(final PrintEvent event) { final SingleSelect target = (SingleSelect) event.getTarget(); - final DataCollection options = SessionManager.getSession().retrieve(Theme.BASE_DATA_OBJECT_TYPE); + final DataCollection options = SessionManager + .getSession() + .retrieve(Theme.BASE_DATA_OBJECT_TYPE); options.addNotEqualsFilter(Theme.LAST_PUBLISHED_DATE, null); options.addOrder(Theme.TITLE); while (options.next()) { diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeForm.java b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeForm.java index 3072f8490..ad76209fe 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeForm.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeForm.java @@ -29,31 +29,34 @@ import com.arsdigita.bebop.event.FormSubmissionListener; import com.arsdigita.bebop.event.FormProcessListener; import com.arsdigita.bebop.event.FormValidationListener; import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.event.ParameterEvent; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.GridPanel; import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.parameters.GlobalizedParameterListener; import com.arsdigita.bebop.parameters.NotEmptyValidationListener; +import com.arsdigita.bebop.parameters.ParameterData; import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.Label; import com.arsdigita.persistence.DataCollection; import com.arsdigita.persistence.SessionManager; import com.arsdigita.util.UncheckedWrapperException; -import com.arsdigita.util.IO; +//import com.arsdigita.util.IO; import com.arsdigita.themedirector.ThemeDirectorConstants; import com.arsdigita.themedirector.ThemeDirector; import com.arsdigita.themedirector.util.GlobalizationUtil; -import com.arsdigita.themedirector.util.ManifestReader; +//import com.arsdigita.themedirector.util.ManifestReader; import com.arsdigita.subsite.Subsite; import com.arsdigita.subsite.Site; import com.arsdigita.toolbox.ui.Cancellable; import com.arsdigita.web.Web; import java.io.File; -import java.io.FileOutputStream; +//import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; +//import java.io.InputStream; import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.DirectoryFileFilter; +//import org.apache.commons.io.filefilter.DirectoryFileFilter; import org.apache.log4j.Logger; @@ -73,9 +76,17 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan private static final Logger s_log = Logger.getLogger(ThemeForm.class); private final ThemeSelectionModel m_theme; + + /* Holds the theme's title. */ private final TextField m_title; + + /* Holds the theme's description. */ private final TextArea m_description; + + /* Holds the theme's URL. */ private final TextField m_url; + + /* Instance of the form's Save/Cancel buttons. */ private final SaveCancelSection m_buttons; /** @@ -119,7 +130,9 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan // Experimental, see above m_url.setLabel(GlobalizationUtil.globalize("theme.url")); m_url.addValidationListener(new NotEmptyValidationListener()); - m_title.setSize(40); + m_url.addValidationListener(new URLFormValidationListener()); + m_url.addValidationListener(new UniqueURLValidationListener()); + m_url.setSize(40); m_url.setHint(GlobalizationUtil.globalize("theme.url_hint")); add(m_url); @@ -133,7 +146,11 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan addSubmissionListener(new ThemeSubmissionListener()); addProcessListener(new ThemeProcessListener()); addInitListener(new ThemeInitListener()); - addValidationListener(new ThemeValidationListener()); + // Form wide validation listener commented out temporarily. All validation + // is done using a parameterValidationListener on each input component. + // A form wide validation listener may be introduced later to display + // an error summerize text and advise what to do. + //addValidationListener(new ThemeValidationListener()); } /** @@ -282,6 +299,8 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan } copyDefaultTheme(newDirectory,null); + // Old way should be removed as soon as thorough testing the + // new method has been completed. // copyDefaultFiles(newDirectory); if (oldDirectory != null && !oldDirectory.exists()) { @@ -334,100 +353,15 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan } } - /** - * ValöidatgionListener class to check the themedirector form input data. - * It's validate method is the entry point and executed when submitting - * the form. - */ - private class ThemeValidationListener implements FormValidationListener { - - /** - * - * @param e - * @throws FormProcessException - */ - @Override - public void validate(FormSectionEvent e) - throws FormProcessException { - PageState state = e.getPageState(); - - String url = (String)m_url.getValue(state); - validateURLForm(state, url); - validateURLUniqueness(state, url); - - // now, validate that the URL does not already exist if this - // is actually a "new" and not an "edit" - Theme theme = m_theme.getSelectedTheme(state); - if (theme == null) { - File currentRoot = new File(Web.getServletContext().getRealPath("/")); - File newDirectory = new File(currentRoot, DEV_THEMES_BASE_DIR + - url); - if (newDirectory.exists()) { - throw new FormProcessException - ("A file with the name " + url + " already exists " + - "in the file system. Contact your system " + - "administrator if you think this is an error."); - } - } - } - } - - /** - * This checks the form of the url...specifically, we are only allowing - * [A-Z,a-z,0-9,_,-]. - * @param state - * @param url - * @throws com.arsdigita.bebop.FormProcessException - */ - public void validateURLForm(PageState state, String url) - throws FormProcessException { - - //Obviously, this is not at all globalized and should - //only be used with English text....however, since we are dealing - // with a string that will be in the file system and will not - // be seen by the end user, this should be fine. - for (int i = 0; i < url.length(); i++) { - char c = url.charAt(i); - if (!(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || - ('0' <= c && c <= '9') || c == '_' || c == '-')) { - throw new FormProcessException - ("The URL can only contain A-Z, a-z, 0-9, _, and -."); - } - } - } - - /** - * This makes sure no other theme has the same URL - * @param state - * @param url - * @throws com.arsdigita.bebop.FormProcessException - */ - public void validateURLUniqueness(PageState state, String url) - throws FormProcessException { - - if ( url != null ) { - DataCollection collection = SessionManager.getSession() - .retrieve(Theme.BASE_DATA_OBJECT_TYPE); - collection.addEqualsFilter("lower(" + Theme.URL + ")", - url.toLowerCase()); - Theme currentTheme = (Theme)m_theme.getSelectedObject(state); - if (currentTheme != null) { - collection.addNotEqualsFilter(Theme.ID, currentTheme.getID()); - } - - if ( collection.size() > 0) { - throw new FormProcessException - ("A theme with this url already exists"); - } - } - } - /** * Copies a complete directory containing the default theme to a newly * created theme's directory without any filtering or other processing. * It assumes, that the source directory contains a complete and working * set of theme files. * + * Developer's note: Why not move into private class ThemeProcessListener + * where it is used (exclusivly). + * * @param newThemeDirectory specifies the target directory. Must not * be null. * @param defaultThemeDirectory Directory containing a complete set of @@ -449,13 +383,188 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan newThemeDirectory); } + + /** + * Themedirector-specific parameter validation listener, verifies that the + * URL parameter value contains only valid characters. + * Helper method to checks the form of the url...specifically, we are + * only allowing [A-Z,a-z,0-9,_,-]. + */ + private class URLFormValidationListener + extends GlobalizedParameterListener { + + /** + * Default Constructor setting a predefined label as error message. + */ + public URLFormValidationListener() { + setError(GlobalizationUtil.globalize( + "theme.form.url_can_contain_only_characters") + ); + } + + /** + * Validate Method required and used to validate input. + * + * @param e ParameterEvent containing the data + */ + @Override + public void validate(ParameterEvent e) { + + ParameterData data = e.getParameterData(); + Object value = data.getValue(); + PageState state = e.getPageState(); + String url = (String)m_url.getValue(state); + + if (value != null) { + String urlString = value.toString().trim(); + + for (int i = 0; i < urlString.length(); i++) { + char c = urlString.charAt(i); + if (!(('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') + || ('0' <= c && c <= '9') || c == '_' || c == '-')) { + // urlString contains illegal character(s) + // adds an error message to the widget object. + data.addError(getError()); + return; + } + } + // non-empty value, just return + return; + } + // Empty or no illegal character found, just return + return; + + } // end method validatge + } // end private class URLFormValidationListener + + + /** + * Themedirector-specific parameter validation listener, verifies that the + * URL parameter is unique. + */ + private class UniqueURLValidationListener + extends GlobalizedParameterListener { + + /** + * Default Constructor setting a predefined label as error message. + */ + public UniqueURLValidationListener() { + setError(GlobalizationUtil.globalize( + "theme.form.url_already_exists") + ); + } + + /** + * Validate Method required and used to validate input. + * + * @param e ParameterEvent containing the data + * @pre URL parameter is not empty and contains valid characters only + * as ensured by previously invoked ValidationListeners. + */ + @Override + public void validate(ParameterEvent e) { + + ParameterData data = e.getParameterData(); + Object value = data.getValue(); + PageState state = e.getPageState(); + String url = (String)m_url.getValue(state); + + if (value != null) { + String urlString = value.toString().trim(); + + DataCollection collection = SessionManager.getSession() + .retrieve(Theme.BASE_DATA_OBJECT_TYPE); + collection.addEqualsFilter("lower(" + Theme.URL + ")", + urlString.toLowerCase()); + Theme currentTheme = (Theme)m_theme.getSelectedObject(state); + if (currentTheme != null) { + collection.addNotEqualsFilter(Theme.ID, currentTheme.getID()); + } + + if ( collection.size() > 0) { + // urlString is not unique but already exists. + // adds an error message to the widget object. + data.addError(getError()); + return; + } + + // unique value, just return + return; + } + // null or any other condition not able to handle here. Just return + + } // end method validate + + } // end private class UniqueURLValidationListener + + + /** + * ValidationListener class to check the themedirector's form input data. + * It's validate method is the entry point and executed when submitting + * the form. + */ + private class ThemeValidationListener implements FormValidationListener { + + /** + * Does the actual validation. + * + * @param fse + * @throws FormProcessException + */ + @Override + public void validate(FormSectionEvent fse) + throws FormProcessException { + + PageState state = fse.getPageState(); + + + // Nothing to do at the Moment + // We should add something like that: + // - acquire a formdata object + // - iterate ober the formdata widgets and check for an + // added error message + // - Add the error to an error list + // - If at least on error has been found, throw a FormProcessException + // With a summerizing text and a list of errors found. + // Text from a FPE is by default shown just below the action buttons + // (Save / Cancel) + + + // in case of an error in any of the input form widgets, + // throw a FPE in give a summerizing message and advice. + // throw new FormProcessException + // ("[String]", + // GlobalizationUtil.globalize("key",errorDetails) + // ); + // } + + + } + + } // end ThemeValidationListener + + + + + // /////////////////////////////////////////////////////////////////////// + // Outdated CODE + // Temporarily retained for easy reference until migration is complete. + // /////////////////////////////////////////////////////////////////////// + + /** * Copies the default theme files to the new directory using a * Manifest file to determine the files to copy. * + * NOTE: + * Old way should be removed as soon as thorough testing the + * new method has been completed. + * + * * @param newDirectory specifies the target directory * @throws IOException */ +/* private void copyDefaultFiles(File newDirectory) throws IOException { ClassLoader loader = Thread.currentThread().getContextClassLoader(); InputStream is = loader.getResourceAsStream @@ -476,34 +585,26 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan new FileWriterManifestReader(is, newDirectory); reader.processFile(); } - +*/ /** * + * NOTE: Part of outdated way to copy a default theme. Copying is now done + * without Manifest file. Class chould be completely removed as soon as + * QA testing is completed. */ +/* private class FileWriterManifestReader extends ManifestReader { private final File m_newDirectory; private final String m_directoryFilter; - /** - * Constructor. - * - * @param stream - * @param newDirectory - */ - FileWriterManifestReader(InputStream stream, File newDirectory) { + FileWriterManifestReader(InputStream stream, File newDirectory) { super(stream); m_newDirectory = newDirectory; m_directoryFilter = ThemeDirector.getConfig().getDefaultThemePath(); } - /** - * - * @param is - * @param filePath - * @param isStyleFile - */ @Override public void processManifestFileLine(InputStream is, String filePath, @@ -541,4 +642,5 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan } } } +*/ } diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeValidationPanel.java b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeValidationPanel.java index e21773686..4cd37b1af 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeValidationPanel.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/ui/ThemeValidationPanel.java @@ -182,11 +182,11 @@ class ThemeValidationPanel extends GridPanel implements ThemeDirectorConstants { containing patterns to search for. Developer's Note: - We used to use a 'resource' tag involing a resource servlet to - deliver the correct file either from database or filesystem. Ir would - require an URL similar to + We used to use a 'resource' tag involving a resource servlet to + deliver the correct file either from database or filesystem. It + would require an URL similar to http://localhost:9008/libreccm/resource/themes/heirloom/apps/theme/xsl/index.xs - where librecms is the context ccm happpens to be installed in. + where librecms is the context CCM happpens to be installed in. Currently we bypass the resource servlet and access the filesystem directly. Must be modified as soon as we deliver the theme from db. */ String stylesheetPath = "http://" + Web.getConfig().getHost().toString() diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java index 15fe09e62..4b7cece07 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeDevelopmentFileManager.java @@ -86,9 +86,12 @@ public class ThemeDevelopmentFileManager 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); @@ -108,8 +111,10 @@ public class ThemeDevelopmentFileManager 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; @@ -117,8 +122,11 @@ public class ThemeDevelopmentFileManager 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() + DEV_THEMES_BASE_DIR; } @@ -134,6 +142,7 @@ public class ThemeDevelopmentFileManager extends ThemeFileManager { // it works if we want the thread to auto-update things for us. // if we decide that we definitely do not want the auto-update // then we should remove this. + @Override protected void updateTheme(Theme theme) { // the first step is to make sure that all files from the theme // are in the db. @@ -154,9 +163,11 @@ public class ThemeDevelopmentFileManager 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.getDraftThemeFiles(); } diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java index 4510f9e35..5801fe2a6 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemeFileManager.java @@ -21,7 +21,8 @@ import com.arsdigita.themedirector.ThemeDirectorConstants; import com.arsdigita.themedirector.ThemeFileCollection; import com.arsdigita.persistence.SessionManager; import com.arsdigita.persistence.TransactionContext; -import com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet; +//import com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet; +import com.arsdigita.web.Web; import java.io.File; import java.io.FileOutputStream; @@ -205,28 +206,18 @@ public abstract class ThemeFileManager extends Thread if (m_baseDirectory == null) { // Because the constructor sets the base directory this should // never happen, but just in case .... - // ThemeDirector may execute in a different web application context - // as core oder CMS. To determine the actual context we may ask - // Themedirector servlet. - - /* OLD code depending on deprecated ContextRegiserServlet - ApplicationCollection collection = Application.retrieveAllApplications(); - collection.filterToApplicationType(ThemeDirector.BASE_DATA_OBJECT_TYPE); - Application app = null; - if (collection.next()) { - // it should only be mounted once but the jsp does not - // care about the application so even if it is mounted multiple - // times that is fine. - app = collection.getApplication(); - } - collection.close(); - String webapp = app.getContextPath(); - ServletContext themeCtx = Web.getServletContext(webapp + '/'); - m_baseDirectory = themeCtx.getRealPath("/"); - */ - ServletContext themeCtx = InternalThemePrefixerServlet - .getThemedirectorContext(); + // ThemeDirector may execute in a different web application context + // as core oder CMS. + // Old non-standard-compliant code had been removed, so currently + // ThemeManager has to be installed into the same context as core. + // To determine the actual context we may ask Themedirector servlet. + // Something like + // ServletContext themeCtx = InternalThemePrefixerServlet + // .getThemedirectorContext(); + // We have to ensure the Servlet is initialized. + + ServletContext themeCtx = Web.getServletContext(); m_baseDirectory = themeCtx.getRealPath("/"); } diff --git a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java index 04161ee93..6edf9348a 100755 --- a/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java +++ b/ccm-themedirector/src/com/arsdigita/themedirector/util/ThemePublishedFileManager.java @@ -32,11 +32,14 @@ import org.apache.log4j.Logger; * runs for the first time, it examines all themes. * * @author Randy Graebner - * * @version $Revision: #2 $ $DateTime: 2004/03/17 09:56:37 $ */ public class ThemePublishedFileManager extends ThemeFileManager { + /** Internal logger instance to faciliate debugging. Enable logging output + * 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); @@ -46,7 +49,8 @@ public class ThemePublishedFileManager extends ThemeFileManager { static private ThemeFileManager s_manager = null; - protected ThemePublishedFileManager(int startupDelay, int pollDelay, + protected ThemePublishedFileManager(int startupDelay, + int pollDelay, String baseDirectory) { super(s_log, startupDelay, pollDelay, baseDirectory); } @@ -128,7 +132,7 @@ public class ThemePublishedFileManager extends ThemeFileManager { /** - * This allows subclasses to filter the collection as appropriate + * This allows subclasses to filter the collection as appropriate. * (e.g. only return "live" files or only "draft" files). */ protected ThemeFileCollection getThemeFilesCollection(Theme theme) {