666 lines
19 KiB
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(" ");
|
|
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
|