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     *****************************************************************************/
010    
011    
012    package org.nanocontainer.script.groovy.buildernodes;
013    
014    import java.util.List;
015    import java.util.Map;
016    
017    import org.nanocontainer.NanoContainer;
018    import org.nanocontainer.script.NodeBuilderDecorationDelegate;
019    import org.nanocontainer.script.ComponentElementHelper;
020    import org.picocontainer.MutablePicoContainer;
021    import org.picocontainer.Parameter;
022    import org.picocontainer.defaults.ConstantParameter;
023    
024    /**
025     *
026     * @author James Strachan
027     * @author Paul Hammant
028     * @author Aslak Hellesøy
029     * @author Michael Rimov
030     * @author Mauro Talevi
031     * @version $Revision: 2695 $
032     */
033    public class ComponentNode extends AbstractBuilderNode {
034    
035        public static final String NODE_NAME =  "component";
036    
037        /**
038         * Attributes 'key'
039         */
040        public static final String KEY = "key";
041    
042        /**
043         * Class attribute.
044         */
045        private static final String CLASS = "class";
046    
047        /**
048         * Class Name Key Attribute.
049         */
050        private static final String CLASS_NAME_KEY = "classNameKey";
051    
052        /**
053         * Instance attribute name.
054         */
055        private static final String INSTANCE = "instance";
056    
057        /**
058         * Parameters attribute name.
059         */
060        private static final String PARAMETERS = "parameters";
061    
062    
063        private final NodeBuilderDecorationDelegate delegate;
064    
065        public ComponentNode(NodeBuilderDecorationDelegate builderDelegate) {
066            super(NODE_NAME);
067    
068            this.delegate = builderDelegate;
069    
070    
071            //Supported attributes.
072            this.addAttribute(KEY)
073                .addAttribute(CLASS)
074                .addAttribute(CLASS_NAME_KEY)
075                .addAttribute(INSTANCE)
076                .addAttribute(PARAMETERS);
077        }
078    
079        /**
080         * Execute the handler for the given node builder.
081         * TODO - wrong Javadoc
082         * @param name Object the parent object.
083         * @param value The Node value. This is almost never used, but it kept
084         *   in for consistency with the Groovy Builder API. Normally set to
085         *   null.
086         * @param current The current node.
087         * @param attributes Map attributes specified in the groovy script for
088         *   the builder node.
089         * @return Object
090         */
091        public Object createNewNode(final Object current, final Map attributes) {
092            delegate.rememberComponentKey(attributes);
093            Object key = attributes.remove(KEY);
094            Object cnkey = attributes.remove(CLASS_NAME_KEY);
095            Object classValue = attributes.remove(CLASS);
096            Object instance = attributes.remove(INSTANCE);
097            List parameters = (List) attributes.remove(PARAMETERS);
098    
099            ComponentElementHelper.makeComponent(cnkey, key, getParameters(parameters), classValue, (NanoContainer) current, instance);
100    
101            return this.getNodeName();
102        }
103    
104        private static Parameter[] getParameters(List paramsList) {
105            if (paramsList == null) {
106                return null;
107            }
108            int n = paramsList.size();
109            Parameter[] parameters = new Parameter[n];
110            for (int i = 0; i < n; ++i) {
111                parameters[i] = toParameter(paramsList.get(i));
112            }
113            return parameters;
114        }
115    
116    
117    
118        private static Parameter toParameter(Object obj) {
119            return obj instanceof Parameter ? (Parameter) obj : new ConstantParameter(obj);
120        }
121    
122    
123    }