View Javadoc
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.server.impl.webservices;
20  
21  import org.apache.chemistry.opencmis.commons.exceptions.CmisBaseException;
22  import org.apache.chemistry.opencmis.commons.exceptions.CmisConstraintException;
23  import org.apache.chemistry.opencmis.commons.exceptions.CmisContentAlreadyExistsException;
24  import org.apache.chemistry.opencmis.commons.exceptions.CmisFilterNotValidException;
25  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
26  import org.apache.chemistry.opencmis.commons.exceptions.CmisNameConstraintViolationException;
27  import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
28  import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
29  import org.apache.chemistry.opencmis.commons.exceptions.CmisPermissionDeniedException;
30  import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
31  import org.apache.chemistry.opencmis.commons.exceptions.CmisStorageException;
32  import org.apache.chemistry.opencmis.commons.exceptions.CmisStreamNotSupportedException;
33  import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
34  import org.apache.chemistry.opencmis.commons.exceptions.CmisVersioningException;
35  import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisException;
36  import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisFaultType;
37  import org.apache.chemistry.opencmis.commons.impl.jaxb.EnumServiceException;
38  import org.apache.chemistry.opencmis.commons.server.CallContext;
39  import org.apache.chemistry.opencmis.commons.server.CmisService;
40  import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory;
41  import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
42  import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
43  import org.apache.chemistry.opencmis.server.impl.ServerVersion;
44  import org.apache.chemistry.opencmis.server.shared.ExceptionHelper;
45  
46  import org.w3c.dom.Node;
47  
48  import java.math.BigInteger;
49  
50  import java.util.List;
51  import java.util.Map;
52  
53  import javax.servlet.ServletContext;
54  import javax.servlet.http.HttpServletRequest;
55  import javax.servlet.http.HttpServletResponse;
56  
57  import javax.xml.ws.WebServiceContext;
58  import javax.xml.ws.handler.MessageContext;
59  
60  
61  /**
62   * This class contains operations used by all services.
63   */
64  public abstract class AbstractService
65  {
66      public static final String CALL_CONTEXT_MAP = "org.apache.chemistry.opencmis.callcontext";
67  
68      /**
69       * Returns the services factory.
70       */
71      protected CmisServiceFactory getServiceFactory( WebServiceContext wsContext )
72      {
73          ServletContext servletContext = (ServletContext) wsContext.getMessageContext(  )
74                                                                    .get( MessageContext.SERVLET_CONTEXT );
75  
76          // get services factory
77          CmisServiceFactory factory = (CmisServiceFactory) servletContext.getAttribute( CmisRepositoryContextListener.SERVICES_FACTORY );
78  
79          if ( factory == null )
80          {
81              throw new CmisRuntimeException( "Service factory not available! Configuration problem?" );
82          }
83  
84          HttpServletResponse httpResp = (HttpServletResponse) wsContext.getMessageContext(  )
85                                                                        .get( MessageContext.SERVLET_RESPONSE );
86          httpResp.setHeader( "Server", ServerVersion.OPENCMIS_SERVER );
87  
88          return factory;
89      }
90  
91      /**
92       * Creates a CallContext object for the Web Service context.
93       */
94      @SuppressWarnings( "unchecked" )
95      protected CallContext createContext( WebServiceContext wsContext, String repositoryId )
96      {
97          CallContextImpl context = new CallContextImpl( CallContext.BINDING_WEBSERVICES, repositoryId, false );
98  
99          MessageContext mc = wsContext.getMessageContext(  );
100         Map<String, String> callContextMap = (Map<String, String>) mc.get( CALL_CONTEXT_MAP );
101 
102         if ( callContextMap != null )
103         {
104             for ( Map.Entry<String, String> e : callContextMap.entrySet(  ) )
105             {
106                 context.put( e.getKey(  ), e.getValue(  ) );
107             }
108         }
109 
110         ServletContext servletContext = (ServletContext) wsContext.getMessageContext(  )
111                                                                   .get( MessageContext.SERVLET_CONTEXT );
112         context.put( CallContext.SERVLET_CONTEXT, servletContext );
113 
114         HttpServletRequest request = (HttpServletRequest) wsContext.getMessageContext(  )
115                                                                    .get( MessageContext.SERVLET_REQUEST );
116         context.put( CallContext.HTTP_SERVLET_REQUEST, request );
117 
118         HttpServletResponse response = (HttpServletResponse) wsContext.getMessageContext(  )
119                                                                       .get( MessageContext.SERVLET_RESPONSE );
120         context.put( CallContext.HTTP_SERVLET_RESPONSE, response );
121 
122         Map<String, List<String>> headers = (Map<String, List<String>>) wsContext.getMessageContext(  )
123                                                                                  .get( MessageContext.HTTP_REQUEST_HEADERS );
124 
125         if ( headers != null )
126         {
127             for ( Map.Entry<String, List<String>> header : headers.entrySet(  ) )
128             {
129                 if ( header.getKey(  ).equalsIgnoreCase( "Accept-Language" ) && ( header.getValue(  ) != null ) )
130                 {
131                     String acceptLanguage = header.getValue(  ).get( 0 );
132 
133                     if ( acceptLanguage != null )
134                     {
135                         String[] locale = acceptLanguage.split( "-" );
136                         context.put( CallContext.LOCALE_ISO639_LANGUAGE, locale[0].trim(  ) );
137 
138                         if ( locale.length > 1 )
139                         {
140                             int x = locale[1].indexOf( ',' );
141 
142                             if ( x == -1 )
143                             {
144                                 context.put( CallContext.LOCALE_ISO3166_COUNTRY, locale[1].trim(  ) );
145                             }
146                             else
147                             {
148                                 context.put( CallContext.LOCALE_ISO3166_COUNTRY, locale[1].substring( 0, x ).trim(  ) );
149                             }
150                         }
151                     }
152 
153                     break;
154                 }
155             }
156         }
157 
158         return context;
159     }
160 
161     /**
162      * Returns the {@link CmisService} object.
163      */
164     protected CmisService getService( WebServiceContext wsContext, String repositoryId )
165     {
166         CmisServiceFactory factory = getServiceFactory( wsContext );
167         CallContext context = createContext( wsContext, repositoryId );
168 
169         return factory.getService( context );
170     }
171 
172     /**
173      * Closes the service instance.
174      */
175     protected void closeService( CmisService service )
176     {
177         if ( service != null )
178         {
179             service.close(  );
180         }
181     }
182 
183     /**
184      * Converts a CMIS exception to the appropriate Web Service exception.
185      */
186     protected CmisException convertException( Exception ex )
187     {
188         CmisFaultType fault = new CmisFaultType(  );
189         fault.setMessage( "Unknown exception" );
190         fault.setCode( BigInteger.ZERO );
191         fault.setType( EnumServiceException.RUNTIME );
192 
193         if ( ex != null )
194         {
195             fault.setMessage( ex.getMessage(  ) );
196 
197             if ( ex instanceof CmisBaseException )
198             {
199                 fault.setCode( ( (CmisBaseException) ex ).getCode(  ) );
200             }
201 
202             if ( ex instanceof CmisConstraintException )
203             {
204                 fault.setType( EnumServiceException.CONSTRAINT );
205             }
206             else if ( ex instanceof CmisContentAlreadyExistsException )
207             {
208                 fault.setType( EnumServiceException.CONTENT_ALREADY_EXISTS );
209             }
210             else if ( ex instanceof CmisFilterNotValidException )
211             {
212                 fault.setType( EnumServiceException.FILTER_NOT_VALID );
213             }
214             else if ( ex instanceof CmisInvalidArgumentException )
215             {
216                 fault.setType( EnumServiceException.INVALID_ARGUMENT );
217             }
218             else if ( ex instanceof CmisNameConstraintViolationException )
219             {
220                 fault.setType( EnumServiceException.NAME_CONSTRAINT_VIOLATION );
221             }
222             else if ( ex instanceof CmisNotSupportedException )
223             {
224                 fault.setType( EnumServiceException.NOT_SUPPORTED );
225             }
226             else if ( ex instanceof CmisObjectNotFoundException )
227             {
228                 fault.setType( EnumServiceException.OBJECT_NOT_FOUND );
229             }
230             else if ( ex instanceof CmisPermissionDeniedException )
231             {
232                 fault.setType( EnumServiceException.PERMISSION_DENIED );
233             }
234             else if ( ex instanceof CmisStorageException )
235             {
236                 fault.setType( EnumServiceException.STORAGE );
237             }
238             else if ( ex instanceof CmisStreamNotSupportedException )
239             {
240                 fault.setType( EnumServiceException.STREAM_NOT_SUPPORTED );
241             }
242             else if ( ex instanceof CmisUpdateConflictException )
243             {
244                 fault.setType( EnumServiceException.UPDATE_CONFLICT );
245             }
246             else if ( ex instanceof CmisVersioningException )
247             {
248                 fault.setType( EnumServiceException.VERSIONING );
249             }
250 
251             Node node = ExceptionHelper.getStacktraceAsNode( ex );
252 
253             if ( node != null )
254             {
255                 fault.getAny(  ).add( node );
256             }
257         }
258 
259         return new CmisException( fault.getMessage(  ), fault, ex );
260     }
261 }