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.camel.component.cxf;
018
019 import java.lang.reflect.Proxy;
020
021 import javax.xml.namespace.QName;
022
023 import org.apache.camel.CamelContext;
024 import org.apache.camel.component.cxf.spring.CxfEndpointBean;
025 import org.apache.camel.component.cxf.util.CxfEndpointUtils;
026 import org.apache.camel.spring.SpringCamelContext;
027 import org.apache.camel.util.ObjectHelper;
028 import org.apache.cxf.Bus;
029 import org.apache.cxf.common.classloader.ClassLoaderUtils;
030 import org.apache.cxf.configuration.spring.ConfigurerImpl;
031 import org.apache.cxf.endpoint.Client;
032 import org.apache.cxf.frontend.ClientFactoryBean;
033 import org.apache.cxf.frontend.ClientProxy;
034 import org.apache.cxf.frontend.ClientProxyFactoryBean;
035 import org.apache.cxf.frontend.ServerFactoryBean;
036 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
037 import org.springframework.context.ConfigurableApplicationContext;
038
039 /**
040 * Defines the <a href="http://camel.apache.org/cxf.html">CXF Endpoint</a>
041 *
042 * @version $Revision: 16003 $
043 */
044 public class CxfSpringEndpoint extends CxfEndpoint {
045
046 private CxfEndpointBean bean;
047 private String beanId;
048 private ConfigurerImpl configurer;
049 private String serviceNamespace;
050 private String serviceLocalName;
051 private String endpointLocalName;
052 private String endpointNamespace;
053
054 public CxfSpringEndpoint(CamelContext context, CxfEndpointBean bean) throws Exception {
055 super(bean.getAddress(), context);
056 init(bean);
057 }
058
059 public CxfSpringEndpoint(CxfComponent component, CxfEndpointBean bean) throws Exception {
060 super(bean.getAddress(), component);
061 init(bean);
062 }
063
064
065 private void init(CxfEndpointBean bean) throws Exception {
066 this.bean = bean;
067 // create configurer
068 configurer = new ConfigurerImpl(((SpringCamelContext)getCamelContext())
069 .getApplicationContext());
070 }
071
072
073 /**
074 *
075 * A help to get the service class. The serviceClass classname in URI
076 * query takes precedence over the serviceClass in CxfEndpointBean.
077 */
078 private Class<?> getSEIClass() throws ClassNotFoundException {
079
080 // get service class
081 Class<?> answer = null;
082 if (getServiceClass() != null) {
083 // classname is specified in URI which overrides the bean properties
084 answer = ClassLoaderUtils.loadClass(getServiceClass(), getClass());
085 } else {
086 answer = bean.getServiceClass();
087 }
088 return answer;
089 }
090
091 protected Bus doGetBus() {
092 return bean.getBus();
093 }
094
095 public CxfEndpointBean getBean() {
096 return bean;
097 }
098
099 // Package private methods
100 // -------------------------------------------------------------------------
101
102 /**
103 * Create a CXF Client
104 */
105 @Override
106 Client createClient() throws Exception {
107
108 // get service class
109 Class<?> cls = getSEIClass();
110
111 if (getDataFormat().equals(DataFormat.POJO)) {
112 ObjectHelper.notNull(cls, CxfConstants.SERVICE_CLASS);
113 }
114
115 if (cls != null) {
116 // create client factory bean
117 ClientProxyFactoryBean factoryBean = createClientFactoryBean(cls);
118
119 // configure client factory bean by CXF configurer
120 configure(factoryBean);
121
122 // setup client factory bean
123 setupClientFactoryBean(factoryBean, cls);
124
125 // fill in values that have not been filled.
126 QName serviceQName = null;
127 try {
128 serviceQName = factoryBean.getServiceName();
129 } catch (IllegalStateException e) {
130 // It throws IllegalStateException if serviceName has not been set.
131 }
132
133 if (serviceQName == null && getServiceLocalName() != null) {
134 factoryBean.setServiceName(new QName(getServiceNamespace(), getServiceLocalName()));
135 }
136 if (factoryBean.getEndpointName() == null && getEndpointLocalName() != null) {
137 factoryBean.setEndpointName(new QName(getEndpointNamespace(), getEndpointLocalName()));
138 }
139
140 return ((ClientProxy)Proxy.getInvocationHandler(factoryBean.create())).getClient();
141 } else {
142 ClientFactoryBean factoryBean = createClientFactoryBean();
143
144 // configure client factory bean by CXF configurer
145 configure(factoryBean);
146
147 // setup client factory bean
148 setupClientFactoryBean(factoryBean);
149
150 // fill in values that have not been filled.
151 QName serviceQName = null;
152 try {
153 serviceQName = factoryBean.getServiceName();
154 } catch (IllegalStateException e) {
155 // It throws IllegalStateException if serviceName has not been set.
156 }
157
158 if (serviceQName == null && getServiceLocalName() != null) {
159 factoryBean.setServiceName(new QName(getServiceNamespace(), getServiceLocalName()));
160 }
161 if (factoryBean.getEndpointName() == null && getEndpointLocalName() != null) {
162 factoryBean.setEndpointName(new QName(getEndpointNamespace(), getEndpointLocalName()));
163 }
164
165 ObjectHelper.notNull(factoryBean.getEndpointName(), "Please provide endpoint/port name");
166 ObjectHelper.notNull(factoryBean.getServiceName(), "Please provide service name");
167 return (Client)factoryBean.create();
168 }
169 }
170
171
172 /**
173 * Create a service factory bean
174 */
175 @Override
176 ServerFactoryBean createServerFactoryBean() throws Exception {
177
178 // get service class
179 Class<?> cls = getSEIClass();
180
181 // create server factory bean
182 // Shouldn't use CxfEndpointUtils.getServerFactoryBean(cls) as it is for
183 // CxfSoapComponent
184 ServerFactoryBean answer = null;
185
186 if (cls == null) {
187 if (!getDataFormat().equals(DataFormat.POJO)) {
188 answer = new ServerFactoryBean(new WSDLServiceFactoryBean());
189 } else {
190 ObjectHelper.notNull(cls, CxfConstants.SERVICE_CLASS);
191 }
192 } else if (CxfEndpointUtils.hasWebServiceAnnotation(cls)) {
193 answer = new JaxWsServerFactoryBean();
194 } else {
195 answer = new ServerFactoryBean();
196 }
197
198 // configure server factory bean by CXF configurer
199 configure(answer);
200
201 // setup server factory bean
202 setupServerFactoryBean(answer, cls);
203
204 // fill in values that have not been filled.
205 if (answer.getServiceName() == null && getServiceLocalName() != null) {
206 answer.setServiceName(new QName(getServiceNamespace(), getServiceLocalName()));
207 }
208 if (answer.getEndpointName() == null && getEndpointLocalName() != null) {
209 answer.setEndpointName(new QName(getEndpointNamespace(), getEndpointLocalName()));
210 }
211
212 if (cls == null) {
213 ObjectHelper.notNull(answer.getEndpointName(), "Please provide endpoint/port name");
214 ObjectHelper.notNull(answer.getServiceName(), "Please provide service name");
215 }
216 return answer;
217 }
218
219 void configure(Object beanInstance) {
220 // check the ApplicationContext states first , and call the refresh if necessary
221 if (((SpringCamelContext)getCamelContext()).getApplicationContext() instanceof ConfigurableApplicationContext) {
222 ConfigurableApplicationContext context = (ConfigurableApplicationContext)((SpringCamelContext)getCamelContext()).getApplicationContext();
223 if (!context.isActive()) {
224 context.refresh();
225 }
226 }
227 configurer.configureBean(beanId, beanInstance);
228 }
229
230 // Properties
231 // -------------------------------------------------------------------------
232 public String getBeanId() {
233 return beanId;
234 }
235
236 // this property will be set by spring
237 public void setBeanId(String id) {
238 this.beanId = id;
239 }
240
241 public void setServiceNamespace(String serviceNamespace) {
242 this.serviceNamespace = serviceNamespace;
243 }
244
245
246 public String getServiceNamespace() {
247 return serviceNamespace;
248 }
249
250
251 public void setServiceLocalName(String serviceLocalName) {
252 this.serviceLocalName = serviceLocalName;
253 }
254
255
256 public String getServiceLocalName() {
257 return serviceLocalName;
258 }
259
260 public String getEndpointLocalName() {
261 return endpointLocalName;
262 }
263
264 public void setEndpointLocalName(String endpointLocalName) {
265 this.endpointLocalName = endpointLocalName;
266 }
267
268
269 public void setEndpointNamespace(String endpointNamespace) {
270 this.endpointNamespace = endpointNamespace;
271 }
272
273
274 public String getEndpointNamespace() {
275 return endpointNamespace;
276 }
277
278
279 }