001 /***************************************************************************** 002 * Copyright (C) PicoContainer 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.picocontainer.script.xml; 010 011 import org.picocontainer.ComponentAdapter; 012 import org.picocontainer.PicoContainer; 013 import org.picocontainer.PicoClassNotFoundException; 014 import org.picocontainer.lifecycle.NullLifecycleStrategy; 015 import org.picocontainer.monitors.NullComponentMonitor; 016 import org.picocontainer.injectors.AdaptingInjection; 017 import org.picocontainer.behaviors.PropertyApplicator; 018 import org.picocontainer.ComponentFactory; 019 020 import java.util.Properties; 021 022 import org.w3c.dom.Element; 023 import org.w3c.dom.Node; 024 import org.w3c.dom.NodeList; 025 026 /** 027 * Implementation of XMLComponentInstanceFactory that uses PropertyApplicator 028 * to create instances from DOM elements. 029 * 030 * @author Paul Hammant 031 * @author Marcos Tarruella 032 * @author Mauro Talevi 033 */ 034 public class BeanComponentInstanceFactory implements XMLComponentInstanceFactory { 035 036 private static final String NAME_ATTRIBUTE = "name"; 037 038 @SuppressWarnings("unchecked") 039 public Object makeInstance(PicoContainer pico, Element element, ClassLoader classLoader) { 040 String className = element.getNodeName(); 041 Object instance; 042 043 if (element.getChildNodes().getLength() == 1) { 044 instance = PropertyApplicator.convert(className, element.getFirstChild().getNodeValue(), classLoader); 045 } else { 046 047 //TODO componentMonitor.newBehavior( .. ) stuff 048 049 PropertyApplicator propertyAdapter = 050 new PropertyApplicator(createComponentAdapter(className, classLoader)); 051 java.util.Properties properties = createProperties(element.getChildNodes()); 052 propertyAdapter.setProperties(properties); 053 instance = propertyAdapter.getComponentInstance(pico, ComponentAdapter.NOTHING.class); 054 } 055 return instance; 056 } 057 058 @SuppressWarnings("unchecked") 059 private ComponentAdapter createComponentAdapter(String className, ClassLoader classLoader) { 060 Class implementation = loadClass(classLoader, className); 061 ComponentFactory factory = new AdaptingInjection(); 062 return factory.createComponentAdapter(new NullComponentMonitor(), new NullLifecycleStrategy(), new Properties(), className, implementation); 063 } 064 065 private Class<?> loadClass(final ClassLoader classLoader, final String className) { 066 try { 067 return classLoader.loadClass(className); 068 } catch (ClassNotFoundException e) { 069 throw new PicoClassNotFoundException(className, e); 070 } 071 } 072 073 private java.util.Properties createProperties(NodeList nodes) { 074 java.util.Properties properties = new java.util.Properties(); 075 for (int i = 0; i < nodes.getLength(); i++) { 076 Node n = nodes.item(i); 077 if (n.getNodeType() == Node.ELEMENT_NODE) { 078 String name = n.getNodeName(); 079 080 //Provide for a new 'name' attribute in properties. 081 if (n.hasAttributes()) { 082 String mappedName = n.getAttributes().getNamedItem(NAME_ATTRIBUTE).getNodeValue(); 083 if (mappedName != null) { 084 name = mappedName; 085 } 086 } 087 088 String value = n.getFirstChild().getNodeValue(); 089 properties.setProperty(name, value); 090 } 091 } 092 return properties; 093 } 094 }