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    }