Passed
Push — master ( c1bcb1...a4e211 )
by Nate
02:14
created

RetrofitBuilder::createDefaultProxyFactory()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 73
Code Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 52
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 73
ccs 52
cts 52
cp 1
rs 6.6896
c 0
b 0
f 0
cc 7
eloc 52
nc 6
nop 0
crap 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
declare(strict_types=1);
8
9
namespace Tebru\Retrofit;
10
11
use Doctrine\Common\Annotations\AnnotationReader;
12
use LogicException;
13
use PhpParser\BuilderFactory;
14
use PhpParser\PrettyPrinter\Standard;
15
use Psr\SimpleCache\CacheInterface;
16
use Symfony\Component\Cache\Simple\ArrayCache;
17
use Symfony\Component\Cache\Simple\ChainCache;
18
use Symfony\Component\Cache\Simple\PhpFilesCache;
19
use Tebru\AnnotationReader\AnnotationReaderAdapter;
20
use Tebru\Retrofit\Annotation as Annot;
21
use Tebru\Retrofit\Finder\ServiceResolver;
22
use Tebru\Retrofit\Internal\AnnotationHandler as AnnotHandler;
23
use Tebru\Retrofit\Internal\AnnotationProcessor;
24
use Tebru\Retrofit\Internal\CallAdapter\CallAdapterProvider;
25
use Tebru\Retrofit\Internal\CallAdapter\DefaultCallAdapterFactory;
26
use Tebru\Retrofit\Internal\Converter\ConverterProvider;
27
use Tebru\Retrofit\Internal\Converter\DefaultConverterFactory;
28
use Tebru\Retrofit\Internal\DefaultProxyFactory;
29
use Tebru\Retrofit\Internal\Filesystem;
30
use Tebru\Retrofit\Internal\ServiceMethod\ServiceMethodFactory;
31
32
/**
33
 * Class RetrofitBuilder
34
 *
35
 * @author Nate Brunette <[email protected]>
36
 */
