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 }