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.activemq.util.IdGenerator;
027 import org.apache.cxf.Bus;
028 import org.apache.cxf.BusFactory;
029 import org.apache.cxf.frontend.ClientProxy;
030 import org.apache.cxf.interceptor.Interceptor;
031 import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
032 import org.apache.cxf.transport.ConduitInitiatorManager;
033 import org.apache.cxf.transport.jbi.JBITransportFactory;
034 import org.apache.servicemix.client.ClientFactory;
035 import org.apache.servicemix.client.ServiceMixClient;
036 import org.apache.servicemix.jbi.container.JBIContainer;
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 JBIContainer 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(),
089 getEndpoint()));
090 }
091 cf.setServiceClass(type);
092 cf.setAddress("jbi://" + new IdGenerator().generateSanitizedId());
093 if (isUseJBIWrapper()) {
094 cf
095 .setBindingId(org.apache.cxf.binding.jbi.JBIConstants.NS_JBI_BINDING);
096 }
097 Bus bus = BusFactory.getDefaultBus();
098 JBITransportFactory jbiTransportFactory = (JBITransportFactory) bus
099 .getExtension(ConduitInitiatorManager.class)
100 .getConduitInitiator(CxfSeComponent.JBI_TRANSPORT_ID);
101 if (getInternalContext() != null) {
102 DeliveryChannel dc = getInternalContext().getDeliveryChannel();
103 if (dc != null) {
104 jbiTransportFactory.setDeliveryChannel(dc);
105 }
106 }
107
108 Object retProxy = cf.create();
109 if (!isUseJBIWrapper() && !isUseSOAPEnvelope()) {
110 removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
111 .getBinding().getInInterceptors(), "ReadHeadersInterceptor");
112 removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
113 .getBinding().getInFaultInterceptors(),
114 "ReadHeadersInterceptor");
115 removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
116 .getBinding().getOutInterceptors(), "SoapOutInterceptor");
117 removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
118 .getBinding().getOutFaultInterceptors(),
119 "SoapOutInterceptor");
120 removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
121 .getBinding().getOutInterceptors(), "StaxOutInterceptor");
122 }
123 return retProxy;
124
125 }
126
127 private void removeInterceptor(List<Interceptor> interceptors,
128 String whichInterceptor) {
129 for (Interceptor interceptor : interceptors) {
130 if (interceptor.getClass().getName().endsWith(whichInterceptor)) {
131 interceptors.remove(interceptor);
132 }
133 }
134 }
135
136 public Class getObjectType() {
137 return type;
138 }
139
140 public boolean isSingleton() {
141 return true;
142 }
143
144 protected ComponentContext getInternalContext() throws Exception {
145 if (context == null) {
146 if (factory == null) {
147 if (container != null) {
148 factory = container.getClientFactory();
149 } else {
150 factory = (ClientFactory) new InitialContext().lookup(name);
151 }
152 }
153 client = factory.createClient();
154 context = client.getContext();
155 }
156 return context;
157 }
158
159 public Class getType() {
160 return type;
161 }
162
163 public void setType(Class type) {
164 this.type = type;
165 }
166
167 public String getEndpoint() {
168 return endpoint;
169 }
170
171 public void setEndpoint(String endpointName) {
172 this.endpoint = endpointName;
173 }
174
175 public QName getInterfaceName() {
176 return interfaceName;
177 }
178
179 public void setInterfaceName(QName interfaceName) {
180 this.interfaceName = interfaceName;
181 }
182
183 public QName getService() {
184 return service;
185 }
186
187 public void setService(QName service) {
188 this.service = service;
189 }
190
191 /**
192 * @return the context
193 */
194 public ComponentContext getContext() {
195 return context;
196 }
197
198 /**
199 * @param context
200 * the context to set
201 */
202 public void setContext(ComponentContext context) {
203 this.context = context;
204 }
205
206 /**
207 * @return the container
208 */
209 public JBIContainer getContainer() {
210 return container;
211 }
212
213 /**
214 * @param container
215 * the container to set
216 */
217 public void setContainer(JBIContainer container) {
218 this.container = container;
219 }
220
221 /**
222 * @return the factory
223 */
224 public ClientFactory getFactory() {
225 return factory;
226 }
227
228 /**
229 * @param factory
230 * the factory to set
231 */
232 public void setFactory(ClientFactory factory) {
233 this.factory = factory;
234 }
235
236 /**
237 * @return the name
238 */
239 public String getName() {
240 return name;
241 }
242
243 /**
244 * @param name
245 * the name to set
246 */
247 public void setName(String name) {
248 this.name = name;
249 }
250
251 /**
252 * @return the propagateSecuritySubject
253 */
254 public boolean isPropagateSecuritySubject() {
255 return propagateSecuritySubject;
256 }
257
258 /**
259 * @param propagateSecuritySubject
260 * the propagateSecuritySubject to set
261 */
262 public void setPropagateSecuritySubject(boolean propagateSecuritySubject) {
263 this.propagateSecuritySubject = propagateSecuritySubject;
264 }
265
266 public void afterPropertiesSet() throws Exception {
267 if (type == null) {
268 throw new IllegalArgumentException("type must be set");
269 }
270 }
271
272 public void destroy() throws Exception {
273 if (client != null) {
274 client.close();
275 client = null;
276 }
277 }
278
279 public void setUseJBIWrapper(boolean useJBIWrapper) {
280 this.useJBIWrapper = useJBIWrapper;
281 }
282
283 public boolean isUseJBIWrapper() {
284 return useJBIWrapper;
285 }
286
287 /**
288 * Specifies if the endpoint expects soap messages when useJBIWrapper is
289 * false, if useJBIWrapper is true then ignore useSOAPEnvelope
290 *
291 * @org.apache.xbean.Property description="Specifies if the endpoint expects
292 * soap messages when useJBIWrapper is false, if
293 * useJBIWrapper is true then ignore
294 * useSOAPEnvelope. The default is
295 * <code>true</code>.
296 */
297 public void setUseSOAPEnvelope(boolean useSOAPEnvelope) {
298 this.useSOAPEnvelope = useSOAPEnvelope;
299 }
300
301 public boolean isUseSOAPEnvelope() {
302 return useSOAPEnvelope;
303 }
304
305 }