Package org.apache.shale.clay.component.chain

Source Code of org.apache.shale.clay.component.chain.PropertyValueCommand

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* $Id: PropertyValueCommand.java 473039 2006-11-09 19:26:41Z gvanmatre $
*/
package org.apache.shale.clay.component.chain;

import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.PropertyNotFoundException;
import javax.faces.el.ValueBinding;

import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.shale.clay.config.beans.AttributeBean;
import org.apache.shale.clay.config.beans.ComponentBean;
import org.apache.shale.util.ConverterHelper;
import org.apache.shale.util.PropertyHelper;

/**
* <p>
* This is the catch all <code>Command</code> to handle all attributes that
* are not an "action", "actionListener", "validator" and "valueChangeListener".
* This <code>Command</code> is invoked from the
* {@link AssignPropertiesCommand} chain.
* <p>
*/
public class PropertyValueCommand extends AbstractCommand implements Command {

    /**
     * <p>Helper class to provide access to the properties of JavaBeans.</p>
     */
    private PropertyHelper propertyHelper = new PropertyHelper();

    /**
     * <p>Helper class to provide access to by-type JavaServer Faces
     * <code>Converter</code> capabilities.</p>
     */
    private ConverterHelper converterHelper = new ConverterHelper();

    /**
     * <p>Sets a property value on the target component.  If the data
     * type of the target bean property is not a String and the property
     * value is a String, the data type is converted to the target type
     * using the <code>ConverterHelper</code>.  The value is applied to
     * the component using <code>PropertyHelper</code>.</p>
     *
     * @param context faces context
     * @param target object with the property
     * @param propertyName name of the target property
     * @param propertyValue value of the target property
     */
    private void setProperty(FacesContext context, Object target, String propertyName, Object propertyValue) {
        Class classz = null;
        StringBuffer actualPropertyName = new StringBuffer(propertyName);

        try {
            classz = propertyHelper.getType(target, actualPropertyName.toString());
        } catch (PropertyNotFoundException e) {
            if (propertyName.length() > "isX".length() && propertyName.startsWith("is")) {
               actualPropertyName.delete(0, 2);
               actualPropertyName.setCharAt(0, Character.toLowerCase(actualPropertyName.charAt(0)));

               classz = propertyHelper.getType(target, actualPropertyName.toString());
            } else {
               throw e;
            }

        }

        if (classz != Object.class && classz != propertyValue.getClass()
            && propertyValue.getClass() == String.class) {

            Object targetValue = converterHelper.asObject(context, classz, (String) propertyValue);
            propertyHelper.setValue(target, actualPropertyName.toString(), targetValue);
        } else {
            propertyHelper.setValue(target, actualPropertyName.toString(), propertyValue);
        }

    }


    /**
     * <p>
     * Looks at the {@link AttributeBean} on the {@link ClayContext} to see
     * if the value is a binding EL.  If it is not it just updates the component
     * with the value.  If the attribute is a value binding expression, then a
     * <code>ValueBinding</code> is created.  If the attribute uses early binding
     * the <code>ValueBinding</code> is executed and result applied to the component.
     * Otherwise, the binding expression is applied to the component in a prepared state.
     * A <code>true</code> value is always returned because this is the default handler.
     * </p>
     *
     * @param context common chains
     * @return <code>true</code> if the chain is complete
     * @exception Exception propagated up to the top of the chain
     */
    public boolean execute(Context context) throws Exception {

        boolean isFinal = true;

        ClayContext clayContext = (ClayContext) context;
        if (clayContext == null) {
            throw new NullPointerException(getMessages().getMessage("clay.null.clayContext"));
        }
        AttributeBean attributeBean = clayContext.getAttribute();
        if (attributeBean == null) {
            throw new NullPointerException(getMessages().getMessage("clay.null.attributeBean"));
        }
        Object child = clayContext.getChild();
        if (child == null) {
            throw new NullPointerException(getMessages().getMessage("clay.null.childComponent"));
        }
        ComponentBean displayElement = clayContext.getDisplayElement();
        if (displayElement == null) {
            throw new NullPointerException(getMessages().getMessage("clay.null.componentBean"));
        }
        FacesContext facesContext = clayContext.getFacesContext();
        if (facesContext == null) {
            throw new NullPointerException(getMessages().getMessage("clay.null.facesContext"));
        }

        // don't try to set the binding attribute of anything but a component
        if (attributeBean.getName().equals("binding")
                && !(child instanceof UIComponent)) {
            return isFinal;

        }
        // skip trying to set the converterId on a converter
        if (attributeBean.getName().equals("converterId")
                && child instanceof Converter) {
            return isFinal;
        }
        // replace all symbols returning the target attribute value
        String expr = replaceMnemonic(clayContext);

        //exit if null or empty string
        if (expr == null) {
           return isFinal;
        }


        String bindingType = attributeBean.getBindingType();
        if (bindingType == null) {
            bindingType = AttributeBean.BINDING_TYPE_NONE;
        }

        //contains expression language
        boolean isEL = isValueReference(expr);
        //use value binding
        boolean isVB = ((bindingType.equals(AttributeBean.BINDING_TYPE_VALUE))
                        && (child instanceof UIComponent));
        //use early binding
        boolean isEarly = bindingType.equals(AttributeBean.BINDING_TYPE_EARLY);

        if (isEL && isVB) {
           getTagUtils().setValueBinding((UIComponent) child, attributeBean.getName(), expr);
        } else if (isEL && isEarly) {
            ValueBinding vb = facesContext.getApplication().createValueBinding(expr);
            Object value = vb.getValue(facesContext);
            try {
                setProperty(facesContext, child, attributeBean.getName(), value);
            } catch (Exception e) {
                 if (child instanceof UIComponent) {
                   ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
                 } else {
                    throw e;
                 }
             }
        } else  {
            try {
               setProperty(facesContext, child, attributeBean.getName(), expr);
            } catch (Exception e) {
                if (child instanceof UIComponent) {
                  ((UIComponent) child).getAttributes().put(attributeBean.getName(), expr);
                } else {
                   if (child.getClass().getName().equals("org.apache.shale.validator.CommonsValidator")) {
                      Map vars = (Map) propertyHelper.getValue(child, "vars");
                      //vars collection is like the components attributes
                      //native support for shale components
                      vars.put(attributeBean.getName(), expr);
                   } else {
                      throw e;
                   }
                }
            }
        }

        return isFinal;
    }

}
TOP

Related Classes of org.apache.shale.clay.component.chain.PropertyValueCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.