Author: pier Date: Mon Nov 1 03:19:56 2004 New Revision: 56226 Modified: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Factory.java Log: Adding support for arrays and collections in component setters
Modified: cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Factory.java ============================================================================== --- cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Factory.java (original) +++ cocoon/whiteboard/kernel/src/org/apache/cocoon/kernel/runtime/Factory.java Mon Nov 1 03:19:56 2004 @@ -13,9 +13,13 @@ package org.apache.cocoon.kernel.runtime; import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; import java.lang.reflect.Proxy; import java.net.URL; +import java.util.HashSet; import java.util.Iterator; +import java.util.Set; +import java.util.StringTokenizer; import org.apache.cocoon.kernel.Kernel; import org.apache.cocoon.kernel.configuration.Configuration; @@ -112,65 +116,92 @@ /** * <p>Configure the specified component from a [EMAIL PROTECTED] Configuration}.</p> */ - public static void configure(Object o, Deployer deployer, Configuration config) + public static void configure(Object obj, Deployer depl, Configuration conf) throws DeployerException { - Iterator iterator = config.children("set"); + Iterator iterator = conf.children("set"); while (iterator.hasNext()) { /* Look up the configurator and figure out the property name */ - Configuration current = (Configuration) iterator.next(); - String property = current.getStringAttribute("property", null); - if (property == null) { + Configuration curr = (Configuration) iterator.next(); + String prop = curr.getStringAttribute("property", null); + if (prop == null) { throw new DeployerException("Property name not specified at " - + current.location()); + + curr.location()); } /* Using beans, access the property descriptor */ - PropertyDescriptor descriptor = null; + PropertyDescriptor descr = null; try { - String s = "set" + property.substring(0, 1).toUpperCase() - + property.substring(1); - descriptor = new PropertyDescriptor(property, o.getClass(), null, s); + String s = "set" + prop.substring(0, 1).toUpperCase() + + prop.substring(1); + descr = new PropertyDescriptor(prop, obj.getClass(), null, s); } catch (Throwable t) { - throw new DeployerException("Unable to retrieve setter method for pro" - + "perty \"" + property + "\" at " + current.location(), t); + throw new DeployerException("Unable to retrieve setter method for " + + "property \"" + prop + "\" at " + curr.location(), t); } /* Do we have to set a value? */ - if (current.hasAttribute("value")) try { - Class type = descriptor.getPropertyType(); - Object value = current.getAttributeAs(property, type); - descriptor.getWriteMethod().invoke(o, new Object[] { value }); + if (curr.hasAttribute("value")) try { + Class type = descr.getPropertyType(); + Object value = curr.getAttributeAs(prop, type); + descr.getWriteMethod().invoke(obj, new Object[] { value }); continue; } catch (Throwable t) { throw new DeployerException("Unable to set value for property \"" - + property + "\" specified at " + current.location(), t); + + prop + "\" specified at " + curr.location(), t); } /* Do we have to set a component? */ - if (current.hasAttribute("component")) try { - Object value = deployer.lookup(current.getStringAttribute("component")); - descriptor.getWriteMethod().invoke(o, new Object[] { value }); + if (curr.hasAttribute("component")) try { + Object value = depl.lookup(curr.getStringAttribute("component")); + descr.getWriteMethod().invoke(obj, new Object[] { value }); continue; } catch (Throwable t) { throw new DeployerException("Unable to set component for property \"" - + property + "\" specified at " + current.location(), t); + + prop + "\" specified at " + curr.location(), t); + } + + /* Do we have to set a set of components? */ + if (curr.hasAttribute("components")) try { + Set s = new HashSet(); + String v = curr.getStringAttribute("components"); + StringTokenizer t = new StringTokenizer(v); + while (t.hasMoreTokens()) s.add(depl.lookup(t.nextToken())); + + /* String to array, if needed... This ain't fun */ + Class type = descr.getPropertyType(); + if (type.isAssignableFrom(Set.class)) { + descr.getWriteMethod().invoke(obj, new Object[] { s }); + } else if (type.isArray()) { + type = type.getComponentType(); + Object a[] = (Object[]) Array.newInstance(type, s.size()); + descr.getWriteMethod().invoke(obj, new Object[] {s.toArray(a)}); + } else { + throw new ClassCastException("Invalid type " + type); + } + + /* No exceptions, continue */ + continue; + + } catch (Throwable t) { + throw new DeployerException("Unable to set component for property \"" + + prop + "\" specified at " + curr.location(), t); } /* Do we have to set the kernel itself? */ - if (current.getBooleanAttribute("kernel", false)) try { - Wiring w = new Wiring(deployer); + if (curr.getBooleanAttribute("kernel", false)) try { + Wiring w = new Wiring(depl); Class i[] = new Class[] { Kernel.class }; - Object value = Proxy.newProxyInstance(deployer.getRuntime(), i, w); - descriptor.getWriteMethod().invoke(o, new Object[] { value }); + Object value = Proxy.newProxyInstance(depl.getRuntime(), i, w); + descr.getWriteMethod().invoke(obj, new Object[] { value }); continue; } catch (Throwable t) { throw new DeployerException("Unable to set kernel for property \"" - + property + "\" specified at " + current.location(), t); + + prop + "\" specified at " + curr.location(), t); } /* We haven't continue(d), something bad happened */ - throw new DeployerException("Invalid declaration at " + current.location()); + throw new DeployerException("Invalid declaration at " + curr.location()); } } }