001: /*****************************************************************************
002: * Copyright (C) NanoContainer Organization. All rights reserved. *
003: * ------------------------------------------------------------------------- *
004: * The software in this package is published under the terms of the BSD *
005: * style license a copy of which has been included with this distribution in *
006: * the LICENSE.txt file. *
007: * *
008: * Original code by James Strachan *
009: *****************************************************************************/package org.nanocontainer.script.groovy.buildernodes;
010:
011: import java.util.Map;
012:
013: import org.nanocontainer.NanoContainer;
014: import org.picocontainer.MutablePicoContainer;
015: import org.nanocontainer.script.NanoContainerMarkupException;
016: import java.util.Iterator;
017: import org.codehaus.groovy.runtime.InvokerHelper;
018:
019: /**
020: * Creates on-the-spot Javabeans configurations and registers the result with
021: * the container via pico.registerCompoenntInstance.
022: * @author James Strachan
023: * @author Paul Hammant
024: * @author Aslak Hellesøy
025: * @author Michael Rimov
026: * @author Mauro Talevi
027: * @version $Revision: 2695 $
028: */
029: public class BeanNode extends AbstractBuilderNode {
030:
031: /**
032: * The name of the node we're handling.
033: */
034: public static final String NODE_NAME = "bean";
035:
036: /**
037: * Bean class attribute.
038: */
039: public static final String BEAN_CLASS = "beanClass";
040:
041: /**
042: * Default constructor.
043: */
044: public BeanNode() {
045: super (NODE_NAME);
046: }
047:
048: public Object createNewNode(Object current, Map attributes) {
049: MutablePicoContainer pico = ((NanoContainer) current).getPico();
050: Object bean = createBean(attributes);
051: pico.registerComponentInstance(bean);
052: return bean;
053: }
054:
055: /**
056: * Instantiates the bean and sets the appropriate attributes. It then
057: * @param attributes Map
058: * @return Object resulting JavaBean.
059: */
060: protected Object createBean(final Map attributes) {
061: Class type = (Class) attributes.remove(BEAN_CLASS);
062: if (type == null) {
063: throw new NanoContainerMarkupException(
064: "Bean must have a beanClass attribute");
065: }
066: try {
067: Object bean = type.newInstance();
068: // now let's set the properties on the bean
069: for (Iterator iter = attributes.entrySet().iterator(); iter
070: .hasNext();) {
071: Map.Entry entry = (Map.Entry) iter.next();
072: String name = entry.getKey().toString();
073: Object value = entry.getValue();
074: InvokerHelper.setProperty(bean, name, value);
075: }
076: return bean;
077: } catch (IllegalAccessException e) {
078: throw new NanoContainerMarkupException(
079: "Failed to create bean of type '" + type
080: + "'. Reason: " + e, e);
081: } catch (InstantiationException e) {
082: throw new NanoContainerMarkupException(
083: "Failed to create bean of type " + type
084: + "'. Reason: " + e, e);
085: }
086: }
087:
088: /**
089: * {@inheritDoc}
090: * <p>This version only checks for 'beanClass' and lets all other attributes
091: * through (since they become property values)</p>
092: * @param specifiedAttributes Map
093: * @throws NanoContainerMarkupException
094: */
095: public void validateScriptedAttributes(Map specifiedAttributes)
096: throws NanoContainerMarkupException {
097: if (!specifiedAttributes.containsKey(BEAN_CLASS)) {
098: throw new NanoContainerMarkupException("Attribute "
099: + BEAN_CLASS + " is required.");
100: }
101:
102: //Assume all other attributes
103: }
104: }
|