venice-dynamo-rewrite/src/dynamo-framework/com/silverwrist/dynamo/dialog/DialogImpl.java

666 lines
19 KiB
Java

/*
* The contents of this file are subject to the Mozilla Public License Version 1.1
* (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
*
* Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
* WARRANTY OF ANY KIND, either express or implied. See the License for the specific
* language governing rights and limitations under the License.
*
* The Original Code is the Venice Web Communities System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.dynamo.dialog;
import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import com.silverwrist.util.*;
import com.silverwrist.util.xml.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.except.*;
class DialogImpl implements Dialog
{
/*--------------------------------------------------------------------------------
* Internal class to "peel off" certain dialog items that are tags
*--------------------------------------------------------------------------------
*/
private class InternalFilter implements DialogItemFactory
{
/*====================================================================
* Attributes
*====================================================================
*/
private DialogItemFactory m_inner;
private HashMap m_rp = new HashMap();
/*====================================================================
* Constructor
*====================================================================
*/
InternalFilter(DialogItemFactory inner)
{
m_inner = inner;
} // end constructor
/*====================================================================
* Implementations from interface DialogItemFactory
*====================================================================
*/
public DialogItem createDialogItem(Element elt, DialogPLAF plaf) throws DialogException
{
try
{ // strip out certain items we need from the element stream
XMLLoader loader = XMLLoader.get();
String tagname = elt.getTagName();
if (tagname.equals("title"))
{ // get title
m_default_title = loader.getText(elt);
if (m_default_title!=null)
m_default_title = m_default_title.trim();
} // end if
else if (tagname.equals("subtitle"))
{ // get subtitle (not required)
DOMElementHelper h = new DOMElementHelper(elt);
m_default_subtitle = h.getElementText();
if (m_default_subtitle!=null)
m_default_subtitle = m_default_subtitle.trim();
} // end else if
else if (tagname.equals("action"))
{ // get action and action type
m_action = loader.getText(elt);
if (m_action!=null)
m_action = m_action.trim();
m_action_type = loader.getAttribute(elt,"type","SERVLET");
} // end else if
else if (tagname.equals("render-param"))
{ // get a rendering parameter
String name = loader.getAttribute(elt,"name");
DOMElementHelper h = new DOMElementHelper(elt);
String value = h.getElementText();
if (value!=null)
value = value.trim();
else
value = "";
m_rp.put(name,value);
} // end else if
else if (tagname.equals("instructions"))
{ // get instructions (not required)
DOMElementHelper h = new DOMElementHelper(elt);
m_default_instructions = h.getElementText();
if (m_default_instructions!=null)
m_default_instructions = m_default_instructions.trim();
} // end else if
else // go create a dialog item
return m_inner.createDialogItem(elt,plaf);
} // end try
catch (XMLLoadException e)
{ // translate XML Load exception to dialog exception
throw new DialogException(e);
} // end catch
return null;
} // end createDialogItem
/*====================================================================
* External operations
*====================================================================
*/
Map renderParams()
{
if (m_rp.isEmpty())
return Collections.EMPTY_MAP;
else
return Collections.unmodifiableMap(m_rp);
} // end renderParams
} // end class InternalFilter
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private DialogPLAF m_plaf;
private String m_name;
private String m_default_button = null;
private String m_default_title = null;
private String m_default_subtitle = null;
private String m_action = null;
private String m_action_type = null;
private String m_default_instructions = null;
private boolean m_any_required;
private boolean m_need_multipart;
private List m_field_order;
private Map m_field_map;
private List m_button_order;
private Map m_button_map;
private List m_hidden_order;
private Map m_hidden_map;
private String m_title = null;
private String m_subtitle = null;
private String m_instructions = null;
private String m_error_message = null;
private Map m_default_render_params;
private HashMap m_render_params;
private Object m_upper_content = null;
private Object m_lower_content = null;
/*--------------------------------------------------------------------------------
* Constructors
*--------------------------------------------------------------------------------
*/
DialogImpl(Element dialog_element, DialogItemFactory item_factory, DialogPLAF plaf) throws DialogException
{
// Copy the look-and-feel object reference.
m_plaf = plaf;
// Get the basic stuff from the root tag itself.
XMLLoader loader = XMLLoader.get();
try
{ // get the dialog name
m_name = loader.getAttribute(dialog_element,"name");
m_default_button = dialog_element.getAttribute("defaultbutton");
} // end try
catch (XMLLoadException e)
{ // translate to DialogException
throw new DialogException(e);
} // end catch
// Load the fields.
ArrayList field_order = new ArrayList();
HashMap field_map = new HashMap();
ArrayList button_order = new ArrayList();
HashMap button_map = new HashMap();
ArrayList hidden_order = new ArrayList();
HashMap hidden_map = new HashMap();
int global_flags = 0;
InternalFilter factory = new InternalFilter(item_factory);
NodeList nl = dialog_element.getChildNodes();
for (int i=0; i<nl.getLength(); i++)
{ // get each item to be implemented here
Node n = nl.item(i);
if (n.getNodeType()==Node.ELEMENT_NODE)
{ // create the dialog items
DialogItem item = factory.createDialogItem((Element)n,plaf);
if (item==null)
continue;
if (item instanceof DialogField)
{ // add the field to the field data structures
global_flags |= ((DialogField)item).getFlags();
field_order.add(item);
field_map.put(item.getName(),item);
} // end if
else if (item instanceof DialogButton)
{ // add the button to the button data structures
button_order.add(item);
button_map.put(item.getName(),item);
} // end else if
else if (item instanceof DialogHiddenItem)
{ // add the hidden item to the hidden data structures
hidden_order.add(item);
hidden_map.put(item.getName(),item);
} // end else if
} // end if
} // end for
// If anything hasn't been specified that should have been, error out now.
if (m_default_title==null)
{ // no default title specified
DialogException de = new DialogException(DialogImpl.class,"DialogMessages","dlg.noTitle");
de.setParameter(0,m_name);
throw de;
} // end if
if (m_action==null)
{ // no action URL specified
DialogException de = new DialogException(DialogImpl.class,"DialogMessages","dlg.noAction");
de.setParameter(0,m_name);
throw de;
} // end if
// "Freeze" the data structures.
field_order.trimToSize();
m_field_order = Collections.unmodifiableList(field_order);
m_field_map = Collections.unmodifiableMap(field_map);
button_order.trimToSize();
m_button_order = Collections.unmodifiableList(button_order);
m_button_map = Collections.unmodifiableMap(button_map);
hidden_order.trimToSize();
m_hidden_order = Collections.unmodifiableList(hidden_order);
m_hidden_map = Collections.unmodifiableMap(hidden_map);
m_default_render_params = factory.renderParams();
// Set the global flags.
m_any_required = ((global_flags & DialogField.FLAG_REQUIRED)!=0);
m_need_multipart = ((global_flags & DialogField.FLAG_ISFILE)!=0);
// Copy defaults to working values.
m_title = m_default_title;
m_subtitle = m_default_subtitle;
m_instructions = m_default_instructions;
m_error_message = null;
m_render_params = new HashMap(m_default_render_params);
} // end constructor
protected DialogImpl(DialogImpl other)
{
// Copy the base data.
m_plaf = other.m_plaf;
m_name = other.m_name;
m_default_title = other.m_default_title;
m_default_subtitle = other.m_default_subtitle;
m_action = other.m_action;
m_action_type = other.m_action_type;
m_default_instructions = other.m_default_instructions;
m_any_required = other.m_any_required;
m_need_multipart = other.m_need_multipart;
m_default_render_params = other.m_default_render_params;
// Clone off the fields.
ArrayList order = new ArrayList();
HashMap map = new HashMap();
Iterator it = other.m_field_order.iterator();
while (it.hasNext())
{ // clone all the fields
DialogField fld = (DialogField)(it.next());
DialogField new_fld = (DialogField)(fld.clone());
order.add(new_fld);
map.put(new_fld.getName(),new_fld);
} // end while
// "Freeze" the field data structures.
order.trimToSize();
m_field_order = Collections.unmodifiableList(order);
m_field_map = Collections.unmodifiableMap(map);
// Since the buttons aren't modified, we can get away with sharing
// the button order and button map.
m_button_order = other.m_button_order;
m_button_map = other.m_button_map;
// Clone off the hidden fields.
order = new ArrayList();
map = new HashMap();
it = other.m_hidden_order.iterator();
while (it.hasNext())
{ // clone all the fields
DialogHiddenItem fld = (DialogHiddenItem)(it.next());
DialogHiddenItem new_fld = (DialogHiddenItem)(fld.clone());
order.add(new_fld);
map.put(new_fld.getName(),new_fld);
} // end while
// "Freeze" the field data structures.
order.trimToSize();
m_hidden_order = Collections.unmodifiableList(order);
m_hidden_map = Collections.unmodifiableMap(map);
// Copy defaults to working values.
m_title = m_default_title;
m_subtitle = m_default_subtitle;
m_instructions = m_default_instructions;
m_error_message = null;
m_render_params = new HashMap(m_default_render_params);
} // end constructor
/*--------------------------------------------------------------------------------
* Internal operations
*--------------------------------------------------------------------------------
*/
protected final DialogField getField(String name)
{
return (DialogField)(m_field_map.get(name));
} // end getField
protected final DialogHiddenItem getHiddenItem(String name)
{
return (DialogHiddenItem)(m_hidden_map.get(name));
} // end getHiddenItem
/*--------------------------------------------------------------------------------
* Implementations from interface NamedObject
*--------------------------------------------------------------------------------
*/
public String getName()
{
return m_name;
} // end getName
/*--------------------------------------------------------------------------------
* Implementations from interface Dialog
*--------------------------------------------------------------------------------
*/
public Object clone()
{
return new DialogImpl(this);
} // end clone
public void render(TextRenderControl control) throws IOException, RenderingException
{
PrintWriter wr = control.getWriter();
URLRewriter rewriter = (URLRewriter)(control.queryService(URLRewriter.class));
// Get the content header and render it.
control.renderSubObject(m_plaf.getContentHeader(m_title,m_subtitle));
// Render the "upper content" object, if any.
if (m_upper_content!=null)
control.renderSubObject(m_upper_content);
// Write the error message.
if (m_error_message!=null)
wr.write("<p align=\"center\" class=\"content\" style=\"color: red; font-weight: bold;\">\n"
+ StringUtils.encodeHTML(m_error_message) + "\n</p>\n");
// Write the start of the form.
wr.write("<form name=\"" + m_name + "\"");
if (m_need_multipart)
wr.write(" enctype=\"multipart/form-data\"");
wr.write(" method=\"POST\" action=\"" + rewriter.rewriteURL(m_action_type,m_action)
+ "\"><div class=\"content\">\n");
// Create the render params parameter.
Map rparam = Collections.unmodifiableMap(m_render_params);
// Render the hidden fields.
Iterator it = m_hidden_order.iterator();
while (it.hasNext())
{ // render each hidden field in turn
DialogHiddenItem hfld = (DialogHiddenItem)(it.next());
hfld.render(control,rparam);
} // end while
// Render the instructions and such.
if (m_instructions!=null)
wr.write("<p>" + m_instructions + "</p>\n");
if (m_any_required)
{ // write out the "required" instructions
ResourceBundle b = ResourceBundle.getBundle("com.silverwrist.dynamo.dialog.DialogMessages",
Locale.getDefault());
wr.write("<p>" + b.getString("required.msg") + "</p>");
} // end if
// Write the form fields out inside a table.
wr.write("<table border=\"0\" align=\"center\" cellpadding=\"6\" cellspacing=\"0\">\n");
it = m_field_order.iterator();
while (it.hasNext())
{ // render each field in turn
DialogField fld = (DialogField)(it.next());
fld.render(control,rparam);
} // end while
wr.write("</table>\n");
if (!(m_button_order.isEmpty()))
{ // render the command buttons at the button
boolean is_first = true;
wr.write("<p align=\"center\" class=\"content\">");
it = m_button_order.iterator();
while (it.hasNext())
{ // render each button in turn, spacing them out
DialogButton bn = (DialogButton)(it.next());
if (is_first)
is_first = false;
else
wr.write("&nbsp;&nbsp;");
bn.render(control,rparam);
} // end while
wr.write("</p>\n");
} // end if
wr.write("</div></form>\n");
// Render the "lower content" object, if any.
if (m_lower_content!=null)
control.renderSubObject(m_lower_content);
} // end render
public void reset()
{
m_title = m_default_title;
m_subtitle = m_default_subtitle;
m_instructions = m_default_instructions;
Iterator it = m_field_order.iterator();
while (it.hasNext())
{ // call reset on each field
DialogField fld = (DialogField)(it.next());
fld.reset();
} // end while
it = m_hidden_order.iterator();
while (it.hasNext())
{ // call reset on each hidden field
DialogHiddenItem hfld = (DialogHiddenItem)(it.next());
hfld.reset();
} // end while
} // end reset
public void load(Request r)
{
Iterator it = m_field_order.iterator();
while (it.hasNext())
{ // call setValueFrom on each field
DialogField fld = (DialogField)(it.next());
fld.setValueFrom(r);
} // end while
it = m_hidden_order.iterator();
while (it.hasNext())
{ // call setValueFrom on each hidden field
DialogHiddenItem hfld = (DialogHiddenItem)(it.next());
hfld.setValueFrom(r);
} // end while
} // end load
public Object getValue(String fieldname)
{
DialogField fld = getField(fieldname);
if (fld==null)
{ // try looking for a hidden field
DialogHiddenItem hfld = getHiddenItem(fieldname);
if (hfld==null)
return null;
else
return hfld.getValue();
} // end if
else
return fld.getValue();
} // end getValue
public boolean containsValue(String fieldname)
{
DialogField fld = getField(fieldname);
if (fld!=null)
return fld.containsValue();
DialogHiddenItem hfld = getHiddenItem(fieldname);
if (hfld!=null)
return hfld.containsValue();
return false;
} // end containsValue
public void setValue(String fieldname, Object value)
{
DialogField fld = getField(fieldname);
if (fld!=null)
fld.setValue(value);
else
{ // try setting a hidden value
DialogHiddenItem hfld = getHiddenItem(fieldname);
if (hfld!=null)
hfld.setValue(value);
} // end else
} // end setValue
public boolean isEnabled(String fieldname)
{
DialogField fld = getField(fieldname);
if (fld==null)
return false;
else
return fld.isEnabled();
} // end isEnabled
public void setEnabled(String fieldname, boolean flag)
{
DialogField fld = getField(fieldname);
if (fld!=null)
fld.setEnabled(flag);
} // end setEnabled
public void validate(Request r) throws ValidationException
{
// validate all the fields individually
Iterator it = m_field_order.iterator();
while (it.hasNext())
{ // call reset on each field
DialogField fld = (DialogField)(it.next());
fld.validate(r);
} // end while
} // end validate
public String getTitle()
{
return m_title;
} // end getTitle
public void setTitle(String s)
{
m_title = s;
} // end setTitle
public String getSubtitle()
{
return m_subtitle;
} // end getSubtitle
public void setSubtitle(String s)
{
m_subtitle = s;
} // end setSubtitle
public String getInstructions()
{
return m_instructions;
} // end getInstructions
public void setInstructions(String s)
{
m_instructions = s;
} // end setInstructions
public void setErrorMessage(String s)
{
m_error_message = s;
} // end setErrorMessage
public String getClickedButton(Request r)
{
Iterator it = m_button_order.iterator();
while (it.hasNext())
{ // look for a clicked button
DialogButton bn = (DialogButton)(it.next());
if (bn.isClicked(r))
return bn.getName();
} // end while
return m_default_button;
} // end getClickedButton
public synchronized void setRenderParam(String name, String value)
{
if (m_render_params.containsKey(name))
m_render_params.put(name,value);
} // end setRenderParam
public synchronized void setUpperContentObject(Object o)
{
m_upper_content = o;
} // end setUpperContentObject
public synchronized void setLowerContentObject(Object o)
{
m_lower_content = o;
} // end setLowerContentObject
} // end class DialogImpl