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.lang.reflect.Field;
020 import java.lang.reflect.Method;
021 import java.util.List;
022 import java.util.Map;
023 import java.util.concurrent.CopyOnWriteArrayList;
024
025 import javax.annotation.PostConstruct;
026 import javax.annotation.PreDestroy;
027 import javax.jbi.component.ComponentContext;
028 import javax.jbi.management.DeploymentException;
029 import javax.jbi.messaging.DeliveryChannel;
030 import javax.jbi.messaging.ExchangeStatus;
031 import javax.jbi.messaging.MessageExchange;
032 import javax.wsdl.WSDLException;
033 import javax.xml.namespace.QName;
034 import javax.xml.ws.WebServiceRef;
035
036 import org.apache.cxf.Bus;
037 import org.apache.cxf.interceptor.Interceptor;
038 import org.apache.cxf.interceptor.InterceptorProvider;
039 import org.apache.cxf.jaxws.EndpointImpl;
040 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
041 import org.apache.cxf.jaxws.ServiceImpl;
042 import org.apache.cxf.jaxws.support.JaxWsImplementorInfo;
043 import org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean;
044 import org.apache.cxf.transport.ConduitInitiatorManager;
045 import org.apache.cxf.transport.jbi.JBIDestination;
046 import org.apache.cxf.transport.jbi.JBIDispatcherUtil;
047 import org.apache.cxf.transport.jbi.JBITransportFactory;
048 import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
049 import org.apache.servicemix.common.endpoints.ProviderEndpoint;
050 import org.apache.servicemix.cxfse.support.ReflectionUtils;
051 import org.apache.servicemix.id.IdGenerator;
052 import org.springframework.util.ReflectionUtils.FieldCallback;
053
054 /**
055 *
056 * @author gnodet
057 * @org.apache.xbean.XBean element="endpoint"
058 */
059 public class CxfSeEndpoint extends ProviderEndpoint implements
060 InterceptorProvider {
061
062 private static final IdGenerator ID_GENERATOR = new IdGenerator();
063
064 private Object pojo;
065
066 private EndpointImpl endpoint;
067
068 private String address;
069
070 private List<Interceptor> in = new CopyOnWriteArrayList<Interceptor>();
071
072 private List<Interceptor> out = new CopyOnWriteArrayList<Interceptor>();
073
074 private List<Interceptor> outFault = new CopyOnWriteArrayList<Interceptor>();
075
076 private List<Interceptor> inFault = new CopyOnWriteArrayList<Interceptor>();
077
078 private Map properties;
079
080 private boolean useJBIWrapper = true;
081
082 /**
083 * @return the pojo
084 */
085 public Object getPojo() {
086 return pojo;
087 }
088
089 /**
090 * @param pojo
091 * the pojo to set
092 */
093 public void setPojo(Object pojo) {
094 this.pojo = pojo;
095 }
096
097 public List<Interceptor> getOutFaultInterceptors() {
098 return outFault;
099 }
100
101 public List<Interceptor> getInFaultInterceptors() {
102 return inFault;
103 }
104
105 public List<Interceptor> getInInterceptors() {
106 return in;
107 }
108
109 public List<Interceptor> getOutInterceptors() {
110 return out;
111 }
112
113 public void setInInterceptors(List<Interceptor> interceptors) {
114 in = interceptors;
115 }
116
117 public void setInFaultInterceptors(List<Interceptor> interceptors) {
118 inFault = interceptors;
119 }
120
121 public void setOutInterceptors(List<Interceptor> interceptors) {
122 out = interceptors;
123 }
124
125 public void setOutFaultInterceptors(List<Interceptor> interceptors) {
126 outFault = interceptors;
127 }
128
129 public Map getProperties() {
130 return properties;
131 }
132
133 public void setProperties(Map properties) {
134 this.properties = properties;
135 }
136
137 /*
138 * (non-Javadoc)
139 *
140 * @see org.apache.servicemix.common.Endpoint#validate()
141 */
142 @Override
143 public void validate() throws DeploymentException {
144 if (getPojo() == null) {
145 throw new DeploymentException("pojo must be set");
146 }
147 JaxWsServiceFactoryBean serviceFactory = new JaxWsServiceFactoryBean();
148 serviceFactory.setPopulateFromClass(true);
149 endpoint = new EndpointImpl(getBus(), getPojo(),
150 new JaxWsServerFactoryBean(serviceFactory));
151 if (isUseJBIWrapper()) {
152 endpoint
153 .setBindingUri(org.apache.cxf.binding.jbi.JBIConstants.NS_JBI_BINDING);
154 }
155 endpoint.setInInterceptors(getInInterceptors());
156 endpoint.setInFaultInterceptors(getInFaultInterceptors());
157 endpoint.setOutInterceptors(getOutInterceptors());
158 endpoint.setOutFaultInterceptors(getOutFaultInterceptors());
159 JaxWsImplementorInfo implInfo = new JaxWsImplementorInfo(getPojo()
160 .getClass());
161 setService(implInfo.getServiceName());
162 setInterfaceName(implInfo.getInterfaceName());
163 setEndpoint(implInfo.getEndpointName().getLocalPart());
164 super.validate();
165 }
166
167 /*
168 * (non-Javadoc)
169 *
170 * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#process(javax.jbi.messaging.MessageExchange)
171 */
172 @Override
173 public void process(MessageExchange exchange) throws Exception {
174 JBITransportFactory jbiTransportFactory = (JBITransportFactory) getBus()
175 .getExtension(ConduitInitiatorManager.class)
176 .getConduitInitiator(CxfSeComponent.JBI_TRANSPORT_ID);
177 JBIDestination jbiDestination = jbiTransportFactory
178 .getDestination(exchange.getService().toString()
179 + exchange.getInterfaceName().toString());
180 DeliveryChannel dc = getContext().getDeliveryChannel();
181
182 jbiDestination.setDeliveryChannel(dc);
183 if (exchange.getStatus() == ExchangeStatus.ACTIVE) {
184 jbiDestination.getJBIDispatcherUtil().dispatch(exchange);
185 }
186 }
187
188 /*
189 * (non-Javadoc)
190 *
191 * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#start()
192 */
193 @Override
194 public void start() throws Exception {
195 super.start();
196 address = "jbi://" + ID_GENERATOR.generateSanitizedId();
197 endpoint.publish(address);
198 setService(endpoint.getServer().getEndpoint().getService().getName());
199 setEndpoint(endpoint.getServer().getEndpoint().getEndpointInfo()
200 .getName().getLocalPart());
201 try {
202 definition = new ServiceWSDLBuilder(getBus(), endpoint.getServer()
203 .getEndpoint().getService().getServiceInfos().iterator()
204 .next()).build();
205 } catch (WSDLException e) {
206 throw new DeploymentException(e);
207 }
208 ReflectionUtils.doWithFields(getPojo().getClass(), new FieldCallback() {
209 public void doWith(Field field) throws IllegalArgumentException,
210 IllegalAccessException {
211 if (field.getAnnotation(WebServiceRef.class) != null) {
212 ServiceImpl s = new ServiceImpl(getBus(), null, null, field
213 .getType());
214 s.addPort(new QName("port"),
215 JBITransportFactory.TRANSPORT_ID, "jbi://"
216 + ID_GENERATOR.generateSanitizedId());
217 Object o = s.getPort(new QName("port"), field.getType());
218 field.setAccessible(true);
219 field.set(getPojo(), o);
220 }
221 }
222 });
223 ReflectionUtils.callLifecycleMethod(getPojo(), PostConstruct.class);
224 injectPojo();
225 }
226
227 @PostConstruct
228 protected void injectPojo() {
229 try {
230 Method mth = pojo.getClass().getMethod("setContext",
231 new Class[] {ComponentContext.class});
232 if (mth != null) {
233 mth.invoke(pojo, new Object[] {getContext()});
234 }
235 } catch (Exception e) {
236 logger
237 .debug("Unable to inject ComponentContext: "
238 + e.getMessage());
239 }
240 }
241
242 /*
243 * (non-Javadoc)
244 *
245 * @see org.apache.servicemix.common.endpoints.ProviderEndpoint#stop()
246 */
247 @Override
248 public void stop() throws Exception {
249 ReflectionUtils.callLifecycleMethod(getPojo(), PreDestroy.class);
250 JBIDispatcherUtil.clean();
251 getBus().shutdown(true);
252 super.stop();
253 }
254
255 protected Bus getBus() {
256 return ((CxfSeComponent) getServiceUnit().getComponent()).getBus();
257 }
258
259 public void setUseJBIWrapper(boolean useJBIWrapper) {
260 this.useJBIWrapper = useJBIWrapper;
261 }
262
263 public boolean isUseJBIWrapper() {
264 return useJBIWrapper;
265 }
266
267 }