nonjsp.application.BuildComponentFromTagImpl.java Source code

Java tutorial

Introduction

Here is the source code for nonjsp.application.BuildComponentFromTagImpl.java

Source

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

// BuildComponentFromTagImpl.java

package nonjsp.application;

import javax.faces.component.UICommand;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectOne;
import javax.faces.el.MethodBinding;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;

import nonjsp.util.Util;

/**
 * <B>BuildComponentFromTagImpl</B> is a class ...
 * <p/>
 * Copy of com.sun.faces.tree.BuildComponentFromTagImpl in order to remove
 * demo dependancy on RI.
 *
 */

public class BuildComponentFromTagImpl extends Object implements BuildComponentFromTag {

    //
    // Protected Constants
    //

    protected static String PARENT = "faces.parent:";

    protected static String PARENT_SELECTONE = PARENT + "javax.faces.UISelectOne";

    /**
     * stores model value of the form temporarily to support implicit mapping
     * of components to properties in the bean.
     */
    protected static String FORM_MODELREF = "faces.FORM_MODELREF";

    protected static Log log = LogFactory.getLog(BuildComponentFromTagImpl.class);

    //
    // Class Variables
    //

    //
    // Instance Variables
    //

    // Attribute Instance Variables

    // Relationship Instance Variables

    /** Store the mapping between shortTagName and component class */

    protected Hashtable classMap;

    //
    // Constructors and Initializers    
    //

    public BuildComponentFromTagImpl() {
        super();
        initializeClassMap();
    }

    //
    // Class methods
    //

    //
    // General Methods
    //

    /** This is a total RAD hack. */

    private void initializeClassMap() {
        classMap = new Hashtable(30);
        // PENDING(edburns): read this from a persistent store
        classMap.put("Form", "javax.faces.component.UIForm");
        classMap.put("Command_Button", "javax.faces.component.UICommand");
        classMap.put("Command_Link", "javax.faces.component.UICommand");
        classMap.put("SelectBoolean_Checkbox", "javax.faces.component.UISelectBoolean");
        classMap.put("RadioGroup", "javax.faces.component.UISelectOne");
        classMap.put("SelectOne_Radio", PARENT_SELECTONE);
        classMap.put("SelectOne_Listbox", "javax.faces.component.UISelectOne");
        classMap.put("SelectOne_Option", PARENT_SELECTONE);
        classMap.put("Output_Text", "javax.faces.component.UIOutput");
        classMap.put("TextEntry_Input", "javax.faces.component.UIInput");
        classMap.put("TextEntry_Secret", "javax.faces.component.UIInput");
        classMap.put("TextEntry_TextArea", "javax.faces.component.UIInput");
        classMap.put("Errors", "javax.faces.component.UIOutput");
    }

    protected boolean isSupportedTag(String shortTagName) {
        return (null != classMap.get(shortTagName));
    }

    /**
     * @return the property name in the UIComponent class that corresponds to
     *         the attrName.
     */
    private String mapAttrNameToPropertyName(String attrName) {
        if (null == attrName) {
            return attrName;
        }

        if (attrName.equals("converter")) {
            attrName = "converterReference";
        }

        if (attrName.equals("selectedValueModel")) {
            attrName = "selectedModelReference";
        }
        return attrName;
    }

    /**
     * @return the property name in the UIComponent class that corresponds to
     *         the attrName.
     */
    private boolean attrRequiresSpecialTreatment(String attrName) {
        boolean result = false;

        if (null == attrName) {
            return result;
        }

        if (attrName.equals("valueChangeListener") || attrName.equals("actionListener") || attrName.equals("action")
                || attrName.equals("required") || attrName.equals("format") || attrName.equals("rangeMaximum")
                || attrName.equals("lengthMaximum") || attrName.equals("value")) {
            result = true;
        }
        return result;
    }

    private void handleSpecialAttr(UIComponent child, String attrName, String attrValue)
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
            NoSuchMethodException {

        Class[] stringArg = { String.class };
        Method attrMethod = null;
        Object objValue = attrValue;

        if (attrName.equals("valueChangeListener")) {
            try {
                attrMethod = child.getClass().getMethod("addValueChangeListener", stringArg);
            } catch (SecurityException e) {
                log.trace("handleSpecialAttr: " + e);
            }
        } else if (attrName.equals("actionListener")) {
            try {
                attrMethod = child.getClass().getMethod("addActionListener", stringArg);
            } catch (SecurityException e) {
                log.trace("handleSpecialAttr: " + e);
            }
        } else if (attrName.equals("action")) {
            try {
                Class[] mbArgs = { MethodBinding.class };
                attrMethod = child.getClass().getMethod("setAction", mbArgs);
                objValue = new ConstantMethodBinding(attrValue);
            } catch (SecurityException e) {
                log.trace("handleSpecialAttr: " + e);
            }
        } else if ((child instanceof UICommand) && attrName.equals("value")) {
            ((UICommand) child).setValue(attrValue);
            return;
        }

        Object[] args = { objValue };
        if (null != attrMethod) {
            attrMethod.invoke(child, args);
        }
    }

    // 
    // Methods from BuildComponentFromTag
    //

