/* * © Copyright IBM Corp. 2012 * * Licensed 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 com.ibm.commons.runtime.beans; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.ibm.commons.runtime.impl.ManagedBeanFactory; import com.ibm.commons.runtime.util.ParameterProcessor; import com.ibm.commons.util.StringUtil; /** * SBT ManagedBean Factory. * * This class creates the managed beans when necessary. * * @author Philippe Riand */ public class AbstractBeanFactory extends ManagedBeanFactory { public static class BeanProperty { private String name; private Object value; public BeanProperty(String name, Object value) { this.name = name; this.value = value; } } public static class Factory implements BeanFactory { private int scope; private String name; private String className; private BeanProperty[] properties; public Factory(int scope, String name, String className, BeanProperty[] properties) { this.scope = scope; this.name = name; this.className = className; this.properties = properties; } @Override public int getScope() { return scope; } @Override public Object create(ClassLoader classLoader) { try { Class<?> c = classLoader.loadClass(className); Object o = c.newInstance(); if(properties!=null) { for(int i=0; i<properties.length; i++) { BeanProperty p = properties[i]; setProperty(o, p.name, p.value); } } return o; } catch (Exception e) { IllegalStateException ie = new IllegalStateException(StringUtil.format("Error while instanciating bean {0}, class {1}",name,className)); ie.initCause(e); throw ie; } } protected void setProperty(Object o, String name, Object value) { try { // A cache is already managed by the JVM for beaninfo BeanInfo bi = Introspector.getBeanInfo(o.getClass()); if(bi!=null) { PropertyDescriptor[] desc = bi.getPropertyDescriptors(); for(int i=0; i<desc.length; i++) { PropertyDescriptor d = desc[i]; if(d.getName().equals(name)) { Method m = d.getWriteMethod(); if(m!=null) { Class<?> pType = d.getPropertyType(); if(pType==String.class) { m.invoke(o, replaceVariables(name,value)); return; } else if(pType==Boolean.class || pType==Boolean.TYPE) { boolean v = Boolean.parseBoolean(replaceVariables(name,value)); m.invoke(o, v); return; } else if(pType==Byte.class || pType==Byte.TYPE) { Byte v = Byte.parseByte(replaceVariables(name,value).trim()); m.invoke(o, v); return; } else if(pType==Short.class || pType==Short.TYPE) { Short v = Short.parseShort(replaceVariables(name,value).trim()); m.invoke(o, v); return; } else if(pType==Integer.class || pType==Integer.TYPE) { Integer v = Integer.parseInt(replaceVariables(name,value).trim()); m.invoke(o, v); return; } else if(pType==Long.class || pType==Long.TYPE) { Long v = Long.parseLong(replaceVariables(name,value).trim()); m.invoke(o, v); return; } else if(pType==Float.class || pType==Float.TYPE) { Float v = Float.parseFloat(replaceVariables(name,value).trim()); m.invoke(o, v); return; } else if(pType==Double.class || pType==Double.TYPE) { Double v = Double.parseDouble(replaceVariables(name,value).trim()); m.invoke(o, v); return; } else if(Map.class.isAssignableFrom(pType)) { if(!(value instanceof Map)) { throw new IllegalArgumentException(StringUtil.format("Invalid property type bean {0}, class {1}, property {2}, should be a Map",this.name,className,name)); } Map<Object,Object> v = new HashMap<Object,Object>(); for(Map.Entry<?,?> e: ((Map<?,?>)value).entrySet()) { v.put(e.getKey(), replaceVariables(name,e.getValue()).trim()); } m.invoke(o, v); } else if(List.class.isAssignableFrom(pType)) { if(!(value instanceof List)) { throw new IllegalArgumentException(StringUtil.format("Invalid property type bean {0}, class {1}, property {2}, should be a List",this.name,className,name)); } List<Object> v = new ArrayList<Object>(); for(Object e: (List<?>)value) { v.add(replaceVariables(name,e).trim()); } m.invoke(o, v); } else { throw new IllegalArgumentException(StringUtil.format("Invalid property type bean {0}, class {1}, property {2}, type {3}",this.name,className,name,pType)); } } } } } } catch (Exception e) { IllegalStateException ie = new IllegalStateException(StringUtil.format("Error while setting bean properties, bean {0}, class {1}",this.name,className)); ie.initCause(e); throw ie; } } private String replaceVariables(String name, Object value) { if(!(value instanceof String)) { throw new IllegalArgumentException(StringUtil.format("Invalid property type bean {0}, class {1}, property {2}, should be a String",this.name,className,name)); } return ParameterProcessor.process((String)value); } } private Factory[] factories; public AbstractBeanFactory() { } public void setFactories(Factory[] factories) { this.factories = factories; } @Override public BeanFactory getBeanFactory(String name) { if(factories!=null) { for(int i=0; i<factories.length; i++) { Factory f = factories[i]; if(StringUtil.equals(name, f.name)) { return f; } } } return null; } }