1 package org.codehaus.xfire.loom; 2 3 import java.util.Collections; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import org.apache.avalon.framework.configuration.Configurable; 8 import org.apache.avalon.framework.configuration.Configuration; 9 import org.apache.avalon.framework.configuration.ConfigurationException; 10 import org.apache.avalon.framework.logger.AbstractLogEnabled; 11 import org.apache.avalon.framework.service.ServiceException; 12 import org.apache.avalon.framework.service.ServiceManager; 13 import org.apache.avalon.framework.service.Serviceable; 14 import org.codehaus.xfire.aegis.AegisBindingProvider; 15 import org.codehaus.xfire.service.Service; 16 import org.codehaus.xfire.service.ServiceFactory; 17 import org.codehaus.xfire.service.ServiceRegistry; 18 import org.codehaus.xfire.service.binding.ObjectBinding; 19 import org.codehaus.xfire.service.binding.ObjectServiceFactory; 20 import org.codehaus.xfire.soap.Soap11; 21 import org.codehaus.xfire.soap.Soap12; 22 import org.codehaus.xfire.soap.SoapVersion; 23 import org.codehaus.xfire.util.ClassLoaderUtils; 24 25 /*** 26 * Default implementation of ServiceDeployer 27 * 28 * @author <a href="mailto:peter.royal@pobox.com">peter royal</a> 29 */ 30 public class DefaultServiceDeployer 31 extends AbstractLogEnabled 32 implements ServiceDeployer, Serviceable, Configurable 33 { 34 private final Map m_services = Collections.synchronizedMap(new HashMap()); 35 36 private ServiceRegistry m_serviceRegistry; 37 private Map m_serviceFactories; 38 39 private ServiceFactory m_defaultServiceFactory; 40 41 private Map m_configurations; 42 43 public void configure(final Configuration configuration) 44 throws ConfigurationException 45 { 46 final Configuration[] kids = configuration.getChildren("service"); 47 48 m_configurations = new HashMap(kids.length); 49 50 for (int i = 0; i < kids.length; i++) 51 { 52 m_configurations.put(kids[i].getAttribute("key"), kids[i]); 53 } 54 55 final Configuration child = configuration.getChild("defaultFactory"); 56 57 m_defaultServiceFactory = (ServiceFactory) m_serviceFactories.get(child.getValue()); 58 59 if (null == m_defaultServiceFactory) 60 { 61 final String msg = "Missing default factory '" + child.getValue() + "' at " + child.getLocation(); 62 throw new ConfigurationException(msg); 63 } 64 } 65 66 public void service(final ServiceManager manager) 67 throws ServiceException 68 { 69 m_serviceRegistry = (ServiceRegistry) manager.lookup(ServiceRegistry.ROLE); 70 m_serviceFactories = (Map) manager.lookup(ServiceFactory.class.getName() + "{}"); 71 } 72 73 public void deploy(final String key, final Object object) 74 throws Exception 75 { 76 if (m_services.containsKey(key)) 77 { 78 throw new IllegalStateException("Service with key '" + key + "' already deployed"); 79 } 80 81 final Configuration configuration = (Configuration) m_configurations.get(key); 82 final Service endpoint; 83 84 if (null == configuration) 85 { 86 if (getLogger().isInfoEnabled()) 87 getLogger().info("No configuration found for '" + key + "', using defaults"); 88 89 endpoint = m_defaultServiceFactory.create(object.getClass()); 90 } 91 else 92 { 93 endpoint = createServiceFromConfiguration(configuration); 94 95 if (getLogger().isDebugEnabled()) 96 getLogger().debug("Created '" + endpoint.getServiceInfo().getName() + "' from key '" + key + "'"); 97 } 98 99 endpoint.getBinding().setInvoker(new ServiceInvoker(object)); 100 101 registerService(key, endpoint); 102 } 103 104 private Service createServiceFromConfiguration(final Configuration configuration) 105 throws ConfigurationException 106 { 107 final ServiceFactory factory = getServiceFactory(configuration.getChild("factory").getValue(null)); 108 String encodingUri = configuration.getChild("encodingStyleURI").getValue(null); 109 final Map propertiesMap = new HashMap(); 110 111 if (encodingUri != null) 112 { 113 propertiesMap.put(AegisBindingProvider.TYPE_MAPPING_KEY, encodingUri); 114 } 115 116 if (factory instanceof ObjectServiceFactory) 117 { 118 ObjectServiceFactory osf = (ObjectServiceFactory) factory; 119 osf.setStyle(configuration.getChild("style").getValue("wrapped")); 120 osf.setUse(configuration.getChild("use").getValue("wrapped")); 121 osf.setSoapVersion(getSoapVersion(configuration.getChild("soapVersion"))); 122 } 123 124 final Configuration[] properties = configuration.getChildren("property"); 125 126 for (int i = 0; i < properties.length; i++) 127 { 128 propertiesMap.put(properties[i].getAttribute("name"), properties[i].getAttribute("value")); 129 } 130 131 final Service service = 132 factory.create(loadClass(configuration.getChild("serviceClass")), 133 configuration.getChild("name").getValue(), 134 configuration.getChild("namespace").getValue(""), 135 propertiesMap); 136 137 return service; 138 } 139 140 private ServiceFactory getServiceFactory(final String key) 141 { 142 if (m_serviceFactories.containsKey(key)) 143 { 144 return (ServiceFactory) m_serviceFactories.get(key); 145 } 146 else 147 { 148 return m_defaultServiceFactory; 149 } 150 } 151 152 private SoapVersion getSoapVersion(final Configuration configuration) 153 throws ConfigurationException 154 { 155 final String value = configuration.getValue("1.1"); 156 157 if (value.equals("1.1")) 158 { 159 return Soap11.getInstance(); 160 } 161 else if (value.equals("1.2")) 162 { 163 return Soap12.getInstance(); 164 } 165 else 166 { 167 final String msg = "Invalid soap version at " + configuration.getLocation() + ". Must be 1.1 or 1.2."; 168 throw new ConfigurationException(msg); 169 } 170 } 171 172 private Class loadClass(final Configuration configuration) 173 throws ConfigurationException 174 { 175 try 176 { 177 return ClassLoaderUtils.loadClass(configuration.getValue(), getClass()); 178 } 179 catch (ClassNotFoundException e) 180 { 181 final String msg = "Unable to load " + configuration.getValue() + " at " + configuration.getLocation(); 182 throw new ConfigurationException(msg, e); 183 } 184 } 185 186 private void registerService(final String key, final Service endpoint) 187 { 188 m_serviceRegistry.register(endpoint); 189 190 m_services.put(key, endpoint.getName()); 191 } 192 193 public void undeploy(final String key) 194 { 195 if (m_services.containsKey(key)) 196 { 197 m_serviceRegistry.unregister((String) m_services.remove(key)); 198 } 199 else if (getLogger().isWarnEnabled()) 200 { 201 getLogger().warn("Attempted to undeploy unknown key: " + key); 202 } 203 } 204 }