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.shared;
20  
21  import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException;
22  import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
23  import org.apache.chemistry.opencmis.commons.server.CallContext;
24  import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
25  
26  import java.io.File;
27  
28  import java.lang.reflect.Method;
29  
30  import java.math.BigInteger;
31  
32  import java.util.Map;
33  
34  import javax.servlet.ServletContext;
35  import javax.servlet.http.HttpServletRequest;
36  import javax.servlet.http.HttpServletResponse;
37  
38  
39  /**
40   * Utility methods that are used by the AtomPub and Browser binding.
41   */
42  public class HttpUtils
43  {
44      private HttpUtils(  )
45      {
46      }
47  
48      /**
49       * Creates a {@link CallContext} object from a servlet request.
50       */
51      public static CallContext createContext( HttpServletRequest request, HttpServletResponse response,
52          ServletContext servletContext, String binding, CallContextHandler callContextHandler, File tempDir,
53          int memoryThreshold )
54      {
55          String[] pathFragments = splitPath( request );
56  
57          String repositoryId = null;
58  
59          if ( pathFragments.length > 0 )
60          {
61              repositoryId = pathFragments[0];
62          }
63  
64          CallContextImpl context = new CallContextImpl( binding, repositoryId, true );
65  
66          // call call context handler
67          if ( callContextHandler != null )
68          {
69              Map<String, String> callContextMap = callContextHandler.getCallContextMap( request );
70  
71              if ( callContextMap != null )
72              {
73                  for ( Map.Entry<String, String> e : callContextMap.entrySet(  ) )
74                  {
75                      context.put( e.getKey(  ), e.getValue(  ) );
76                  }
77              }
78          }
79  
80          // servlet context and HTTP servlet request and response
81          context.put( CallContext.SERVLET_CONTEXT, servletContext );
82          context.put( CallContext.HTTP_SERVLET_REQUEST, request );
83          context.put( CallContext.HTTP_SERVLET_RESPONSE, response );
84  
85          // temp files
86          context.put( CallContext.TEMP_DIR, tempDir );
87          context.put( CallContext.MEMORY_THRESHOLD, memoryThreshold );
88  
89          // decode range
90          String rangeHeader = request.getHeader( "Range" );
91  
92          if ( rangeHeader != null )
93          {
94              rangeHeader = rangeHeader.trim(  );
95  
96              BigInteger offset = null;
97              BigInteger length = null;
98  
99              int eq = rangeHeader.indexOf( '=' );
100             int ds = rangeHeader.indexOf( '-' );
101 
102             if ( ( eq > 0 ) && ( ds > eq ) )
103             {
104                 String offsetStr = rangeHeader.substring( eq + 1, ds ).trim(  );
105 
106                 if ( offsetStr.length(  ) > 0 )
107                 {
108                     offset = new BigInteger( offsetStr );
109                 }
110 
111                 if ( ds < rangeHeader.length(  ) )
112                 {
113                     String lengthStr = rangeHeader.substring( ds + 1 ).trim(  );
114 
115                     if ( lengthStr.length(  ) > 0 )
116                     {
117                         if ( offset == null )
118                         {
119                             length = new BigInteger( lengthStr );
120                         }
121                         else
122                         {
123                             length = ( new BigInteger( lengthStr ) ).subtract( offset );
124                         }
125                     }
126 
127                     if ( offset != null )
128                     {
129                         context.put( CallContext.OFFSET, offset );
130                     }
131 
132                     if ( length != null )
133                     {
134                         context.put( CallContext.LENGTH, length );
135                     }
136                 }
137             }
138         }
139 
140         // get locale
141         String acceptLanguage = request.getHeader( "Accept-Language" );
142 
143         if ( acceptLanguage != null )
144         {
145             String[] locale = acceptLanguage.split( "-" );
146             context.put( CallContext.LOCALE_ISO639_LANGUAGE, locale[0].trim(  ) );
147 
148             if ( locale.length > 1 )
149             {
150                 int x = locale[1].indexOf( ',' );
151 
152                 if ( x == -1 )
153                 {
154                     context.put( CallContext.LOCALE_ISO3166_COUNTRY, locale[1].trim(  ) );
155                 }
156                 else
157                 {
158                     context.put( CallContext.LOCALE_ISO3166_COUNTRY, locale[1].substring( 0, x ).trim(  ) );
159                 }
160             }
161         }
162 
163         return context;
164     }
165 
166     /**
167      * Splits the path into its fragments.
168      */
169     public static String[] splitPath( HttpServletRequest request )
170     {
171         String p = request.getPathInfo(  );
172 
173         if ( p == null )
174         {
175             return new String[0];
176         }
177 
178         return p.substring( 1 ).split( "/" );
179     }
180 
181     // -------------------------------------------------------------------------
182     // --- parameters ---
183     // -------------------------------------------------------------------------
184 
185     /**
186      * Extracts a string parameter.
187      */
188     @SuppressWarnings( "unchecked" )
189     public static String getStringParameter( HttpServletRequest request, String name )
190     {
191         if ( name == null )
192         {
193             return null;
194         }
195 
196         Map<String, String[]> parameters = (Map<String, String[]>) request.getParameterMap(  );
197 
198         for ( Map.Entry<String, String[]> parameter : parameters.entrySet(  ) )
199         {
200             if ( name.equalsIgnoreCase( parameter.getKey(  ) ) )
201             {
202                 if ( parameter.getValue(  ) == null )
203                 {
204                     return null;
205                 }
206 
207                 return parameter.getValue(  )[0];
208             }
209         }
210 
211         return null;
212     }
213 
214     /**
215      * Extracts a boolean parameter (with default).
216      */
217     public static boolean getBooleanParameter( HttpServletRequest request, String name, boolean def )
218     {
219         String value = getStringParameter( request, name );
220 
221         if ( ( value == null ) || ( value.length(  ) == 0 ) )
222         {
223             return def;
224         }
225 
226         return Boolean.valueOf( value );
227     }
228 
229     /**
230      * Extracts a boolean parameter.
231      */
232     public static Boolean getBooleanParameter( HttpServletRequest request, String name )
233     {
234         String value = getStringParameter( request, name );
235 
236         if ( ( value == null ) || ( value.length(  ) == 0 ) )
237         {
238             return null;
239         }
240 
241         return Boolean.valueOf( value );
242     }
243 
244     /**
245      * Extracts an integer parameter (with default).
246      */
247     public static BigInteger getBigIntegerParameter( HttpServletRequest request, String name, long def )
248     {
249         BigInteger result = getBigIntegerParameter( request, name );
250 
251         if ( result == null )
252         {
253             result = BigInteger.valueOf( def );
254         }
255 
256         return result;
257     }
258 
259     /**
260      * Extracts an integer parameter.
261      */
262     public static BigInteger getBigIntegerParameter( HttpServletRequest request, String name )
263     {
264         String value = getStringParameter( request, name );
265 
266         if ( ( value == null ) || ( value.length(  ) == 0 ) )
267         {
268             return null;
269         }
270 
271         try
272         {
273             return new BigInteger( value );
274         }
275         catch ( Exception e )
276         {
277             throw new CmisInvalidArgumentException( "Invalid parameter '" + name + "'!" );
278         }
279     }
280 
281     /**
282      * Extracts an enum parameter.
283      */
284     @SuppressWarnings( "unchecked" )
285     public static <T> T getEnumParameter( HttpServletRequest request, String name, Class<T> clazz )
286     {
287         String value = getStringParameter( request, name );
288 
289         if ( ( value == null ) || ( value.length(  ) == 0 ) )
290         {
291             return null;
292         }
293 
294         try
295         {
296             Method m = clazz.getMethod( "fromValue", new Class[] { String.class } );
297 
298             return (T) m.invoke( null, new Object[] { value } );
299         }
300         catch ( Exception e )
301         {
302             if ( e instanceof IllegalArgumentException )
303             {
304                 throw new CmisInvalidArgumentException( "Invalid parameter '" + name + "'!" );
305             }
306 
307             throw new CmisRuntimeException( e.getMessage(  ), e );
308         }
309     }
310 }