View Javadoc

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 }