View Javadoc

1   /*
2    * Copyright 2007 Hippo
3    *
4    * Licensed under the Apache License, Version 2.0 (the  "License"); 
5    * you may not use this file except in compliance with the License. 
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" 
12   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
13   * See the License for the specific language governing permissions and 
14   * limitations under the License.
15   */
16  package nl.hippo.client.webdav.method;
17  
18  import java.io.IOException;
19  
20  import nl.hippo.client.api.ClientException;
21  import nl.hippo.client.api.DocumentNotFoundException;
22  import nl.hippo.client.webdav.HttpClientPool;
23  import nl.hippo.client.webdav.WebdavConfig;
24  import nl.hippo.client.webdav.WebdavLogger;
25  import nl.hippo.client.webdav.WebdavRequest;
26  import nl.hippo.client.webdav.WebdavResponse;
27  import nl.hippo.client.webdav.caching.WebdavCacheHandler;
28  
29  import org.apache.commons.httpclient.DefaultMethodRetryHandler;
30  import org.apache.commons.httpclient.HttpClient;
31  import org.apache.commons.httpclient.HttpMethodBase;
32  
33  /**
34   * Abstract base class for all Webdav methods.
35   */
36  abstract class WebdavMethod {
37  
38      interface WebdavMethodCallback {
39          WebdavResponse doExec(HttpClient client) throws ClientException;
40      }
41  
42      /**
43       * Configuration of this WebdavMethod
44       */
45      protected WebdavConfig config;
46  
47      protected WebdavMethod(WebdavConfig config) {
48          this.config = config;
49      }
50  
51      /**
52       * This is for HttpMethods like PUT which don't need a cache
53       * @param callback
54       * @return WebdavResponse
55       * @throws ClientException
56       */
57      protected WebdavResponse execute(WebdavMethodCallback callback, WebdavRequest request) throws ClientException {
58          WebdavResponse result = null;
59          HttpClient client = null;
60          try {
61              try {
62                  client = (HttpClient) HttpClientPool.getPool().borrowObject(config);
63              } catch (Exception e) {
64                  throw new ClientException("Exception while initializing HttpClient", e);
65              }
66              result = callback.doExec(client);
67              if (result.isDocumentNotFound()) {
68                  WebdavLogger.log.info(
69                          new StringBuffer("Document not found : ")
70                              .append("(")
71                              .append(request.getMethod())
72                              .append(") ")
73                              .append(request.getPath().getFullPath())
74                              .toString());
75                  throw new DocumentNotFoundException("Document not found: " + request.getPath().getFullPath());
76              } else if (!result.isValid()) {
77                  WebdavLogger.log.error(
78                       new StringBuffer("Server response is not valid, HTTP response code is ")
79                           .append(result.getResponseCode())
80                           .append(" (")
81                           .append(request.getMethod())
82                           .append(": ")
83                           .append(request.getPath().getFullPath())
84                           .append(")")
85                           .toString());
86              }
87              
88          } finally {
89              try {
90                  HttpClientPool.getPool().returnObject(config, client);
91              } catch (Exception e) {
92                  throw new ClientException("Exception while returning HttpClient to pool.", e);
93              }
94          }
95  
96          return result;
97      }
98  
99      protected WebdavResponse execute(WebdavMethodCallback callback, WebdavRequest request, WebdavCacheHandler cache)
100             throws ClientException {
101         WebdavResponse result = cache.getWebdavResponse(request);
102         
103         // cached result
104         if (result != null) {
105             if (WebdavLogger.log.isDebugEnabled()) {
106                 WebdavLogger.log.debug(new StringBuffer("Serving from cache: ").append("(").append(
107                     request.getMethod()).append(") ").append(request.getPath().getFullPath()).toString());
108             }
109             if (result.isDocumentNotFound()) {
110                 throw new DocumentNotFoundException("Document not found: " + request.getPath().getFullPath());
111             }
112             return result;
113         }
114         
115 
116         if (WebdavLogger.log.isDebugEnabled()) {
117             WebdavLogger.log.debug(new StringBuffer("Trying to fetch from repository: ").append("(").append(
118                 request.getMethod()).append(") ").append(request.getPath().getFullPath()).toString());
119         }
120         
121         HttpClient client = null;
122 
123         try {
124             client = (HttpClient) HttpClientPool.getPool().borrowObject(config);
125         } catch (Exception e) {
126             throw new ClientException("Exception while initializing HttpClient", e);
127         }
128         
129         try {
130             result = callback.doExec(client);
131             if (!result.isValid()) {
132                 if (result.isDocumentNotFound()) {
133                     WebdavLogger.log.warn(new StringBuffer("Document not found : ").append("(").append(
134                             request.getMethod()).append(") ").append(request.getPath().getFullPath()).toString());
135                 } else {
136                     WebdavLogger.log.info(new StringBuffer("Request to server failed, HTTP response code is ")
137                             .append(result.getResponseCode()).append(" (").append(request.getMethod()).append(": ")
138                             .append(request.getPath().getFullPath()).append(")").toString());
139                     if (WebdavLogger.log.isDebugEnabled()) {
140                         StringBuffer debugLog = new StringBuffer("Server response is:\n");
141                         try {
142                             debugLog.append(result.getResponseAsPrettyPrintedString("UTF-8"));
143                         } catch (ClientException e) {
144                             debugLog.append("Failed to log server response: ").append(e.getMessage());
145                         }
146                         WebdavLogger.log.debug(debugLog.toString());
147                     }
148                 }
149             }
150         } finally {
151             try {
152                 HttpClientPool.getPool().returnObject(config, client);
153             } catch (Exception e) {
154                 throw new ClientException("Exception while returning HttpClient to pool.", e);
155             }
156         }
157         
158         cache.store(result);
159         if (result.isDocumentNotFound()) {
160             throw new DocumentNotFoundException("Document not found: " + request.getPath().getFullPath());
161         }
162         return result;
163     }
164     
165 
166     /**
167     * Retries up to three times
168     *
169     * @return httpclient response code
170     */
171     protected int executeMethod(HttpClient httpclient, HttpMethodBase method) throws IOException {
172         DefaultMethodRetryHandler retryHandler = new DefaultMethodRetryHandler();
173         retryHandler.setRetryCount(3);
174         method.setMethodRetryHandler(retryHandler);
175         return httpclient.executeMethod(method);
176     }
177 
178 }