This project has retired. For details please refer to its Attic page.
AbstractPortProvider xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.client.bindings.spi.webservices;
20  
21  import java.net.URL;
22  import java.util.Collections;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  
27  import javax.xml.namespace.QName;
28  import javax.xml.ws.BindingProvider;
29  import javax.xml.ws.Service;
30  import javax.xml.ws.handler.MessageContext;
31  import javax.xml.ws.http.HTTPException;
32  
33  import org.apache.chemistry.opencmis.client.bindings.impl.ClientVersion;
34  import org.apache.chemistry.opencmis.client.bindings.impl.CmisBindingsHelper;
35  import org.apache.chemistry.opencmis.client.bindings.spi.BindingSession;
36  import org.apache.chemistry.opencmis.commons.SessionParameter;
37  import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
38  import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
39  import org.apache.chemistry.opencmis.commons.exceptions.CmisProxyAuthenticationException;
40  import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
41  import org.apache.chemistry.opencmis.commons.exceptions.CmisUnauthorizedException;
42  import org.apache.chemistry.opencmis.commons.impl.jaxb.ACLService;
43  import org.apache.chemistry.opencmis.commons.impl.jaxb.ACLServicePort;
44  import org.apache.chemistry.opencmis.commons.impl.jaxb.DiscoveryService;
45  import org.apache.chemistry.opencmis.commons.impl.jaxb.DiscoveryServicePort;
46  import org.apache.chemistry.opencmis.commons.impl.jaxb.MultiFilingService;
47  import org.apache.chemistry.opencmis.commons.impl.jaxb.MultiFilingServicePort;
48  import org.apache.chemistry.opencmis.commons.impl.jaxb.NavigationService;
49  import org.apache.chemistry.opencmis.commons.impl.jaxb.NavigationServicePort;
50  import org.apache.chemistry.opencmis.commons.impl.jaxb.ObjectService;
51  import org.apache.chemistry.opencmis.commons.impl.jaxb.ObjectServicePort;
52  import org.apache.chemistry.opencmis.commons.impl.jaxb.PolicyService;
53  import org.apache.chemistry.opencmis.commons.impl.jaxb.PolicyServicePort;
54  import org.apache.chemistry.opencmis.commons.impl.jaxb.RelationshipService;
55  import org.apache.chemistry.opencmis.commons.impl.jaxb.RelationshipServicePort;
56  import org.apache.chemistry.opencmis.commons.impl.jaxb.RepositoryService;
57  import org.apache.chemistry.opencmis.commons.impl.jaxb.RepositoryServicePort;
58  import org.apache.chemistry.opencmis.commons.impl.jaxb.VersioningService;
59  import org.apache.chemistry.opencmis.commons.impl.jaxb.VersioningServicePort;
60  import org.apache.chemistry.opencmis.commons.spi.AuthenticationProvider;
61  import org.apache.commons.logging.Log;
62  import org.apache.commons.logging.LogFactory;
63  
64  public abstract class AbstractPortProvider {
65  
66      private static final Log log = LogFactory.getLog(AbstractPortProvider.class);
67  
68      public static final String CMIS_NAMESPACE = "http://docs.oasis-open.org/ns/cmis/ws/200908/";
69  
70      public static final String REPOSITORY_SERVICE = "RepositoryService";
71      public static final String OBJECT_SERVICE = "ObjectService";
72      public static final String DISCOVERY_SERVICE = "DiscoveryService";
73      public static final String NAVIGATION_SERVICE = "NavigationService";
74      public static final String MULTIFILING_SERVICE = "MultiFilingService";
75      public static final String VERSIONING_SERVICE = "VersioningService";
76      public static final String RELATIONSHIP_SERVICE = "RelationshipService";
77      public static final String POLICY_SERVICE = "PolicyService";
78      public static final String ACL_SERVICE = "ACLService";
79  
80      protected static final int CHUNK_SIZE = (64 * 1024) - 1;
81  
82      private BindingSession session;
83      protected boolean useCompression;
84      protected boolean useClientCompression;
85      protected String acceptLanguage;
86  
87      public BindingSession getSession() {
88          return session;
89      }
90  
91      public void setSession(BindingSession session) {
92          this.session = session;
93  
94          Object compression = session.get(SessionParameter.COMPRESSION);
95          useCompression = (compression != null) && Boolean.parseBoolean(compression.toString());
96  
97          Object clientCompression = session.get(SessionParameter.CLIENT_COMPRESSION);
98          useClientCompression = (clientCompression != null) && Boolean.parseBoolean(clientCompression.toString());
99  
100         if (session.get(CmisBindingsHelper.ACCEPT_LANGUAGE) instanceof String) {
101             acceptLanguage = session.get(CmisBindingsHelper.ACCEPT_LANGUAGE).toString();
102         }
103     }
104 
105     /**
106      * Return the Repository Service port object.
107      */
108     public RepositoryServicePort getRepositoryServicePort() {
109         return (RepositoryServicePort) getPortObject(SessionParameter.WEBSERVICES_REPOSITORY_SERVICE);
110     }
111 
112     /**
113      * Return the Navigation Service port object.
114      */
115     public NavigationServicePort getNavigationServicePort() {
116         return (NavigationServicePort) getPortObject(SessionParameter.WEBSERVICES_NAVIGATION_SERVICE);
117     }
118 
119     /**
120      * Return the Object Service port object.
121      */
122     public ObjectServicePort getObjectServicePort() {
123         return (ObjectServicePort) getPortObject(SessionParameter.WEBSERVICES_OBJECT_SERVICE);
124     }
125 
126     /**
127      * Return the Versioning Service port object.
128      */
129     public VersioningServicePort getVersioningServicePort() {
130         return (VersioningServicePort) getPortObject(SessionParameter.WEBSERVICES_VERSIONING_SERVICE);
131     }
132 
133     /**
134      * Return the Discovery Service port object.
135      */
136     public DiscoveryServicePort getDiscoveryServicePort() {
137         return (DiscoveryServicePort) getPortObject(SessionParameter.WEBSERVICES_DISCOVERY_SERVICE);
138     }
139 
140     /**
141      * Return the MultiFiling Service port object.
142      */
143     public MultiFilingServicePort getMultiFilingServicePort() {
144         return (MultiFilingServicePort) getPortObject(SessionParameter.WEBSERVICES_MULTIFILING_SERVICE);
145     }
146 
147     /**
148      * Return the Relationship Service port object.
149      */
150     public RelationshipServicePort getRelationshipServicePort() {
151         return (RelationshipServicePort) getPortObject(SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE);
152     }
153 
154     /**
155      * Return the Policy Service port object.
156      */
157     public PolicyServicePort getPolicyServicePort() {
158         return (PolicyServicePort) getPortObject(SessionParameter.WEBSERVICES_POLICY_SERVICE);
159     }
160 
161     /**
162      * Return the ACL Service port object.
163      */
164     public ACLServicePort getACLServicePort() {
165         return (ACLServicePort) getPortObject(SessionParameter.WEBSERVICES_ACL_SERVICE);
166     }
167 
168     public void endCall(Object portObject) {
169         AuthenticationProvider authProvider = CmisBindingsHelper.getAuthenticationProvider(session);
170         if (authProvider != null) {
171             BindingProvider bp = (BindingProvider) portObject;
172             String url = (String) bp.getRequestContext().get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
173             @SuppressWarnings("unchecked")
174             Map<String, List<String>> headers = (Map<String, List<String>>) bp.getResponseContext().get(
175                     MessageContext.HTTP_RESPONSE_HEADERS);
176             Integer statusCode = (Integer) bp.getResponseContext().get(MessageContext.HTTP_RESPONSE_CODE);
177             authProvider.putResponseHeaders(url, statusCode == null ? -1 : statusCode, headers);
178         }
179     }
180 
181     // ---- internal ----
182 
183     /**
184      * Gets a port object from the session or (re-)initializes the port objects.
185      */
186     @SuppressWarnings("unchecked")
187     protected Object getPortObject(String serviceKey) {
188         Map<String, Service> serviceMap = (Map<String, Service>) session.get(SpiSessionParameter.SERVICES);
189 
190         // does the service map exist?
191         if (serviceMap == null) {
192             session.writeLock();
193             try {
194                 // try again
195                 serviceMap = (Map<String, Service>) session.get(SpiSessionParameter.SERVICES);
196                 if (serviceMap == null) {
197                     serviceMap = Collections.synchronizedMap(new HashMap<String, Service>());
198                     session.put(SpiSessionParameter.SERVICES, serviceMap, true);
199                 }
200 
201                 if (serviceMap.containsKey(serviceKey)) {
202                     return createPortObject(serviceMap.get(serviceKey));
203                 }
204 
205                 // create service object
206                 Service serviceObject = initServiceObject(serviceKey);
207                 serviceMap.put(serviceKey, serviceObject);
208 
209                 // create port object
210                 return createPortObject(serviceObject);
211             } finally {
212                 session.writeUnlock();
213             }
214         }
215 
216         // is the service in the service map?
217         if (!serviceMap.containsKey(serviceKey)) {
218             session.writeLock();
219             try {
220                 // try again
221                 if (serviceMap.containsKey(serviceKey)) {
222                     return createPortObject(serviceMap.get(serviceKey));
223                 }
224 
225                 // create object
226                 Service serviceObject = initServiceObject(serviceKey);
227                 serviceMap.put(serviceKey, serviceObject);
228 
229                 return createPortObject(serviceObject);
230             } finally {
231                 session.writeUnlock();
232             }
233         }
234 
235         return createPortObject(serviceMap.get(serviceKey));
236     }
237 
238     /**
239      * Creates a service object.
240      */
241     protected Service initServiceObject(String serviceKey) {
242 
243         if (log.isDebugEnabled()) {
244             log.debug("Initializing Web Service " + serviceKey + "...");
245         }
246 
247         Service serviceObject;
248         try {
249             // get WSDL URL
250             URL wsdlUrl = new URL((String) session.get(serviceKey));
251 
252             // build the requested service object
253             if (SessionParameter.WEBSERVICES_REPOSITORY_SERVICE.equals(serviceKey)) {
254                 serviceObject = new RepositoryService(wsdlUrl, new QName(CMIS_NAMESPACE, REPOSITORY_SERVICE));
255             } else if (SessionParameter.WEBSERVICES_NAVIGATION_SERVICE.equals(serviceKey)) {
256                 serviceObject = new NavigationService(wsdlUrl, new QName(CMIS_NAMESPACE, NAVIGATION_SERVICE));
257             } else if (SessionParameter.WEBSERVICES_OBJECT_SERVICE.equals(serviceKey)) {
258                 serviceObject = new ObjectService(wsdlUrl, new QName(CMIS_NAMESPACE, OBJECT_SERVICE));
259             } else if (SessionParameter.WEBSERVICES_VERSIONING_SERVICE.equals(serviceKey)) {
260                 serviceObject = new VersioningService(wsdlUrl, new QName(CMIS_NAMESPACE, VERSIONING_SERVICE));
261             } else if (SessionParameter.WEBSERVICES_DISCOVERY_SERVICE.equals(serviceKey)) {
262                 serviceObject = new DiscoveryService(wsdlUrl, new QName(CMIS_NAMESPACE, DISCOVERY_SERVICE));
263             } else if (SessionParameter.WEBSERVICES_MULTIFILING_SERVICE.equals(serviceKey)) {
264                 serviceObject = new MultiFilingService(wsdlUrl, new QName(CMIS_NAMESPACE, MULTIFILING_SERVICE));
265             } else if (SessionParameter.WEBSERVICES_RELATIONSHIP_SERVICE.equals(serviceKey)) {
266                 serviceObject = new RelationshipService(wsdlUrl, new QName(CMIS_NAMESPACE, RELATIONSHIP_SERVICE));
267             } else if (SessionParameter.WEBSERVICES_POLICY_SERVICE.equals(serviceKey)) {
268                 serviceObject = new PolicyService(wsdlUrl, new QName(CMIS_NAMESPACE, POLICY_SERVICE));
269             } else if (SessionParameter.WEBSERVICES_ACL_SERVICE.equals(serviceKey)) {
270                 serviceObject = new ACLService(wsdlUrl, new QName(CMIS_NAMESPACE, ACL_SERVICE));
271             } else {
272                 throw new CmisRuntimeException("Cannot find Web Services service object [" + serviceKey + "]!");
273             }
274         } catch (CmisBaseException ce) {
275             throw ce;
276         } catch (Exception e) {
277             String message = "Cannot initalize Web Services service object [" + serviceKey + "]: " + e.getMessage();
278 
279             if (e instanceof HTTPException) {
280                 HTTPException he = (HTTPException) e;
281                 if (he.getStatusCode() == 401) {
282                     throw new CmisUnauthorizedException(message, e);
283                 } else if (he.getStatusCode() == 407) {
284                     throw new CmisProxyAuthenticationException(message, e);
285                 }
286             }
287 
288             throw new CmisConnectionException(message, e);
289         }
290 
291         return serviceObject;
292     }
293 
294     protected void setHTTPHeaders(Object portObject, Map<String, List<String>> httpHeaders) {
295         if (httpHeaders == null) {
296             httpHeaders = new HashMap<String, List<String>>();
297         }
298 
299         // CMIS client header
300         httpHeaders.put("X-CMIS-Client", Collections.singletonList(ClientVersion.OPENCMIS_CLIENT));
301 
302         // compression
303         if (useCompression) {
304             httpHeaders.put("Accept-Encoding", Collections.singletonList("gzip"));
305         }
306 
307         // client compression
308         if (useClientCompression) {
309             httpHeaders.put("Content-Encoding", Collections.singletonList("gzip"));
310         }
311 
312         // locale
313         if (acceptLanguage != null) {
314             httpHeaders.put("Accept-Language", Collections.singletonList(acceptLanguage));
315         }
316 
317         ((BindingProvider) portObject).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
318     }
319 
320     /**
321      * Creates a port object.
322      */
323     protected abstract Object createPortObject(Service service);
324 }