Last part of ThemeDirector code fix. Errors in validation of input fields is now displayed along the respective input field. Fixed uncought exception, unclosed result set, various missing globalization.
git-svn-id: https://svn.libreccm.org/ccm/trunk@2682 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
6c272debdd
commit
a7119bb541
|
|
@ -94,7 +94,7 @@ public class DecisionTreeTargetEditForm extends Form
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param selArticle the current article
|
* @param selTree
|
||||||
* @param selTarget the current section
|
* @param selTarget the current section
|
||||||
* @param container container which this form is added to
|
* @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.
|
* Returns the save/cancel section from this form.
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public SaveCancelSection getSaveCancelSection() {
|
public SaveCancelSection getSaveCancelSection() {
|
||||||
return m_saveCancelSection;
|
return m_saveCancelSection;
|
||||||
|
|
@ -213,7 +214,9 @@ public class DecisionTreeTargetEditForm extends Form
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Form initialisation hook. Sets the options for select widgets.
|
/** Form initialisation hook. Sets the options for select widgets.
|
||||||
|
* @param fse
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void init(FormSectionEvent fse) {
|
public void init(FormSectionEvent fse) {
|
||||||
PageState state = fse.getPageState();
|
PageState state = fse.getPageState();
|
||||||
FormData data = fse.getFormData();
|
FormData data = fse.getFormData();
|
||||||
|
|
@ -276,6 +279,7 @@ public class DecisionTreeTargetEditForm extends Form
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m_targetSectionWidget.addPrintListener(new PrintListener() {
|
m_targetSectionWidget.addPrintListener(new PrintListener() {
|
||||||
|
@Override
|
||||||
public void prepare(PrintEvent e) {
|
public void prepare(PrintEvent e) {
|
||||||
initTargetOptions(e);
|
initTargetOptions(e);
|
||||||
}
|
}
|
||||||
|
|
@ -287,6 +291,7 @@ public class DecisionTreeTargetEditForm extends Form
|
||||||
add(m_targetSectionWidget);
|
add(m_targetSectionWidget);
|
||||||
|
|
||||||
addValidationListener(new FormValidationListener() {
|
addValidationListener(new FormValidationListener() {
|
||||||
|
@Override
|
||||||
public final void validate(final FormSectionEvent event)
|
public final void validate(final FormSectionEvent event)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
final PageState state = event.getPageState();
|
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
|
* Called on form submission. Check to see if the user clicked the
|
||||||
* cancel button. If they did, don't continue with the form.
|
* cancel button. If they did, don't continue with the form.
|
||||||
|
* @param event
|
||||||
|
* @throws com.arsdigita.bebop.FormProcessException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void submitted(FormSectionEvent event)
|
public void submitted(FormSectionEvent event)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
PageState state = event.getPageState();
|
PageState state = event.getPageState();
|
||||||
|
|
@ -332,7 +340,10 @@ public class DecisionTreeTargetEditForm extends Form
|
||||||
/**
|
/**
|
||||||
* Called after form has been validated. Create the new
|
* Called after form has been validated. Create the new
|
||||||
* DecisionTreeOptionTarget and assign it to the current DecisionTree.
|
* DecisionTreeOptionTarget and assign it to the current DecisionTree.
|
||||||
|
* @param event
|
||||||
|
* @throws com.arsdigita.bebop.FormProcessException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void process(FormSectionEvent event) throws FormProcessException {
|
public void process(FormSectionEvent event) throws FormProcessException {
|
||||||
PageState state = event.getPageState();
|
PageState state = event.getPageState();
|
||||||
FormData data = event.getFormData();
|
FormData data = event.getFormData();
|
||||||
|
|
|
||||||
|
|
@ -238,32 +238,43 @@ public class Form extends FormSection implements BebopConstants {
|
||||||
return form;
|
return form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ps
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
protected void generateErrors(PageState ps, Element parent) {
|
protected void generateErrors(PageState ps, Element parent) {
|
||||||
|
|
||||||
for (Iterator it = getFormData(ps).getErrors(); it.hasNext(); ) {
|
for (Iterator it = getFormData(ps).getErrors(); it.hasNext(); ) {
|
||||||
Element errors = parent.newChildElement(BEBOP_FORMERRORS,
|
Element errors = parent.newChildElement(BEBOP_FORMERRORS,
|
||||||
BEBOP_XML_NS);
|
BEBOP_XML_NS);
|
||||||
errors.addAttribute
|
errors.addAttribute("message",
|
||||||
("message",
|
(String)((GlobalizedMessage) it.next()).localize
|
||||||
(String) ((GlobalizedMessage) it.next()).localize
|
(ps.getRequest())
|
||||||
(ps.getRequest()));
|
);
|
||||||
errors.addAttribute("id", getName());
|
errors.addAttribute("id", getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Determine whether or not this Form will redirect after its
|
* <p>Determine whether or not this Form will redirect after its
|
||||||
* process listeners are fired.</p>
|
* process listeners are fired.</p>
|
||||||
|
*
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean isRedirecting() {
|
public boolean isRedirecting() {
|
||||||
return m_isRedirecting;
|
return m_isRedirecting;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Setting the redirecting flag will cause the Form to clear
|
* Setting the redirecting flag will cause the Form to clear the
|
||||||
* the control event and redirect back to the current URL, after
|
* control event and redirect back to the current URL, after
|
||||||
* firing all process listeners. Doing so means that a user
|
* firing all process listeners. Doing so means that a user reload
|
||||||
* reload will not cause the form to be resubmitted. The default
|
* will not cause the form to be resubmitted. The default value for
|
||||||
* value for this flag is false.</p>
|
* this flag is false.
|
||||||
|
*
|
||||||
|
* @param isRedirecting
|
||||||
*/
|
*/
|
||||||
public void setRedirecting(boolean isRedirecting) {
|
public void setRedirecting(boolean isRedirecting) {
|
||||||
Assert.isUnlocked(this);
|
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
|
* Responds to the request by processing this form with the HTTP request
|
||||||
* given in <code>state</code>.
|
* given in <code>state</code>.
|
||||||
|
* @see #process process(...)
|
||||||
*
|
*
|
||||||
* @param state represents the current request
|
* @param state represents the current request
|
||||||
* @see #process process(...)
|
* @throws javax.servlet.ServletException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void respond(PageState state) throws ServletException {
|
public void respond(PageState state) throws ServletException {
|
||||||
final FormData data = process(state);
|
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
|
* right set of init, validation, and process listeners, depending on
|
||||||
* whether this is an initial request to the form and whether the form
|
* whether this is an initial request to the form and whether the form
|
||||||
* submission was valid. Submission listeners are always run.
|
* submission was valid. Submission listeners are always run.
|
||||||
*
|
|
||||||
* @param state represents the current request
|
|
||||||
*
|
|
||||||
* @return the values extracted from the HTTP request contained
|
|
||||||
* in <code>state</code>.
|
|
||||||
* @see #getFormData
|
* @see #getFormData
|
||||||
|
*
|
||||||
|
* @param state represents the current request
|
||||||
|
* @return the values extracted from the HTTP request contained
|
||||||
|
* in <code>state</code>.
|
||||||
|
* @throws com.arsdigita.bebop.FormProcessException
|
||||||
* @pre state != null
|
* @pre state != null
|
||||||
* @post return != null
|
* @post return != null
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public FormData process(PageState state) throws FormProcessException {
|
public FormData process(PageState state) throws FormProcessException {
|
||||||
Assert.exists(state, "PageState");
|
Assert.exists(state, "PageState");
|
||||||
FormData result = new FormData(getModel(), state.getRequest());
|
FormData result = new FormData(getModel(), state.getRequest());
|
||||||
|
|
@ -476,6 +490,7 @@ public class Form extends FormSection implements BebopConstants {
|
||||||
*/
|
*/
|
||||||
protected void traverse() {
|
protected void traverse() {
|
||||||
Traversal formRegistrar = new Traversal() {
|
Traversal formRegistrar = new Traversal() {
|
||||||
|
@Override
|
||||||
protected void act(Component c) {
|
protected void act(Component c) {
|
||||||
if ( c == Form.this ) {
|
if ( c == Form.this ) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -497,6 +512,7 @@ public class Form extends FormSection implements BebopConstants {
|
||||||
*
|
*
|
||||||
* @param p page in which to register this form
|
* @param p page in which to register this form
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void register(Page p) {
|
public void register(Page p) {
|
||||||
traverse();
|
traverse();
|
||||||
p.addComponent(this);
|
p.addComponent(this);
|
||||||
|
|
@ -504,6 +520,7 @@ public class Form extends FormSection implements BebopConstants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
|
* @param model
|
||||||
*/
|
*/
|
||||||
public void excludeParameterFromExport(ParameterModel model) {
|
public void excludeParameterFromExport(ParameterModel model) {
|
||||||
getModel().excludeFormParameterFromExport(model);
|
getModel().excludeFormParameterFromExport(model);
|
||||||
|
|
@ -516,6 +533,7 @@ public class Form extends FormSection implements BebopConstants {
|
||||||
*/
|
*/
|
||||||
private void initFormData() {
|
private void initFormData() {
|
||||||
m_formData = new RequestLocal() {
|
m_formData = new RequestLocal() {
|
||||||
|
@Override
|
||||||
protected Object initialValue(PageState s) {
|
protected Object initialValue(PageState s) {
|
||||||
// TODO: We need to come up with the right strategy for
|
// TODO: We need to come up with the right strategy for
|
||||||
// how we deal with FormProcessExceptions. Are they fatal
|
// how we deal with FormProcessExceptions. Are they fatal
|
||||||
|
|
@ -524,7 +542,8 @@ public class Form extends FormSection implements BebopConstants {
|
||||||
return process(s);
|
return process(s);
|
||||||
} catch (FormProcessException e) {
|
} catch (FormProcessException e) {
|
||||||
s_log.error("Form Process exception", 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 <code>this</code>.
|
* @return a human-readable representation of <code>this</code>.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return super.toString() + " " +
|
return super.toString() + " " +
|
||||||
"[" + getName() + "," + getAction() + "," + getMethod() + "," +
|
"[" + 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) {
|
protected void setFormData(PageState state, FormData data) {
|
||||||
m_formData.set(state, data);
|
m_formData.set(state, data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,8 @@ import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
import com.arsdigita.util.URLRewriter;
|
import com.arsdigita.util.URLRewriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the data associated with forms and
|
* Manages the data associated with forms and other remote sources.
|
||||||
* other remote sources.
|
|
||||||
*
|
|
||||||
* <p>The basic task of a <code>FormData</code> object is to transform
|
* <p>The basic task of a <code>FormData</code> object is to transform
|
||||||
* a set of key-value string pairs into a validated set of Java data
|
* 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
|
* 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;
|
private boolean m_isSubmission;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure that no one can create this object from outside the
|
* Ensure that no one can create this object from outside the package
|
||||||
* package without supplying meaningful parameters
|
* without supplying meaningful parameters
|
||||||
*/
|
*/
|
||||||
private FormData() {}
|
private FormData() {}
|
||||||
|
|
||||||
|
|
@ -277,9 +276,8 @@ public class FormData implements Map, Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates this <code>FormData</code> object according to its
|
* Validates this <code>FormData</code> object according to its form model.
|
||||||
* form model. If the <code>FormData</code> is already valid,
|
* If the <code>FormData</code> is already valid, does nothing.
|
||||||
* does nothing.
|
|
||||||
*
|
*
|
||||||
* @param state describes the current page state
|
* @param state describes the current page state
|
||||||
* @pre state != null
|
* @pre state != null
|
||||||
|
|
@ -300,9 +298,8 @@ public class FormData implements Map, Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates this <code>FormData</code> object against its
|
* Validates this <code>FormData</code> object against its form model,
|
||||||
* form model, regardless of whether the object is currently
|
* regardless of whether the object is currently valid.
|
||||||
* valid.
|
|
||||||
*
|
*
|
||||||
* @param state describes the current page state
|
* @param state describes the current page state
|
||||||
* @pre state != null
|
* @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
|
* @param message the error message
|
||||||
* @pre message != null
|
* @pre message != null
|
||||||
|
|
|
||||||
|
|
@ -52,16 +52,17 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* The top-level container for all Bebop components and containers.
|
||||||
* The top-level container for all Bebop components and containers. </p>
|
|
||||||
*
|
*
|
||||||
* <UL> <LI>Holds references to the components of a page.</LI> <LI>Provides methods for servicing
|
* <UL>
|
||||||
* requests and for notifying other components that a request for this page has been received
|
* <LI>Holds references to the components of a page.</LI>
|
||||||
* through {@link ActionListener ActionListeners}.</LI>
|
* <LI>Provides methods for servicing requests and for notifying other
|
||||||
*
|
* components that a request for this page has been received through
|
||||||
* <LI>Tracks request parameters for stateful components, such as tabbed panes and sortable
|
* {@link ActionListener ActionListeners}.</LI>
|
||||||
* tables.</LI> </UL>
|
* <LI>Tracks request parameters for stateful components, such as tabbed panes
|
||||||
* <p>
|
* and sortable tables.</LI>
|
||||||
|
* </UL>
|
||||||
|
*
|
||||||
* A typical <code>Page</code> may be created as follows: null <blockquote><pre><code>
|
* A typical <code>Page</code> may be created as follows: null <blockquote><pre><code>
|
||||||
* Page p = new Page("Hello World");
|
* Page p = new Page("Hello World");
|
||||||
* p.add(new Label("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";
|
static final String INVISIBLE = INTERNAL + "i";
|
||||||
/**
|
/**
|
||||||
* Map of stateful components (id --> Component) SortedMap used because component based hash for
|
* Map of stateful components (id --> Component) SortedMap used because
|
||||||
* page is based on concatenation of component ids, and so need to guarantee that they are
|
* component based hash for page is based on concatenation of component ids,
|
||||||
* returned in the same order for the same page - cg.
|
* and so need to guarantee that they are returned in the same order for
|
||||||
|
* the same page - cg.
|
||||||
*/
|
*/
|
||||||
private SortedMap m_componentMap;
|
private SortedMap m_componentMap;
|
||||||
private List m_components;
|
private List m_components;
|
||||||
|
|
@ -132,13 +134,14 @@ public class Page extends BlockStylable implements Container {
|
||||||
private List m_actionListeners;
|
private List m_actionListeners;
|
||||||
private List m_requestListeners;
|
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
|
* The title of the page to be added in the head of HTML output. The title
|
||||||
* to allow developers to add PrintListeners to dynamically change the value of 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;
|
private Label m_title;
|
||||||
/**
|
/**
|
||||||
* Stores the actual title for the current request. The title may be generated with a
|
* Stores the actual title for the current request. The title may be
|
||||||
* PrintListener of the m_title Label.
|
* generated with a PrintListener of the m_title Label.
|
||||||
*/
|
*/
|
||||||
private RequestLocal m_currentTitle;
|
private RequestLocal m_currentTitle;
|
||||||
/**
|
/**
|
||||||
|
|
@ -172,54 +175,58 @@ public class Page extends BlockStylable implements Container {
|
||||||
private boolean m_useHttpSession = false;
|
private boolean m_useHttpSession = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if this page should export state through the HttpSession instead of
|
* Returns <code>true</code> if this page should export state through the
|
||||||
* the URL query string.
|
* HttpSession instead of the URL query string.
|
||||||
* <P>
|
* <P>
|
||||||
* If this returns <code>true</code>, then PageState.stateAsURL() will only export the control
|
* If this returns <code>true</code>, then PageState.stateAsURL() will only
|
||||||
* event as a URL query string. If this returns <code>false</code>, then stateAsURL() will
|
* export the control event as a URL query string. If this returns
|
||||||
* export the entire page state.
|
* <code>false</code>, then stateAsURL() will export the entire page state.
|
||||||
*
|
|
||||||
*
|
|
||||||
* @see PageState#stateAsURL
|
* @see PageState#stateAsURL
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if this page should export state through the HttpSession;
|
* @return <code>true</code> if this page should export state through the
|
||||||
* <code>false</code> if it should export using the URL query string.
|
* HttpSession;
|
||||||
|
* <code>false</code> if it should export using the URL query
|
||||||
|
* string.
|
||||||
*/
|
*/
|
||||||
public boolean isUsingHttpSession() {
|
public boolean isUsingHttpSession() {
|
||||||
return m_useHttpSession;
|
return m_useHttpSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates to this page whether it should export its entire state to subsequent requests
|
* Indicates to this page whether it should export its entire state to
|
||||||
* through the URL query string, or if it should use the HttpSession instead and only use the
|
* subsequent requests through the URL query string, or if it should use the
|
||||||
* URL query string for the control event.
|
* HttpSession instead and only use the URL query string for the control
|
||||||
|
* event.
|
||||||
*
|
*
|
||||||
* @see PageState#stateAsURL
|
* @see PageState#stateAsURL
|
||||||
*
|
*
|
||||||
* @param b <code>true</code> if PageState.stateAsURL() will export only the control event as a
|
* @param b <code>true</code> if PageState.stateAsURL() will export only the
|
||||||
* URL query string. <code>false</code> if stateAsURL() will export the entire page
|
* control event as a URL query string. <code>false</code> if stateAsURL()
|
||||||
* state.
|
* will export the entire page state.
|
||||||
*/
|
*/
|
||||||
public void setUsingHttpSession(boolean b) {
|
public void setUsingHttpSession(boolean b) {
|
||||||
m_useHttpSession = 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 title title for this page
|
||||||
*
|
|
||||||
* @param panel container for this page
|
* @param panel container for this page
|
||||||
|
* @deprecated use Page(Lab el, Container) instead.
|
||||||
*/
|
*/
|
||||||
public Page(String title, Container panel) {
|
public Page(String title, Container panel) {
|
||||||
this(new Label(title), panel);
|
this(new Label(title), panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 title title for this page as (globalized) Label
|
||||||
* @param panel container for this page
|
* @param panel container for this page
|
||||||
*/
|
*/
|
||||||
public Page(Label title, Container panel) {
|
public Page(Label title, Container panel) {
|
||||||
|
|
@ -231,7 +238,7 @@ public class Page extends BlockStylable implements Container {
|
||||||
m_components = new ArrayList();
|
m_components = new ArrayList();
|
||||||
m_componentMap = new TreeMap();
|
m_componentMap = new TreeMap();
|
||||||
setErrorDisplay(new PageErrorDisplay());
|
setErrorDisplay(new PageErrorDisplay());
|
||||||
setTitle(title);
|
m_title = title;
|
||||||
|
|
||||||
// Initialize the RequestLocal where the title for the current
|
// Initialize the RequestLocal where the title for the current
|
||||||
// request will be kept
|
// 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
|
* @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
|
* @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
|
* Adds a component with the specified layout constraints to this container.
|
||||||
* are defined in each layout container as static ints. To specify multiple constraints, use
|
* Layout constraints are defined in each layout container as static ints.
|
||||||
* bitwise OR.
|
* To specify multiple constraints, use bitwise OR.
|
||||||
*
|
*
|
||||||
* @param c component to add to this container
|
* @param c component to add to this container
|
||||||
*
|
* @param constraints layout constraints (a bitwise OR of static ints in the
|
||||||
* @param constraints layout constraints (a bitwise OR of static ints in the particular layout)
|
* particular layout)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void add(Component c, int constraints) {
|
public void add(Component c, int constraints) {
|
||||||
|
|
@ -315,17 +324,20 @@ public class Page extends BlockStylable implements Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if this list contains the specified element. More formally, returns
|
* Returns <code>true</code> if this list contains the specified element.
|
||||||
* <code>true</code> if and only if this list contains at least one element e such that (o==null
|
* More formally, returns <code>true</code> if and only if this list
|
||||||
* ? e==null : o.equals(e)).
|
* contains at least one element e such that (o==null ? e==null :
|
||||||
|
* o.equals(e)).
|
||||||
* <P>
|
* <P>
|
||||||
* This method returns <code>true</code> only if the component has been directly added to this
|
* This method returns <code>true</code> only if the component has been
|
||||||
* container. If this container contains another container that contains this component, this
|
* directly added to this container. If this container contains another
|
||||||
* method returns <code>false</code>.
|
* container that contains this component, this method returns
|
||||||
|
* <code>false</code>.
|
||||||
*
|
*
|
||||||
* @param o element whose presence in this container is to be tested
|
* @param o element whose presence in this container is to be tested
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if this Container contains the specified component directly;
|
* @return <code>true</code> if this Container contains the specified
|
||||||
|
* component directly;
|
||||||
* <code>false</code> otherwise.
|
* <code>false</code> otherwise.
|
||||||
*/
|
*/
|
||||||
@Override
|
@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
|
* Returns the component at the specified position. Each call to the add
|
||||||
* index. Since the user has no control over the index of added components (other than counting
|
* method increments the index. Since the user has no control over the index
|
||||||
* each call to add), this method should be used in conjunction with indexOf.
|
* 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
|
* @param index the index of the item to be retrieved from this Container
|
||||||
*
|
|
||||||
* @return the component at the specified position in this container.
|
* @return the component at the specified position in this container.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -351,14 +363,12 @@ public class Page extends BlockStylable implements Container {
|
||||||
* Gets the index of a component.
|
* Gets the index of a component.
|
||||||
*
|
*
|
||||||
* @param c component to search for
|
* @param c component to search for
|
||||||
*
|
* @return the index in this list of the first occurrence of the specified
|
||||||
* @return the index in this list of the first occurrence of the specified element, or -1 if
|
* element, or -1 if this list does not contain this element.
|
||||||
* this list does not contain this element.
|
|
||||||
*
|
*
|
||||||
* @pre c != null
|
* @pre c != null
|
||||||
* @post contains(c) implies (return >= 0) && (return < size())
|
* @post contains(c) implies (return >= 0) && (return < size())
|
||||||
* @pos
|
* @post !contains(c) implies return == -1
|
||||||
* t !contains(c) implies return == -1
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int indexOf(Component c) {
|
public int indexOf(Component c) {
|
||||||
|
|
@ -368,8 +378,8 @@ public class Page extends BlockStylable implements Container {
|
||||||
/**
|
/**
|
||||||
* Returns <code>true</code> if the container contains no components.
|
* Returns <code>true</code> if the container contains no components.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if this container contains no * * components; <code>false</code>
|
* @return <code>true</code> if this container contains no components;
|
||||||
* otherwise.
|
* <code>false</code> otherwise.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
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
|
* Returns the number of elements in this container. This does not
|
||||||
* components that are indirectly contained in this container.
|
* recursively count the components that are indirectly contained in this
|
||||||
|
* container.
|
||||||
*
|
*
|
||||||
* @return the number of components directly 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 the <code>Page</code> uses for rendering its components.
|
* Returns the panel that the <code>Page</code> uses for rendering its
|
||||||
|
* components.
|
||||||
*
|
*
|
||||||
* @return the panel.
|
* @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
|
* Set the Container used for rendering components on this page. Caution
|
||||||
* this function, as the existing container is simply overwritten.
|
* should be used with this function, as the existing container is simply
|
||||||
|
* overwritten.
|
||||||
*
|
*
|
||||||
|
* @param c
|
||||||
* @author Matthew Booth (mbooth@redhat.com)
|
* @author Matthew Booth (mbooth@redhat.com)
|
||||||
*/
|
*/
|
||||||
public void setPanel(Container c) {
|
public void setPanel(Container c) {
|
||||||
|
|
@ -412,8 +426,7 @@ public class Page extends BlockStylable implements Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* Retrieves the title of this page.
|
||||||
* Retrieves the title of this page. </p>
|
|
||||||
*
|
*
|
||||||
* @return the static 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.
|
* Retrieves the title of this page as a Bebop label component.
|
||||||
*
|
*
|
||||||
* @param state the state of the current request
|
* @param state the state of the current request
|
||||||
*
|
|
||||||
* @return the title of the page for the current request.
|
* @return the title of the page for the current request.
|
||||||
*/
|
*/
|
||||||
public final Label getTitle(PageState state) {
|
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
|
* Sets the {@link Component} that will display the validation errors in the
|
||||||
* {@link PageState}. Any validation error in the <code>PageState</code> will cause the
|
* current {@link PageState}. Any validation error in the
|
||||||
* <code>Page</code> to completely ignore all other components and render only the error display
|
* <code>PageState</code> will cause the <code>Page</code> to completely
|
||||||
* component.
|
* ignore all other components and render only the error display component.
|
||||||
* <p>
|
* <p>
|
||||||
* 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
|
* @param c the component that will display the validation errors in the current
|
||||||
* <code>PageState</code>
|
* <code>PageState</code>
|
||||||
|
|
@ -469,12 +482,13 @@ public class Page extends BlockStylable implements Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link Component} that will display the validation errors in the current
|
* Gets the {@link Component} that will display the validation errors in the
|
||||||
* {@link PageState}. Any validation error in the <code>PageState</code> will cause the
|
* current {@link PageState}. Any validation error in the
|
||||||
* <code>Page</code> to completely ignore all other components and render only the error display
|
* <code>PageState</code> will cause the <code>Page</code> to completely
|
||||||
* component.
|
* ignore all other components and render only the error display component.
|
||||||
* <p>
|
* <p>
|
||||||
* 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
|
* @return the component that will display the validation errors in the current
|
||||||
* <code>PageState</code>.
|
* <code>PageState</code>.
|
||||||
|
|
@ -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
|
* Adds a client-side stylesheet that should be used in HTML output.
|
||||||
* client-side stylesheets can be added with this method. To use a CSS stylesheet, call
|
* Arbitrarily many client-side stylesheets can be added with this method.
|
||||||
* something like <code>setStyleSheet("style.css", "text/css")</code>.
|
* To use a CSS stylesheet, call something like
|
||||||
|
* <code>setStyleSheet("style.css", "text/css")</code>.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* These values will ultimately wind up in a <tt><link></tt>
|
* These values will ultimately wind up in a <tt><link></tt>
|
||||||
* tag in the head of the HTML page.
|
* tag in the head of the HTML page.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Note that the stylesheet set with this call has nothing to do with the XSLT stylesheet
|
* Note that the stylesheet set with this call has nothing to do with the
|
||||||
* (transformer) that is applied to the XML generated from this page!
|
* XSLT stylesheet (transformer) that is applied to the XML generated from
|
||||||
|
* this page!
|
||||||
*
|
*
|
||||||
* @param styleSheetURI the location of the stylesheet
|
* @param styleSheetURI the location of the stylesheet
|
||||||
* @param mimeType the MIME type of the stylesheet, usually
|
* @param mimeType the MIME type of the stylesheet, usually
|
||||||
* <tt>text/css</tt>
|
* <tt>text/css</tt>
|
||||||
*
|
*
|
||||||
* @pre ! isLocked()
|
* @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
|
* Adds a global state parameter to this page. Global parameters are values
|
||||||
* preserved between requests, but that have no special connection to any of the components on
|
* that need to be preserved between requests, but that have no special
|
||||||
* the page. For a page that displays details about an item, a global parameter would be used to
|
* connection to any of the components on the page. For a page that displays
|
||||||
* identify the item.
|
* details about an item, a global parameter would be used to identify the
|
||||||
*
|
* item.
|
||||||
* <p>
|
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
|
* If the parameter was previously added as a component state parameter, its
|
||||||
|
* name is unmangled and stays unmangled.
|
||||||
* @see #addComponentStateParam
|
* @see #addComponentStateParam
|
||||||
*
|
*
|
||||||
|
* @param p the global parameter to add
|
||||||
* @pre ! isLocked()
|
* @pre ! isLocked()
|
||||||
* @pre parameter != null
|
* @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)
|
* Constructs the top nodes of the DOM or JDOM tree. Used by
|
||||||
* below.
|
* generateXML(PageState, Document) below.
|
||||||
* <p>
|
* <p>
|
||||||
* Generates DOM fragment:
|
* Generates DOM fragment:
|
||||||
* <pre>
|
* <pre>
|
||||||
|
|
@ -541,12 +555,13 @@ public class Page extends BlockStylable implements Container {
|
||||||
* ... page content gnerated by children ...
|
* ... page content gnerated by children ...
|
||||||
* </bebop:page></pre> The content of the <tt><title></tt>
|
* </bebop:page></pre> The content of the <tt><title></tt>
|
||||||
* element can be set by calling {@link #setTitle setTitle}. The
|
* element can be set by calling {@link #setTitle setTitle}. The
|
||||||
* <tt><stylesheet></tt> element will only be present if a stylesheet has been set with {@link
|
* <tt><stylesheet></tt> element will only be present if a stylesheet
|
||||||
|
* has been set with {@link
|
||||||
* #setStyleSheet setStyleSheet}.
|
* #setStyleSheet setStyleSheet}.
|
||||||
*
|
*
|
||||||
* @param ps the page state for the current page
|
* @param ps the page state for the current page
|
||||||
* @param parent the DOM node for the whole Document
|
* @param parent the DOM node for the whole Document
|
||||||
*
|
* @return
|
||||||
* @pre isLocked()
|
* @pre isLocked()
|
||||||
*/
|
*/
|
||||||
protected Element generateXMLHelper(PageState ps, Document parent) {
|
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
|
* Constructs a DOM or JDOM tree with all components on the page. The tree
|
||||||
* that results from the {@link javax.servlet.http.HttpServletRequest} kept in the
|
* represents the page that results from the
|
||||||
|
* {@link javax.servlet.http.HttpServletRequest} kept in the
|
||||||
* <code>state</code>.
|
* <code>state</code>.
|
||||||
*
|
*
|
||||||
* @param state the page state produced by {@link #process}
|
* @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.
|
* Do nothing. Top-level add nodes is meaningless.
|
||||||
|
*
|
||||||
|
* @param elt
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void generateXML(PageState state, Element elt) {
|
public void generateXML(PageState state, Element elt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a PageState object and processes it by calling the respond method on the selected
|
* Creates a PageState object and processes it by calling the respond method
|
||||||
* component. Processes a request by notifying the component from which the process originated
|
* on the selected component. Processes a request by notifying the component
|
||||||
* and {@link #fireActionEvent
|
* from which the process originated and {@link #fireActionEvent
|
||||||
* broadcasts} an {@link ActionEvent} to all the listeners that registered with
|
* broadcasts} an {@link ActionEvent} to all the listeners that registered
|
||||||
* {@link #addActionListener addActionListener}.
|
* with {@link #addActionListener addActionListener}.
|
||||||
*
|
|
||||||
* @see #generateXML(PageState,Document) generateXML
|
* @see #generateXML(PageState,Document) generateXML
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param response
|
||||||
|
* @return
|
||||||
|
* @throws javax.servlet.ServletException
|
||||||
* @pre isLocked()
|
* @pre isLocked()
|
||||||
* @pre request != null
|
* @pre request != null
|
||||||
* @pre response != 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
|
* Builds a DOM Document from the current request state by doing a
|
||||||
* current set of components in this Page, calling generateXML on each. Does NOT do the
|
* depth-first tree walk on the current set of components in this Page,
|
||||||
* rendering. If the HTTP response has already been committed, does not build the XML document.
|
* 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.
|
|
||||||
*
|
*
|
||||||
|
* @return a DOM ready for rendering, or null if the response has already
|
||||||
|
* been committed.
|
||||||
* @post res.isCommitted() == (return == null)
|
* @post res.isCommitted() == (return == null)
|
||||||
*/
|
*/
|
||||||
public Document buildDocument(HttpServletRequest req,
|
public Document buildDocument(HttpServletRequest req,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@ public class FormSectionEvent extends PageEvent {
|
||||||
* @param state the state of the enclosing page
|
* @param state the state of the enclosing page
|
||||||
* @param formData the form data constructed so far
|
* @param formData the form data constructed so far
|
||||||
*/
|
*/
|
||||||
public FormSectionEvent(Object source, PageState state,
|
public FormSectionEvent(Object source,
|
||||||
|
PageState state,
|
||||||
FormData formData) {
|
FormData formData) {
|
||||||
super(source, state);
|
super(source, state);
|
||||||
_formData = formData;
|
_formData = formData;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import java.util.EventListener;
|
||||||
* @author Uday Mathur
|
* @author Uday Mathur
|
||||||
* @version $Id: FormValidationListener.java 287 2005-02-22 00:29:02Z sskracic $
|
* @version $Id: FormValidationListener.java 287 2005-02-22 00:29:02Z sskracic $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public interface FormValidationListener extends EventListener {
|
public interface FormValidationListener extends EventListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,23 +48,14 @@ public interface FormValidationListener extends EventListener {
|
||||||
* be handled internally, or if they are unrecoverable may be
|
* be handled internally, or if they are unrecoverable may be
|
||||||
* rethrown as instances of <code>FormProcessException</code>.
|
* rethrown as instances of <code>FormProcessException</code>.
|
||||||
*
|
*
|
||||||
* @param model The form model describing the structure and properties
|
* @param e FormSectionEvent containing the FormData as well as the
|
||||||
* of the form data included with this request. The validation procedure
|
* PageState.
|
||||||
* may require knowledge of form or parameter properties to complete.
|
* 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
|
* @exception FormProcessException ff the data does not pass the check.
|
||||||
* 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. */
|
|
||||||
|
|
||||||
void validate(FormSectionEvent e) throws FormProcessException;
|
void validate(FormSectionEvent e) throws FormProcessException;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,8 @@ import com.arsdigita.bebop.FormProcessException;
|
||||||
import java.util.EventListener;
|
import java.util.EventListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the interface
|
* Defines the interface for a class that validates the values of a
|
||||||
* for a class that validates the values of a single parameter.
|
* single parameter.
|
||||||
*
|
*
|
||||||
* @author Karl Goldstein
|
* @author Karl Goldstein
|
||||||
* @author Uday Mathur
|
* @author Uday Mathur
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.bebop.form;
|
package com.arsdigita.bebop.form;
|
||||||
|
|
||||||
|
|
||||||
import com.arsdigita.bebop.event.PageEvent;
|
import com.arsdigita.bebop.event.PageEvent;
|
||||||
import com.arsdigita.bebop.event.PrintEvent;
|
import com.arsdigita.bebop.event.PrintEvent;
|
||||||
import com.arsdigita.bebop.event.PrintListener;
|
import com.arsdigita.bebop.event.PrintListener;
|
||||||
|
|
@ -41,25 +40,25 @@ import java.util.TooManyListenersException;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search and select Bebop widget. This widget is used to allow a user to
|
* Search and select Bebop widget. This widget is used to allow a user to search
|
||||||
* search for a particular item over a potentially very large set. Depending
|
* for a particular item over a potentially very large set. Depending on the
|
||||||
* on the size of the dataset, the user will either see a search box or a
|
* size of the dataset, the user will either see a search box or a selection box
|
||||||
* selection box (with all valid items). The search box will then change to
|
* (with all valid items). The search box will then change to a selection box
|
||||||
* a selection box once the user submits the form, allowing them then to
|
* once the user submits the form, allowing them then to choose the items they
|
||||||
* choose the items they desire.
|
* desire.
|
||||||
* <p>
|
* <p>
|
||||||
* The datasource for SearchAndSelect is provided by an implentation of the
|
* 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
|
* @author Patrick McNeill
|
||||||
* @version $Id: SearchAndSelect.java 287 2005-02-22 00:29:02Z sskracic $
|
* @version $Id: SearchAndSelect.java 287 2005-02-22 00:29:02Z sskracic $
|
||||||
* @since 4.5
|
* @since 4.5
|
||||||
*/
|
*/
|
||||||
public class SearchAndSelect extends FormSection
|
public class SearchAndSelect extends FormSection
|
||||||
implements BebopConstants, PrintListener {
|
implements BebopConstants, PrintListener {
|
||||||
|
|
||||||
private static final Logger s_cat =
|
private static final Logger s_cat
|
||||||
Logger.getLogger(SearchAndSelect.class);
|
= Logger.getLogger(SearchAndSelect.class);
|
||||||
|
|
||||||
protected String m_name;
|
protected String m_name;
|
||||||
// name of this super-widget
|
// name of this super-widget
|
||||||
|
|
@ -92,7 +91,7 @@ public class SearchAndSelect extends FormSection
|
||||||
protected Object m_this = this;
|
protected Object m_this = this;
|
||||||
// so "this" will work in my anonymous inner classes
|
// so "this" will work in my anonymous inner classes
|
||||||
|
|
||||||
protected TextField m_outputTextWidget;
|
protected TextField m_outputTextWidget;
|
||||||
protected Widget m_outputSelectWidget;
|
protected Widget m_outputSelectWidget;
|
||||||
// internal widgets used render either a text box, a checkbox, or a select
|
// 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
|
* Creates the output widgets and adds them all to the form
|
||||||
*/
|
*/
|
||||||
private void initializeOutputWidget () {
|
private void initializeOutputWidget() {
|
||||||
m_oldValueWidget = new Hidden(getName() + ".oldvalue");
|
m_oldValueWidget = new Hidden(getName() + ".oldvalue");
|
||||||
add(m_oldValueWidget);
|
add(m_oldValueWidget);
|
||||||
|
|
||||||
m_outputTextWidget = new TextField(getName() + ".text");
|
m_outputTextWidget = new TextField(getName() + ".text");
|
||||||
add(m_outputTextWidget);
|
add(m_outputTextWidget);
|
||||||
|
|
||||||
if ( m_isMultiple ) {
|
if (m_isMultiple) {
|
||||||
if ( m_useCheckboxes ) {
|
if (m_useCheckboxes) {
|
||||||
m_outputSelectWidget = new CheckboxGroup(getName() + ".select");
|
m_outputSelectWidget = new CheckboxGroup(getName() + ".select");
|
||||||
} else {
|
} else {
|
||||||
m_outputSelectWidget =
|
m_outputSelectWidget
|
||||||
new MultipleSelect(getName() + ".select");
|
= new MultipleSelect(getName() + ".select");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_outputSelectWidget = new SingleSelect(getName() + ".select");
|
m_outputSelectWidget = new SingleSelect(getName() + ".select");
|
||||||
|
|
@ -138,31 +137,31 @@ public class SearchAndSelect extends FormSection
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepare(PrintEvent e) {
|
public void prepare(PrintEvent e) {
|
||||||
if ( m_results == null ) {
|
if (m_results == null) {
|
||||||
m_results = m_listener.getModel(new PageEvent(this, e.getPageState()));
|
m_results = m_listener.getModel(new PageEvent(this, e.getPageState()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_results == null ) {
|
if (m_results == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_results.setQuery ( m_query );
|
m_results.setQuery(m_query);
|
||||||
|
|
||||||
if ( m_isSearchLocked ||
|
if (m_isSearchLocked
|
||||||
( ( ( ! m_oldValue.equals("") &&
|
|| (((!m_oldValue.equals("")
|
||||||
m_oldValue.equals(m_value) ) ||
|
&& m_oldValue.equals(m_value))
|
||||||
( m_maxViewableResults >= m_results.resultsCount() ) ) &&
|
|| (m_maxViewableResults >= m_results.resultsCount()))
|
||||||
( m_results.resultsCount() > 0 ) ) ) {
|
&& (m_results.resultsCount() > 0))) {
|
||||||
|
|
||||||
OptionGroup outputWidget = (OptionGroup)e.getTarget();
|
OptionGroup outputWidget = (OptionGroup) e.getTarget();
|
||||||
|
|
||||||
if ( m_isOptional && ! m_isMultiple ) {
|
if (m_isOptional && !m_isMultiple) {
|
||||||
outputWidget.addOption( new Option ( "", "None" ) );
|
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(
|
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));
|
s_cat.debug(" " + m_results.getID(i));
|
||||||
}
|
}
|
||||||
|
|
@ -174,8 +173,8 @@ public class SearchAndSelect extends FormSection
|
||||||
*
|
*
|
||||||
* @param name the name of the widget
|
* @param name the name of the widget
|
||||||
*/
|
*/
|
||||||
public SearchAndSelect ( String name ) {
|
public SearchAndSelect(String name) {
|
||||||
this( name, false, false );
|
this(name, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -186,9 +185,9 @@ public class SearchAndSelect extends FormSection
|
||||||
* @param isMultiple whether or not the widget accepts multiple values
|
* @param isMultiple whether or not the widget accepts multiple values
|
||||||
* @param useCheckboxes use checkboxes or a multiselect
|
* @param useCheckboxes use checkboxes or a multiselect
|
||||||
*/
|
*/
|
||||||
public SearchAndSelect ( String name,
|
public SearchAndSelect(String name,
|
||||||
boolean isMultiple ) {
|
boolean isMultiple) {
|
||||||
this( name, isMultiple, false );
|
this(name, isMultiple, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -199,9 +198,9 @@ public class SearchAndSelect extends FormSection
|
||||||
* @param isMultiple whether or not the widget accepts multiple values
|
* @param isMultiple whether or not the widget accepts multiple values
|
||||||
* @param useCheckboxes use checkboxes or a multiselect
|
* @param useCheckboxes use checkboxes or a multiselect
|
||||||
*/
|
*/
|
||||||
public SearchAndSelect ( String name,
|
public SearchAndSelect(String name,
|
||||||
boolean isMultiple,
|
boolean isMultiple,
|
||||||
boolean useCheckboxes ) {
|
boolean useCheckboxes) {
|
||||||
|
|
||||||
super(new SimpleContainer());
|
super(new SimpleContainer());
|
||||||
|
|
||||||
|
|
@ -218,103 +217,103 @@ public class SearchAndSelect extends FormSection
|
||||||
* that the error messages generated here are not displayed to the
|
* that the error messages generated here are not displayed to the
|
||||||
* user as the error field is also used as a help field.
|
* user as the error field is also used as a help field.
|
||||||
*/
|
*/
|
||||||
super.addValidationListener ( new FormValidationListener() {
|
super.addValidationListener(new FormValidationListener() {
|
||||||
public void validate ( FormSectionEvent e ) {
|
@Override
|
||||||
FormData data = e.getFormData();
|
public void validate(FormSectionEvent e) {
|
||||||
|
FormData data = e.getFormData();
|
||||||
|
|
||||||
m_results = m_listener.getModel(
|
m_results = m_listener.getModel(
|
||||||
new PageEvent(m_this, e.getPageState()));
|
new PageEvent(m_this, e.getPageState()));
|
||||||
|
|
||||||
if ( m_results == null ) {
|
if (m_results == null) {
|
||||||
return;
|
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);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
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
|
public final void setSearchAndSelectListener(SearchAndSelectListener listener) {
|
||||||
(SearchAndSelectListener listener) {
|
|
||||||
m_listener = listener;
|
m_listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,38 +322,38 @@ public class SearchAndSelect extends FormSection
|
||||||
*
|
*
|
||||||
* @return the name of the widget
|
* @return the name of the widget
|
||||||
*/
|
*/
|
||||||
public final String getName () {
|
public final String getName() {
|
||||||
return m_name;
|
return m_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal function to retrieve a single text value for the widget.
|
* Internal function to retrieve a single text value for the widget.
|
||||||
*/
|
*/
|
||||||
private String getTextValue ( PageState state ) {
|
private String getTextValue(PageState state) {
|
||||||
if ( m_value != null ) {
|
if (m_value != null) {
|
||||||
return m_value;
|
return m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_isSearchLocked ) {
|
if (m_isSearchLocked) {
|
||||||
if ( m_isMultiple ) {
|
if (m_isMultiple) {
|
||||||
return ((String[])m_outputSelectWidget.getValue(state))[0];
|
return ((String[]) m_outputSelectWidget.getValue(state))[0];
|
||||||
} else {
|
} else {
|
||||||
return (String)m_outputSelectWidget.getValue(state);
|
return (String) m_outputSelectWidget.getValue(state);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return (String)m_outputTextWidget.getValue(state);
|
return (String) m_outputTextWidget.getValue(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the type of HTML form element to create.
|
* Determine the type of HTML form element to create. This will not
|
||||||
* This will not necessarily be accurate until generateWidget is called
|
* necessarily be accurate until generateWidget is called as the query will
|
||||||
* as the query will be unavailable until that point.
|
* be unavailable until that point.
|
||||||
*
|
*
|
||||||
* @return "text" or "select" depending on the result size
|
* @return "text" or "select" depending on the result size
|
||||||
*/
|
*/
|
||||||
public String getType () {
|
public String getType() {
|
||||||
if ( m_isSearchLocked ) {
|
if (m_isSearchLocked) {
|
||||||
return m_outputSelectWidget.getType();
|
return m_outputSelectWidget.getType();
|
||||||
} else {
|
} else {
|
||||||
return "text";
|
return "text";
|
||||||
|
|
@ -366,7 +365,7 @@ public class SearchAndSelect extends FormSection
|
||||||
*
|
*
|
||||||
* @return boolean -- true for multiple, false for single
|
* @return boolean -- true for multiple, false for single
|
||||||
*/
|
*/
|
||||||
public final boolean isMultiple () {
|
public final boolean isMultiple() {
|
||||||
return m_isMultiple;
|
return m_isMultiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,7 +374,7 @@ public class SearchAndSelect extends FormSection
|
||||||
*
|
*
|
||||||
* @return true for optional, false otherwise
|
* @return true for optional, false otherwise
|
||||||
*/
|
*/
|
||||||
public final boolean isOptional () {
|
public final boolean isOptional() {
|
||||||
return m_isOptional;
|
return m_isOptional;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -384,96 +383,96 @@ public class SearchAndSelect extends FormSection
|
||||||
*
|
*
|
||||||
* @param isOptional true for optional, false for required
|
* @param isOptional true for optional, false for required
|
||||||
*/
|
*/
|
||||||
public SearchAndSelect setOptional ( boolean isOptional ) {
|
public SearchAndSelect setOptional(boolean isOptional) {
|
||||||
m_isOptional = isOptional;
|
m_isOptional = isOptional;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates if the widget is composed of multiple HTML elements.
|
* Indicates if the widget is composed of multiple HTML elements. Always
|
||||||
* Always returns true, as the widget makes use of a hidden element and
|
* returns true, as the widget makes use of a hidden element and another
|
||||||
* another element.
|
* element.
|
||||||
*
|
*
|
||||||
* @return true
|
* @return true
|
||||||
*/
|
*/
|
||||||
public boolean isCompound () {
|
public boolean isCompound() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the XML datastructure for this widget. Adds a hidden,
|
* Generates the XML datastructure for this widget. Adds a hidden, a
|
||||||
* a textbox, checkbox group, or select, and possibly some number of
|
* textbox, checkbox group, or select, and possibly some number of
|
||||||
* formErrors.
|
* formErrors.
|
||||||
*
|
*
|
||||||
* @param state the state of the page
|
* @param state the state of the page
|
||||||
* @param parent the parent widget
|
* @param parent the parent widget
|
||||||
*/
|
*/
|
||||||
public void generateXML( PageState state, Element parent ) {
|
public void generateXML(PageState state, Element parent) {
|
||||||
if ( m_results == null ) {
|
if (m_results == null) {
|
||||||
m_results = m_listener.getModel(new PageEvent(this, state));
|
m_results = m_listener.getModel(new PageEvent(this, state));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_results == null ) {
|
if (m_results == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_isSearchLocked ||
|
if (m_isSearchLocked
|
||||||
( ( ( ! m_oldValue.equals("") &&
|
|| (((!m_oldValue.equals("")
|
||||||
m_oldValue.equals(m_value) ) ||
|
&& m_oldValue.equals(m_value))
|
||||||
( m_maxViewableResults >= m_results.resultsCount() ) ) &&
|
|| (m_maxViewableResults >= m_results.resultsCount()))
|
||||||
( m_results.resultsCount() > 0 ) ) ) {
|
&& (m_results.resultsCount() > 0))) {
|
||||||
m_outputSelectWidget.generateXML ( state, parent );
|
m_outputSelectWidget.generateXML(state, parent);
|
||||||
} else {
|
} 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
|
* Generate the error messages for this widget. This widget has some
|
||||||
* specialized error messages, so it is necessary to override the
|
* specialized error messages, so it is necessary to override the default
|
||||||
* default error generator. Basically, the m_results field won't be
|
* error generator. Basically, the m_results field won't be available
|
||||||
* available outside this class, so this needs to be internal.
|
* outside this class, so this needs to be internal.
|
||||||
*
|
*
|
||||||
* @param state the state of the page
|
* @param state the state of the page
|
||||||
* @param parent the parent widget
|
* @param parent the parent widget
|
||||||
*/
|
*/
|
||||||
protected void generateErrors ( PageState state, Element parent ) {
|
protected void generateErrors(PageState state, Element parent) {
|
||||||
String curValue = getTextValue(state);
|
String curValue = getTextValue(state);
|
||||||
|
|
||||||
if ( m_results == null ) {
|
if (m_results == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_results.resultsCount() > m_maxViewableResults ) {
|
if (m_results.resultsCount() > m_maxViewableResults) {
|
||||||
|
|
||||||
Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS);
|
Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS);
|
||||||
|
|
||||||
if ( ( curValue == null ) || ( curValue.equals("") ) ) {
|
if ((curValue == null) || (curValue.equals(""))) {
|
||||||
error.addAttribute("message",
|
error.addAttribute("message",
|
||||||
"Please enter a comma-delimited search");
|
"Please enter a comma-delimited search");
|
||||||
} else if ( ( ! m_oldValue.equals( curValue ) ) &&
|
} else if ((!m_oldValue.equals(curValue))
|
||||||
! m_isSearchLocked ) {
|
&& !m_isSearchLocked) {
|
||||||
error.addAttribute("message",
|
error.addAttribute("message",
|
||||||
"Your search returned " +
|
"Your search returned "
|
||||||
m_results.resultsCount() +" matches. " +
|
+ m_results.resultsCount() + " matches. "
|
||||||
"Please refine your search or leave the " +
|
+ "Please refine your search or leave the "
|
||||||
"search as it is to see all results.");
|
+ "search as it is to see all results.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_results.resultsCount() == 0 ) {
|
if (m_results.resultsCount() == 0) {
|
||||||
if ( !curValue.equals("") ) {
|
if (!curValue.equals("")) {
|
||||||
Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS);
|
Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS);
|
||||||
error.addAttribute("message",
|
error.addAttribute("message",
|
||||||
"Your search returned no matches. Please " +
|
"Your search returned no matches. Please "
|
||||||
"try again");
|
+ "try again");
|
||||||
} else {
|
} else {
|
||||||
Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS);
|
Element error = parent.newChildElement("bebop:formErrors", BEBOP_XML_NS);
|
||||||
error.addAttribute("message", "WARNING -- NO DATA FOUND");
|
error.addAttribute("message", "WARNING -- NO DATA FOUND");
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ import com.arsdigita.bebop.parameters.ParameterModel;
|
||||||
import com.arsdigita.bebop.parameters.StringParameter;
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
import com.arsdigita.bebop.util.BebopConstants;
|
import com.arsdigita.bebop.util.BebopConstants;
|
||||||
import com.arsdigita.globalization.GlobalizedMessage;
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
import com.arsdigita.kernel.Kernel;
|
// import com.arsdigita.kernel.Kernel;
|
||||||
import com.arsdigita.util.Assert;
|
import com.arsdigita.util.Assert;
|
||||||
import com.arsdigita.xml.Element;
|
import com.arsdigita.xml.Element;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ public abstract class GlobalizedParameterListener
|
||||||
return BUNDLE_NAME;
|
return BUNDLE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the error message for this parameter.
|
* Set the error message for this parameter.
|
||||||
*
|
*
|
||||||
|
|
@ -56,6 +55,7 @@ public abstract class GlobalizedParameterListener
|
||||||
protected void setError(GlobalizedMessage error) {
|
protected void setError(GlobalizedMessage error) {
|
||||||
m_error = error;
|
m_error = error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the error message for this parameter.
|
* Get the error message for this parameter.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -24,39 +24,61 @@ import com.arsdigita.bebop.event.ParameterEvent;
|
||||||
import com.arsdigita.globalization.GlobalizedMessage;
|
import com.arsdigita.globalization.GlobalizedMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the parameter's value is non-empty.
|
* Verifies that the parameter's value is non-empty.
|
||||||
* A value is considererd non-empty if it exists in the page state,
|
* A value is considererd non-empty if it exists in the page state,
|
||||||
* and it contains some data besides whitespace.
|
* and it contains some data besides whitespace.
|
||||||
*
|
*
|
||||||
* @author Karl Goldstein
|
* @author Karl Goldstein
|
||||||
* @author Uday Mathur
|
* @author Uday Mathur
|
||||||
* @author Stas Freidin
|
* @author Stas Freidin
|
||||||
* @author Rory Solomon
|
* @author Rory Solomon
|
||||||
* @author Bill Schneider
|
* @author Bill Schneider
|
||||||
* @version $Id: NotEmptyValidationListener.java 1502 2007-03-20 11:38:53Z chrisgilbert23 $
|
* @version $Id: NotEmptyValidationListener.java 1502 2007-03-20 11:38:53Z chrisgilbert23 $
|
||||||
*/
|
*/
|
||||||
public class NotEmptyValidationListener extends GlobalizedParameterListener {
|
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) {
|
public NotEmptyValidationListener(String label) {
|
||||||
setError(new GlobalizedMessage(label, getBundleBaseName()));
|
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) {
|
public NotEmptyValidationListener(GlobalizedMessage error) {
|
||||||
setError(error);
|
setError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate Method required and used to validate input.
|
||||||
|
*
|
||||||
|
* @param e ParameterEvent containing the data
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
public void validate (ParameterEvent e) {
|
public void validate (ParameterEvent e) {
|
||||||
|
|
||||||
ParameterData data = e.getParameterData();
|
ParameterData data = e.getParameterData();
|
||||||
Object value = data.getValue();
|
Object value = data.getValue();
|
||||||
|
|
||||||
if (value != null) {
|
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('\u00A0'));
|
||||||
valueString = StringUtils.strip(valueString, Character.toString('\u2007'));
|
valueString = StringUtils.strip(valueString, Character.toString('\u2007'));
|
||||||
if (valueString.length() > 0) {
|
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());
|
data.addError(getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,14 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 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 class NotWhiteSpaceValidationListener extends NotEmptyValidationListener {
|
||||||
|
|
||||||
public NotWhiteSpaceValidationListener(String title) {
|
public NotWhiteSpaceValidationListener(String title) {
|
||||||
|
|
@ -32,10 +32,11 @@ public class NotWhiteSpaceValidationListener extends NotEmptyValidationListener
|
||||||
|
|
||||||
public NotWhiteSpaceValidationListener() {
|
public NotWhiteSpaceValidationListener() {
|
||||||
setError(new GlobalizedMessage
|
setError(new GlobalizedMessage
|
||||||
("parameter_is_required", getBundleBaseName()));
|
("bebop.parameters.parameter_is_required", getBundleBaseName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotWhiteSpaceValidationListener(GlobalizedMessage error) {
|
public NotWhiteSpaceValidationListener(GlobalizedMessage error) {
|
||||||
setError(error);
|
setError(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
@ -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_empty_or_not_found=is empty or was not found.
|
||||||
file_too_large=is too large
|
file_too_large=is too large
|
||||||
uri_parameter_is_invalid=This parameter must be a URI formatted according to RFC2396
|
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.
|
||||||
|
|
|
||||||
|
|
@ -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_empty_or_not_found=ist leer oder wurde nicht gefunden.
|
||||||
file_too_large=ist zu gro\u00df
|
file_too_large=ist zu gro\u00df
|
||||||
uri_parameter_is_invalid=Dieser Parameter muss ein URI sein, das entsprechend RFC2396 formatiert wird
|
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!
|
||||||
|
|
|
||||||
|
|
@ -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_empty_or_not_found=is empty or was not found.
|
||||||
file_too_large=is too large
|
file_too_large=is too large
|
||||||
uri_parameter_is_invalid=This parameter must be a URI formatted according to RFC2396
|
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.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
bebop.parameters.parameter_is_required=Este par\u00e1metro es requerido
|
bebop.parameters.parameter_is_required=Este par\u00e1metro es requerido
|
||||||
string_in_range=Este par\u00e1metro no tiene entre {0} y {1} caracteres
|
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}
|
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.
|
||||||
|
|
|
||||||
|
|
@ -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}
|
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}
|
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
|
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.
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,9 @@ public class GlobalizedMessage {
|
||||||
* @param args An Object[] of arguments to interpolate into the retrieved
|
* @param args An Object[] of arguments to interpolate into the retrieved
|
||||||
* message.
|
* 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);
|
this(key, bundleName);
|
||||||
setArgs(args);
|
setArgs(args);
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +178,8 @@ public class GlobalizedMessage {
|
||||||
* GlobalizedObject?
|
* GlobalizedObject?
|
||||||
*/
|
*/
|
||||||
public Object localize() {
|
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?
|
* GlobalizedObject?
|
||||||
*/
|
*/
|
||||||
public Object localize(final HttpServletRequest request) {
|
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 {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>For debugging, not for localizing!</p>
|
* For debugging, not for localizing.
|
||||||
*
|
*
|
||||||
* If you need a String, use an additional localize() to get an object
|
* If you need a String, use an additional localize() to get an object
|
||||||
* and cast it to String. e.g.
|
* and cast it to String. e.g.
|
||||||
|
|
|
||||||
|
|
@ -65,9 +65,9 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
|
||||||
protected TextField m_url;
|
protected TextField m_url;
|
||||||
protected TextField m_screenName;
|
protected TextField m_screenName;
|
||||||
protected EmailList m_emailList;
|
protected EmailList m_emailList;
|
||||||
private PasswordValidationListener m_pwListener;
|
private final PasswordValidationListener m_pwListener;
|
||||||
private NotEmptyValidationListener m_notNullListener;
|
private final NotEmptyValidationListener m_notNullListener;
|
||||||
private SecurityConfig securityConfig = SecurityConfig.getConfig();
|
private final SecurityConfig securityConfig = SecurityConfig.getConfig();
|
||||||
|
|
||||||
public UserForm(String formName) {
|
public UserForm(String formName) {
|
||||||
super(formName);
|
super(formName);
|
||||||
|
|
@ -184,6 +184,7 @@ class UserForm extends Form implements FormValidationListener, AdminConstants {
|
||||||
* password-confirm field. Also verifies that primary email
|
* password-confirm field. Also verifies that primary email
|
||||||
* address and screen name are unique amoung all users.
|
* address and screen name are unique amoung all users.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void validate(FormSectionEvent event)
|
public void validate(FormSectionEvent event)
|
||||||
throws FormProcessException {
|
throws FormProcessException {
|
||||||
PageState ps = event.getPageState();
|
PageState ps = event.getPageState();
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ public class Web {
|
||||||
/**
|
/**
|
||||||
* Processes an URL String trying to identify a corresponding recource
|
* Processes an URL String trying to identify a corresponding recource
|
||||||
* which is mapped to the given path String. The method ensures that the
|
* 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).
|
* (returning null).
|
||||||
*
|
*
|
||||||
* The resourcePath may be stored at various sources (file system, jar file,
|
* The resourcePath may be stored at various sources (file system, jar file,
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,10 @@
|
||||||
*/
|
*/
|
||||||
package com.arsdigita.simplesurvey.ui.admin;
|
package com.arsdigita.simplesurvey.ui.admin;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
import com.arsdigita.bebop.event.FormProcessListener;
|
import com.arsdigita.bebop.event.FormProcessListener;
|
||||||
import com.arsdigita.bebop.event.FormInitListener;
|
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.Form;
|
||||||
import com.arsdigita.bebop.FormProcessException;
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
import com.arsdigita.bebop.PageState;
|
import com.arsdigita.bebop.PageState;
|
||||||
|
|
@ -42,22 +40,20 @@ import com.arsdigita.simplesurvey.Survey;
|
||||||
import com.arsdigita.simplesurvey.Poll;
|
import com.arsdigita.simplesurvey.Poll;
|
||||||
// import com.arsdigita.simplesurvey.SimpleSurveyUtil;
|
// import com.arsdigita.simplesurvey.SimpleSurveyUtil;
|
||||||
import com.arsdigita.simplesurvey.ui.SurveySelectionModel;
|
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.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PropertiesForm extends Form {
|
public class PropertiesForm extends Form {
|
||||||
|
|
||||||
private SurveySelectionModel m_survey;
|
private SurveySelectionModel m_survey;
|
||||||
private Class m_type;
|
private Class m_type;
|
||||||
|
|
||||||
|
|
||||||
private TextField m_surveyName;
|
private TextField m_surveyName;
|
||||||
private TextArea m_description;
|
private TextArea m_description;
|
||||||
private Date m_startDate;
|
private Date m_startDate;
|
||||||
|
|
@ -65,26 +61,31 @@ public class PropertiesForm extends Form {
|
||||||
private RadioGroup m_responsesPublic;
|
private RadioGroup m_responsesPublic;
|
||||||
private RadioGroup m_quizType;
|
private RadioGroup m_quizType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param survey
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
public PropertiesForm(SurveySelectionModel survey,
|
public PropertiesForm(SurveySelectionModel survey,
|
||||||
Class type) {
|
Class type) {
|
||||||
|
|
||||||
super("properties" + type.getName());
|
super("properties" + type.getName());
|
||||||
|
|
||||||
m_survey = survey;
|
m_survey = survey;
|
||||||
m_type = type;
|
m_type = type;
|
||||||
|
|
||||||
m_surveyName = new TextField("surveyName");
|
m_surveyName = new TextField("surveyName");
|
||||||
m_surveyName.addValidationListener(new NotWhiteSpaceValidationListener());
|
m_surveyName.addValidationListener(new NotEmptyValidationListener());
|
||||||
m_description = new TextArea("description");
|
m_description = new TextArea("description");
|
||||||
|
|
||||||
|
|
||||||
m_startDate = new Date("startDate");
|
m_startDate = new Date("startDate");
|
||||||
m_endDate = new Date("endDate");
|
m_endDate = new Date("endDate");
|
||||||
|
|
||||||
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.name")));
|
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.name")));
|
||||||
add(m_surveyName);
|
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.setRows(20);
|
||||||
m_description.setCols(60);
|
m_description.setCols(60);
|
||||||
add(m_description);
|
add(m_description);
|
||||||
|
|
@ -95,44 +96,40 @@ public class PropertiesForm extends Form {
|
||||||
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.end_date")));
|
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.end_date")));
|
||||||
add(m_endDate);
|
add(m_endDate);
|
||||||
|
|
||||||
|
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.should_quiz_responses_be_public")));
|
||||||
|
m_responsesPublic = new RadioGroup("responsesPublic");
|
||||||
add(new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.should_quiz_responses_be_public")));
|
Option o1 = new Option("true", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.Yes")));
|
||||||
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")));
|
Option o2 = new Option("false", new Label(GlobalizationUtil.globalize("simplesurvey.ui.admin.No")));
|
||||||
m_responsesPublic.addOption(o1);
|
m_responsesPublic.addOption(o1);
|
||||||
m_responsesPublic.addOption(o2);
|
m_responsesPublic.addOption(o2);
|
||||||
add(m_responsesPublic);
|
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);
|
|
||||||
|
|
||||||
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());
|
addInitListener(new SurveyInitListener());
|
||||||
addProcessListener(new PropertiesFormProcessListener());
|
addProcessListener(new PropertiesFormProcessListener());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private class SurveyInitListener implements FormInitListener {
|
private class SurveyInitListener implements FormInitListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param e
|
* @param e
|
||||||
* @throws FormProcessException
|
* @throws FormProcessException
|
||||||
*/
|
*/
|
||||||
public void init(FormSectionEvent e) throws FormProcessException {
|
public void init(FormSectionEvent e) throws FormProcessException {
|
||||||
|
|
||||||
PageState state = e.getPageState();
|
PageState state = e.getPageState();
|
||||||
|
|
||||||
|
|
@ -145,10 +142,10 @@ public class PropertiesForm extends Form {
|
||||||
m_startDate.setValue(state, survey.getStartDate());
|
m_startDate.setValue(state, survey.getStartDate());
|
||||||
m_endDate.setValue(state, survey.getEndDate());
|
m_endDate.setValue(state, survey.getEndDate());
|
||||||
m_quizType.setValue(state, survey.getQuizType());
|
m_quizType.setValue(state, survey.getQuizType());
|
||||||
if ( survey.responsesArePublic() ) {
|
if (survey.responsesArePublic()) {
|
||||||
m_responsesPublic.setValue(state, "true");
|
m_responsesPublic.setValue(state, "true");
|
||||||
} else {
|
} else {
|
||||||
m_responsesPublic.setValue(state,"false");
|
m_responsesPublic.setValue(state, "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -158,7 +155,7 @@ public class PropertiesForm extends Form {
|
||||||
Calendar startCalendar = new GregorianCalendar();
|
Calendar startCalendar = new GregorianCalendar();
|
||||||
startCalendar.add(Calendar.DATE, 0);
|
startCalendar.add(Calendar.DATE, 0);
|
||||||
java.util.Date startDate = startCalendar.getTime();
|
java.util.Date startDate = startCalendar.getTime();
|
||||||
Calendar endCalendar = new GregorianCalendar();
|
Calendar endCalendar = new GregorianCalendar();
|
||||||
endCalendar.add(Calendar.DATE, 15);
|
endCalendar.add(Calendar.DATE, 15);
|
||||||
java.util.Date endDate = endCalendar.getTime();
|
java.util.Date endDate = endCalendar.getTime();
|
||||||
|
|
||||||
|
|
@ -170,17 +167,15 @@ public class PropertiesForm extends Form {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private class PropertiesFormProcessListener implements FormProcessListener {
|
private class PropertiesFormProcessListener implements FormProcessListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param e
|
* @param e
|
||||||
* @throws FormProcessException
|
* @throws FormProcessException
|
||||||
*/
|
*/
|
||||||
public void process(FormSectionEvent e) throws FormProcessException {
|
public void process(FormSectionEvent e) throws FormProcessException {
|
||||||
|
|
||||||
|
|
@ -188,7 +183,7 @@ public class PropertiesForm extends Form {
|
||||||
|
|
||||||
Survey survey;
|
Survey survey;
|
||||||
PersistentForm form;
|
PersistentForm form;
|
||||||
|
|
||||||
if (m_survey.isSelected(state)) {
|
if (m_survey.isSelected(state)) {
|
||||||
survey = m_survey.getSelectedSurvey(state);
|
survey = m_survey.getSelectedSurvey(state);
|
||||||
form = survey.getForm();
|
form = survey.getForm();
|
||||||
|
|
@ -197,27 +192,26 @@ public class PropertiesForm extends Form {
|
||||||
|
|
||||||
// PackageInstance is old style application, no longer used.
|
// PackageInstance is old style application, no longer used.
|
||||||
// survey.setPackageInstance(SimpleSurveyUtil.getPackageInstance(state));
|
// survey.setPackageInstance(SimpleSurveyUtil.getPackageInstance(state));
|
||||||
|
|
||||||
form = new PersistentForm();
|
form = new PersistentForm();
|
||||||
survey.setForm(form);
|
survey.setForm(form);
|
||||||
}
|
}
|
||||||
|
|
||||||
form.setAdminName((String)m_surveyName.getValue(state));
|
form.setAdminName((String) m_surveyName.getValue(state));
|
||||||
form.setHTMLName(getHTMLName((String)m_surveyName.getValue(state)));
|
form.setHTMLName(getHTMLName((String) m_surveyName.getValue(state)));
|
||||||
form.setDescription((String)m_description.getValue(state));
|
form.setDescription((String) m_description.getValue(state));
|
||||||
form.save();
|
form.save();
|
||||||
|
|
||||||
survey.setStartDate((java.util.Date)m_startDate.getValue(state));
|
survey.setStartDate((java.util.Date) m_startDate.getValue(state));
|
||||||
survey.setEndDate((java.util.Date)m_endDate.getValue(state));
|
survey.setEndDate((java.util.Date) m_endDate.getValue(state));
|
||||||
survey.setResponsesPublic(new Boolean((String) m_responsesPublic.getValue(state)));
|
survey.setResponsesPublic(new Boolean((String) m_responsesPublic.getValue(state)));
|
||||||
survey.setQuizType((String) m_quizType.getValue(state));
|
survey.setQuizType((String) m_quizType.getValue(state));
|
||||||
survey.save();
|
survey.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param surveyName
|
* @param surveyName
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String getHTMLName(String surveyName) {
|
private String getHTMLName(String surveyName) {
|
||||||
String htmlName = surveyName.trim().toLowerCase();
|
String htmlName = surveyName.trim().toLowerCase();
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ public class ThemeDirectorConfig extends AbstractConfig {
|
||||||
"defaultThemeURLAttribute";
|
"defaultThemeURLAttribute";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Purpose uncodumented.
|
* Purpose undocumented.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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.save_button_hint=Save the details in the form
|
||||||
theme.cancel_button_hint=Abort changes & reset the form.
|
theme.cancel_button_hint=Abort changes & reset the form.
|
||||||
theme.cancel_button_pressed_msg=cancel pressed
|
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.
|
||||||
|
|
|
||||||
|
|
@ -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.save_button_hint=Speichern der Angaben in dem Formular.
|
||||||
theme.cancel_button_hint=Verwerfen der Eintragungen und R\u00fccksetzen des Formulars.
|
theme.cancel_button_hint=Verwerfen der Eintragungen und R\u00fccksetzen des Formulars.
|
||||||
theme.cancel_button_pressed_msg=Vorgang abgebrochen
|
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.
|
||||||
|
|
|
||||||
|
|
@ -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.save_button_hint=Save the details in the form
|
||||||
theme.cancel_button_hint=Abort changes & reset the form.
|
theme.cancel_button_hint=Abort changes & reset the form.
|
||||||
theme.cancel_button_pressed_msg=cancel pressed
|
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.
|
||||||
|
|
|
||||||
|
|
@ -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.save_button_hint=Save the details in the form
|
||||||
theme.cancel_button_hint=Abort changes & reset the form.
|
theme.cancel_button_hint=Abort changes & reset the form.
|
||||||
theme.cancel_button_pressed_msg=cancel pressed
|
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.
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class InternalThemePrefixerServlet extends InternalPrefixerServlet {
|
||||||
* by editing /WEB-INF/conf/log4j.properties int the runtime environment
|
* by editing /WEB-INF/conf/log4j.properties int the runtime environment
|
||||||
* and set
|
* and set
|
||||||
* com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet=DEBUG
|
* com.arsdigita.themedirector.dispatcher.InternalThemePrefixerServlet=DEBUG
|
||||||
* by uncommenting or adding the line. */
|
* by uncommenting or adding the line. */
|
||||||
private static final Logger s_log =
|
private static final Logger s_log =
|
||||||
Logger.getLogger(InternalPrefixerServlet.class);
|
Logger.getLogger(InternalPrefixerServlet.class);
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ public class InternalThemePrefixerServlet extends InternalPrefixerServlet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String prefix = pathInfo;
|
String prefix;
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
String themeName = pathInfo.substring(0, pathInfo.indexOf(path));
|
String themeName = pathInfo.substring(0, pathInfo.indexOf(path));
|
||||||
prefix = m_prefix + themeName;
|
prefix = m_prefix + themeName;
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,13 @@ import org.apache.log4j.Logger;
|
||||||
*
|
*
|
||||||
* @author Randy Graebner <randyg@redhat.com>
|
* @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 =
|
private static final Logger s_log =
|
||||||
Logger.getLogger(ThemeContainer.class);
|
Logger.getLogger(ThemeContainer.class);
|
||||||
|
|
||||||
|
|
@ -61,7 +65,8 @@ public class ThemeContainer extends SimpleContainer implements ThemeDirectorCons
|
||||||
private SimpleContainer m_mainPanel;
|
private SimpleContainer m_mainPanel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
*
|
||||||
* @param model
|
* @param model
|
||||||
* @param parent
|
* @param parent
|
||||||
*/
|
*/
|
||||||
|
|
@ -228,6 +233,11 @@ public class ThemeContainer extends SimpleContainer implements ThemeDirectorCons
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private class ProductionFilesDownloadLink extends Link {
|
private class ProductionFilesDownloadLink extends Link {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param model
|
||||||
|
*/
|
||||||
ProductionFilesDownloadLink(final ThemeSelectionModel model) {
|
ProductionFilesDownloadLink(final ThemeSelectionModel model) {
|
||||||
super(new Label(GlobalizationUtil.globalize
|
super(new Label(GlobalizationUtil.globalize
|
||||||
("theme.download_prod_theme_files")),
|
("theme.download_prod_theme_files")),
|
||||||
|
|
@ -245,6 +255,11 @@ public class ThemeContainer extends SimpleContainer implements ThemeDirectorCons
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param state
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isVisible(PageState state) {
|
public boolean isVisible(PageState state) {
|
||||||
return super.isVisible(state) &&
|
return super.isVisible(state) &&
|
||||||
|
|
|
||||||
|
|
@ -52,18 +52,20 @@ import java.util.TooManyListenersException;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the base page for controlling themes in the system. It
|
* This is the base page for controlling themes in the system. It contains
|
||||||
* contains a list of the themes on the left side and it manages the state
|
* a list of the themes on the left side and it manages the state to show the
|
||||||
* to show the correct forms/containers on the left
|
* 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
|
/** Internal logger instance to faciliate debugging. Enable logging output
|
||||||
* by editing /WEB-INF/conf/log4j.properties int the runtime environment
|
* by editing /WEB-INF/conf/log4j.properties int the runtime environment
|
||||||
* and set com.arsdigita.templating.ui.ThemeControlPanel=DEBUG
|
* and set com.arsdigita.themedirector.ui.ThemeControlPanel=DEBUG
|
||||||
* by uncommenting or adding the line. */
|
* by uncommenting or adding the line. */
|
||||||
private static final Logger LOGGER = Logger.getLogger(ThemeControlPanel.class);
|
private static final Logger LOGGER = Logger.getLogger(ThemeControlPanel.class);
|
||||||
private final ThemeSelectionModel selectionModel;
|
private final ThemeSelectionModel selectionModel;
|
||||||
|
/** Stored the theme form object, which shopws widget / data for a theme. */
|
||||||
private final Form themeForm;
|
private final Form themeForm;
|
||||||
private final BigDecimalParameter defaultThemeParam = new BigDecimalParameter("defaultTheme");
|
private final BigDecimalParameter defaultThemeParam = new BigDecimalParameter("defaultTheme");
|
||||||
|
|
||||||
|
|
@ -121,19 +123,28 @@ public class ThemeControlPanel extends SelectionPanel implements ThemeDirectorCo
|
||||||
addAction(defaultThemeForm);
|
addAction(defaultThemeForm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
private Form createDefaultThemeForm() {
|
private Form createDefaultThemeForm() {
|
||||||
|
|
||||||
final Form defaultThemeForm = new Form("defaultThemeForm", new SimpleContainer());
|
final Form defaultThemeForm = new Form("defaultThemeForm",
|
||||||
defaultThemeForm.add(new Label(GlobalizationUtil.globalize("theme.set_default_theme")));
|
new SimpleContainer());
|
||||||
|
defaultThemeForm.add(new Label(GlobalizationUtil.globalize(
|
||||||
|
"theme.set_default_theme")));
|
||||||
|
|
||||||
final SingleSelect themes = new SingleSelect(defaultThemeParam);
|
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 {
|
try {
|
||||||
themes.addPrintListener(new PrintListener() {
|
themes.addPrintListener(new PrintListener() {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(final PrintEvent event) {
|
public void prepare(final PrintEvent event) {
|
||||||
final SingleSelect target = (SingleSelect) event.getTarget();
|
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.addNotEqualsFilter(Theme.LAST_PUBLISHED_DATE, null);
|
||||||
options.addOrder(Theme.TITLE);
|
options.addOrder(Theme.TITLE);
|
||||||
while (options.next()) {
|
while (options.next()) {
|
||||||
|
|
|
||||||
|
|
@ -29,31 +29,34 @@ import com.arsdigita.bebop.event.FormSubmissionListener;
|
||||||
import com.arsdigita.bebop.event.FormProcessListener;
|
import com.arsdigita.bebop.event.FormProcessListener;
|
||||||
import com.arsdigita.bebop.event.FormValidationListener;
|
import com.arsdigita.bebop.event.FormValidationListener;
|
||||||
import com.arsdigita.bebop.event.FormSectionEvent;
|
import com.arsdigita.bebop.event.FormSectionEvent;
|
||||||
|
import com.arsdigita.bebop.event.ParameterEvent;
|
||||||
import com.arsdigita.bebop.FormProcessException;
|
import com.arsdigita.bebop.FormProcessException;
|
||||||
import com.arsdigita.bebop.GridPanel;
|
import com.arsdigita.bebop.GridPanel;
|
||||||
import com.arsdigita.bebop.PageState;
|
import com.arsdigita.bebop.PageState;
|
||||||
|
import com.arsdigita.bebop.parameters.GlobalizedParameterListener;
|
||||||
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
|
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
|
||||||
|
import com.arsdigita.bebop.parameters.ParameterData;
|
||||||
import com.arsdigita.bebop.parameters.StringParameter;
|
import com.arsdigita.bebop.parameters.StringParameter;
|
||||||
import com.arsdigita.bebop.Label;
|
import com.arsdigita.bebop.Label;
|
||||||
import com.arsdigita.persistence.DataCollection;
|
import com.arsdigita.persistence.DataCollection;
|
||||||
import com.arsdigita.persistence.SessionManager;
|
import com.arsdigita.persistence.SessionManager;
|
||||||
import com.arsdigita.util.UncheckedWrapperException;
|
import com.arsdigita.util.UncheckedWrapperException;
|
||||||
import com.arsdigita.util.IO;
|
//import com.arsdigita.util.IO;
|
||||||
import com.arsdigita.themedirector.ThemeDirectorConstants;
|
import com.arsdigita.themedirector.ThemeDirectorConstants;
|
||||||
import com.arsdigita.themedirector.ThemeDirector;
|
import com.arsdigita.themedirector.ThemeDirector;
|
||||||
import com.arsdigita.themedirector.util.GlobalizationUtil;
|
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.Subsite;
|
||||||
import com.arsdigita.subsite.Site;
|
import com.arsdigita.subsite.Site;
|
||||||
import com.arsdigita.toolbox.ui.Cancellable;
|
import com.arsdigita.toolbox.ui.Cancellable;
|
||||||
import com.arsdigita.web.Web;
|
import com.arsdigita.web.Web;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
//import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
//import java.io.InputStream;
|
||||||
import org.apache.commons.io.FileUtils;
|
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;
|
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 static final Logger s_log = Logger.getLogger(ThemeForm.class);
|
||||||
|
|
||||||
private final ThemeSelectionModel m_theme;
|
private final ThemeSelectionModel m_theme;
|
||||||
|
|
||||||
|
/* Holds the theme's title. */
|
||||||
private final TextField m_title;
|
private final TextField m_title;
|
||||||
|
|
||||||
|
/* Holds the theme's description. */
|
||||||
private final TextArea m_description;
|
private final TextArea m_description;
|
||||||
|
|
||||||
|
/* Holds the theme's URL. */
|
||||||
private final TextField m_url;
|
private final TextField m_url;
|
||||||
|
|
||||||
|
/* Instance of the form's Save/Cancel buttons. */
|
||||||
private final SaveCancelSection m_buttons;
|
private final SaveCancelSection m_buttons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -119,7 +130,9 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan
|
||||||
// Experimental, see above
|
// Experimental, see above
|
||||||
m_url.setLabel(GlobalizationUtil.globalize("theme.url"));
|
m_url.setLabel(GlobalizationUtil.globalize("theme.url"));
|
||||||
m_url.addValidationListener(new NotEmptyValidationListener());
|
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"));
|
m_url.setHint(GlobalizationUtil.globalize("theme.url_hint"));
|
||||||
add(m_url);
|
add(m_url);
|
||||||
|
|
||||||
|
|
@ -133,7 +146,11 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan
|
||||||
addSubmissionListener(new ThemeSubmissionListener());
|
addSubmissionListener(new ThemeSubmissionListener());
|
||||||
addProcessListener(new ThemeProcessListener());
|
addProcessListener(new ThemeProcessListener());
|
||||||
addInitListener(new ThemeInitListener());
|
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);
|
copyDefaultTheme(newDirectory,null);
|
||||||
|
// Old way should be removed as soon as thorough testing the
|
||||||
|
// new method has been completed.
|
||||||
// copyDefaultFiles(newDirectory);
|
// copyDefaultFiles(newDirectory);
|
||||||
|
|
||||||
if (oldDirectory != null && !oldDirectory.exists()) {
|
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
|
* Copies a complete directory containing the default theme to a newly
|
||||||
* created theme's directory without any filtering or other processing.
|
* created theme's directory without any filtering or other processing.
|
||||||
* It assumes, that the source directory contains a complete and working
|
* It assumes, that the source directory contains a complete and working
|
||||||
* set of theme files.
|
* 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
|
* @param newThemeDirectory specifies the target directory. Must not
|
||||||
* be null.
|
* be null.
|
||||||
* @param defaultThemeDirectory Directory containing a complete set of
|
* @param defaultThemeDirectory Directory containing a complete set of
|
||||||
|
|
@ -449,13 +383,188 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan
|
||||||
newThemeDirectory);
|
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
|
* Copies the default theme files to the new directory using a
|
||||||
* Manifest file to determine the files to copy.
|
* 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
|
* @param newDirectory specifies the target directory
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
private void copyDefaultFiles(File newDirectory) throws IOException {
|
private void copyDefaultFiles(File newDirectory) throws IOException {
|
||||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
InputStream is = loader.getResourceAsStream
|
InputStream is = loader.getResourceAsStream
|
||||||
|
|
@ -476,34 +585,26 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan
|
||||||
new FileWriterManifestReader(is, newDirectory);
|
new FileWriterManifestReader(is, newDirectory);
|
||||||
reader.processFile();
|
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 class FileWriterManifestReader extends ManifestReader {
|
||||||
private final File m_newDirectory;
|
private final File m_newDirectory;
|
||||||
private final String m_directoryFilter;
|
private final String m_directoryFilter;
|
||||||
|
|
||||||
/**
|
FileWriterManifestReader(InputStream stream, File newDirectory) {
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param stream
|
|
||||||
* @param newDirectory
|
|
||||||
*/
|
|
||||||
FileWriterManifestReader(InputStream stream, File newDirectory) {
|
|
||||||
super(stream);
|
super(stream);
|
||||||
m_newDirectory = newDirectory;
|
m_newDirectory = newDirectory;
|
||||||
|
|
||||||
m_directoryFilter = ThemeDirector.getConfig().getDefaultThemePath();
|
m_directoryFilter = ThemeDirector.getConfig().getDefaultThemePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param is
|
|
||||||
* @param filePath
|
|
||||||
* @param isStyleFile
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void processManifestFileLine(InputStream is,
|
public void processManifestFileLine(InputStream is,
|
||||||
String filePath,
|
String filePath,
|
||||||
|
|
@ -541,4 +642,5 @@ public class ThemeForm extends Form implements Cancellable, ThemeDirectorConstan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -182,11 +182,11 @@ class ThemeValidationPanel extends GridPanel implements ThemeDirectorConstants {
|
||||||
containing patterns to search for.
|
containing patterns to search for.
|
||||||
|
|
||||||
Developer's Note:
|
Developer's Note:
|
||||||
We used to use a 'resource' tag involing a resource servlet to
|
We used to use a 'resource' tag involving a resource servlet to
|
||||||
deliver the correct file either from database or filesystem. Ir would
|
deliver the correct file either from database or filesystem. It
|
||||||
require an URL similar to
|
would require an URL similar to
|
||||||
http://localhost:9008/libreccm/resource/themes/heirloom/apps/theme/xsl/index.xs
|
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
|
Currently we bypass the resource servlet and access the filesystem
|
||||||
directly. Must be modified as soon as we deliver the theme from db. */
|
directly. Must be modified as soon as we deliver the theme from db. */
|
||||||
String stylesheetPath = "http://" + Web.getConfig().getHost().toString()
|
String stylesheetPath = "http://" + Web.getConfig().getHost().toString()
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,12 @@ public class ThemeDevelopmentFileManager extends ThemeFileManager {
|
||||||
* process the file. A startupDelay of 0 means that this is a no-op
|
* 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
|
* @param pollDelay number of seconds to wait between checks if the file
|
||||||
* has any entries.
|
* has any entries.
|
||||||
|
* @param baseDirectory
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ThemeFileManager startWatchingFiles
|
public static ThemeFileManager startWatchingFiles(int startupDelay,
|
||||||
(int startupDelay, int pollDelay, String baseDirectory) {
|
int pollDelay,
|
||||||
|
String baseDirectory) {
|
||||||
if (s_manager == null) {
|
if (s_manager == null) {
|
||||||
s_log.info("Starting Theme File Manager Thread with the base " +
|
s_log.info("Starting Theme File Manager Thread with the base " +
|
||||||
"directory of " + baseDirectory);
|
"directory of " + baseDirectory);
|
||||||
|
|
@ -108,8 +111,10 @@ public class ThemeDevelopmentFileManager extends ThemeFileManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns the current thread or null if the thread has not
|
* This returns the current thread or null if the thread has not
|
||||||
* yet been started.
|
* yet been started.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ThemeFileManager getInstance() {
|
public static ThemeFileManager getInstance() {
|
||||||
return s_manager;
|
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() {
|
protected String getManagerSpecificDirectory() {
|
||||||
return getBaseDirectory() + DEV_THEMES_BASE_DIR;
|
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.
|
// 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
|
// if we decide that we definitely do not want the auto-update
|
||||||
// then we should remove this.
|
// then we should remove this.
|
||||||
|
@Override
|
||||||
protected void updateTheme(Theme theme) {
|
protected void updateTheme(Theme theme) {
|
||||||
// the first step is to make sure that all files from the theme
|
// the first step is to make sure that all files from the theme
|
||||||
// are in the db.
|
// are in the db.
|
||||||
|
|
@ -154,9 +163,11 @@ public class ThemeDevelopmentFileManager 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).
|
* (e.g. only return "live" files or only "draft" files).
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
protected ThemeFileCollection getThemeFilesCollection(Theme theme) {
|
protected ThemeFileCollection getThemeFilesCollection(Theme theme) {
|
||||||
return theme.getDraftThemeFiles();
|
return theme.getDraftThemeFiles();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ import com.arsdigita.themedirector.ThemeDirectorConstants;
|
||||||
import com.arsdigita.themedirector.ThemeFileCollection;
|
import com.arsdigita.themedirector.ThemeFileCollection;
|
||||||
import com.arsdigita.persistence.SessionManager;
|
import com.arsdigita.persistence.SessionManager;
|
||||||
import com.arsdigita.persistence.TransactionContext;
|
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.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
|
@ -205,28 +206,18 @@ public abstract class ThemeFileManager extends Thread
|
||||||
if (m_baseDirectory == null) {
|
if (m_baseDirectory == null) {
|
||||||
// Because the constructor sets the base directory this should
|
// Because the constructor sets the base directory this should
|
||||||
// never happen, but just in case ....
|
// 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();
|
// ThemeDirector may execute in a different web application context
|
||||||
ServletContext themeCtx = Web.getServletContext(webapp + '/');
|
// as core oder CMS.
|
||||||
m_baseDirectory = themeCtx.getRealPath("/");
|
// Old non-standard-compliant code had been removed, so currently
|
||||||
*/
|
// ThemeManager has to be installed into the same context as core.
|
||||||
ServletContext themeCtx = InternalThemePrefixerServlet
|
// To determine the actual context we may ask Themedirector servlet.
|
||||||
.getThemedirectorContext();
|
// Something like
|
||||||
|
// ServletContext themeCtx = InternalThemePrefixerServlet
|
||||||
|
// .getThemedirectorContext();
|
||||||
|
// We have to ensure the Servlet is initialized.
|
||||||
|
|
||||||
|
ServletContext themeCtx = Web.getServletContext();
|
||||||
m_baseDirectory = themeCtx.getRealPath("/");
|
m_baseDirectory = themeCtx.getRealPath("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,14 @@ import org.apache.log4j.Logger;
|
||||||
* runs for the first time, it examines all themes.
|
* runs for the first time, it examines all themes.
|
||||||
*
|
*
|
||||||
* @author <a href="mailto:randyg@redhat.com">Randy Graebner</a>
|
* @author <a href="mailto:randyg@redhat.com">Randy Graebner</a>
|
||||||
*
|
|
||||||
* @version $Revision: #2 $ $DateTime: 2004/03/17 09:56:37 $
|
* @version $Revision: #2 $ $DateTime: 2004/03/17 09:56:37 $
|
||||||
*/
|
*/
|
||||||
public class ThemePublishedFileManager extends ThemeFileManager {
|
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 =
|
private static Logger s_log =
|
||||||
Logger.getLogger(ThemePublishedFileManager.class);
|
Logger.getLogger(ThemePublishedFileManager.class);
|
||||||
|
|
||||||
|
|
@ -46,7 +49,8 @@ public class ThemePublishedFileManager extends ThemeFileManager {
|
||||||
static private ThemeFileManager s_manager = null;
|
static private ThemeFileManager s_manager = null;
|
||||||
|
|
||||||
|
|
||||||
protected ThemePublishedFileManager(int startupDelay, int pollDelay,
|
protected ThemePublishedFileManager(int startupDelay,
|
||||||
|
int pollDelay,
|
||||||
String baseDirectory) {
|
String baseDirectory) {
|
||||||
super(s_log, startupDelay, pollDelay, 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).
|
* (e.g. only return "live" files or only "draft" files).
|
||||||
*/
|
*/
|
||||||
protected ThemeFileCollection getThemeFilesCollection(Theme theme) {
|
protected ThemeFileCollection getThemeFilesCollection(Theme theme) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue