001    package com.sptci.echo2;
002    
003    import java.beans.PropertyChangeEvent;
004    import java.beans.IntrospectionException;
005    import java.beans.PropertyDescriptor;
006    import java.io.Serializable;
007    import java.util.HashMap;
008    import java.util.logging.Logger;
009    
010    import nextapp.echo2.app.ListBox;
011    import nextapp.echo2.app.SelectField;
012    import nextapp.echo2.app.button.AbstractButton;
013    import nextapp.echo2.app.text.TextComponent;
014    
015    /**
016     * A sub-class of {@link PropertyChangeListener} used to synchronise 
017     * changes made to properties in Echo2 UI components to the
018     * {@link #bean} java bean.
019     *
020     * <p>Copyright 2006 Sans Pareil Technologies, Inc.</p>
021     * @author Rakesh Vidyadharan 2006-01-22
022     * @version $Id: ModelPropertyChangeListener.java,v 1.1 2006/02/13 23:07:28 rakesh Exp $
023     */
024    public class ModelPropertyChangeListener extends PropertyChangeListener 
025      implements Serializable
026    {
027      /**
028       * The logger used to log errors to
029       */
030      private static transient final Logger logger =
031        Logger.getLogger( "com.sptci.echo2.ModelPropertyChangeListener" );
032    
033      /**
034       * Create a new instance of the class using the specified java bean.
035       *
036       * @param bean The data object which is to be managed.
037       * @throws IntrospectionException If errors are encountered while
038       *   introspecting the {@link #bean} class.
039       */
040      public ModelPropertyChangeListener( Object bean )
041        throws IntrospectionException
042      {
043        super( bean );
044      }
045    
046      /**
047       * Over-riddent implementation of the method defined in <code>
048       * PropertyChangeListener</code>.  Checks for valid <code>Echo2
049       * </code> components and ignores all other mouse and keyboard
050       * events.
051       *
052       * @see #modify
053       * @param event A <code>PropertyChangeEvent</code> object describing 
054       *   the event source and the property that has changed.
055       * @throws BindingException If errors are encountered while
056       *   attempting to modify the {@link #bean}.
057       */
058      public void propertyChange( PropertyChangeEvent event )
059      {
060        String name = null;
061    
062        if ( event.getSource() instanceof 
063            nextapp.echo2.app.text.TextComponent && 
064            event.getPropertyName().equals( "text" ) )
065        {
066          name = ( (TextComponent) event.getSource() ).getActionCommand();
067        }
068        else if ( event.getSource() instanceof 
069            nextapp.echo2.app.button.AbstractButton && 
070            event.getPropertyName().equals( "selected" ) )
071        {
072          name = ( (AbstractButton) event.getSource() ).getActionCommand();
073        }
074        else if ( event.getSource() instanceof nextapp.echo2.app.SelectField )
075        {
076          SelectField field = (SelectField) event.getSource();
077          name = field.getActionCommand();
078          Object newValue = field.getSelectedItem();
079          event = new PropertyChangeEvent( event.getSource(),
080              name, event.getOldValue(), newValue );
081        }
082        else if ( event.getSource() instanceof nextapp.echo2.app.ListBox )
083        {
084          ListBox box = (ListBox) event.getSource();
085          name = box.getActionCommand();
086          Object newValue = box.getSelectedValues();
087          event = new PropertyChangeEvent( event.getSource(),
088              name, event.getOldValue(), newValue );
089        }
090        else
091        {
092          logger.warning( "unknown event source: " + event.getSource() +
093              " name: " + event.getPropertyName() +
094              " value: " + event.getNewValue() );
095        }
096    
097        modify( name, event );
098      }
099    
100      /**
101       * Modify the property with the specified <code>name</code> with the 
102       * new value in the specified <code>event</code>.
103       *
104       * @see #parseName
105       * @param name The name of the field that is to be modified.
106       * @param event A <code>PropertyChangeEvent</code> object describing 
107       *   the event source and the property that has changed.
108       * @throws BindingException If errors are encountered while
109       *   attempting to modify the field with <code>name</code> in
110       *   {@link #bean}.
111       */
112      protected void modify( String name, PropertyChangeEvent event )
113      {
114        name = parseName( name );
115        PropertyDescriptor descriptor = properties.get( name );
116        if ( descriptor != null )
117        {
118          if ( descriptor.getWriteMethod() == null )
119          {
120            throw new BindingException( "No write method for property: " +
121                event.getPropertyName() + " in bean: " +
122                bean.getClass().getName() );
123          }
124    
125          if ( descriptor.getPropertyType().isPrimitive() )
126          {
127            modifyPrimitive( event, descriptor );
128          }
129          else
130          {
131            modifyObject( event, descriptor );
132          }
133        }
134      }
135    }