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