View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.impl.client.cache;
28  
29  import java.io.Closeable;
30  import java.io.File;
31  import java.io.IOException;
32  
33  import org.apache.http.client.cache.HttpCacheInvalidator;
34  import org.apache.http.client.cache.HttpCacheStorage;
35  import org.apache.http.client.cache.ResourceFactory;
36  import org.apache.http.impl.client.HttpClientBuilder;
37  import org.apache.http.impl.execchain.ClientExecChain;
38  
39  /**
40   * Builder for {@link org.apache.http.impl.client.CloseableHttpClient}
41   * instances capable of client-side caching.
42   *
43   * @since 4.3
44   */
45  public class CachingHttpClientBuilder extends HttpClientBuilder {
46  
47      private ResourceFactory resourceFactory;
48      private HttpCacheStorage storage;
49      private File cacheDir;
50      private CacheConfig cacheConfig;
51      private SchedulingStrategy schedulingStrategy;
52      private HttpCacheInvalidator httpCacheInvalidator;
53      private boolean deleteCache;
54  
55      public static CachingHttpClientBuilder create() {
56          return new CachingHttpClientBuilder();
57      }
58  
59      protected CachingHttpClientBuilder() {
60          super();
61          this.deleteCache = true;
62      }
63  
64      public final CachingHttpClientBuilder setResourceFactory(
65              final ResourceFactory resourceFactory) {
66          this.resourceFactory = resourceFactory;
67          return this;
68      }
69  
70      public final CachingHttpClientBuilder setHttpCacheStorage(
71              final HttpCacheStorage storage) {
72          this.storage = storage;
73          return this;
74      }
75  
76      public final CachingHttpClientBuilder setCacheDir(
77              final File cacheDir) {
78          this.cacheDir = cacheDir;
79          return this;
80      }
81  
82      public final CachingHttpClientBuilder setCacheConfig(
83              final CacheConfig cacheConfig) {
84          this.cacheConfig = cacheConfig;
85          return this;
86      }
87  
88      public final CachingHttpClientBuilder setSchedulingStrategy(
89              final SchedulingStrategy schedulingStrategy) {
90          this.schedulingStrategy = schedulingStrategy;
91          return this;
92      }
93  
94      public final CachingHttpClientBuilder setHttpCacheInvalidator(
95              final HttpCacheInvalidator cacheInvalidator) {
96          this.httpCacheInvalidator = cacheInvalidator;
97          return this;
98      }
99  
100     public CachingHttpClientBuilder setDeleteCache(final boolean deleteCache) {
101         this.deleteCache = deleteCache;
102         return this;
103     }
104 
105     @Override
106     protected ClientExecChain decorateMainExec(final ClientExecChain mainExec) {
107         final CacheConfig config = this.cacheConfig != null ? this.cacheConfig : CacheConfig.DEFAULT;
108         // We copy the instance fields to avoid changing them, and rename to avoid accidental use of the wrong version
109         ResourceFactory resourceFactoryCopy = this.resourceFactory;
110         if (resourceFactoryCopy == null) {
111             if (this.cacheDir == null) {
112                 resourceFactoryCopy = new HeapResourceFactory();
113             } else {
114                 resourceFactoryCopy = new FileResourceFactory(cacheDir);
115             }
116         }
117         HttpCacheStorage storageCopy = this.storage;
118         if (storageCopy == null) {
119             if (this.cacheDir == null) {
120                 storageCopy = new BasicHttpCacheStorage(config);
121             } else {
122                 final ManagedHttpCacheStoragecheStorage.html#ManagedHttpCacheStorage">ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
123                 if (this.deleteCache) {
124                     addCloseable(new Closeable() {
125 
126                         @Override
127                         public void close() throws IOException {
128                             managedStorage.shutdown();
129                         }
130 
131                     });
132                 } else {
133                     addCloseable(managedStorage);
134                 }
135                 storageCopy = managedStorage;
136             }
137         }
138         final AsynchronousValidator revalidator = createAsynchronousRevalidator(config);
139         final CacheKeyGeneratorKeyGenerator.html#CacheKeyGenerator">CacheKeyGenerator uriExtractor = new CacheKeyGenerator();
140 
141         HttpCacheInvalidator cacheInvalidator = this.httpCacheInvalidator;
142         if (cacheInvalidator == null) {
143             cacheInvalidator = new CacheInvalidator(uriExtractor, storageCopy);
144         }
145 
146         return new CachingExec(mainExec,
147                 new BasicHttpCache(
148                         resourceFactoryCopy,
149                         storageCopy, config,
150                         uriExtractor,
151                         cacheInvalidator), config, revalidator);
152     }
153 
154     private AsynchronousValidator createAsynchronousRevalidator(final CacheConfig config) {
155         if (config.getAsynchronousWorkersMax() > 0) {
156             final SchedulingStrategy configuredSchedulingStrategy = createSchedulingStrategy(config);
157             final AsynchronousValidatornousValidator.html#AsynchronousValidator">AsynchronousValidator revalidator = new AsynchronousValidator(
158                     configuredSchedulingStrategy);
159             addCloseable(revalidator);
160             return revalidator;
161         }
162         return null;
163     }
164 
165     private SchedulingStrategy createSchedulingStrategy(final CacheConfig config) {
166         return schedulingStrategy != null ? schedulingStrategy : new ImmediateSchedulingStrategy(config);
167     }
168 
169 }