blob: cd12f05aa35989b716e8f37514ed96afae0f6034 [file] [log] [blame]
/*
* $Id$
* $Revision$
* $Date$
*
* ================================================================================
* Copyright (c)
* All rechten voorbehouden.
*/
package objectedit;
import java.beans.IndexedPropertyDescriptor;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import wicket.AttributeModifier;
import wicket.WicketRuntimeException;
import wicket.markup.html.basic.Label;
import wicket.markup.html.form.TextField;
import wicket.markup.html.list.ListItem;
import wicket.markup.html.list.ListView;
import wicket.markup.html.panel.Panel;
import wicket.model.IModel;
import wicket.model.Model;
/**
* Panel for generic bean displaying/ editing.
*
* @author Eelco Hillenius
*/
public class BeanPanel extends Panel
{
/** cache for editors. */
private static Map cachedEditors = new HashMap();
/** edit mode. */
private EditMode editMode = new EditMode(EditMode.MODE_READ_ONLY);
/**
* Construct.
* @param id component id
* @param bean JavaBean to be edited or displayed
*/
public BeanPanel(String id, Serializable bean)
{
this(id, new Model(bean));
}
/**
* Construct.
* @param id component id
* @param beanModel model with the JavaBean to be edited or displayed
*/
public BeanPanel(String id, IModel beanModel)
{
super(id, beanModel);
add(new Label("displayName", new DisplayNameModel(beanModel)));
add(new PropertyList("propertiesList", new PropertyDescriptorListModel(beanModel)));
}
/**
* Gets the editor for the given property.
* @param panelId id of panel; must be used for constructing any panel
* @param descriptor property descriptor
* @return the editor
*/
protected Panel getPropertyEditor(String panelId, PropertyDescriptor descriptor)
{
Class type = descriptor.getPropertyType();
PropertyEditor editor = (PropertyEditor)cachedEditors.get(type);
if (editor != null)
{
return editor;
}
editor = findCustomEditor(panelId, descriptor);
if (editor == null)
{
if (descriptor instanceof IndexedPropertyDescriptor)
{
throw new WicketRuntimeException("index properties not supported yet ");
}
else
{
editor = new SimplePropertyPanel(panelId, getModel(), descriptor);
}
}
cachedEditors.put(type, editor);
return editor;
}
/**
* Finds a possible custom editor by looking for the type name + 'PropertyEditor'
* (e.g. mypackage.MyBean has editor mypackage.MyBeanEditor).
* @param panelId id of panel; must be used for constructing any panel
* @param descriptor property descriptor
* @return PropertyEditor if found or null
*/
private PropertyEditor findCustomEditor(String panelId, PropertyDescriptor descriptor)
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null)
{
classLoader = getClass().getClassLoader();
}
Class type = descriptor.getPropertyType();
String editorTypeName = type.getName() + "PropertyEditor";
try
{
Class editorClass = classLoader.loadClass(editorTypeName);
try
{
Constructor constructor = editorClass.getConstructor(
new Class[]{String.class, IModel.class, PropertyDescriptor.class});
Object[] args = new Object[]{panelId, BeanPanel.this.getModel(), descriptor};
PropertyEditor editor = (PropertyEditor)constructor.newInstance(args);
return editor;
}
catch (SecurityException e)
{
throw new WicketRuntimeException(e);
}
catch (NoSuchMethodException e)
{
throw new WicketRuntimeException(e);
}
catch (InstantiationException e)
{
throw new WicketRuntimeException(e);
}
catch (IllegalAccessException e)
{
throw new WicketRuntimeException(e);
}
catch (InvocationTargetException e)
{
throw new WicketRuntimeException(e);
}
}
catch(ClassNotFoundException e)
{
// ignore; there just is no custom editor
}
return null;
}
/**
* Lists all properties of the target object.
*/
private final class PropertyList extends ListView
{
/**
* Construct.
* @param id component name
* @param model the model
*/
public PropertyList(String id, PropertyDescriptorListModel model)
{
super(id, model);
}
/**
* @see wicket.markup.html.list.ListView#populateItem(wicket.markup.html.list.ListItem)
*/
protected void populateItem(ListItem item)
{
PropertyDescriptor descriptor = (PropertyDescriptor)item.getModelObject();
item.add(new Label("displayName", descriptor.getDisplayName()));
Panel propertyEditor = getPropertyEditor("editor", descriptor);
item.add(propertyEditor);
}
}
/**
* Default panel for a simple property.
*/
private final class SimplePropertyPanel extends PropertyEditor
{
/**
* Construct.
* @param id component id
* @param beanModel model with the target bean
* @param descriptor property descriptor
*/
public SimplePropertyPanel(String id, IModel beanModel, final PropertyDescriptor descriptor)
{
super(id, beanModel, descriptor);
Class type = descriptor.getPropertyType();
TextField valueTextField = new TextField("value",
new PropertyDescriptorModel(beanModel, descriptor), type);
EditModeReplacementModel replacementModel =
new EditModeReplacementModel(editMode, descriptor);
valueTextField.add(new AttributeModifier("disabled", false, replacementModel));
add(valueTextField);
}
}
}