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.cxfse.interceptors.AttachmentInInterceptor;
037    import org.apache.servicemix.cxfse.interceptors.AttachmentOutInterceptor;
038    import org.apache.servicemix.jbi.container.JBIContainer;
039    
040    import org.springframework.beans.factory.DisposableBean;
041    import org.springframework.beans.factory.FactoryBean;
042    import org.springframework.beans.factory.InitializingBean;
043    
044    /**
045     * 
046     * @author ffang
047     * @org.apache.xbean.XBean element="proxy" description="A CXF proxy"
048     * 
049     */
050    public class CxfSeProxyFactoryBean implements FactoryBean, InitializingBean,
051            DisposableBean {
052    
053        private String name = ClientFactory.DEFAULT_JNDI_NAME;
054    
055        private JBIContainer container;
056    
057        private ClientFactory factory;
058    
059        private ComponentContext context;
060    
061        private Class type;
062    
063        private Object proxy;
064    
065        private QName service;
066    
067        private QName interfaceName;
068    
069        private String endpoint;
070    
071        private boolean propagateSecuritySubject;
072    
073        private ServiceMixClient client;
074    
075        private boolean useJBIWrapper = true;
076    
077        private boolean useSOAPEnvelope = true;
078        
079        private boolean mtomEnabled;
080    
081        public Object getObject() throws Exception {
082            if (proxy == null) {
083                proxy = createProxy();
084            }
085            return proxy;
086        }
087    
088        private Object createProxy() throws Exception {
089            JaxWsProxyFactoryBean cf = new JaxWsProxyFactoryBean();
090            cf.setServiceName(getService());
091            if (getEndpoint() != null) {
092                cf.setEndpointName(new QName(getService().getNamespaceURI(),
093                        getEndpoint()));
094            }
095            cf.setServiceClass(type);
096            cf.setAddress("jbi://" + new IdGenerator().generateSanitizedId());
097            if (isUseJBIWrapper()) {
098                cf
099                        .setBindingId(org.apache.cxf.binding.jbi.JBIConstants.NS_JBI_BINDING);
100            }
101            Bus bus = BusFactory.getDefaultBus();
102            JBITransportFactory jbiTransportFactory = (JBITransportFactory) bus
103                    .getExtension(ConduitInitiatorManager.class)
104                    .getConduitInitiator(CxfSeComponent.JBI_TRANSPORT_ID);
105            if (getInternalContext() != null) {
106                DeliveryChannel dc = getInternalContext().getDeliveryChannel();
107                if (dc != null) {
108                    jbiTransportFactory.setDeliveryChannel(dc);
109                }
110            }
111    
112            Object retProxy = cf.create();
113            if (!isUseJBIWrapper() && !isUseSOAPEnvelope()) {
114                removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
115                        .getBinding().getInInterceptors(), "ReadHeadersInterceptor");
116                removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
117                        .getBinding().getInFaultInterceptors(),
118                        "ReadHeadersInterceptor");
119                removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
120                        .getBinding().getOutInterceptors(), "SoapOutInterceptor");
121                removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
122                        .getBinding().getOutFaultInterceptors(),
123                        "SoapOutInterceptor");
124                removeInterceptor(ClientProxy.getClient(retProxy).getEndpoint()
125                        .getBinding().getOutInterceptors(), "StaxOutInterceptor");
126            }
127            if (isMtomEnabled()) {
128                ClientProxy.getClient(retProxy).getEndpoint()
129                    .getBinding().getInInterceptors().add(new AttachmentInInterceptor());
130                ClientProxy.getClient(retProxy).getEndpoint()
131                    .getBinding().getOutInterceptors().add(new AttachmentOutInterceptor());
132            }
133            return retProxy;
134    
135        }
136    
137        private void removeInterceptor(List<Interceptor> interceptors,
138                String whichInterceptor) {
139            for (Interceptor interceptor : interceptors) {
140                if (interceptor.getClass().getName().endsWith(whichInterceptor)) {
141                    interceptors.remove(interceptor);
142                }
143            }
144        }
145    
146        public Class getObjectType() {
147            return type;
148        }
149    
150        public boolean isSingleton() {
151            return true;
152        }
153    
154        protected ComponentContext getInternalContext() throws Exception {
155            if (context == null) {
156                if (factory == null) {
157                    if (container != null) {
158                        factory = container.getClientFactory();
159                    } else {
160                        factory = (ClientFactory) new InitialContext().lookup(name);
161                    }
162                }
163                client = factory.createClient();
164                context = client.getContext();
165            }
166            return context;
167        }
168    
169        public Class getType() {
170            return type;
171        }
172    
173        public void setType(Class type) {
174            this.type = type;
175        }
176    
177        public String getEndpoint() {
178            return endpoint;
179        }
180    
181        public void setEndpoint(String endpointName) {
182            this.endpoint = endpointName;
183        }
184    
185        public QName getInterfaceName() {
186            return interfaceName;
187        }
188    
189        public void setInterfaceName(QName interfaceName) {
190            this.interfaceName = interfaceName;
191        }
192    
193        public QName getService() {
194            return service;
195        }
196    
197        public void setService(QName service) {
198            this.service = service;
199        }
200    
201        /**
202         * @return the context
203         */
204        public ComponentContext getContext() {
205            return context;
206        }
207    
208        /**
209         * @param context
210         *            the context to set
211         */
212        public void setContext(ComponentContext context) {
213            this.context = context;
214        }
215    
216        /**
217         * @return the container
218         */
219        public JBIContainer getContainer() {
220            return container;
221        }
222    
223        /**
224         * @param container
225         *            the container to set
226         */
227        public void setContainer(JBIContainer container) {
228            this.container = container;
229        }
230    
231        /**
232         * @return the factory
233         */
234        public ClientFactory getFactory() {
235            return factory;
236        }
237    
238        /**
239         * @param factory
240         *            the factory to set
241         */
242        public void setFactory(ClientFactory factory) {
243            this.factory = factory;
244        }
245    
246        /**
247         * @return the name
248         */
249        public String getName() {
250            return name;
251        }
252    
253        /**
254         * @param name
255         *            the name to set
256         */
257        public void setName(String name) {
258            this.name = name;
259        }
260    
261        /**
262         * @return the propagateSecuritySubject
263         */
264        public boolean isPropagateSecuritySubject() {
265            return propagateSecuritySubject;
266        }
267    
268        /**
269         * @param propagateSecuritySubject
270         *            the propagateSecuritySubject to set
271         */
272        public void setPropagateSecuritySubject(boolean propagateSecuritySubject) {
273            this.propagateSecuritySubject = propagateSecuritySubject;
274        }
275    
276        public void afterPropertiesSet() throws Exception {
277            if (type == null) {
278                throw new IllegalArgumentException("type must be set");
279            }
280        }
281    
282        public void destroy() throws Exception {
283            if (client != null) {
284                client.close();
285                client = null;
286            }
287        }
288    
289        public void setUseJBIWrapper(boolean useJBIWrapper) {
290            this.useJBIWrapper = useJBIWrapper;
291        }
292    
293        public boolean isUseJBIWrapper() {
294            return useJBIWrapper;
295        }
296    
297        /**
298         * Specifies if the endpoint expects soap messages when useJBIWrapper is
299         * false, if useJBIWrapper is true then ignore useSOAPEnvelope
300         * 
301         * @org.apache.xbean.Property description="Specifies if the endpoint expects
302         *                            soap messages when useJBIWrapper is false, if
303         *                            useJBIWrapper is true then ignore
304         *                            useSOAPEnvelope. The default is
305         *                            <code>true</code>.
306         */
307        public void setUseSOAPEnvelope(boolean useSOAPEnvelope) {
308            this.useSOAPEnvelope = useSOAPEnvelope;
309        }
310    
311        public boolean isUseSOAPEnvelope() {
312            return useSOAPEnvelope;
313        }
314        
315        public void setMtomEnabled(boolean mtomEnabled) {
316            this.mtomEnabled = mtomEnabled;
317        }
318    
319        public boolean isMtomEnabled() {
320            return mtomEnabled;
321        }
322    
323    }