1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.http.impl.cache;
28
29 import java.io.File;
30 import java.util.concurrent.ScheduledExecutorService;
31 import java.util.concurrent.ScheduledThreadPoolExecutor;
32 import java.util.function.Function;
33
34 import org.apache.hc.client5.http.cache.HttpCacheContext;
35 import org.apache.hc.client5.http.cache.HttpCacheEntryFactory;
36 import org.apache.hc.client5.http.cache.HttpCacheStorage;
37 import org.apache.hc.client5.http.cache.ResourceFactory;
38 import org.apache.hc.client5.http.classic.ExecChainHandler;
39 import org.apache.hc.client5.http.impl.ChainElement;
40 import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
41 import org.apache.hc.client5.http.impl.schedule.ImmediateSchedulingStrategy;
42 import org.apache.hc.client5.http.protocol.HttpClientContext;
43 import org.apache.hc.client5.http.schedule.SchedulingStrategy;
44 import org.apache.hc.core5.http.config.NamedElementChain;
45 import org.apache.hc.core5.http.protocol.HttpContext;
46
47
48
49
50
51
52
53 public class CachingHttpClientBuilder extends HttpClientBuilder {
54
55 private ResourceFactory resourceFactory;
56 private HttpCacheStorage storage;
57 private File cacheDir;
58 private SchedulingStrategy schedulingStrategy;
59 private CacheConfig cacheConfig;
60 private boolean deleteCache;
61
62 public static CachingHttpClientBuilder create() {
63 return new CachingHttpClientBuilder();
64 }
65
66 protected CachingHttpClientBuilder() {
67 super();
68 addResponseInterceptorFirst(ResponseCacheConformance.INSTANCE);
69 addResponseInterceptorLast(ResponseViaCache.INSTANCE);
70 addRequestInterceptorLast(RequestViaCache.INSTANCE);
71 this.deleteCache = true;
72 }
73
74 public final CachingHttpClientBuilder setResourceFactory(
75 final ResourceFactory resourceFactory) {
76 this.resourceFactory = resourceFactory;
77 return this;
78 }
79
80 public final CachingHttpClientBuilder setHttpCacheStorage(final HttpCacheStorage storage) {
81 this.storage = storage;
82 return this;
83 }
84
85 public final CachingHttpClientBuilder setCacheDir(final File cacheDir) {
86 this.cacheDir = cacheDir;
87 return this;
88 }
89
90 public final CachingHttpClientBuilder setSchedulingStrategy(final SchedulingStrategy schedulingStrategy) {
91 this.schedulingStrategy = schedulingStrategy;
92 return this;
93 }
94
95 public final CachingHttpClientBuilder setCacheConfig(final CacheConfig cacheConfig) {
96 this.cacheConfig = cacheConfig;
97 return this;
98 }
99
100
101
102
103 @Deprecated
104 public final CachingHttpClientBuilder setHttpCacheInvalidator(final org.apache.hc.client5.http.cache.HttpCacheInvalidator cacheInvalidator) {
105 return this;
106 }
107
108 public final CachingHttpClientBuilder setDeleteCache(final boolean deleteCache) {
109 this.deleteCache = deleteCache;
110 return this;
111 }
112
113 @Override
114 protected void customizeExecChain(final NamedElementChain<ExecChainHandler> execChainDefinition) {
115 final CacheConfig config = this.cacheConfig != null ? this.cacheConfig : CacheConfig.DEFAULT;
116
117 ResourceFactory resourceFactoryCopy = this.resourceFactory;
118 if (resourceFactoryCopy == null) {
119 if (this.cacheDir == null) {
120 resourceFactoryCopy = new HeapResourceFactory();
121 } else {
122 resourceFactoryCopy = new FileResourceFactory(cacheDir);
123 }
124 }
125 HttpCacheStorage storageCopy = this.storage;
126 if (storageCopy == null) {
127 if (this.cacheDir == null) {
128 storageCopy = new BasicHttpCacheStorage(config);
129 } else {
130 final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
131 if (this.deleteCache) {
132 addCloseable(managedStorage::shutdown);
133 } else {
134 addCloseable(managedStorage);
135 }
136 storageCopy = managedStorage;
137 }
138 }
139 final HttpCache httpCache = new BasicHttpCache(
140 resourceFactoryCopy,
141 HttpCacheEntryFactory.INSTANCE,
142 storageCopy,
143 CacheKeyGenerator.INSTANCE);
144
145 DefaultCacheRevalidator cacheRevalidator = null;
146 if (config.getAsynchronousWorkers() > 0) {
147 final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
148 addCloseable(executorService::shutdownNow);
149 cacheRevalidator = new DefaultCacheRevalidator(
150 executorService,
151 this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
152 }
153 final CachingExec cachingExec = new CachingExec(
154 httpCache,
155 cacheRevalidator,
156 config);
157 execChainDefinition.addBefore(ChainElement.PROTOCOL.name(), cachingExec, ChainElement.CACHING.name());
158 }
159
160 @Override
161 protected Function<HttpContext, HttpClientContext> contextAdaptor() {
162 return HttpCacheContext::castOrCreate;
163 }
164
165 }