001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.cxfse;
018
019 import java.util.List;
020
021 import javax.jbi.component.ComponentContext;
022 import javax.jbi.messaging.DeliveryChannel;
023 import javax.naming.InitialContext;
024 import javax.xml.namespace.QName;
025
026 import org.apache.cxf.Bus;
027 import org.apache.cxf.BusFactory;
028 import org.apache.cxf.frontend.ClientProxy;
029 import org.apache.cxf.interceptor.Interceptor;
030 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
031 import org.apache.cxf.transport.ConduitInitiatorManager;
032 import org.apache.cxf.transport.jbi.JBITransportFactory;
033 import org.apache.servicemix.id.IdGenerator;
034 import org.apache.servicemix.jbi.api.ClientFactory;
035 import org.apache.servicemix.jbi.api.Container;
036 import org.apache.servicemix.jbi.api.ServiceMixClient;
037
038 import org.springframework.beans.factory.DisposableBean;
039 import org.springframework.beans.factory.FactoryBean;
040 import org.springframework.beans.factory.InitializingBean;
041
042 /**
043 *
044 * @author ffang
045 * @org.apache.xbean.XBean element="proxy" description="A CXF proxy"
046 *
047 */
048 public class CxfSeProxyFactoryBean implements FactoryBean, InitializingBean,
049 DisposableBean {
050
051 private String name = ClientFactory.DEFAULT_JNDI_NAME;
052
053 private Container container;
054
055 private ClientFactory factory;
056
057 private ComponentContext context;
058
059 private Class type;
060
061 private Object proxy;
062
063 private QName service;
064
065 private QName interfaceName;
066
067 private String endpoint;
068
069 private boolean propagateSecuritySubject;
070
071 private ServiceMixClient client;
072
073 private boolean useJBIWrapper = true;
074
075 private boolean useSOAPEnvelope = true;
076
077 public Object getObject() throws Exception {
078 if (proxy == null) {
079 proxy = createProxy();
080 }
081 return proxy;
082 }
083
084 private Object createProxy() throws Exception {
085 JaxWsProxyFactoryBean cf = new JaxWsProxyFactoryBean();
086 cf.setServiceName(getService());
087 if (getEndpoint() != null) {
088 cf.setEndpointName(new QName(getService().getNamespaceURI(), getEndpoint()));
089 }
090 cf.setServiceClass(type);
091 cf.setAddress("jbi://" + new IdGenerator().generateSanitizedId());
092 if (isUseJBIWrapper()) {
093 cf.setBindingId(org.apache.cxf.binding.jbi.JBIConstants.NS_JBI_BINDING);
094 }
095 Bus bus = BusFactory.getDefaultBus();
096 JBITransportFactory jbiTransportFactory = (JBITransportFactory) bus
097 .getExtension(ConduitInitiatorManager.class)
098 .getConduitInitiator(JBITransportFactory.TRANSPORT_ID);
099 if (getInternalContext() != null) {
100 DeliveryChannel dc = getInternalContext().getDeliveryChannel();
101 if (dc != null) {
102 jbiTransportFactory.setDeliveryChannel(dc);
103 }
104 }
105 Object proxy = cf.create();
106 if (!isUseJBIWrapper() && !isUseSOAPEnvelope()) {
107 removeInterceptor(ClientProxy.getClient(proxy).getEndpoint().getBinding().getInInterceptors(),
108 "ReadHeadersInterceptor");
109 removeInterceptor(ClientProxy.getClient(proxy).getEndpoint().getBinding().getInFaultInterceptors(),
110 "ReadHeadersInterceptor");
111 removeInterceptor(ClientProxy.getClient(proxy).getEndpoint().getBinding().getOutInterceptors(),
112 "SoapOutInterceptor");
113 removeInterceptor(ClientProxy.getClient(proxy).getEndpoint().getBinding().getOutFaultInterceptors(),
114 "SoapOutInterceptor");
115 removeInterceptor(ClientProxy.getClient(proxy).getEndpoint().getBinding().getOutInterceptors(),
116 "StaxOutInterceptor");
117 }
118 return proxy;
119 }
120
121 private void removeInterceptor(List<Interceptor> interceptors, String whichInterceptor) {
122 for (Interceptor interceptor : interceptors) {
123 if (interceptor.getClass().getName().endsWith(whichInterceptor)) {
124 interceptors.remove(interceptor);
125 }
126 }
127 }
128
129 public Class getObjectType() {
130 return type;
131 }
132
133 public boolean isSingleton() {
134 return true;
135 }
136
137 protected ComponentContext getInternalContext() throws Exception {
138 if (context == null) {
139 if (factory == null) {
140 if (container != null) {
141 factory = container.getClientFactory();
142 } else {
143 factory = (ClientFactory) new InitialContext().lookup(name);
144 }
145 }
146 client = factory.createClient();
147 context = client.getContext();
148 }
149 return context;
150 }
151
152 public Class getType() {
153 return type;
154 }
155
156 public void setType(Class type) {
157 this.type = type;
158 }
159
160 public String getEndpoint() {
161 return endpoint;
162 }
163
164 public void setEndpoint(String endpointName) {
165 this.endpoint = endpointName;
166 }
167
168 public QName getInterfaceName() {
169 return interfaceName;
170 }
171
172 public void setInterfaceName(QName interfaceName) {
173 this.interfaceName = interfaceName;
174 }
175
176 public QName getService() {
177 return service;
178 }
179
180 public void setService(QName service) {
181 this.service = service;
182 }
183
184 /**
185 * @return the context
186 */
187 public ComponentContext getContext() {
188 return context;
189 }
190
191 /**
192 * @param context
193 * the context to set
194 */
195 public void setContext(ComponentContext context) {
196 this.context = context;
197 }
198
199 /**
200 * @return the container
201 */
202 public Container getContainer() {
203 return container;
204 }
205
206 /**
207 * @param container
208 * the container to set
209 */
210 public void setContainer(Container container) {
211 this.container = container;
212 }
213
214 /**
215 * @return the factory
216 */
217 public ClientFactory getFactory() {
218 return factory;
219 }
220
221 /**
222 * @param factory
223 * the factory to set
224 */
225 public void setFactory(ClientFactory factory) {
226 this.factory = factory;
227 }
228
229 /**
230 * @return the name
231 */
232 public String getName() {
233 return name;
234 }
235
236 /**
237 * @param name
238 * the name to set
239 */
240 public void setName(String name) {
241 this.name = name;
242 }
243
244 /**
245 * @return the propagateSecuritySubject
246 */
247 public boolean isPropagateSecuritySubject() {
248 return propagateSecuritySubject;
249 }
250
251 /**
252 * @param propagateSecuritySubject
253 * the propagateSecuritySubject to set
254 */
255 public void setPropagateSecuritySubject(boolean propagateSecuritySubject) {
256 this.propagateSecuritySubject = propagateSecuritySubject;
257 }
258
259 public void afterPropertiesSet() throws Exception {
260 if (type == null) {
261 throw new IllegalArgumentException("type must be set");
262 }
263 }
264
265 public void destroy() throws Exception {
266 if (client != null) {
267 client.close();
268 client = null;
269 }
270 }
271
272 /**
273 * Specifies if the endpoint expects messages that are encased in the
274 * JBI wrapper used for SOAP messages. Ignore the value of useSOAPEnvelope
275 * if useJBIWrapper is true
276 *
277 * @org.apache.xbean.Property description="Specifies if the endpoint expects to receive the JBI wrapper in the message received from the NMR. The default is <code>true</code>.
278 * Ignore the value of useSOAPEnvelope if useJBIWrapper is true"
279 * */
280 public void setUseJBIWrapper(boolean useJBIWrapper) {
281 this.useJBIWrapper = useJBIWrapper;
282 }
283
284 public boolean isUseJBIWrapper() {
285 return useJBIWrapper;
286 }
287
288 /**
289 * Specifies if the endpoint expects soap messages when useJBIWrapper is false,
290 * if useJBIWrapper is true then ignore useSOAPEnvelope
291 *
292 * @org.apache.xbean.Property description="Specifies if the endpoint expects soap messages when useJBIWrapper is false,
293 * if useJBIWrapper is true then ignore useSOAPEnvelope. The default is <code>true</code>.
294 * */
295 public void setUseSOAPEnvelope(boolean useSOAPEnvelope) {
296 this.useSOAPEnvelope = useSOAPEnvelope;
297 }
298
299 public boolean isUseSOAPEnvelope() {
300 return useSOAPEnvelope;
301 }
302
303 }