1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.chemistry.opencmis.client.bindings.spi.webservices;
20
21 import java.io.BufferedInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.lang.ref.SoftReference;
25 import java.lang.reflect.Constructor;
26 import java.lang.reflect.InvocationTargetException;
27 import java.math.BigInteger;
28 import java.net.MalformedURLException;
29 import java.net.URL;
30 import java.util.ArrayDeque;
31 import java.util.Collections;
32 import java.util.EnumMap;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.concurrent.locks.ReentrantLock;
38
39 import javax.xml.namespace.QName;
40 import javax.xml.parsers.ParserConfigurationException;
41 import javax.xml.ws.BindingProvider;
42 import javax.xml.ws.Service;
43 import javax.xml.ws.WebServiceFeature;
44 import javax.xml.ws.handler.HandlerResolver;
45 import javax.xml.ws.handler.MessageContext;
46 import javax.xml.ws.http.HTTPException;
47
48 import org.apache.chemistry.opencmis.client.bindings.impl.ClientVersion;
49 import org.apache.chemistry.opencmis.client.bindings.impl.CmisBindingsHelper;
50 import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
51 import org.apache.chemistry.opencmis.client.bindings.spi.http.HttpInvoker;
52 import org.apache.chemistry.opencmis.client.bindings.spi.http.Response;
53 import org.apache.chemistry.opencmis.commons.SessionParameter;
54 import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
55 import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
56 import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
57 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
58 import org.apache.chemistry.opencmis.commons.exceptions.CmisProxyAuthenticationException;
59 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
60 import org.apache.chemistry.opencmis.commons.exceptions.CmisTooManyRequestsException;
61 import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
62 import org.apache.chemistry.opencmis.commons.impl.IOUtils;
63 import org.apache.chemistry.opencmis.commons.impl.UrlBuilder;
64 import org.apache.chemistry.opencmis.commons.impl.XMLUtils;
65 import org.apache.chemistry.opencmis.commons.impl.jaxb.ACLService;
66 import org.apache.chemistry.opencmis.commons.impl.jaxb.ACLServicePort;
67 import org.apache.chemistry.opencmis.commons.impl.jaxb.DiscoveryService;
68 import org.apache.chemistry.opencmis.commons.impl.jaxb.DiscoveryServicePort;
69 import org.apache.chemistry.opencmis.commons.impl.jaxb.MultiFilingService;
70 import org.apache.chemistry.opencmis.commons.impl.jaxb.MultiFilingServicePort;
71 import org.apache.chemistry.opencmis.commons.impl.jaxb.NavigationService;
72 import org.apache.chemistry.opencmis.commons.impl.jaxb.NavigationServicePort;
73 import org.apache.chemistry.opencmis.commons.impl.jaxb.ObjectService;
74 import org.apache.chemistry.opencmis.commons.impl.jaxb.ObjectServicePort;
75 import org.apache.chemistry.opencmis.commons.impl.jaxb.PolicyService;
76 import org.apache.chemistry.opencmis.commons.impl.jaxb.PolicyServicePort;
77 import org.apache.chemistry.opencmis.commons.impl.jaxb.RelationshipService;
78 import org.apache.chemistry.opencmis.commons.impl.jaxb.RelationshipServicePort;
79 import org.apache.chemistry.opencmis.commons.impl.jaxb.RepositoryService;
80 import org.apache.chemistry.opencmis.commons.impl.jaxb.RepositoryServicePort;
81 import org.apache.chemistry.opencmis.commons.impl.jaxb.VersioningService;
82 import org.apache.chemistry.opencmis.commons.impl.jaxb.VersioningServicePort;
83 import org.apache.chemistry.opencmis.commons.spi.AuthenticationProvider;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
86 import org.w3c.dom.Document;
87 import org.w3c.dom.Element;
88 import org.w3c.dom.NodeList;
89 import org.xml.sax.SAXException;
90
91 public abstract class AbstractPortProvider {
92
93 private static final Logger LOG = LoggerFactory.getLogger(AbstractPortProvider.class);
94
95 private static final int PORT_CACHE_SIZE = 5;
96
97 protected static final int CHUNK_SIZE = (64 * 1024) - 1;
98
99 protected enum CmisWebSerivcesService {
100 REPOSITORY_SERVICE("RepositoryService", false, RepositoryService.class, RepositoryServicePort.class,
101 SessionParameter.WEBSERVICES_REPOSITORY_SERVICE,
102 SessionParameter.WEBSERVICES_REPOSITORY_SERVICE_ENDPOINT),
103
104 NAVIGATION_SERVICE("NavigationService", false, NavigationService.class, NavigationServicePort.class,
105 SessionParameter.WEBSERVICES_NAVIGATION_SERVICE,
106 SessionParameter.WEBSERVICES_NAVIGATION_SERVICE_ENDPOINT),
107
108 OBJECT_SERVICE("ObjectService", true, ObjectService.class, ObjectServicePort.class,
109 SessionParameter.WEBSERVICES_OBJECT_SERVICE, SessionParameter.WEBSERVICES_OBJECT_SERVICE_ENDPOINT),
110
111 VERSIONING_SERVICE("VersioningService", true, VersioningService.class, VersioningServicePort.class,
112 SessionParameter.WEBSERVICES_VERSIONING_SERVICE,
113 SessionParameter.WEBSERVICES_VERSIONING_SERVICE_ENDPOINT),
114
115 DISCOVERY_SERVICE("DiscoveryService", false, DiscoveryService.class, DiscoveryServicePort.class,
116 SessionParameter.WEBSERVICES_DISCOVERY_SERVICE, SessionParameter.WEBSERVICES_DISCOVERY_SERVICE_ENDPOINT),
117
118 MULTIFILING_SERVICE("MultiFilingService", false, MultiFilingService.class, MultiFilingServicePort.class,
119 SessionParameter.WEBSERVICES_MULTIFILING_SERVICE,
120 SessionParameter.WEBSERVICES_MULTIFILING_SERVICE_ENDPOINT),
121
122 RELATIONSHIP_SERVICE("RelationshipService", false, RelationshipService.class, RelationshipServicePort.class,
123 SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE,
124 SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE_ENDPOINT),
125
126 POLICY_SERVICE("PolicyService", false, PolicyService.class, PolicyServicePort.class,
127 SessionParameter.WEBSERVICES_POLICY_SERVICE, SessionParameter.WEBSERVICES_POLICY_SERVICE_ENDPOINT),
128
129 ACL_SERVICE("ACLService", false, ACLService.class, ACLServicePort.class,
130 SessionParameter.WEBSERVICES_ACL_SERVICE, SessionParameter.WEBSERVICES_ACL_SERVICE_ENDPOINT);
131
132 private final String name;
133 private final QName qname;
134 private final boolean handlesContent;
135 private final Class<? extends Service> serviceClass;
136 private final Class<?> portClass;
137 private final String wsdlKey;
138 private final String endpointKey;
139
140 CmisWebSerivcesService(String localname, boolean handlesContent, Class<? extends Service> serviceClass,
141 Class<?> port11Class, String wsdlKey, String endpointKey) {
142 this.name = localname;
143 this.qname = new QName("http://docs.oasis-open.org/ns/cmis/ws/200908/", localname);
144 this.handlesContent = handlesContent;
145 this.serviceClass = serviceClass;
146 this.portClass = port11Class;
147 this.wsdlKey = wsdlKey;
148 this.endpointKey = endpointKey;
149 }
150
151 public String getServiceName() {
152 return name;
153 }
154
155 public QName getQName() {
156 return qname;
157 }
158
159 public boolean handlesContent() {
160 return handlesContent;
161 }
162
163 public Class<? extends Service> getServiceClass() {
164 return serviceClass;
165 }
166
167 public Class<?> getPortClass() {
168 return portClass;
169 }
170
171 public String getWsdlKey() {
172 return wsdlKey;
173 }
174
175 public String getEndpointKey() {
176 return endpointKey;
177 }
178 }
179
180 class CmisServiceHolder {
181 private final CmisWebSerivcesService service;
182 private SoftReference<Service> serviceObject;
183 private final URL endpointUrl;
184
185 public CmisServiceHolder(final CmisWebSerivcesService service, final URL endpointUrl)
186 throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
187 this.service = service;
188 this.endpointUrl = endpointUrl;
189 this.serviceObject = new SoftReference<Service>(createServiceObject());
190 }
191
192 private Service createServiceObject() throws InstantiationException, IllegalAccessException,
193 InvocationTargetException, NoSuchMethodException {
194 final Constructor<? extends Service> serviceConstructor = service.getServiceClass().getConstructor(
195 new Class<?>[] { URL.class, QName.class });
196
197 URL wsdlUrl = service.getPortClass().getResource("/wsdl/cmis11/CMISWS-Service.wsdl");
198 if (LOG.isDebugEnabled()) {
199 LOG.debug("Session {}: WSDL URL: {}", getSession().getSessionId(), wsdlUrl.toExternalForm());
200 }
201
202 Service newService = serviceConstructor.newInstance(new Object[] { wsdlUrl, service.getQName() });
203
204 AuthenticationProvider authProvider = CmisBindingsHelper.getAuthenticationProvider(getSession());
205 if (authProvider != null) {
206 HandlerResolver handlerResolver = authProvider.getHandlerResolver();
207 if (handlerResolver != null) {
208 newService.setHandlerResolver(handlerResolver);
209 }
210 }
211
212 return newService;
213 }
214
215 public CmisWebSerivcesService getService() {
216 return service;
217 }
218
219 public Service getServiceObject() throws InstantiationException, IllegalAccessException,
220 InvocationTargetException, NoSuchMethodException {
221 Service result = serviceObject.get();
222 if (result == null) {
223 result = createServiceObject();
224 serviceObject = new SoftReference<Service>(result);
225 }
226
227 return result;
228 }
229
230 public URL getEndpointUrl() {
231 return endpointUrl;
232 }
233
234 public String getServiceName() {
235 return service.getServiceName();
236 }
237 }
238
239 private BindingSession session;
240 private boolean useCompression;
241 private boolean useClientCompression;
242 private String acceptLanguage;
243
244 private final ReentrantLock portObjectLock = new ReentrantLock();
245 private final EnumMap<CmisWebSerivcesService, ArrayDeque<SoftReference<BindingProvider>>> portObjectCache = new EnumMap<CmisWebSerivcesService, ArrayDeque<SoftReference<BindingProvider>>>(
246 CmisWebSerivcesService.class);
247
248 public BindingSession getSession() {
249 return session;
250 }
251
252 public void setSession(BindingSession session) {
253 this.session = session;
254
255 final Object compression = session.get(SessionParameter.COMPRESSION);
256 useCompression = (compression != null) && Boolean.parseBoolean(compression.toString());
257
258 final Object clientCompression = session.get(SessionParameter.CLIENT_COMPRESSION);
259 useClientCompression = (clientCompression != null) && Boolean.parseBoolean(clientCompression.toString());
260
261 if (session.get(CmisBindingsHelper.ACCEPT_LANGUAGE) instanceof String) {
262 acceptLanguage = session.get(CmisBindingsHelper.ACCEPT_LANGUAGE).toString();
263 }
264 }
265
266 public boolean useCompression() {
267 return useCompression;
268 }
269
270 public boolean useClientCompression() {
271 return useClientCompression;
272 }
273
274 public String getAcceptLanguage() {
275 return acceptLanguage;
276 }
277
278
279
280
281 public RepositoryServicePort getRepositoryServicePort(CmisVersion cmisVersion, String soapAction) {
282 BindingProvider portObject = getPortObject(CmisWebSerivcesService.REPOSITORY_SERVICE);
283 setSoapAction(portObject, soapAction, cmisVersion);
284
285 return (RepositoryServicePort) portObject;
286 }
287
288
289
290
291 public NavigationServicePort getNavigationServicePort(CmisVersion cmisVersion, String soapAction) {
292 BindingProvider portObject = getPortObject(CmisWebSerivcesService.NAVIGATION_SERVICE);
293 setSoapAction(portObject, soapAction, cmisVersion);
294
295 return (NavigationServicePort) portObject;
296 }
297
298
299
300
301 public ObjectServicePort getObjectServicePort(CmisVersion cmisVersion, String soapAction) {
302 BindingProvider portObject = getPortObject(CmisWebSerivcesService.OBJECT_SERVICE);
303 setSoapAction(portObject, soapAction, cmisVersion);
304
305 return (ObjectServicePort) portObject;
306 }
307
308
309
310
311 public VersioningServicePort getVersioningServicePort(CmisVersion cmisVersion, String soapAction) {
312 BindingProvider portObject = getPortObject(CmisWebSerivcesService.VERSIONING_SERVICE);
313 setSoapAction(portObject, soapAction, cmisVersion);
314
315 return (VersioningServicePort) portObject;
316 }
317
318
319
320
321 public DiscoveryServicePort getDiscoveryServicePort(CmisVersion cmisVersion, String soapAction) {
322 BindingProvider portObject = getPortObject(CmisWebSerivcesService.DISCOVERY_SERVICE);
323 setSoapAction(portObject, soapAction, cmisVersion);
324
325 return (DiscoveryServicePort) portObject;
326 }
327
328
329
330
331 public MultiFilingServicePort getMultiFilingServicePort(CmisVersion cmisVersion, String soapAction) {
332 BindingProvider portObject = getPortObject(CmisWebSerivcesService.MULTIFILING_SERVICE);
333 setSoapAction(portObject, soapAction, cmisVersion);
334
335 return (MultiFilingServicePort) portObject;
336 }
337
338
339
340
341 public RelationshipServicePort getRelationshipServicePort(CmisVersion cmisVersion, String soapAction) {
342 BindingProvider portObject = getPortObject(CmisWebSerivcesService.RELATIONSHIP_SERVICE);
343 setSoapAction(portObject, soapAction, cmisVersion);
344
345 return (RelationshipServicePort) portObject;
346 }
347
348
349
350
351 public PolicyServicePort getPolicyServicePort(CmisVersion cmisVersion, String soapAction) {
352 BindingProvider portObject = getPortObject(CmisWebSerivcesService.POLICY_SERVICE);
353 setSoapAction(portObject, soapAction, cmisVersion);
354
355 return (PolicyServicePort) portObject;
356 }
357
358
359
360
361 public ACLServicePort getACLServicePort(CmisVersion cmisVersion, String soapAction) {
362 BindingProvider portObject = getPortObject(CmisWebSerivcesService.ACL_SERVICE);
363 setSoapAction(portObject, soapAction, cmisVersion);
364
365 return (ACLServicePort) portObject;
366 }
367
368 public void endCall(Object portObject) {
369 AuthenticationProvider authProvider = CmisBindingsHelper.getAuthenticationProvider(session);
370 if (authProvider != null && portObject instanceof BindingProvider) {
371 BindingProvider bp = (BindingProvider) portObject;
372 String url = (String) bp.getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
373 if (bp.getResponseContext() != null) {
374 @SuppressWarnings("unchecked")
375 Map<String, List<String>> headers = (Map<String, List<String>>) bp.getResponseContext().get(
376 MessageContext.HTTP_RESPONSE_HEADERS);
377 Integer statusCode = (Integer) bp.getResponseContext().get(MessageContext.HTTP_RESPONSE_CODE);
378 authProvider.putResponseHeaders(url, statusCode == null ? -1 : statusCode, headers);
379 }
380
381 CmisWebSerivcesService service = null;
382
383 if (portObject instanceof RepositoryServicePort) {
384 service = CmisWebSerivcesService.REPOSITORY_SERVICE;
385 } else if (portObject instanceof NavigationServicePort) {
386 service = CmisWebSerivcesService.NAVIGATION_SERVICE;
387 } else if (portObject instanceof ObjectServicePort) {
388 service = CmisWebSerivcesService.OBJECT_SERVICE;
389 } else if (portObject instanceof VersioningServicePort) {
390 service = CmisWebSerivcesService.VERSIONING_SERVICE;
391 } else if (portObject instanceof DiscoveryServicePort) {
392 service = CmisWebSerivcesService.DISCOVERY_SERVICE;
393 } else if (portObject instanceof MultiFilingServicePort) {
394 service = CmisWebSerivcesService.MULTIFILING_SERVICE;
395 } else if (portObject instanceof RelationshipServicePort) {
396 service = CmisWebSerivcesService.RELATIONSHIP_SERVICE;
397 } else if (portObject instanceof PolicyServicePort) {
398 service = CmisWebSerivcesService.POLICY_SERVICE;
399 } else if (portObject instanceof ACLServicePort) {
400 service = CmisWebSerivcesService.ACL_SERVICE;
401 }
402
403 if (service == null) {
404 return;
405 }
406
407 portObjectLock.lock();
408 try {
409 ArrayDeque<SoftReference<BindingProvider>> queue = portObjectCache.get(service);
410 if (queue == null) {
411 throw new CmisRuntimeException("This is a bug!");
412 }
413
414 if (queue.size() < PORT_CACHE_SIZE) {
415 queue.push(new SoftReference<BindingProvider>(bp));
416 } else {
417 Iterator<SoftReference<BindingProvider>> iter = queue.iterator();
418 while (iter.hasNext()) {
419 SoftReference<BindingProvider> ref = iter.next();
420 if (ref.get() == null) {
421 iter.remove();
422 queue.push(new SoftReference<BindingProvider>(bp));
423 break;
424 }
425 }
426 }
427 } finally {
428 portObjectLock.unlock();
429 }
430 }
431 }
432
433
434
435 @SuppressWarnings("unchecked")
436 protected BindingProvider getPortObject(final CmisWebSerivcesService service) {
437 Map<CmisWebSerivcesService, CmisServiceHolder> serviceMap = (Map<CmisWebSerivcesService, CmisServiceHolder>) session
438 .get(SpiSessionParameter.SERVICES);
439
440
441 if (serviceMap == null) {
442 session.writeLock();
443 try {
444
445 serviceMap = (Map<CmisWebSerivcesService, CmisServiceHolder>) session.get(SpiSessionParameter.SERVICES);
446 if (serviceMap == null) {
447 serviceMap = new EnumMap<CmisWebSerivcesService, CmisServiceHolder>(CmisWebSerivcesService.class);
448 session.put(SpiSessionParameter.SERVICES, serviceMap, true);
449 }
450
451 if (serviceMap.containsKey(service)) {
452 return createPortObject(serviceMap.get(service));
453 }
454
455
456 CmisServiceHolder serviceholder = initServiceObject(service);
457 serviceMap.put(service, serviceholder);
458
459
460 return createPortObject(serviceholder);
461 } finally {
462 session.writeUnlock();
463 }
464 }
465
466
467 if (!serviceMap.containsKey(service)) {
468 session.writeLock();
469 try {
470
471 if (serviceMap.containsKey(service)) {
472 return createPortObject(serviceMap.get(service));
473 }
474
475
476 CmisServiceHolder serviceholder = initServiceObject(service);
477 serviceMap.put(service, serviceholder);
478
479 return createPortObject(serviceholder);
480 } finally {
481 session.writeUnlock();
482 }
483 }
484
485 return createPortObject(serviceMap.get(service));
486 }
487
488
489
490
491 protected CmisServiceHolder initServiceObject(final CmisWebSerivcesService service) {
492 if (LOG.isDebugEnabled()) {
493 LOG.debug("Session {}: Initializing Web Service {} ...", getSession().getSessionId(),
494 service.getServiceName());
495 }
496
497 try {
498
499 URL endpointUrl = null;
500
501 String wsdlUrlStr = (String) session.get(service.getWsdlKey());
502 if (wsdlUrlStr != null) {
503 endpointUrl = getEndpointUrlFromWsdl(wsdlUrlStr, service);
504 } else {
505 String endpointUrlStr = (String) session.get(service.getEndpointKey());
506 if (endpointUrlStr != null) {
507 endpointUrl = new URL(endpointUrlStr);
508 }
509 }
510
511 if (endpointUrl == null) {
512 throw new CmisRuntimeException("Neither a WSDL URL nor an endpoint URL is specified for the service "
513 + service.getServiceName() + "!");
514 }
515
516
517 return new CmisServiceHolder(service, endpointUrl);
518 } catch (CmisBaseException ce) {
519 throw ce;
520 } catch (HTTPException he) {
521 String message = "Cannot connect to Web Services [" + service.getServiceName() + "]: " + he.getMessage();
522 if (he.getStatusCode() == 401) {
523 throw new CmisUnauthorizedException(message, he);
524 } else if (he.getStatusCode() == 404) {
525 throw new CmisObjectNotFoundException(message, he);
526 } else if (he.getStatusCode() == 407) {
527 throw new CmisProxyAuthenticationException(message, he);
528 } else if (he.getStatusCode() == 429) {
529 throw new CmisTooManyRequestsException(message, he);
530 } else if (he.getStatusCode() == 301 || he.getStatusCode() == 302 || he.getStatusCode() == 303
531 || he.getStatusCode() == 307) {
532 throw new CmisConnectionException("Redirects are not supported (HTTP status code " + he.getStatusCode()
533 + "): " + message, he);
534 } else {
535 throw new CmisConnectionException(message, he);
536 }
537 } catch (InvocationTargetException ite) {
538 String message = "Cannot initalize Web Services service object [" + service.getServiceName() + "]: "
539 + ite.getCause().getMessage();
540 throw new CmisConnectionException(message, ite);
541 } catch (Exception e) {
542 String message = "Cannot initalize Web Services service object [" + service.getServiceName() + "]: "
543 + e.getMessage();
544 throw new CmisConnectionException(message, e);
545 }
546 }
547
548
549
550
551 private URL getEndpointUrlFromWsdl(final String wsdlUrl, final CmisWebSerivcesService service) {
552 InputStream wsdlStream;
553 URL url;
554
555
556 try {
557 url = new URL(wsdlUrl);
558 } catch (MalformedURLException e) {
559 throw new CmisConnectionException("Invalid WSDL URL: " + wsdlUrl, e);
560 }
561
562
563 if (url.getProtocol().equalsIgnoreCase("http") || url.getProtocol().equalsIgnoreCase("https")) {
564
565 HttpInvoker hi = CmisBindingsHelper.getHttpInvoker(session);
566 Response wsdlResponse = hi.invokeGET(new UrlBuilder(wsdlUrl), session);
567
568 if (wsdlResponse.getResponseCode() != 200) {
569 throw new CmisConnectionException("Cannot access WSDL: " + wsdlUrl, BigInteger.ZERO,
570 wsdlResponse.getErrorContent());
571 } else {
572 wsdlStream = wsdlResponse.getStream();
573 }
574 } else {
575
576 try {
577 wsdlStream = url.openStream();
578 } catch (IOException e) {
579 throw new CmisConnectionException("Cannot access WSDL: " + wsdlUrl, e);
580 }
581 }
582
583
584 try {
585 final Document doc = XMLUtils.parseDomDocument(new BufferedInputStream(wsdlStream, 64 * 1024));
586
587 NodeList serivceList = doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/", "service");
588 for (int i = 0; i < serivceList.getLength(); i++) {
589 Element serviceNode = (Element) serivceList.item(i);
590
591 String name = serviceNode.getAttribute("name");
592 if (name == null) {
593 continue;
594 }
595
596 if (!service.getQName().getLocalPart().equals(name)) {
597 continue;
598 }
599
600 NodeList portList = serviceNode.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/", "port");
601 if (portList.getLength() < 1) {
602 throw new CmisRuntimeException("This service has no ports: " + service.getServiceName());
603 }
604
605 Element port = (Element) portList.item(0);
606
607 NodeList addressList = port.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/soap/", "address");
608 if (addressList.getLength() < 1) {
609
610 addressList = port.getElementsByTagNameNS("http://schemas.xmlsoap.org/wsdl/soap12/", "address");
611 }
612 if (addressList.getLength() < 1) {
613 throw new CmisRuntimeException("This service has no endpoint address: " + service.getServiceName());
614 }
615
616 Element address = (Element) addressList.item(0);
617
618 String location = address.getAttribute("location");
619 if (location == null) {
620 throw new CmisRuntimeException("This service has no endpoint address: " + service.getServiceName());
621 }
622
623 try {
624 return new URL(location);
625 } catch (MalformedURLException e) {
626 throw new CmisRuntimeException("This service provides an invalid endpoint address: "
627 + service.getServiceName(), e);
628 }
629 }
630
631 throw new CmisRuntimeException("This service does not provide an endpoint address: "
632 + service.getServiceName());
633 } catch (ParserConfigurationException pe) {
634 throw new CmisRuntimeException("Cannot parse this WSDL: " + wsdlUrl, pe);
635 } catch (SAXException se) {
636 throw new CmisRuntimeException("Cannot parse this WSDL: " + wsdlUrl, se);
637 } catch (IOException ioe) {
638 throw new CmisRuntimeException("Cannot read this WSDL: " + wsdlUrl, ioe);
639 } finally {
640 IOUtils.closeQuietly(wsdlStream);
641 }
642 }
643
644
645
646
647 protected void setHTTPHeaders(BindingProvider portObject, Map<String, List<String>> httpHeaders) {
648 if (httpHeaders == null) {
649 httpHeaders = new HashMap<String, List<String>>();
650 }
651
652
653 httpHeaders.put("X-CMIS-Client", Collections.singletonList((String) session.get(SessionParameter.USER_AGENT,
654 ClientVersion.OPENCMIS_USER_AGENT)));
655
656
657 if (useCompression) {
658 httpHeaders.put("Accept-Encoding", Collections.singletonList("gzip"));
659 }
660
661
662 if (useClientCompression) {
663 httpHeaders.put("Content-Encoding", Collections.singletonList("gzip"));
664 }
665
666
667 if (acceptLanguage != null) {
668 httpHeaders.put("Accept-Language", Collections.singletonList(acceptLanguage));
669 }
670
671 portObject.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
672 }
673
674
675
676
677 protected void setEndpointUrl(BindingProvider portObject, URL endpointUrl) {
678 if (endpointUrl == null) {
679 return;
680 }
681
682 portObject.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointUrl.toString());
683 }
684
685
686
687
688 protected void setSoapAction(BindingProvider portObject, String soapAction, CmisVersion cmisVersion) {
689 portObject.getRequestContext().put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
690
691 if (cmisVersion == CmisVersion.CMIS_1_0) {
692 portObject.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, "");
693 } else {
694 portObject.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY, soapAction);
695 }
696 }
697
698
699
700
701 protected BindingProvider createPortObjectFromServiceHolder(final CmisServiceHolder serviceHolder,
702 WebServiceFeature... features) throws Exception {
703 portObjectLock.lock();
704 try {
705 ArrayDeque<SoftReference<BindingProvider>> queue = portObjectCache.get(serviceHolder.getService());
706 if (queue == null) {
707 queue = new ArrayDeque<SoftReference<BindingProvider>>();
708 portObjectCache.put(serviceHolder.getService(), queue);
709 }
710
711 while (!queue.isEmpty()) {
712 BindingProvider bp = queue.pop().get();
713 if (bp != null) {
714 return bp;
715 }
716 }
717 } finally {
718 portObjectLock.unlock();
719 }
720
721 return (BindingProvider) serviceHolder.getServiceObject().getPort(serviceHolder.getService().getPortClass(),
722 features);
723 }
724
725
726
727
728 protected abstract BindingProvider createPortObject(CmisServiceHolder serviceHolder);
729 }