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 *****************************************************************************/ 009 package org.nanocontainer.script.xml; 010 011 import org.picocontainer.ComponentAdapter; 012 import org.picocontainer.Parameter; 013 import org.picocontainer.PicoContainer; 014 import org.picocontainer.defaults.BeanPropertyComponentAdapter; 015 import org.picocontainer.defaults.ComponentAdapterFactory; 016 import org.picocontainer.defaults.DefaultComponentAdapterFactory; 017 import org.w3c.dom.Element; 018 import org.w3c.dom.Node; 019 import org.w3c.dom.NodeList; 020 021 import java.net.MalformedURLException; 022 import java.util.Properties; 023 024 /** 025 * Implementation of XMLComponentInstanceFactory that uses BeanPropertyComponentAdapter 026 * to create instances from DOM elements. 027 * 028 * @author Paul Hammant 029 * @author Marcos Tarruella 030 * @author Mauro Talevi 031 */ 032 public class BeanComponentInstanceFactory implements XMLComponentInstanceFactory { 033 034 private static final String NAME_ATTRIBUTE = "name"; 035 036 public Object makeInstance(PicoContainer pico, Element element, ClassLoader classLoader) throws ClassNotFoundException, MalformedURLException { 037 String className = element.getNodeName(); 038 Object instance = null; 039 040 if (element.getChildNodes().getLength() == 1) { 041 instance = BeanPropertyComponentAdapter.convert(className, element.getFirstChild().getNodeValue(), classLoader); 042 } else { 043 BeanPropertyComponentAdapter propertyComponentAdapter = 044 new BeanPropertyComponentAdapter(createComponentAdapter(className, classLoader)); 045 Properties properties = createProperties(element.getChildNodes()); 046 propertyComponentAdapter.setProperties(properties); 047 instance = propertyComponentAdapter.getComponentInstance(pico); 048 } 049 return instance; 050 } 051 052 private ComponentAdapter createComponentAdapter(String className, ClassLoader classLoader) throws ClassNotFoundException { 053 Class implementation = classLoader.loadClass(className); 054 ComponentAdapterFactory factory = new DefaultComponentAdapterFactory(); 055 return factory.createComponentAdapter(className, implementation, new Parameter[]{}); 056 } 057 058 private Properties createProperties(NodeList nodes) { 059 Properties properties = new Properties(); 060 for (int i = 0; i < nodes.getLength(); i++) { 061 Node n = nodes.item(i); 062 if (n.getNodeType() == Node.ELEMENT_NODE) { 063 String name = n.getNodeName(); 064 065 //Provide for a new 'name' attribute in properties. 066 if (n.hasAttributes()) { 067 String mappedName = n.getAttributes().getNamedItem(NAME_ATTRIBUTE).getNodeValue(); 068 if (mappedName != null) { 069 name = mappedName; 070 } 071 } 072 073 String value = n.getFirstChild().getNodeValue(); 074 properties.setProperty(name, value); 075 } 076 } 077 return properties; 078 } 079 }