All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.faces.mgbean.ManagedBeanBuilder Maven / Gradle / Ivy

/*
 * 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.dev.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.
 */

package com.sun.faces.mgbean;

import com.sun.faces.RIConstants;
import com.sun.faces.util.MessageUtils;

import javax.el.ExpressionFactory;
import javax.faces.context.FacesContext;
import javax.faces.component.UIComponent;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 

This builder creates standard managed beans, i.e. beans * that aren't List or Map instances.

*/ public class ManagedBeanBuilder extends BeanBuilder { private List properties; private enum PropertyType { MAP, LIST, BEAN } // ------------------------------------------------------------ Constructors public ManagedBeanBuilder(ManagedBeanInfo beanInfo) { super(beanInfo); } // ------------------------------------------------ Methods from BeanBuilder @Override void bake() { if (!isBaked()) { super.bake(); if (beanInfo.hasManagedProperties()) { properties = new ArrayList(beanInfo.getManagedProperties().size()); String propertyName = null; try { for (ManagedBeanInfo.ManagedProperty property : beanInfo.getManagedProperties()) { propertyName = property.getPropertyName(); switch (getPropertyType(property)) { case MAP: bakeMapProperty(property); break; case LIST: bakeListProperty(property); break; default: bakeBeanProperty(property); } } } catch (Exception e) { if (e instanceof ManagedBeanPreProcessingException) { throw (ManagedBeanPreProcessingException) e; } else { String message = MessageUtils .getExceptionMessageString(MessageUtils.MANAGED_BEAN_PROPERTY_UNKNOWN_PROCESSING_ERROR_ID, propertyName); throw new ManagedBeanPreProcessingException(message, e, ManagedBeanPreProcessingException.Type.UNCHECKED); } } } baked(); Introspector.flushFromCaches(getBeanClass()); } } protected void buildBean(Object bean, FacesContext context) { if (properties != null) { for (BakedProperty property : properties) { property.set(bean, context); } } } // --------------------------------------------------------- Private Methods private PropertyType getPropertyType(ManagedBeanInfo.ManagedProperty property) { if (property.hasListEntry()) { if (property.hasMapEntry() || property.hasPropertyValue()) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_LIST_PROPERTY_CONFIG_ERROR_ID, property.getPropertyName(), beanInfo.getName()); throw new ManagedBeanPreProcessingException(message); } return PropertyType.LIST; } if (property.hasMapEntry()) { if (property.hasPropertyValue()) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_MAP_PROPERTY_CONFIG_ERROR_ID, property.getPropertyName(), beanInfo.getName()); throw new ManagedBeanPreProcessingException(message); } return PropertyType.MAP; } return PropertyType.BEAN; } private void bakeMapProperty(ManagedBeanInfo.ManagedProperty property) { ManagedBeanInfo.MapEntry rawEntry = property.getMapEntry(); Map mapEntries = getBakedMap(rawEntry.getKeyClass(), rawEntry.getValueClass(), rawEntry.getEntries()); // Find property setter and validate. PropertyDescriptor pd = getPropertyDescriptor(property.getPropertyName()); if (pd == null) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_DOES_NOT_EXIST_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } else { if (pd.getWriteMethod() != null) { Class[] params = pd.getWriteMethod().getParameterTypes(); if (!Map.class.isAssignableFrom(params[0])) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_MAP_PROPERTY_INCORRECT_SETTER_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } } else { // no write method, let's hope there is a read method that returns // a non-null map if (pd.getReadMethod() == null) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_DOES_NOT_EXIST_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } else { Class returnType = pd.getReadMethod().getReturnType(); if (!Map.class.isAssignableFrom(returnType)) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_MAP_PROPERTY_INCORRECT_GETTER_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } } } } if (!this.hasMessages()) { // all clear - create the BakedMapProperty and add it to the properties // map BakedMapProperty baked = new BakedMapProperty(mapEntries, pd); properties.add(baked); } } private void bakeListProperty(ManagedBeanInfo.ManagedProperty property) { ManagedBeanInfo.ListEntry rawEntry = property.getListEntry(); List listEntry = getBakedList(rawEntry.getValueClass(), rawEntry.getValues()); PropertyDescriptor pd = getPropertyDescriptor(property.getPropertyName()); if (pd == null) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_DOES_NOT_EXIST_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } else { if (pd.getReadMethod() == null) { // a null read method means we create a new List or // array and pass it to the bean. Validate that the // setter takes either an array or List. if (pd.getWriteMethod() == null) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_DOES_NOT_EXIST_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } else { Class[] params = pd.getWriteMethod().getParameterTypes(); if (params.length != 1) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_INCORRECT_ARGS_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } else { if (!params[0].isArray() && !List.class.isAssignableFrom(params[0])) { String message = MessageUtils .getExceptionMessageString( MessageUtils.MANAGED_BEAN_LIST_SETTER_DOES_NOT_ACCEPT_LIST_OR_ARRAY_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } } } } else { // a getter exists. ensure it returns a List or array. // if it returns an array, ensure a setter exists Class retType = pd.getReadMethod().getReturnType(); if (retType.isArray()) { if (pd.getWriteMethod() == null) { String message = MessageUtils .getExceptionMessageString( MessageUtils.MANAGED_BEAN_LIST_GETTER_ARRAY_NO_SETTER_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } // validate setter } else { if (!List.class.isAssignableFrom(retType)) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_LIST_GETTER_DOES_NOT_RETURN_LIST_OR_ARRAY_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } } } } if (!this.hasMessages()) { BakedListProperty baked = new BakedListProperty(listEntry, pd); properties.add(baked); } } private void bakeBeanProperty(ManagedBeanInfo.ManagedProperty property) { String className = property.getPropertyClass(); PropertyDescriptor pd = getPropertyDescriptor(property.getPropertyName()); if (pd == null || pd.getWriteMethod() == null) { if (!UIComponent.class.isAssignableFrom(getBeanClass())) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_DOES_NOT_EXIST_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } } else { Method method = pd.getWriteMethod(); Class[] param = method.getParameterTypes(); if (param.length != 1) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_PROPERTY_INCORRECT_ARGS_ERROR_ID, property.getPropertyName(), beanInfo.getName()); queueMessage(message); } } Expression value = null; if (pd != null) { Class propertyClass; if (className != null) { propertyClass = loadClass(className); } else { propertyClass = pd.getPropertyType(); } if (className != null) { if (!pd.getWriteMethod().getParameterTypes()[0] .isAssignableFrom(propertyClass)) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_DEFINED_PROPERTY_CLASS_NOT_COMPATIBLE_ERROR_ID, property.getPropertyName(), beanInfo.getName(), property.getPropertyClass()); queueMessage(message); } } String propertyValue = property.getPropertyValue(); if (!ManagedBeanInfo.NULL_VALUE.equals(propertyValue)) { value = new Expression(propertyValue, propertyClass); } } else { String propertyValue = property.getPropertyValue(); if (!ManagedBeanInfo.NULL_VALUE.equals(propertyValue)) { value = new Expression(propertyValue, String.class); } } if (!this.hasMessages()) { BakedBeanProperty baked = new BakedBeanProperty(property.getPropertyName(), pd, value); properties.add(baked); } } private PropertyDescriptor getPropertyDescriptor(String propertyName) { try { BeanInfo beanInfo = Introspector.getBeanInfo(getBeanClass()); PropertyDescriptor pds[] = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor pd : pds) { if (propertyName.equals(pd.getName())) { return pd; } } } catch (IntrospectionException ie) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_INTROSPECTION_ERROR_ID, beanInfo.getName()); throw new ManagedBeanPreProcessingException(message); } return null; } // ----------------------------------------------------------- Inner Classes private static interface BakedProperty { abstract void set(Object bean, FacesContext context); } // END BakedProperty private class BakedMapProperty implements BakedProperty { Map mapEntries; PropertyDescriptor pd; BakedMapProperty(Map mapEntries, PropertyDescriptor pd) { this.mapEntries = mapEntries; this.pd = pd; } public void set(Object bean, FacesContext context) { Method readMethod = pd.getReadMethod(); Map target = null; boolean mapReturned = false; if (readMethod != null) { // see if a Map already exists, if so, we'll // add the config entries to the existing try { target = (Map) readMethod.invoke(bean, RIConstants.EMPTY_METH_ARGS); mapReturned = (target != null); } catch (Exception ignored) { // ignored } } if (target == null) { //noinspection CollectionWithoutInitialCapacity target = new HashMap(); } initMap(mapEntries, target, context); if (!mapReturned) { Method writeMethod = pd.getWriteMethod(); try { writeMethod.invoke(bean, target); } catch (Exception e) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_UNABLE_TO_SET_PROPERTY_ERROR_ID, pd.getName(), beanInfo.getName()); throw new ManagedBeanPreProcessingException(message, e); } } } } // END BakedMapProperty private class BakedListProperty implements BakedProperty { private List listEntries; private PropertyDescriptor pd; BakedListProperty(List listEntries, PropertyDescriptor pd) { this.listEntries = listEntries; this.pd = pd; } public void set(Object bean, FacesContext context) { // check to see if there is a value returned by // the getter, if any. Method readMethod = pd.getReadMethod(); Object temp = null; if (readMethod != null) { try { temp = readMethod.invoke(bean, RIConstants.EMPTY_METH_ARGS); } catch (Exception ignored) { // ignored } } List target = null; if (temp != null) { if (temp.getClass().isArray()) { for (int i = 0, len = Array.getLength(temp); i < len; i++) { if (target == null) { target = new ArrayList(len); } //noinspection unchecked target.add(Array.get(temp, i)); } } else { target = (List) temp; } } if (target == null) { //noinspection CollectionWithoutInitialCapacity target = new ArrayList(); } ExpressionFactory expFactory = context.getApplication().getExpressionFactory(); initList(listEntries, target, context); // handle the case where the getter returned a non-null value if (temp != null && !temp.getClass().isArray()) { // the returned object was a List - no action // necessary return; } else if (temp != null) { // getter returned an array. Converter the List // 'target' to an array and call the setter Class arrayType = temp.getClass().getComponentType(); Object result = Array.newInstance(arrayType, target.size()); for (int i = 0, len = target.size(); i < len; i++) { Array.set(result, i, expFactory.coerceToType(target.get(i), arrayType)); } try { pd.getWriteMethod().invoke(bean, result); } catch (Exception e) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_UNABLE_TO_SET_PROPERTY_ERROR_ID, pd.getName(), beanInfo.getName()); throw new ManagedBeanCreationException(message, e); } } else { // no value returned from the getter. Method writeMethod = pd.getWriteMethod(); Class[] param = writeMethod.getParameterTypes(); if (param[0].isArray()) { Class arrayType = param[0].getComponentType(); Object result = Array.newInstance(arrayType, target.size()); for (int i = 0, len = target.size(); i < len; i++) { Array.set(result, i, expFactory.coerceToType(target.get(i), arrayType)); } try { writeMethod.invoke(bean, result); } catch (Exception e) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_UNABLE_TO_SET_PROPERTY_ERROR_ID, pd.getName(), beanInfo.getName()); throw new ManagedBeanCreationException(message, e); } } else { try { writeMethod.invoke(bean, target); } catch (Exception e) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_UNABLE_TO_SET_PROPERTY_ERROR_ID, pd.getName(), beanInfo.getName()); throw new ManagedBeanCreationException(message, e); } } } } } // END BakedListProperty private class BakedBeanProperty implements BakedProperty { private String propertyName; private PropertyDescriptor pd; private Expression value; BakedBeanProperty(String propertyName, PropertyDescriptor pd, Expression value) { this.propertyName = propertyName; this.pd = pd; this.value = value; } public void set(Object bean, FacesContext context) { if (pd != null) { Method writeMethod = pd.getWriteMethod(); try { writeMethod.invoke(bean, ((value != null) ? value.evaluate(context.getELContext()) : null)); } catch (Exception e) { String message = MessageUtils.getExceptionMessageString( MessageUtils.MANAGED_BEAN_UNABLE_TO_SET_PROPERTY_ERROR_ID, pd.getName(), beanInfo.getName()); throw new ManagedBeanCreationException(message, e); } } else { // no PropertyDescriptor means this bean is a UIComponent ((UIComponent) bean).getAttributes() .put(propertyName, ((value != null) ? value .evaluate(context.getELContext()) : "")); } } } // END BakedBeanProperty }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy