org.openmobster.core.mobileObject.TestBeanSyntax.java Source code

Java tutorial

Introduction

Here is the source code for org.openmobster.core.mobileObject.TestBeanSyntax.java

Source

/**
 * Copyright (c) {2003,2011} {openmobster@gmail.com} {individual contributors as indicated by the @authors tag}.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.openmobster.core.mobileObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.Array;

import java.beans.PropertyDescriptor;
import java.util.StringTokenizer;
import java.util.Collection;
import java.util.ArrayList;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.log4j.Logger;

import junit.framework.TestCase;

/**
 * @author openmobster@gmail.com
 */
public class TestBeanSyntax extends TestCase {
    private static Logger log = Logger.getLogger(TestBeanSyntax.class);

    public void testIndexedProperties() throws Exception {
        MockPOJO pojo = new MockPOJO();

        this.setNestedProperty(pojo, "children[0].parent.value", "embeddedParent");
        this.setNestedProperty(pojo, "children[0].parent.strings[0]", "embeddedStrings");
        this.setNestedProperty(pojo, "childArray[0]", "stringArray://0");
        this.setNestedProperty(pojo, "child.parent.value", "child://parent");

        //Assert the state
        this.assertTrue("children must not be null!!!",
                pojo.getChildren() != null && !pojo.getChildren().isEmpty());
        MockChild child = pojo.getChildren().get(0);
        assertEquals("Value must match!!", "embeddedParent", child.getParent().getValue());
        assertEquals("Value must match!!", "child://parent", pojo.getChild().getParent().getValue());
    }

    //----------------------------------------------------------------------------------------------
    private void setNestedProperty(Object mobileBean, String nestedProperty, String value) throws Exception {
        StringTokenizer st = new StringTokenizer(nestedProperty, ".");
        Object courObj = mobileBean;

        while (st.hasMoreTokens()) {
            String token = st.nextToken();

            PropertyDescriptor metaData = PropertyUtils.getPropertyDescriptor(courObj, token);
            if (token.indexOf('[') != -1 && token.indexOf(']') != -1) {
                String indexedPropertyName = token.substring(0, token.indexOf('['));
                metaData = PropertyUtils.getPropertyDescriptor(courObj, indexedPropertyName);
            }

            if (!st.hasMoreTokens()) {
                if (Collection.class.isAssignableFrom(metaData.getPropertyType())
                        || metaData.getPropertyType().isArray()) {
                    //An IndexedProperty                  
                    courObj = this.initializeIndexedProperty(courObj, token, metaData);
                }

                //Actually set the value of the property
                if (!metaData.getPropertyType().isArray()) {
                    PropertyUtils.setNestedProperty(mobileBean, nestedProperty,
                            ConvertUtils.convert(value, metaData.getPropertyType()));
                } else {
                    PropertyUtils.setNestedProperty(mobileBean, nestedProperty,
                            ConvertUtils.convert(value, metaData.getPropertyType().getComponentType()));
                }
            } else {
                if (Collection.class.isAssignableFrom(metaData.getPropertyType())
                        || metaData.getPropertyType().isArray()) {
                    //An IndexedProperty                  
                    courObj = this.initializeIndexedProperty(courObj, token, metaData);
                } else {
                    //A Simple Property
                    courObj = this.initializeSimpleProperty(courObj, token, metaData);
                }
            }
        }
    }

    private Object initializeSimpleProperty(Object parentObject, String property,
            PropertyDescriptor propertyMetaData) throws Exception {
        Object propertyValue = null;

        //A Regular Property
        propertyValue = PropertyUtils.getProperty(parentObject, property);
        if (propertyValue == null) {
            Object newlyInitialized = propertyMetaData.getPropertyType().newInstance();
            PropertyUtils.setProperty(parentObject, property, newlyInitialized);
            propertyValue = newlyInitialized;
        }

        return propertyValue;
    }

    private Object initializeIndexedProperty(Object parentObject, String property,
            PropertyDescriptor propertyMetaData) throws Exception {
        Object element = null;

        //Find the Class of the elementType
        Class elementType = null;

        if (!propertyMetaData.getPropertyType().isArray()) {
            ParameterizedType returnType = (ParameterizedType) propertyMetaData.getReadMethod()
                    .getGenericReturnType();
            Type[] actualTypes = returnType.getActualTypeArguments();
            for (Type actualType : actualTypes) {
                elementType = (Class) actualType;
            }
        } else {
            elementType = propertyMetaData.getPropertyType().getComponentType();
        }

        //An IndexedProperty
        Object indexedProperty = PropertyUtils.getProperty(parentObject, propertyMetaData.getName());

        //Initialize the IndexedProperty (An Array or Collection)
        if (indexedProperty == null) {
            if (propertyMetaData.getPropertyType().isArray()) {
                //TODO: Remove hardcoded array size                     
                PropertyUtils.setProperty(parentObject, propertyMetaData.getName(),
                        Array.newInstance(elementType, 1));
            } else {
                //Handle Collection Construction
                PropertyUtils.setProperty(parentObject, propertyMetaData.getName(), new ArrayList());
            }
            indexedProperty = PropertyUtils.getProperty(parentObject, propertyMetaData.getName());
        }

        //Check to see if the index specified by the field requires creation of new
        //element
        try {
            element = PropertyUtils.getIndexedProperty(parentObject, property);
        } catch (IndexOutOfBoundsException iae) {
            Object newlyInitialized = elementType.newInstance();

            if (!propertyMetaData.getPropertyType().isArray()) {
                ((Collection) indexedProperty).add(newlyInitialized);
            } else {
                //TODO: Remove hardcoded array index
                Array.set(indexedProperty, 0, newlyInitialized);
            }

            element = newlyInitialized;
        }

        return element;
    }
}