blob: 7b196252b142eeac8de487dca2b8aa757ce099c7 [file] [log] [blame]
/*
* 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.
*/
package org.apache.myfaces.trinidaddemo.table;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class TableBuilder implements java.io.Serializable
{
@SuppressWarnings("unchecked")
public TableBuilder()
{
// no arg contructor needed for usage as managed-bean
_beanProps = Collections.EMPTY_LIST;
_data = Collections.EMPTY_LIST;
_result = null;
}
public void setBeanClass(String klass)
{
_beanClass = klass;
}
public void setBeanProperties(List<Object> props)
{
if (props == null)
throw new NullPointerException("beanProperties");
_beanProps = props;
}
public void setBeanData(List<?> data)
{
if (data == null)
throw new NullPointerException("beanData");
_data = data;
}
public List<?> getTableData()
throws ClassNotFoundException, IntrospectionException, InstantiationException,
IllegalAccessException, InvocationTargetException
{
if (_result == null)
{
_result = _getAsList();
}
return _result;
}
private List<Object> _getAsList()
throws ClassNotFoundException, IntrospectionException, InstantiationException,
IllegalAccessException, InvocationTargetException
{
if (_beanClass == null)
throw new NullPointerException("beanClass");
Class<?> beanClass = Class.forName(_beanClass);
_setPropertySetters(beanClass, _beanProps);
int sz = _beanProps.size();
List<Object> result = new ArrayList<Object>(sz);
Iterator<?> cells = _data.iterator();
while(cells.hasNext())
{
Object beanInstance = beanClass.newInstance();
for(int i=0; i<sz; i++)
{
Object value = cells.next();
Method setter = (Method) _beanProps.get(i);
Class<?> expectedType = setter.getParameterTypes()[0];
if (!expectedType.isAssignableFrom(value.getClass()))
{
value = _convert(value, expectedType);
}
setter.invoke(beanInstance, new Object[] {value});
}
result.add(beanInstance);
}
return result;
}
private Object _convert(Object instance, Class<?> expectedType)
{
if (Integer.TYPE == expectedType)
{
return new Integer(instance.toString());
}
throw new IllegalArgumentException("Could not convert instance:"+instance+
" of class:"+instance.getClass()+" into "+expectedType);
}
private void _setPropertySetters(Class<?> klass, List<Object> props)
throws IntrospectionException
{
BeanInfo beanInfo = Introspector.getBeanInfo(klass);
PropertyDescriptor[] descs = beanInfo.getPropertyDescriptors();
for(int i=0, sz=props.size(); i<sz; i++)
{
String name = (String)props.get(i);
PropertyDescriptor desc = _getDescriptor(descs, name);
if (desc == null)
{
throw new IllegalArgumentException("property:"+name+" not found on:"
+klass);
}
Method setter = desc.getWriteMethod();
if (setter == null)
{
throw new IllegalArgumentException("No way to set property:"+name+" on:"
+klass);
}
props.set(i, setter);
}
}
private PropertyDescriptor _getDescriptor(
PropertyDescriptor[] descs,
String name)
{
for(int i=0; i<descs.length; i++)
{
PropertyDescriptor desc = descs[i];
if (name.equals(desc.getName()))
return desc;
}
return null;
}
private String _beanClass = null;
// Transient as it contains java.lang.reflect.Method objects
private transient List<Object> _beanProps;
private List<?> _data;
private List<?> _result;
}