View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.module.cxf;
8   
9   import org.mule.api.MuleContext;
10  import org.mule.api.MuleException;
11  import org.mule.api.context.MuleContextAware;
12  import org.mule.api.lifecycle.Disposable;
13  import org.mule.api.lifecycle.Initialisable;
14  import org.mule.api.lifecycle.InitialisationException;
15  import org.mule.config.spring.SpringRegistry;
16  import org.mule.module.cxf.support.MuleHeadersInInterceptor;
17  import org.mule.module.cxf.support.MuleHeadersOutInterceptor;
18  import org.mule.module.cxf.support.MuleProtocolHeadersOutInterceptor;
19  import org.mule.module.cxf.transport.MuleUniversalTransport;
20  
21  import java.lang.reflect.Field;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.cxf.Bus;
27  import org.apache.cxf.BusException;
28  import org.apache.cxf.BusFactory;
29  import org.apache.cxf.bus.spring.SpringBusFactory;
30  import org.apache.cxf.common.util.ASMHelper;
31  import org.apache.cxf.jaxb.JAXBDataBinding;
32  import org.apache.cxf.transport.ConduitInitiatorManager;
33  import org.apache.cxf.transport.DestinationFactoryManager;
34  import org.springframework.context.ApplicationContext;
35  
36  /**
37   * Provides global CXF configuration defaults.
38   */
39  public class CxfConfiguration implements Initialisable, Disposable, MuleContextAware
40  {
41      public static final String CXF = "cxf";
42      public static final String CONFIGURATION_LOCATION = "configurationLocation";
43      public static final String DEFAULT_MULE_NAMESPACE_URI = "http://www.muleumo.org";
44      public static final String BUS_PROPERTY = CXF;
45  
46      protected transient Log logger = LogFactory.getLog(getClass());
47  
48      // The CXF Bus object
49      private Bus bus;
50      private String configurationLocation;
51      private boolean initializeStaticBusInstance;
52      private MuleContext muleContext;
53      private boolean enableMuleSoapHeaders = true;
54      
55      public void initialise() throws InitialisationException
56      {
57          BusFactory.setDefaultBus(null);
58          ApplicationContext context = (ApplicationContext) muleContext.getRegistry().lookupObject(SpringRegistry.SPRING_APPLICATION_CONTEXT);
59  
60          if (configurationLocation != null)
61          {
62              bus = new SpringBusFactory(context).createBus(configurationLocation, true);
63          }
64          else
65          {
66              bus = new SpringBusFactory().createBus((String) null, true);
67          }
68  
69          if (!initializeStaticBusInstance)
70          {
71              BusFactory.setDefaultBus(null);
72          }
73  
74          MuleUniversalTransport transport = new MuleUniversalTransport(this);
75          DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class);
76          dfm.registerDestinationFactory("http://schemas.xmlsoap.org/soap/http", transport);
77          dfm.registerDestinationFactory("http://schemas.xmlsoap.org/wsdl/soap/http", transport);
78          dfm.registerDestinationFactory("http://cxf.apache.org/transports/http/configuration", transport);
79          dfm.registerDestinationFactory("http://schemas.xmlsoap.org/wsdl/http/", transport);
80          dfm.registerDestinationFactory("http://www.w3.org/2003/05/soap/bindings/HTTP/", transport);
81          dfm.registerDestinationFactory("http://cxf.apache.org/transports/jms", transport);
82          dfm.registerDestinationFactory("http://cxf.apache.org/transports/http", transport);
83          
84          dfm.registerDestinationFactory(MuleUniversalTransport.TRANSPORT_ID, transport);
85  
86          ConduitInitiatorManager extension = bus.getExtension(ConduitInitiatorManager.class);
87          try
88          {
89              // Force the HTTP transport to load if available, otherwise it could
90              // overwrite our namespaces later
91              extension.getConduitInitiator("http://schemas.xmlsoap.org/soap/http");
92          }
93          catch (BusException e1)
94          {
95              // If unavailable eat exception and continue
96          }
97          extension.registerConduitInitiator("http://cxf.apache.org/transports/http", transport);
98          extension.registerConduitInitiator("http://schemas.xmlsoap.org/wsdl/soap/", transport);
99          extension.registerConduitInitiator("http://schemas.xmlsoap.org/soap/http", transport);
100         extension.registerConduitInitiator("http://schemas.xmlsoap.org/soap/http/", transport);
101         extension.registerConduitInitiator("http://schemas.xmlsoap.org/wsdl/soap/http", transport);
102         extension.registerConduitInitiator("http://schemas.xmlsoap.org/wsdl/http/", transport);
103         extension.registerConduitInitiator("http://www.w3.org/2003/05/soap/bindings/HTTP/", transport);
104         extension.registerConduitInitiator("http://cxf.apache.org/transports/http/configuration", transport);
105         extension.registerConduitInitiator("http://cxf.apache.org/bindings/xformat", transport);
106         extension.registerConduitInitiator("http://cxf.apache.org/transports/jms", transport);
107         extension.registerConduitInitiator(MuleUniversalTransport.TRANSPORT_ID, transport);
108         
109         bus.getOutInterceptors().add(new MuleProtocolHeadersOutInterceptor());
110         bus.getOutFaultInterceptors().add(new MuleProtocolHeadersOutInterceptor());
111 
112         if (enableMuleSoapHeaders)
113         {
114             bus.getInInterceptors().add(new MuleHeadersInInterceptor());
115             bus.getInFaultInterceptors().add(new MuleHeadersInInterceptor());
116             bus.getOutInterceptors().add(new MuleHeadersOutInterceptor());
117             bus.getOutFaultInterceptors().add(new MuleHeadersOutInterceptor());
118         }
119     }
120 
121     public void dispose()
122     {
123         bus.shutdown(true);
124         // clear static caches preventing memory leaks on redeploy
125         // needed because cxf core classes are loaded by the Mule system classloader, not app's
126         JAXBDataBinding.clearCaches();
127         try
128         {
129             // ASMHelper.LOADER_MAP is a protected static field
130             final Field cacheField = ASMHelper.class.getDeclaredField("LOADER_MAP");
131             cacheField.setAccessible(true);
132             // static field
133             final Map cache = (Map) cacheField.get(null);
134             cache.clear();
135         }
136         catch (Throwable t)
137         {
138             logger.warn("Error disposing CxfConfiguration, this may cause a memory leak", t);
139         }
140     }
141 
142     public Bus getCxfBus()
143     {
144         return bus;
145     }
146 
147     public void setCxfBus(Bus bus)
148     {
149         this.bus = bus;
150     }
151 
152     public String getConfigurationLocation()
153     {
154         return configurationLocation;
155     }
156 
157     public void setConfigurationLocation(String configurationLocation)
158     {
159         this.configurationLocation = configurationLocation;
160     }
161     
162     public boolean isInitializeStaticBusInstance()
163     {
164         return initializeStaticBusInstance;
165     }
166 
167     public void setInitializeStaticBusInstance(boolean initializeStaticBusInstance)
168     {
169         this.initializeStaticBusInstance = initializeStaticBusInstance;
170     }
171 
172     public void setMuleContext(MuleContext context)
173     {
174         this.muleContext = context;
175     }
176 
177     public MuleContext getMuleContext()
178     {
179         return muleContext;
180     }
181 
182     public static CxfConfiguration getConfiguration(MuleContext muleContext) throws MuleException
183     {
184         CxfConfiguration configuration = muleContext.getRegistry().get(CxfConstants.DEFAULT_CXF_CONFIGURATION);
185         if (configuration == null) 
186         {
187             configuration = new CxfConfiguration();
188             configuration.setMuleContext(muleContext);
189             configuration.initialise();
190             muleContext.getRegistry().registerObject(CxfConstants.DEFAULT_CXF_CONFIGURATION, configuration);
191         }
192         return configuration;
193     }
194 
195     public boolean isEnableMuleSoapHeaders()
196     {
197         return enableMuleSoapHeaders;
198     }
199 
200     public void setEnableMuleSoapHeaders(boolean enableMuleSoapHeaders)
201     {
202         this.enableMuleSoapHeaders = enableMuleSoapHeaders;
203     }
204 
205 }