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 }