Some formating and cleanup

git-svn-id: https://svn.libreccm.org/ccm/trunk@2741 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2014-07-08 08:56:10 +00:00
parent c3ed9c05d4
commit cde2e962a2
4 changed files with 208 additions and 223 deletions

View File

@ -18,8 +18,6 @@
*/ */
package com.arsdigita.cms.portlet; package com.arsdigita.cms.portlet;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageFactory;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent; import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.cms.CMS; import com.arsdigita.cms.CMS;
@ -30,15 +28,10 @@ import com.arsdigita.cms.ContentSection;
import com.arsdigita.cms.ContentSectionCollection; import com.arsdigita.cms.ContentSectionCollection;
import com.arsdigita.cms.ItemCollection; import com.arsdigita.cms.ItemCollection;
import com.arsdigita.cms.dispatcher.SimpleXMLGenerator; import com.arsdigita.cms.dispatcher.SimpleXMLGenerator;
import com.arsdigita.cms.portlet.utils.HttpServletRequestAdapter;
import com.arsdigita.cms.portlet.utils.HttpServletResponseAdapter;
import com.arsdigita.domain.DataObjectNotFoundException; import com.arsdigita.domain.DataObjectNotFoundException;
import com.arsdigita.domain.DomainObjectFactory; import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.persistence.OID; import com.arsdigita.persistence.OID;
import com.arsdigita.portal.JSRPortlet; import com.arsdigita.portal.JSRPortlet;
import com.arsdigita.templating.PresentationManager;
import com.arsdigita.templating.Templating;
import com.arsdigita.xml.Document;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
import java.io.IOException; import java.io.IOException;
@ -54,9 +47,6 @@ import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequestDispatcher; import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest; import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse; import javax.portlet.RenderResponse;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;

View File

