/*<license>
  Copyright 2004, PeopleWare n.v.
  NO RIGHTS ARE GRANTED FOR THE USE OF THIS SOFTWARE, EXCEPT, IN WRITING,
  TO SELECTED PARTIES.
</license>*/
package be.peopleware.value_II;


import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
import java.util.Locale;

import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.convert.ConverterException;
import javax.faces.el.EvaluationException;
import javax.faces.el.ValueBinding;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * <p>This implementation of {@link AbstractPropertyEditorConverter} finds
 *   the target type by looking at the <code>component</code> value binding,
 *   and finds a {@link PropertyEditor} by asking the {@link PropertyEditorManager}
 *   one for the target type. This means a converter of this type
 *   works completely automatic if the system can find the
 *   {@link PropertyEditor} type.</p>
 * <p><strong>It is however still necessary to tell JavaServer Faces about
 *   this converter for each separate type that needs to use it, with an
 *   entry in <kbd>faces-config.xml</kbd>:</strong></p>
 * <pre>
 * &lt;converter&gt;
 *   &lt;converter-for-class&gt;<var>FqcnOfTargetType</var>&lt;/converter-for-class&gt;
 *   &lt;converter-class&gt;be.peopleware.jsf_II.convert.AutomaticPropertyEditorConverter&lt;/converter-class&gt;
 * &lt;/converter&gt;
 * </pre>
 *
 * @author Jan Dockx
 * @author PeopleWare n.v.
 */
public class AutomaticPropertyEditorConverter extends AbstractPropertyEditorConverter {

  /*<section name="Meta Information">*/
  //------------------------------------------------------------------
  /** {@value} */
  public static final String CVS_REVISION = "$Revision$"; //$NON-NLS-1$
  /** {@value} */
  public static final String CVS_DATE = "$Date$"; //$NON-NLS-1$
  /** {@value} */
  public static final String CVS_STATE = "$State$"; //$NON-NLS-1$
  /** {@value} */
  public static final String CVS_TAG = "$Name$"; //$NON-NLS-1$
  /*</section>*/

  private static final Log LOG =
    LogFactory.getLog(AutomaticPropertyEditorConverter.class);


  /**
   * A {@link PropertyEditor} for the
   * {@link ValueBinding#getType(FacesContext) type of the value binding}
   * is requested from the {@link PropertyEditorManager}. If no such
   * editor is found, a {@link ConverterException} is thrown.
   * If the retrieved {@link PropertyEditor} is of type,
   * {@link DisplayLocaleBasedEnumerationValueEditor},
   * the {@link DisplayLocaleBasedEnumerationValueEditor#setDisplayLocale(Locale) display locale}
   * of the editor is set to the locale of the current {@link UIViewRoot}.
   *
   * @basic
   * @throws ConverterException
   *         PropertyEditorManager.findEditor(
   *           component.getValueBinding("value").getType(context)
   *         ) == null;
   *         No {@link PropertyEditor} found for the type of the value binding
   *         of <code>component</code>
   */
  protected PropertyEditor getPropertyEditor(final FacesContext context,
      final UIComponent component) throws ConverterException {
    assert component != null;
    assert context != null;
    if ($propertyEditor == null) {
      LOG.debug("no PropertyEditor in cache; retrieving fresh one");
      try {
        // try to find target type
        Class targetType = component.getValueBinding("value").getType(context);
          /* throws EvaluationException < PropertyNotFoundException
             throws NullPointerException, not  for component == null, context == null
             or "value" == null, but because their might not be a value binding */
        if (targetType.isArray()) {
          LOG.debug("target type " + targetType + " is an array. Converting " +
                    "arrays makes no sense, we probably want to convert elements " +
                    "of the array (and the component is a compound handling " +
                    "component, like selectMany). We'll look for a converter for the " +
                    "component type.");
          targetType = targetType.getComponentType();
        }
        // try to find a property editor for target type
        LOG.debug("target type of component value binding \"value\": " + targetType);
        $propertyEditor = PropertyEditorManager.findEditor(targetType);
        if ($propertyEditor == null) { // still
          LOG.debug("no PropertyEditor found for type \"" + targetType + "\"");
          throw new ConverterException("Could not locate a PropertyEditor for type "
                                       + targetType);
        }
        else {
          LOG.debug("PropertyEditor found: " + $propertyEditor);
          if ($propertyEditor instanceof DisplayLocaleBasedEnumerationValueEditor) {
            assert $propertyEditor != null;
            Locale displayLocale = context.getViewRoot().getLocale();
            LOG.debug("PropertyEditor is of type DisplayLocaleBasedEnumerationValueEditor; "
                      + "setting display locale to " + displayLocale);
            ((DisplayLocaleBasedEnumerationValueEditor)$propertyEditor).
                setDisplayLocale(displayLocale);
          }
        }
      }
      catch (NullPointerException npExc) {
        new ConverterException("Could not retrieve target type from component, "
                               + "because there is no value binding");
      }
      catch (EvaluationException eExc) { // and PropertyNotFoundException
        new ConverterException("Could not retrieve target type from component", eExc);
      }
    }
    LOG.debug("returning PropertyEditor: " + $propertyEditor);
    return $propertyEditor;
  }

  private PropertyEditor $propertyEditor;

}

@@ -5,18 +5,16 @@
 icense%3E%0A
-  
 Copyrigh
@@ -19,17 +19,28 @@
 ght 2004
-,
+ - $Date$ by
  PeopleW
@@ -51,104 +51,533 @@
 n.v.
-%0A  NO RIGHTS ARE GRANTED FOR THE USE OF THI
+.%0A%0ALicensed under the Apache License, Version 2.0 (the %22License%22);%0Ayou may not use this file except in compliance with the License.%0AYou may obtain a copy of the License at%0A%0A    http://www.apache.org/licenses/LICENSE-2.0%0A%0AUnless required by applicable law or agreed to in writing, software%0Adistributed under the License is distributed on an %22AS IS%22 BASIS,%0AWITHOUT WARRANTIES OR CONDITION
 S 
-S
 OF
-TWARE, EXCEPT, IN WRITING,%0A  TO SELECTED PARTIES
+ ANY KIND, either express or implied.%0ASee the License for the specific language governing permissions and%0Alimitations under the License
 .%0A%3C/
@@ -591,16 +591,17 @@
 %3E*/%0A
+%0A
 package 
 be.p
@@ -596,29 +596,38 @@
 package 
-be.peoplew
+org.ppwcode.vernacul
 ar
-e
 .value_I
@@ -627,16 +627,17 @@
 value_II
+I
 ;%0A%0A%0Aimpo

package name fixed; doesn't compile yet: dependency on jsf