    public UIComponent createComponentForTag(String shortTagName) {
        UIComponent result = null;
        if (!tagHasComponent(shortTagName)) {
            return result;
        }

        String className = (String) classMap.get(shortTagName);
        Class componentClass;

        // PENDING(edburns): this can be way optimized
        try {
            componentClass = Util.loadClass(className);
            result = (UIComponent) componentClass.newInstance();
        } catch (IllegalAccessException iae) {
            throw new RuntimeException("Can't create instance for " + className + ": " + iae.getMessage());
        } catch (InstantiationException ie) {
            throw new RuntimeException("Can't create instance for " + className + ": " + ie.getMessage());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Can't find class for " + className + ": " + e.getMessage());
        }

        return result;
    }

    public boolean tagHasComponent(String shortTagName) {
        boolean result = false;
        String value;

        // Return true if the classMap has an entry for shortTagName, and
        // the entry does not start with the string PARENT.

        if (null != (value = (String) classMap.get(shortTagName))) {
            result = 0 != value.indexOf(PARENT);
        }
        return result;
    }

    public boolean isNestedComponentTag(String shortTagName) {
        boolean result = false;
        String value;

        // Return true if the classMap has an entry for shortTagName, and
        // the entry DOES start with the string PARENT.

        if (null != (value = (String) classMap.get(shortTagName))) {
            result = 0 == value.indexOf(PARENT);
        }
        return result;
    }

    public void handleNestedComponentTag(UIComponent parent, String shortTagName, Attributes attrs) {

        if (null == parent || null == shortTagName || null == attrs) {
            return;
        }
        String val = (String) classMap.get(shortTagName);
        if (null == val || (0 != val.indexOf(PARENT))) {
            return;
        }

        // At this point, we know that we are in a nested tag.

        // PENDING(edburns): check that parent is really the correct parent
        // for this shortTagName, for now, it's just UISelectOne

        UISelectOne uiSelectOne = (UISelectOne) parent;

        int attrLen, i = 0;
        String attrName, attrValue;
        String itemLabel = null, itemValue = null, itemDesc = null;
        boolean checked = false;

        attrLen = attrs.getLength();
        for (i = 0; i < attrLen; i++) {
            attrName = mapAttrNameToPropertyName(attrs.getLocalName(i));
            attrValue = attrs.getValue(i);

            if (attrName.equals("value")) {
                itemValue = attrValue;
            }
            if (attrName.equals("label")) {
                itemLabel = attrValue;
            }
            if (attrName.equals("description")) {
                itemDesc = attrValue;
            }
            if ((attrName.equals("checked") || attrName.equals("selected")) && attrValue.equals("true")) {
                checked = true;
            }
        }

        /********** PENDING(edburns): Fix this for non-jsp example
         SelectItem [] oldItems = (SelectItem []) uiSelectOne.getItems();
         SelectItem [] newItems = null;
            
         if (null != oldItems) {
         newItems = new SelectItem[oldItems.length + 1];
         System.arraycopy(oldItems, 0, newItems, 0, oldItems.length);
         newItems[oldItems.length] = new SelectItem(itemValue, itemLabel,
         itemDesc);
         }
         else {
         newItems = new SelectItem[1];
         newItems[0] = new SelectItem(itemValue, itemLabel, itemDesc);
         }
            
         uiSelectOne.setItems(newItems);
         // if it is checked, make sure the model knows about it.
         // we should update selectedValue only if it is null
         // in the model bean otherwise we would be overwriting
         // the value in model bean, losing any earlier updates.
         if (checked && null == uiSelectOne.getSelectedValue()) {
         uiSelectOne.setSelectedValue(itemValue);
         }
         ***************/
    }

    public void applyAttributesToComponentInstance(UIComponent child, Attributes attrs) {
        int attrLen, i = 0;
        String attrName, attrValue;

        attrLen = attrs.getLength();
        for (i = 0; i < attrLen; i++) {
            attrName = mapAttrNameToPropertyName(attrs.getLocalName(i));
            attrValue = attrs.getValue(i);

            // First, try to set it as a bean property
            try {
                PropertyUtils.setNestedProperty(child, attrName, attrValue);
            } catch (NoSuchMethodException e) {
                // If that doesn't work, see if it requires special
                // treatment
                try {
                    if (attrRequiresSpecialTreatment(attrName)) {
                        handleSpecialAttr(child, attrName, attrValue);
                    } else {
                        // If that doesn't work, this will.
                        child.getAttributes().put(attrName, attrValue);
                    }
                } catch (IllegalAccessException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                } catch (IllegalArgumentException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                } catch (InvocationTargetException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                } catch (NoSuchMethodException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                }
            } catch (IllegalArgumentException e) {
                try {
                    if (attrRequiresSpecialTreatment(attrName)) {
                        handleSpecialAttr(child, attrName, attrValue);
                    } else {
                        // If that doesn't work, this will.
                        child.getAttributes().put(attrName, attrValue);
                    }
                } catch (IllegalAccessException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                } catch (IllegalArgumentException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                } catch (InvocationTargetException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                } catch (NoSuchMethodException innerE) {
                    innerE.printStackTrace();
                    log.trace(innerE.getMessage());
                }
            } catch (InvocationTargetException e) {
                e.printStackTrace();
                log.trace(e.getMessage());
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                log.trace(e.getMessage());
            }
        }

        // cleanup: make sure we have the necessary required attributes
        if (child.getId() == null) {
            String gId = "foo" + Util.generateId();
            child.setId(gId);
        }

    }

} // end of class BuildComponentFromTagImpl