37
class RetrofitBuilder
38
{
39
    /**
40
     * A cache interface to be used in place of defaults
41
     *
42
     * If this is set, [@see RetrofitBuilder::$shouldCache] will be ignored for internal
43
     * caches, however, [@see RetrofitBuilder::$shouldCache] and
44
     * [@see RetrofitBuilder::$cacheDir] will still be used to cache proxy clients.
45
     *
46
     * @var CacheInterface
47
     */
48
    private $cache;
49
50
    /**
51
     * Directory to store generated proxy clients
52
     *
53
     * @var string
54
     */
55
    private $cacheDir;
56
57
    /**
58
     * A Retrofit http client used to make requests
59
     *
60
     * @var HttpClient
61
     */
62
    private $httpClient;
63
64
    /**
65
     * The service's base url
66
     *
67
     * @var string
68
     */
69
    private $baseUrl;
70
71
    /**
72
     * An array of factories used to create [@see CallAdapter]s
73
     *
74
     * @var CallAdapterFactory[]
75
     */
76
    private $callAdapterFactories = [];
77
78
    /**
79
     * An array of factories used to convert types
80
     *
81
     * @var ConverterFactory[]
82
     */
83
    private $converterFactories = [];
84
85
    /**
86
     * An array of factories used to create [@see Proxy] objects
87
     *
88
     * @var ProxyFactory[]
89
     */
90
    private $proxyFactories = [];
91
92
    /**
93
     * An array of handlers used to modify the request based on an annotation
94
     *
95
     * @var AnnotationHandler[]
96
     */
97
    private $annotationHandlers = [];
98
99
    /**
100
     * If we should cache the proxies
101
     *
102
     * @var bool
103
     */
104
    private $shouldCache = false;
105
106
    /**
107
     * Override default cache adapters
108
     *
109
     * @param CacheInterface $cache
110
     * @return RetrofitBuilder
111
     */
112 1
    public function setCache(CacheInterface $cache): RetrofitBuilder
113
    {
114 1
        $this->cache = $cache;
115
116 1
        return $this;
117
    }
118
119
    /**
120
     * Set the cache directory
121
     *
122
     * @param string $cacheDir
123
     * @return RetrofitBuilder
124
     */
125 1
    public function setCacheDir(string $cacheDir): RetrofitBuilder
126
    {
127 1
        $this->cacheDir = $cacheDir;
128
129 1
        return $this;
130
    }
131
132
    /**
133
     * Set the Retrofit http client
134
     *
135
     * @param HttpClient $client
136
     * @return RetrofitBuilder
137
     */
138 22
    public function setHttpClient(HttpClient $client): RetrofitBuilder
139
    {
140 22
        $this->httpClient = $client;
141
142 22
        return $this;
143
    }
144
145
    /**
146
     * Set the base url
147
     *
148
     * @param string $baseUrl
149
     * @return RetrofitBuilder
150
     */
151 22
    public function setBaseUrl(string $baseUrl): RetrofitBuilder
152
    {
153 22
        $this->baseUrl = $baseUrl;
154
155 22
        return $this;
156
    }
157
158
    /**
159
     * Add a [@see CallAdapterFactory]
160
     *
161
     * @param CallAdapterFactory $callAdapterFactory
162
     * @return RetrofitBuilder
163
     */
164 1
    public function addCallAdapterFactory(CallAdapterFactory $callAdapterFactory): RetrofitBuilder
165
    {
166 1
        $this->callAdapterFactories[] = $callAdapterFactory;
167
168 1
        return $this;
169
    }
170
171
    /**
172
     * Add a [@see ConverterFactory]
173
     *
174
     * @param ConverterFactory $converterFactory
175
     * @return RetrofitBuilder
176
     */
177 2
    public function addConverterFactory(ConverterFactory $converterFactory): RetrofitBuilder
178
    {
179 2
        $this->converterFactories[] = $converterFactory;
180
181 2
        return $this;
182
    }
183
184
    /**
185
     * Add a [@see ProxyFactory]
186
     *
187
     * @param ProxyFactory $proxyFactory
188
     * @return RetrofitBuilder
189
     */
190 1
    public function addProxyFactory(ProxyFactory $proxyFactory): RetrofitBuilder
191
    {
192 1
        $this->proxyFactories[] = $proxyFactory;
193
194 1
        return $this;
195
    }
196
197
    /**
198
     * Add an [@see AnnotationHandler]
199
     *
200
     * @param string $annotationName
201
     * @param AnnotationHandler $annotationHandler
202
     * @return RetrofitBuilder
203
     */
204 1
    public function addAnnotationHandler(string $annotationName, AnnotationHandler $annotationHandler): RetrofitBuilder
205
    {
206 1
        $this->annotationHandlers[$annotationName] = $annotationHandler;
207
208 1
        return $this;
209
    }
210
211
    /**
212
     * Enable caching proxies
213
     *
214
     * @param bool $enable
215
     * @return RetrofitBuilder
216
     */
217 2
    public function enableCache(bool $enable = true): RetrofitBuilder
218
    {
219 2
        $this->shouldCache = $enable;
220
221 2
        return $this;
222
    }
223
224
    /**
225
     * Build a retrofit instance
226
     *
227
     * @return Retrofit
228
     * @throws \LogicException
229
     */
230 21
    public function build(): Retrofit
231
    {
232 21
        $defaultProxyFactory = $this->createDefaultProxyFactory();
233 18
        foreach ($this->proxyFactories as $proxyFactory) {
234 1
            if ($proxyFactory instanceof DefaultProxyFactoryAware) {
235 1
                $proxyFactory->setDefaultProxyFactory($defaultProxyFactory);
236
            }
237
        }
238 18
        $this->proxyFactories[] = $defaultProxyFactory;
239
240 18
        return new Retrofit(new ServiceResolver(), $this->proxyFactories);
241
    }
242
243
    /**
244
     * Creates the default proxy factory and all necessary dependencies
245
     *
246
     * @return ProxyFactory
247
     * @throws \LogicException
248
     */
249 21
    private function createDefaultProxyFactory(): ProxyFactory
250
    {
251 21
        if ($this->baseUrl === null) {
252 1
            throw new LogicException('Retrofit: Base URL must be provided');
253
        }
254
255 20
        if ($this->httpClient === null) {
256 1
            throw new LogicException('Retrofit: Must set http client to make requests');
257
        }
258
259 19
        if ($this->shouldCache && $this->cacheDir === null) {
260 1
            throw new LogicException('Retrofit: If caching is enabled, must specify cache directory');
261
        }
262
263 18
        $this->cacheDir .= '/retrofit';
264
265
        // add defaults to any user registered
266 18
        $this->callAdapterFactories[] = new DefaultCallAdapterFactory();
267 18
        $this->converterFactories[] = new DefaultConverterFactory();
268
269 18
        if ($this->cache === null) {
270 17
            $this->cache = $this->shouldCache === true
271 1
                ? new ChainCache([new ArrayCache(0, false), new PhpFilesCache('', 0, $this->cacheDir)])
272 16
                : new ArrayCache(0, false);
273
        }
274
275 18
        $httpRequestHandler = new AnnotHandler\HttpRequestAnnotHandler();
276
277
        /** @noinspection ClassConstantUsageCorrectnessInspection */
278 18
        $annotationHandlers = array_merge(
279
            [
280 18
                Annot\Body::class => new AnnotHandler\BodyAnnotHandler(),
281 18
                Annot\DELETE::class => $httpRequestHandler,
282 18
                Annot\Field::class => new AnnotHandler\FieldAnnotHandler(),
283 18
                Annot\FieldMap::class => new AnnotHandler\FieldMapAnnotHandler(),
284 18
                Annot\GET::class => $httpRequestHandler,
285 18
                Annot\HEAD::class => $httpRequestHandler,
286 18
                Annot\Header::class => new AnnotHandler\HeaderAnnotHandler(),
287 18
                Annot\HeaderMap::class => new AnnotHandler\HeaderMapAnnotHandler(),
288 18
                Annot\Headers::class => new AnnotHandler\HeadersAnnotHandler(),
289 18
                Annot\OPTIONS::class => $httpRequestHandler,
290 18
                Annot\Part::class => new AnnotHandler\PartAnnotHandler(),
291 18
                Annot\PartMap::class => new AnnotHandler\PartMapAnnotHandler(),
292 18
                Annot\PATCH::class => $httpRequestHandler,
293 18
                Annot\Path::class => new AnnotHandler\PathAnnotHandler(),
294 18
                Annot\POST::class => $httpRequestHandler,
295 18
                Annot\PUT::class => $httpRequestHandler,
296 18
                Annot\Query::class => new AnnotHandler\QueryAnnotHandler(),
297 18
                Annot\QueryMap::class => new AnnotHandler\QueryMapAnnotHandler(),
298 18
                Annot\QueryName::class => new AnnotHandler\QueryNameAnnotHandler(),
299 18
                Annot\REQUEST::class => $httpRequestHandler,
300 18
                Annot\Url::class => new AnnotHandler\UrlAnnotHandler(),
301
            ],
302 18
            $this->annotationHandlers
303
        );
304 18
        $serviceMethodFactory = new ServiceMethodFactory(
305 18
            new AnnotationProcessor($annotationHandlers),
306 18
            new CallAdapterProvider($this->callAdapterFactories),
307 18
            new ConverterProvider($this->converterFactories),
308 18
            new AnnotationReaderAdapter(new AnnotationReader(), $this->cache),
309 18
            $this->baseUrl
310
        );
311
312 18
        return new DefaultProxyFactory(
313 18
            new BuilderFactory(),
314 18
            new Standard(),
315 18
            $serviceMethodFactory,
316 18
            $this->httpClient,
317 18
            new Filesystem(),
318 18
            $this->shouldCache,
319 18
            $this->cacheDir
320
        );
321
    }
322
}
323