@ -179,7 +179,7 @@ public final class BebopConfig extends AbstractConfig {
} }
/** /**
* Gets the location of DHTML editor's xource file * Gets the location of DHTML editor's source file
*/ */
public final String getDHTMLEditorSrcFile() { public final String getDHTMLEditorSrcFile() {
return (String) get(m_dhtmlEditorSrcFile); return (String) get(m_dhtmlEditorSrcFile);

View File

@ -54,15 +54,14 @@ import org.apache.log4j.Logger;
/** /**
* The top-level container for all Bebop components and containers. * The top-level container for all Bebop components and containers.
* *
* <UL> * <UL>
* <LI>Holds references to the components of a page.</LI> * <LI>Holds references to the components of a page.</LI>
* <LI>Provides methods for servicing requests and for notifying other * <LI>Provides methods for servicing requests and for notifying other components that a request for
* components that a request for this page has been received through * this page has been received through {@link ActionListener ActionListeners}.</LI>
* {@link ActionListener ActionListeners}.</LI> * <LI>Tracks request parameters for stateful components, such as tabbed panes and sortable
* <LI>Tracks request parameters for stateful components, such as tabbed panes * tables.</LI>
* and sortable tables.</LI>
* </UL> * </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");
@ -115,10 +114,9 @@ public class Page extends SimpleComponent implements Container {
*/ */
static final String INVISIBLE = INTERNAL + "i"; static final String INVISIBLE = INTERNAL + "i";
/** /**
* Map of stateful components (id --> Component) SortedMap used because * Map of stateful components (id --> Component) SortedMap used because component based hash for
* component based hash for page is based on concatenation of component ids, * page is based on concatenation of component ids, and so need to guarantee that they are
* and so need to guarantee that they are returned in the same order for * returned in the same order for the same page - cg.
* the same page - cg.
*/ */
private SortedMap m_componentMap; private SortedMap m_componentMap;
private List m_components; private List m_components;
@ -134,14 +132,13 @@ public class Page extends SimpleComponent 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 * The title of the page to be added in the head of HTML output. The title is wrapped in a Label
* is wrapped in a Label to allow developers to add PrintListeners to * to allow developers to add PrintListeners to dynamically change the value of the title.
* 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 * Stores the actual title for the current request. The title may be generated with a
* generated with a PrintListener of the m_title Label. * PrintListener of the m_title Label.
*/ */
private RequestLocal m_currentTitle; private RequestLocal m_currentTitle;
/** /**
@ -175,34 +172,32 @@ public class Page extends SimpleComponent implements Container {
private boolean m_useHttpSession = false; private boolean m_useHttpSession = false;
/** /**
* Returns <code>true</code> if this page should export state through the * Returns <code>true</code> if this page should export state through the HttpSession instead of
* HttpSession instead of the URL query string. * the URL query string.
* <P> * <P>
* If this returns <code>true</code>, then PageState.stateAsURL() will only * If this returns <code>true</code>, then PageState.stateAsURL() will only export the control
* export the control event as a URL query string. If this returns * event as a URL query string. If this returns <code>false</code>, then stateAsURL() will
* <code>false</code>, then stateAsURL() will export the entire page state. * export the entire page state.
*
* @see PageState#stateAsURL * @see PageState#stateAsURL
* *
* @return <code>true</code> if this page should export state through the * @return <code>true</code> if this page should export state through the HttpSession;
* HttpSession; * <code>false</code> if it should export using the URL query string.
* <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 * Indicates to this page whether it should export its entire state to subsequent requests
* subsequent requests through the URL query string, or if it should use the * through the URL query string, or if it should use the HttpSession instead and only use the
* HttpSession instead and only use the URL query string for the control * URL query string for the control event.
* event.
* *
* @see PageState#stateAsURL * @see PageState#stateAsURL
* *
* @param b <code>true</code> if PageState.stateAsURL() will export only the * @param b <code>true</code> if PageState.stateAsURL() will export only the control event as a
* control event as a URL query string. <code>false</code> if stateAsURL() * URL query string. <code>false</code> if stateAsURL() will export the entire page
* will export the entire page state. * state.
*/ */
public void setUsingHttpSession(boolean b) { public void setUsingHttpSession(boolean b) {
m_useHttpSession = b; m_useHttpSession = b;
@ -211,12 +206,12 @@ public class Page extends SimpleComponent implements Container {
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
// Constructor Section // Constructor Section
// //////////////////////////////////////////////////////////////////////// // ////////////////////////////////////////////////////////////////////////
/** /**
* Constructor, 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. * @deprecated use Page(Lab el, Container) instead.
*/ */
public Page(String title, Container panel) { public Page(String title, Container panel) {
@ -240,9 +235,10 @@ public class Page extends SimpleComponent implements Container {
setErrorDisplay(new PageErrorDisplay()); setErrorDisplay(new PageErrorDisplay());
m_title = 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
m_currentTitle = new RequestLocal() { m_currentTitle = new RequestLocal() {
@Override @Override
protected Object initialValue(PageState state) { protected Object initialValue(PageState state) {
return m_title.firePrintEvent(state); return m_title.firePrintEvent(state);
@ -250,7 +246,7 @@ public class Page extends SimpleComponent implements Container {
}; };
// Initialize the set of state parameters to hold // Initialize the set of state parameters to hold
// the ones necessary for keeping track of the selected component and // the ones necessary for keeping track of the selected component and
// the name and value of a 'control event' // the name and value of a 'control event'
m_selected = new StringParameter(SELECTED); m_selected = new StringParameter(SELECTED);
@ -277,8 +273,7 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Creates an empty page with the specified title and implicit BoxPanel * Creates an empty page with the specified title and implicit BoxPanel container.
* container.
* *
* @param title title for this page * @param title title for this page
*/ */
@ -289,8 +284,7 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Creates an empty page with the specified title and implicit BoxPanel * Creates an empty page with the specified title and implicit BoxPanel container.
* container.
* *
* @param title title for this page * @param title title for this page
*/ */
@ -310,13 +304,12 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Adds a component with the specified layout constraints to this container. * Adds a component with the specified layout constraints to this container. Layout constraints
* Layout constraints are defined in each layout container as static ints. * are defined in each layout container as static ints. To specify multiple constraints, use
* To specify multiple constraints, use bitwise OR. * 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) {
@ -324,20 +317,17 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Returns <code>true</code> if this list contains the specified element. * Returns <code>true</code> if this list contains the specified element. More formally, returns
* More formally, returns <code>true</code> if and only if this list * <code>true</code> if and only if this list contains at least one element e such that (o==null
* contains at least one element e such that (o==null ? e==null : * ? e==null : o.equals(e)).
* o.equals(e)).
* <P> * <P>
* This method returns <code>true</code> only if the component has been * This method returns <code>true</code> only if the component has been directly added to this
* directly added to this container. If this container contains another * container. If this container contains another container that contains this component, this
* container that contains this component, this method returns * method returns <code>false</code>.
* <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 * @return <code>true</code> if this Container contains the specified component directly;
* component directly;
* <code>false</code> otherwise. * <code>false</code> otherwise.
*/ */
@Override @Override
@ -346,12 +336,12 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Returns the component at the specified position. Each call to the add * Returns the component at the specified position. Each call to the add method increments the
* method increments the index. Since the user has no control over the index * index. Since the user has no control over the index of added components (other than counting
* of added components (other than counting each call to add), this method * each call to add), this method should be used in conjunction with indexOf.
* 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
@ -363,12 +353,14 @@ public class Page extends SimpleComponent 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 *
* element, or -1 if this list does not contain this element. * @return the index in this list of the first occurrence of the specified element, or -1 if
* this list does not contain this element.
* *
* @pre c != null * @pre c != null
* @post contains(c) implies (return >= 0) && (return < size()) * @post contains(c) implies (return >= 0) && (return < size())
* @post !contains(c) implies return == -1 * @pos
* t !contains(c) implies return == -1
*/ */
@Override @Override
public int indexOf(Component c) { public int indexOf(Component c) {
@ -378,8 +370,8 @@ public class Page extends SimpleComponent 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; * @return <code>true</code> if this container contains no components; <code>false</code>
* <code>false</code> otherwise. * otherwise.
*/ */
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
@ -387,9 +379,8 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Returns the number of elements in this container. This does not * Returns the number of elements in this container. This does not recursively count the
* recursively count the components that are indirectly contained in this * components that are indirectly contained in this container.
* container.
* *
* @return the number of components directly in this container. * @return the number of components directly in this container.
*/ */
@ -404,8 +395,7 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Returns the panel that the <code>Page</code> uses for rendering its * Returns the panel that the <code>Page</code> uses for rendering its components.
* components.
* *
* @return the panel. * @return the panel.
*/ */
@ -414,11 +404,11 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Set the Container used for rendering components on this page. Caution * Set the Container used for rendering components on this page. Caution should be used with
* should be used with this function, as the existing container is simply * this function, as the existing container is simply overwritten.
* overwritten.
* *
* @param c * @param c
*
* @author Matthew Booth (mbooth@redhat.com) * @author Matthew Booth (mbooth@redhat.com)
*/ */
public void setPanel(Container c) { public void setPanel(Container c) {
@ -438,6 +428,7 @@ public class Page extends SimpleComponent 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) {
@ -465,13 +456,12 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Sets the {@link Component} that will display the validation errors in the * Sets the {@link Component} that will display the validation errors in the current
* current {@link PageState}. Any validation error in the * {@link PageState}. Any validation error in the <code>PageState</code> will cause the
* <code>PageState</code> will cause the <code>Page</code> to completely * <code>Page</code> to completely ignore all other components and render only the error display
* ignore all other components and render only the error display component. * component.
* <p> * <p>
* By default, a {@link PageErrorDisplay} component is used to display the * By default, a {@link PageErrorDisplay} component is used to display the validation errors.
* 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>
@ -482,13 +472,12 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Gets the {@link Component} that will display the validation errors in the * Gets the {@link Component} that will display the validation errors in the current
* current {@link PageState}. Any validation error in the * {@link PageState}. Any validation error in the <code>PageState</code> will cause the
* <code>PageState</code> will cause the <code>Page</code> to completely * <code>Page</code> to completely ignore all other components and render only the error display
* ignore all other components and render only the error display component. * component.
* <p> * <p>
* By default, a {@link PageErrorDisplay} component is used to display the * By default, a {@link PageErrorDisplay} component is used to display the validation errors.
* 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>.
@ -498,23 +487,21 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Adds a client-side stylesheet that should be used in HTML output. * Adds a client-side stylesheet that should be used in HTML output. Arbitrarily many
* Arbitrarily many client-side stylesheets can be added with this method. * client-side stylesheets can be added with this method. To use a CSS stylesheet, call
* To use a CSS stylesheet, call something like * something like <code>setStyleSheet("style.css", "text/css")</code>.
* <code>setStyleSheet("style.css", "text/css")</code>.
* *
* <p> * <p>
* These values will ultimately wind up in a <tt>&lt;link&gt;</tt> * These values will ultimately wind up in a <tt>&lt;link&gt;</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 * Note that the stylesheet set with this call has nothing to do with the XSLT stylesheet
* XSLT stylesheet (transformer) that is applied to the XML generated from * (transformer) that is applied to the XML generated from this page!
* 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()
*/ */
@ -523,17 +510,18 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Adds a global state parameter to this page. Global parameters are values * Adds a global state parameter to this page. Global parameters are values that need to be
* that need to be preserved between requests, but that have no special * preserved between requests, but that have no special connection to any of the components on
* connection to any of the components on the page. For a page that displays * the page. For a page that displays details about an item, a global parameter would be used to
* details about an item, a global parameter would be used to identify the * identify the item.
* item. *
* If the parameter was previously added as a component state parameter, its name is unmangled
* and stays unmangled.
* *
* 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 * @param p the global parameter to add
*
* @pre ! isLocked() * @pre ! isLocked()
* @pre parameter != null * @pre parameter != null
*/ */
@ -544,8 +532,8 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Constructs the top nodes of the DOM or JDOM tree. Used by * Constructs the top nodes of the DOM or JDOM tree. Used by generateXML(PageState, Document)
* generateXML(PageState, Document) below. * below.
* <p> * <p>
* Generates DOM fragment: * Generates DOM fragment:
* <pre> * <pre>
@ -555,13 +543,14 @@ public class Page extends SimpleComponent implements Container {
* ... page content gnerated by children ... * ... page content gnerated by children ...
* &lt;/bebop:page></pre> The content of the <tt>&lt;title&gt;</tt> * &lt;/bebop:page></pre> The content of the <tt>&lt;title&gt;</tt>
* element can be set by calling {@link #setTitle setTitle}. The * element can be set by calling {@link #setTitle setTitle}. The
* <tt>&lt;stylesheet&gt;</tt> element will only be present if a stylesheet * <tt>&lt;stylesheet&gt;</tt> element will only be present if a stylesheet has been set with {@link
* 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 *
* @return
*
* @pre isLocked() * @pre isLocked()
*/ */
protected Element generateXMLHelper(PageState ps, Document parent) { protected Element generateXMLHelper(PageState ps, Document parent) {
@ -584,9 +573,8 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Constructs a DOM or JDOM tree with all components on the page. The tree * Constructs a DOM or JDOM tree with all components on the page. The tree represents the page
* represents the page that results from the * that results from the {@link javax.servlet.http.HttpServletRequest} kept in 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}
@ -604,7 +592,7 @@ public class Page extends SimpleComponent implements Container {
Element page = generateXMLHelper(state, parent); Element page = generateXMLHelper(state, parent);
// If the page state has errors, ignore all the components and // If the page state has errors, ignore all the components and
// render only the error display component // render only the error display component
if (state.getErrors().hasNext()) { if (state.getErrors().hasNext()) {
m_errorDisplay.generateXML(state, page); m_errorDisplay.generateXML(state, page);
@ -627,7 +615,7 @@ public class Page extends SimpleComponent implements Container {
/** /**
* Do nothing. Top-level add nodes is meaningless. * Do nothing. Top-level add nodes is meaningless.
* *
* @param elt * @param elt
*/ */
@Override @Override
@ -635,17 +623,20 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Creates a PageState object and processes it by calling the respond method * Creates a PageState object and processes it by calling the respond method on the selected
* on the selected component. Processes a request by notifying the component * component. Processes a request by notifying the component from which the process originated
* from which the process originated and {@link #fireActionEvent * and {@link #fireActionEvent
* broadcasts} an {@link ActionEvent} to all the listeners that registered * broadcasts} an {@link ActionEvent} to all the listeners that registered with
* with {@link #addActionListener addActionListener}. * {@link #addActionListener addActionListener}.
*
* @see #generateXML(PageState,Document) generateXML * @see #generateXML(PageState,Document) generateXML
* *
* @param request * @param request
* @param response * @param response
* @return *
* @throws javax.servlet.ServletException * @return
*
* @throws javax.servlet.ServletException
* @pre isLocked() * @pre isLocked()
* @pre request != null * @pre request != null
* @pre response != null * @pre response != null
@ -677,7 +668,7 @@ public class Page extends SimpleComponent implements Container {
DeveloperSupport.endStage("Bebop Request Event"); DeveloperSupport.endStage("Bebop Request Event");
} }
// Validate the state; any errors in the state will be displayed // Validate the state; any errors in the state will be displayed
// by generateXML // by generateXML
state.forceValidate(); state.forceValidate();
@ -698,13 +689,12 @@ public class Page extends SimpleComponent implements Container {
} }
/** /**
* Builds a DOM Document from the current request state by doing a * Builds a DOM Document from the current request state by doing a depth-first tree walk on the
* depth-first tree walk on the current set of components in this Page, * current set of components in this Page, calling generateXML on each. Does NOT do the
* calling generateXML on each. Does NOT do the rendering. If the HTTP * rendering. If the HTTP response has already been committed, does not build the XML document.
* 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,
@ -714,7 +704,7 @@ public class Page extends SimpleComponent implements Container {
Document doc = new Document(); Document doc = new Document();
PageState state = process(req, res); PageState state = process(req, res);
// only generate XML document if the response is not already // only generate XML document if the response is not already
// committed // committed
if (!res.isCommitted()) { if (!res.isCommitted()) {
try { try {
@ -745,6 +735,7 @@ public class Page extends SimpleComponent implements Container {
Assert.isUnlocked(this); Assert.isUnlocked(this);
Traversal componentRegistrar = new Traversal() { Traversal componentRegistrar = new Traversal() {
@Override @Override
protected void act(Component c) { protected void act(Component c) {
addComponent(c); addComponent(c);
@ -778,6 +769,7 @@ public class Page extends SimpleComponent implements Container {
} }
m_stateModel.lock(); m_stateModel.lock();
Traversal componentLocker = new Traversal() { Traversal componentLocker = new Traversal() {
@Override @Override
protected void act(Component c) { protected void act(Component c) {
c.lock(); c.lock();
@ -963,7 +955,7 @@ public class Page extends SimpleComponent implements Container {
if (m_componentMap.get(key) != null) { if (m_componentMap.get(key) != null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Component key must not be duplicated. The key " + key "Component key must not be duplicated. The key " + key
+ " is shared by more than one component."); + " is shared by more than one component.");
} }
m_componentMap.put(key, c); m_componentMap.put(key, c);
m_components.add(c); m_components.add(c);
@ -1026,8 +1018,7 @@ public class Page extends SimpleComponent implements Container {
* 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
* @pos
* t !contains(c) implies return == -1 * t !contains(c) implies return == -1
*/ */
public int stateIndex(Component c) { public int stateIndex(Component c) {
@ -1055,8 +1046,7 @@ public class Page extends SimpleComponent implements Container {
/** /**
* Gets a page component by index. * Gets a page component by index.
* *
* @pre (i >= 0) && (i < size()) * @pre (i >= 0) && (i < size()) @pos
* @pos
* t return != null * t return != null
*/ */
public Component getComponent(int i) { public Component getComponent(int i) {
@ -1152,6 +1142,7 @@ public class Page extends SimpleComponent implements Container {
void reset(final PageState ps, Component cmpnt) { void reset(final PageState ps, Component cmpnt) {
Traversal resetter = new Traversal() { Traversal resetter = new Traversal() {
@Override @Override
protected void act(Component c) { protected void act(Component c) {
Collection cp = getComponentParameters(c); Collection cp = getComponentParameters(c);
@ -1184,8 +1175,8 @@ public class Page extends SimpleComponent implements Container {
} else { } else {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Cannot generate prefix for component: key is null " "Cannot generate prefix for component: key is null "
+ "and component " + c.toString() + "/" + c.getKey() + "and component " + c.toString() + "/" + c.getKey()
+ " did not register with page."); + " did not register with page.");
} }
} }
return COMPONENT_PREFIX + key + DELIMITER; return COMPONENT_PREFIX + key + DELIMITER;

View File

@ -26,18 +26,15 @@ import com.arsdigita.bebop.Bebop;
import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.ParameterModel; import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter; import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.web.Web;
import com.arsdigita.xml.Element; import com.arsdigita.xml.Element;
/** /**
* Displays and manages a WYSIWYG HTML editor that takes advantage of * Displays and manages a WYSIWYG HTML editor that takes advantage of DHTML scripting features. This
* DHTML scripting features. * class can use: - <a href="http://www.xinha.org>Xinha</a>
* This class can use:
* - <a href="http://www.xinha.org>Xinha</a>
* - <a href="http://www.fckeditor.net">FCKeditor</a> * - <a href="http://www.fckeditor.net">FCKeditor</a>
* - HTMLarea for backwards compatibility, development discontinued * - HTMLarea for backwards compatibility, development discontinued Editor is choosen based on the
* Editor is choosen based on the config parameter waf.bebop.dhtml_editor, * config parameter waf.bebop.dhtml_editor, default is "Xinha", which is the successor of HTMLarea
* default is "Xinha", which is the successor of HTMLarea
* *
* @author Jim Parsons * @author Jim Parsons
* @author Richard Li * @author Richard Li
@ -49,17 +46,18 @@ import com.arsdigita.xml.Element;
public class DHTMLEditor extends TextArea { public class DHTMLEditor extends TextArea {
/** /**
* Constant for specifying <tt>OFF</tt> value for the <tt>WRAP</tt> attribute * Constant for specifying <tt>OFF</tt> value for the <tt>WRAP</tt> attribute of this image
* of this image input. * input.
* *
* See <a href="http: * See <a href="http:
* //developer.netscape.com/docs/manuals/htmlguid/tags10.htm#1340340">here</a> * //developer.netscape.com/docs/manuals/htmlguid/tags10.htm#1340340">here</a>
* for a description of what this attribute does. */ * for a description of what this attribute does.
*/
public static final int OFF = 0; public static final int OFF = 0;
/** /**
* Constant for specifying <tt>HARD</tt> value for the <tt>WRAP</tt> attribute * Constant for specifying <tt>HARD</tt> value for the <tt>WRAP</tt> attribute of this image
* of this image input. * input.
* *
* See <a href="http:// * See <a href="http://
* developer.netscape.com/docs/manuals/htmlguid/tags10.htm#1340340">here</a> * developer.netscape.com/docs/manuals/htmlguid/tags10.htm#1340340">here</a>
@ -68,14 +66,13 @@ public class DHTMLEditor extends TextArea {
public static final int HARD = 1; public static final int HARD = 1;
/** /**
* Constant for specifying <tt>SOFT</tt> value for the <tt>WRAP</tt> attribute * Constant for specifying <tt>SOFT</tt> value for the <tt>WRAP</tt> attribute of this image
* of this image input. See <a href="http:// * input. See <a href="http://
* developer.netscape.com/docs/manuals/htmlguid/tags10.htm#1340340">here</a> * developer.netscape.com/docs/manuals/htmlguid/tags10.htm#1340340">here</a>
* for a description of what this attribute does. * for a description of what this attribute does.
*/ */
public static final int SOFT = 2; public static final int SOFT = 2;
/** /**
* Config objects for supported DHTMP editors * Config objects for supported DHTMP editors
*/ */
@ -83,23 +80,22 @@ public class DHTMLEditor extends TextArea {
// WARNING: Processing of these default values by CMSConfig does NOT // WARNING: Processing of these default values by CMSConfig does NOT
// work correctly because of deviciencies in unmarshal method there. // work correctly because of deviciencies in unmarshal method there.
public static final Config STANDARD = new Config("Xinha.Config",
public static final Config STANDARD = "/assets/xinha/CCMcoreXinhaConfig.js");
new Config("Xinha.Config",
"/assets/xinha/CCMcoreXinhaConfig.js");
/** Example FCKEditor configuration. */
public static final Config FCK_STANDARD =
new Config("FCKEditor.Config.StyleDefault",
"/assets/fckeditor/config/fckconfigstyledefault.js");
public static final Config FCK_CMSADMIN =
new Config("FCKEditor.Config.StyleCMSAdmin",
"/assets/fckeditor/config/fckconfigstylecmsadmin.js");
/** Example old HTMLarea configuration. */ /**
public static final Config HTMLAREA = * Example FCKEditor configuration.
new Config("HTMLArea.Config", null); */
public static final Config FCK_STANDARD = new Config("FCKEditor.Config.StyleDefault",
"/assets/fckeditor/config/fckconfigstyledefault.js");
public static final Config FCK_CMSADMIN = new Config("FCKEditor.Config.StyleCMSAdmin",
"/assets/fckeditor/config/fckconfigstylecmsadmin.js");
/**
* Example old HTMLarea configuration.
*/
public static final Config HTMLAREA = new Config("HTMLArea.Config", null);
private String m_name; private String m_name;
private String m_path; private String m_path;
@ -107,25 +103,26 @@ public class DHTMLEditor extends TextArea {
public Config(String name) { public Config(String name) {
this(name, null); this(name, null);
} }
public Config(String name, public Config(String name,
String path) { String path) {
m_name = name; m_name = name;
m_path = path; m_path = path;
} }
public String getName() { public String getName() {
return m_name; return m_name;
} }
public String getPath() { public String getPath() {
return m_path; return m_path;
} }
public static Config valueOf(String cfg) { public static Config valueOf(String cfg) {
int offset = cfg.indexOf(","); int offset = cfg.indexOf(",");
if (offset != -1) { if (offset != -1) {
return new Config(cfg.substring(0, offset), return new Config(cfg.substring(0, offset),
cfg.substring(offset+1)); cfg.substring(offset + 1));
} else { } else {
return new Config(cfg); return new Config(cfg);
} }
@ -138,6 +135,7 @@ public class DHTMLEditor extends TextArea {
return m_name + "," + m_path; return m_name + "," + m_path;
} }
} }
} //end config object(s) } //end config object(s)
private Config m_config; private Config m_config;
@ -146,7 +144,7 @@ public class DHTMLEditor extends TextArea {
/** /**
* Constructor * Constructor
* *
* @param name * @param name
*/ */
public DHTMLEditor(String name) { public DHTMLEditor(String name) {
@ -155,6 +153,7 @@ public class DHTMLEditor extends TextArea {
/** /**
* Constructor * Constructor
*
* @param model * @param model
*/ */
public DHTMLEditor(ParameterModel model) { public DHTMLEditor(ParameterModel model) {
@ -163,6 +162,7 @@ public class DHTMLEditor extends TextArea {
/** /**
* Constructor * Constructor
*
* @param model * @param model
* @param config * @param config
*/ */
@ -175,7 +175,7 @@ public class DHTMLEditor extends TextArea {
} }
/** /**
* Returns a string naming the type of this widget. * Returns a string naming the type of this widget.
*/ */
public String getType() { public String getType() {
return "DHTMLEditor"; return "DHTMLEditor";
@ -183,15 +183,16 @@ public class DHTMLEditor extends TextArea {
public String getEditorURL() { public String getEditorURL() {
return Bebop.getConfig().getDHTMLEditorSrcFile().substring( return Bebop.getConfig().getDHTMLEditorSrcFile().substring(
0, Bebop.getConfig().getDHTMLEditorSrcFile().lastIndexOf("/") + 1); 0, Bebop.getConfig().getDHTMLEditorSrcFile().lastIndexOf("/") + 1);
} }
public String getEditorSrc() { public String getEditorSrc() {
return Bebop.getConfig().getDHTMLEditorSrcFile(); return Bebop.getConfig().getDHTMLEditorSrcFile();
} }
/** /**
* deprecated - use {@link setConfig(Config)} * deprecated - use {@link setConfig(Config)}
*
* @param config * @param config
*/ */
public void setConfig(String config) { public void setConfig(String config) {
@ -199,7 +200,7 @@ public class DHTMLEditor extends TextArea {
} }
public void setConfig(Config config) { public void setConfig(Config config) {
m_config = config; m_config = config;
} }
public void addPlugin(String name) { public void addPlugin(String name) {
@ -208,15 +209,16 @@ public class DHTMLEditor extends TextArea {
/** /**
* Prevent the specified button from being displayed in the editor toolbar. * Prevent the specified button from being displayed in the editor toolbar.
*
* @param name name of the button, as specified in the btnList of the htmlarea.js file * @param name name of the button, as specified in the btnList of the htmlarea.js file
* *
*/ */
public void hideButton(String name) { public void hideButton(String name) {
m_hiddenButtons.add(name); m_hiddenButtons.add(name);
} }
/** /**
* Sets the <tt>ROWS</tt> attribute for the <tt>TEXTAREA</tt> tag. * Sets the <tt>ROWS</tt> attribute for the <tt>TEXTAREA</tt> tag.
*/ */
@Override @Override
public void setRows(int rows) { public void setRows(int rows) {
@ -224,7 +226,7 @@ public class DHTMLEditor extends TextArea {
} }
/** /**
* Sets the <tt>COLS</tt> attribute for the <tt>TEXTAREA</tt> tag. * Sets the <tt>COLS</tt> attribute for the <tt>TEXTAREA</tt> tag.
*/ */
@Override @Override
public void setCols(int cols) { public void setCols(int cols) {
@ -232,22 +234,22 @@ public class DHTMLEditor extends TextArea {
} }
/** /**
* Sets the <tt>COLS</tt> attribute for the <tt>TEXTAREA</tt> tag. * Sets the <tt>COLS</tt> attribute for the <tt>TEXTAREA</tt> tag.
*/ */
@Override @Override
public void setWrap(int wrap) { public void setWrap(int wrap) {
String wrapString = null; String wrapString = null;
switch (wrap) { switch (wrap) {
case OFF: case OFF:
wrapString = "off"; wrapString = "off";
break; break;
case HARD: case HARD:
wrapString = "hard"; wrapString = "hard";
break; break;
case SOFT: case SOFT:
wrapString = "soft"; wrapString = "soft";
break; break;
} }
if (wrapString != null) { if (wrapString != null) {
@ -258,8 +260,7 @@ public class DHTMLEditor extends TextArea {
/** /**
* The XML tag. * The XML tag.
* *
* @return The tag to be used for the top level DOM element * @return The tag to be used for the top level DOM element generated for this type of Widget.
* generated for this type of Widget.
*/ */
@Override @Override
protected String getElementTag() { protected String getElementTag() {
@ -268,49 +269,52 @@ public class DHTMLEditor extends TextArea {
/** /**
* Generates the DOM for the DHTML editor widget * Generates the DOM for the DHTML editor widget
* <p>Generates DOM fragment: * <p>
* <p><code>&lt;bebop:dhtmleditor name=... value=... [onXXX=...]/> * Generates DOM fragment:
* </code> * <p>
* <code>&lt;bebop:dhtmleditor name=... value=... [onXXX=...]/>
* </code>
*/ */
@Override @Override
public void generateWidget( PageState state, Element parent ) { public void generateWidget(PageState state, Element parent) {
String value = getParameterData(state).marshal(); String value = getParameterData(state).marshal();
Element editor = parent.newChildElement(getElementTag(), BEBOP_XML_NS); Element editor = parent.newChildElement(getElementTag(), BEBOP_XML_NS);
editor.addAttribute("name", getName()); editor.addAttribute("name", getName());
// Set the needed config params so they don't have to be hardcoded in the theme // Set the needed config params so they don't have to be hardcoded in the theme
editor.addAttribute("editor_url", getEditorURL()); editor.addAttribute("editor_url", Web.getWebappContextPath().concat(getEditorURL()));
editor.addAttribute("editor_src", getEditorSrc()); editor.addAttribute("editor_src", Web.getWebappContextPath().concat(getEditorSrc()));
if ( value != null ) { if (value != null) {
editor.setText(value); editor.setText(value);
} }
exportAttributes(editor); exportAttributes(editor);
Element config = editor.newChildElement("bebop:config", BEBOP_XML_NS); Element config = editor.newChildElement("bebop:config", BEBOP_XML_NS);
config.addAttribute("name", m_config.getName()); config.addAttribute("name", m_config.getName());
if (m_config.getPath() != null) { if (m_config.getPath() != null) {
config.addAttribute("path", m_config.getPath()); config.addAttribute("path", Web.getWebappContextPath().concat(m_config.getPath()));
} }
if (m_hiddenButtons.size() > 0) { if (m_hiddenButtons.size() > 0) {
StringBuffer hiddenButtons = new StringBuffer(); StringBuffer hiddenButtons = new StringBuffer();
// list must start and end with a space // list must start and end with a space
hiddenButtons.append(" "); hiddenButtons.append(" ");
Iterator hidden = m_hiddenButtons.iterator(); Iterator hidden = m_hiddenButtons.iterator();
while (hidden.hasNext()) { while (hidden.hasNext()) {
hiddenButtons.append(hidden.next()); hiddenButtons.append(hidden.next());
hiddenButtons.append(" "); hiddenButtons.append(" ");
} }
config.addAttribute("hidden-buttons", hiddenButtons.toString()); config.addAttribute("hidden-buttons", hiddenButtons.toString());
} }
Iterator plugins = m_plugins.iterator(); Iterator plugins = m_plugins.iterator();
while (plugins.hasNext()) { while (plugins.hasNext()) {
String name = (String)plugins.next(); String name = (String) plugins.next();
Element plugin = editor.newChildElement("bebop:plugin", BEBOP_XML_NS); Element plugin = editor.newChildElement("bebop:plugin", BEBOP_XML_NS);
plugin.addAttribute("name", name); plugin.addAttribute("name", name);
} }
} }
} }