]> git.argeo.org Git - gpl/argeo-slc.git/blob - RemoteRepository.java
aaa9acc272713462a54975b7f6f7314387de987a
[gpl/argeo-slc.git] / RemoteRepository.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 Sonatype, Inc.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Sonatype, Inc. - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.aether.repository;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19
20 /**
21 * A repository on a remote server.
22 */
23 public final class RemoteRepository
24 implements ArtifactRepository
25 {
26
27 private static final Pattern URL_PATTERN =
28 Pattern.compile( "([^:/]+(:[^:/]{2,}+(?=://))?):(//([^@/]*@)?([^/:]+))?.*" );
29
30 private final String id;
31
32 private final String type;
33
34 private final String url;
35
36 private final String host;
37
38 private final String protocol;
39
40 private final RepositoryPolicy releasePolicy;
41
42 private final RepositoryPolicy snapshotPolicy;
43
44 private final Proxy proxy;
45
46 private final Authentication authentication;
47
48 private final List<RemoteRepository> mirroredRepositories;
49
50 private final boolean repositoryManager;
51
52 RemoteRepository( Builder builder )
53 {
54 if ( builder.prototype != null )
55 {
56 id = ( builder.delta & Builder.ID ) != 0 ? builder.id : builder.prototype.id;
57 type = ( builder.delta & Builder.TYPE ) != 0 ? builder.type : builder.prototype.type;
58 url = ( builder.delta & Builder.URL ) != 0 ? builder.url : builder.prototype.url;
59 releasePolicy =
60 ( builder.delta & Builder.RELEASES ) != 0 ? builder.releasePolicy : builder.prototype.releasePolicy;
61 snapshotPolicy =
62 ( builder.delta & Builder.SNAPSHOTS ) != 0 ? builder.snapshotPolicy : builder.prototype.snapshotPolicy;
63 proxy = ( builder.delta & Builder.PROXY ) != 0 ? builder.proxy : builder.prototype.proxy;
64 authentication =
65 ( builder.delta & Builder.AUTH ) != 0 ? builder.authentication : builder.prototype.authentication;
66 repositoryManager =
67 ( builder.delta & Builder.REPOMAN ) != 0 ? builder.repositoryManager
68 : builder.prototype.repositoryManager;
69 mirroredRepositories =
70 ( builder.delta & Builder.MIRRORED ) != 0 ? copy( builder.mirroredRepositories )
71 : builder.prototype.mirroredRepositories;
72 }
73 else
74 {
75 id = builder.id;
76 type = builder.type;
77 url = builder.url;
78 releasePolicy = builder.releasePolicy;
79 snapshotPolicy = builder.snapshotPolicy;
80 proxy = builder.proxy;
81 authentication = builder.authentication;
82 repositoryManager = builder.repositoryManager;
83 mirroredRepositories = copy( builder.mirroredRepositories );
84 }
85
86 Matcher m = URL_PATTERN.matcher( url );
87 if ( m.matches() )
88 {
89 protocol = m.group( 1 );
90 String host = m.group( 5 );
91 this.host = ( host != null ) ? host : "";
92 }
93 else
94 {
95 protocol = host = "";
96 }
97 }
98
99 private static List<RemoteRepository> copy( List<RemoteRepository> repos )
100 {
101 if ( repos == null || repos.isEmpty() )
102 {
103 return Collections.emptyList();
104 }
105 return Collections.unmodifiableList( Arrays.asList( repos.toArray( new RemoteRepository[repos.size()] ) ) );
106 }
107
108 public String getId()
109 {
110 return id;
111 }
112
113 public String getContentType()
114 {
115 return type;
116 }
117
118 /**
119 * Gets the (base) URL of this repository.
120 *
121 * @return The (base) URL of this repository, never {@code null}.
122 */
123 public String getUrl()
124 {
125 return url;
126 }
127
128 /**
129 * Gets the protocol part from the repository's URL, for example {@code file} or {@code http}. As suggested by RFC
130 * 2396, section 3.1 "Scheme Component", the protocol name should be treated case-insensitively.
131 *
132 * @return The protocol or an empty string if none, never {@code null}.
133 */
134 public String getProtocol()
135 {
136 return protocol;
137 }
138
139 /**
140 * Gets the host part from the repository's URL.
141 *
142 * @return The host or an empty string if none, never {@code null}.
143 */
144 public String getHost()
145 {
146 return host;
147 }
148
149 /**
150 * Gets the policy to apply for snapshot/release artifacts.
151 *
152 * @param snapshot {@code true} to retrieve the snapshot policy, {@code false} to retrieve the release policy.
153 * @return The requested repository policy, never {@code null}.
154 */
155 public RepositoryPolicy getPolicy( boolean snapshot )
156 {
157 return snapshot ? snapshotPolicy : releasePolicy;
158 }
159
160 /**
161 * Gets the proxy that has been selected for this repository.
162 *
163 * @return The selected proxy or {@code null} if none.
164 */
165 public Proxy getProxy()
166 {
167 return proxy;
168 }
169
170 /**
171 * Gets the authentication that has been selected for this repository.
172 *
173 * @return The selected authentication or {@code null} if none.
174 */
175 public Authentication getAuthentication()
176 {
177 return authentication;
178 }
179
180 /**
181 * Gets the repositories that this repository serves as a mirror for.
182 *
183 * @return The (read-only) repositories being mirrored by this repository, never {@code null}.
184 */
185 public List<RemoteRepository> getMirroredRepositories()
186 {
187 return mirroredRepositories;
188 }
189
190 /**
191 * Indicates whether this repository refers to a repository manager or not.
192 *
193 * @return {@code true} if this repository is a repository manager, {@code false} otherwise.
194 */
195 public boolean isRepositoryManager()
196 {
197 return repositoryManager;
198 }
199
200 @Override
201 public String toString()
202 {
203 StringBuilder buffer = new StringBuilder( 256 );
204 buffer.append( getId() );
205 buffer.append( " (" ).append( getUrl() );
206 buffer.append( ", " ).append( getContentType() );
207 boolean r = getPolicy( false ).isEnabled(), s = getPolicy( true ).isEnabled();
208 if ( r && s )
209 {
210 buffer.append( ", releases+snapshots" );
211 }
212 else if ( r )
213 {
214 buffer.append( ", releases" );
215 }
216 else if ( s )
217 {
218 buffer.append( ", snapshots" );
219 }
220 else
221 {
222 buffer.append( ", disabled" );
223 }
224 if ( isRepositoryManager() )
225 {
226 buffer.append( ", managed" );
227 }
228 buffer.append( ")" );
229 return buffer.toString();
230 }
231
232 @Override
233 public boolean equals( Object obj )
234 {
235 if ( this == obj )
236 {
237 return true;
238 }
239 if ( obj == null || !getClass().equals( obj.getClass() ) )
240 {
241 return false;
242 }
243
244 RemoteRepository that = (RemoteRepository) obj;
245
246 return eq( url, that.url ) && eq( type, that.type ) && eq( id, that.id )
247 && eq( releasePolicy, that.releasePolicy ) && eq( snapshotPolicy, that.snapshotPolicy )
248 && eq( proxy, that.proxy ) && eq( authentication, that.authentication )
249 && eq( mirroredRepositories, that.mirroredRepositories ) && repositoryManager == that.repositoryManager;
250 }
251
252 private static <T> boolean eq( T s1, T s2 )
253 {
254 return s1 != null ? s1.equals( s2 ) : s2 == null;
255 }
256
257 @Override
258 public int hashCode()
259 {
260 int hash = 17;
261 hash = hash * 31 + hash( url );
262 hash = hash * 31 + hash( type );
263 hash = hash * 31 + hash( id );
264 hash = hash * 31 + hash( releasePolicy );
265 hash = hash * 31 + hash( snapshotPolicy );
266 hash = hash * 31 + hash( proxy );
267 hash = hash * 31 + hash( authentication );
268 hash = hash * 31 + hash( mirroredRepositories );
269 hash = hash * 31 + ( repositoryManager ? 1 : 0 );
270 return hash;
271 }
272
273 private static int hash( Object obj )
274 {
275 return obj != null ? obj.hashCode() : 0;
276 }
277
278 /**
279 * A builder to create remote repositories.
280 */
281 public static final class Builder
282 {
283
284 private static final RepositoryPolicy DEFAULT_POLICY = new RepositoryPolicy();
285
286 static final int ID = 0x0001, TYPE = 0x0002, URL = 0x0004, RELEASES = 0x0008, SNAPSHOTS = 0x0010,
287 PROXY = 0x0020, AUTH = 0x0040, MIRRORED = 0x0080, REPOMAN = 0x0100;
288
289 int delta;
290
291 RemoteRepository prototype;
292
293 String id;
294
295 String type;
296
297 String url;
298
299 RepositoryPolicy releasePolicy = DEFAULT_POLICY;
300
301 RepositoryPolicy snapshotPolicy = DEFAULT_POLICY;
302
303 Proxy proxy;
304
305 Authentication authentication;
306
307 List<RemoteRepository> mirroredRepositories;
308
309 boolean repositoryManager;
310
311 /**
312 * Creates a new repository builder.
313 *
314 * @param id The identifier of the repository, may be {@code null}.
315 * @param type The type of the repository, may be {@code null}.
316 * @param url The (base) URL of the repository, may be {@code null}.
317 */
318 public Builder( String id, String type, String url )
319 {
320 this.id = ( id != null ) ? id : "";
321 this.type = ( type != null ) ? type : "";
322 this.url = ( url != null ) ? url : "";
323 }
324
325 /**
326 * Creates a new repository builder which uses the specified remote repository as a prototype for the new one.
327 * All properties which have not been set on the builder will be copied from the prototype when building the
328 * repository.
329 *
330 * @param prototype The remote repository to use as prototype, must not be {@code null}.
331 */
332 public Builder( RemoteRepository prototype )
333 {
334 if ( prototype == null )
335 {
336 throw new IllegalArgumentException( "repository prototype missing" );
337 }
338 this.prototype = prototype;
339 }
340
341 /**
342 * Builds a new remote repository from the current values of this builder. The state of the builder itself
343 * remains unchanged.
344 *
345 * @return The remote repository, never {@code null}.
346 */
347 public RemoteRepository build()
348 {
349 if ( prototype != null && delta == 0 )
350 {
351 return prototype;
352 }
353 return new RemoteRepository( this );
354 }
355
356 private <T> void delta( int flag, T builder, T prototype )
357 {
358 boolean equal = ( builder != null ) ? builder.equals( prototype ) : prototype == null;
359 if ( equal )
360 {
361 delta &= ~flag;
362 }
363 else
364 {
365 delta |= flag;
366 }
367 }
368
369 /**
370 * Sets the identifier of the repository.
371 *
372 * @param id The identifier of the repository, may be {@code null}.
373 * @return This builder for chaining, never {@code null}.
374 */
375 public Builder setId( String id )
376 {
377 this.id = ( id != null ) ? id : "";
378 if ( prototype != null )
379 {
380 delta( ID, this.id, prototype.getId() );
381 }
382 return this;
383 }
384
385 /**
386 * Sets the type of the repository, e.g. "default".
387 *
388 * @param type The type of the repository, may be {@code null}.
389 * @return This builder for chaining, never {@code null}.
390 */
391 public Builder setContentType( String type )
392 {
393 this.type = ( type != null ) ? type : "";
394 if ( prototype != null )
395 {
396 delta( TYPE, this.type, prototype.getContentType() );
397 }
398 return this;
399 }
400
401 /**
402 * Sets the (base) URL of the repository.
403 *
404 * @param url The URL of the repository, may be {@code null}.
405 * @return This builder for chaining, never {@code null}.
406 */
407 public Builder setUrl( String url )
408 {
409 this.url = ( url != null ) ? url : "";
410 if ( prototype != null )
411 {
412 delta( URL, this.url, prototype.getUrl() );
413 }
414 return this;
415 }
416
417 /**
418 * Sets the policy to apply for snapshot and release artifacts.
419 *
420 * @param policy The repository policy to set, may be {@code null} to use a default policy.
421 * @return This builder for chaining, never {@code null}.
422 */
423 public Builder setPolicy( RepositoryPolicy policy )
424 {
425 this.releasePolicy = this.snapshotPolicy = ( policy != null ) ? policy : DEFAULT_POLICY;
426 if ( prototype != null )
427 {
428 delta( RELEASES, this.releasePolicy, prototype.getPolicy( false ) );
429 delta( SNAPSHOTS, this.snapshotPolicy, prototype.getPolicy( true ) );
430 }
431 return this;
432 }
433
434 /**
435 * Sets the policy to apply for release artifacts.
436 *
437 * @param releasePolicy The repository policy to set, may be {@code null} to use a default policy.
438 * @return This builder for chaining, never {@code null}.
439 */
440 public Builder setReleasePolicy( RepositoryPolicy releasePolicy )
441 {
442 this.releasePolicy = ( releasePolicy != null ) ? releasePolicy : DEFAULT_POLICY;
443 if ( prototype != null )
444 {
445 delta( RELEASES, this.releasePolicy, prototype.getPolicy( false ) );
446 }
447 return this;
448 }
449
450 /**
451 * Sets the policy to apply for snapshot artifacts.
452 *
453 * @param snapshotPolicy The repository policy to set, may be {@code null} to use a default policy.
454 * @return This builder for chaining, never {@code null}.
455 */
456 public Builder setSnapshotPolicy( RepositoryPolicy snapshotPolicy )
457 {
458 this.snapshotPolicy = ( snapshotPolicy != null ) ? snapshotPolicy : DEFAULT_POLICY;
459 if ( prototype != null )
460 {
461 delta( SNAPSHOTS, this.snapshotPolicy, prototype.getPolicy( true ) );
462 }
463 return this;
464 }
465
466 /**
467 * Sets the proxy to use in order to access the repository.
468 *
469 * @param proxy The proxy to use, may be {@code null}.
470 * @return This builder for chaining, never {@code null}.
471 */
472 public Builder setProxy( Proxy proxy )
473 {
474 this.proxy = proxy;
475 if ( prototype != null )
476 {
477 delta( PROXY, this.proxy, prototype.getProxy() );
478 }
479 return this;
480 }
481
482 /**
483 * Sets the authentication to use in order to access the repository.
484 *
485 * @param authentication The authentication to use, may be {@code null}.
486 * @return This builder for chaining, never {@code null}.
487 */
488 public Builder setAuthentication( Authentication authentication )
489 {
490 this.authentication = authentication;
491 if ( prototype != null )
492 {
493 delta( AUTH, this.authentication, prototype.getAuthentication() );
494 }
495 return this;
496 }
497
498 /**
499 * Sets the repositories being mirrored by the repository.
500 *
501 * @param mirroredRepositories The repositories being mirrored by the repository, may be {@code null}.
502 * @return This builder for chaining, never {@code null}.
503 */
504 public Builder setMirroredRepositories( List<RemoteRepository> mirroredRepositories )
505 {
506 if ( this.mirroredRepositories == null )
507 {
508 this.mirroredRepositories = new ArrayList<RemoteRepository>();
509 }
510 else
511 {
512 this.mirroredRepositories.clear();
513 }
514 if ( mirroredRepositories != null )
515 {
516 this.mirroredRepositories.addAll( mirroredRepositories );
517 }
518 if ( prototype != null )
519 {
520 delta( MIRRORED, this.mirroredRepositories, prototype.getMirroredRepositories() );
521 }
522 return this;
523 }
524
525 /**
526 * Adds the specified repository to the list of repositories being mirrored by the repository. If this builder
527 * was {@link #RemoteRepository.Builder(RemoteRepository) constructed from a prototype}, the given repository
528 * will be added to the list of mirrored repositories from the prototype.
529 *
530 * @param mirroredRepository The repository being mirrored by the repository, may be {@code null}.
531 * @return This builder for chaining, never {@code null}.
532 */
533 public Builder addMirroredRepository( RemoteRepository mirroredRepository )
534 {
535 if ( mirroredRepository != null )
536 {
537 if ( this.mirroredRepositories == null )
538 {
539 this.mirroredRepositories = new ArrayList<RemoteRepository>();
540 if ( prototype != null )
541 {
542 mirroredRepositories.addAll( prototype.getMirroredRepositories() );
543 }
544 }
545 mirroredRepositories.add( mirroredRepository );
546 if ( prototype != null )
547 {
548 delta |= MIRRORED;
549 }
550 }
551 return this;
552 }
553
554 /**
555 * Marks the repository as a repository manager or not.
556 *
557 * @param repositoryManager {@code true} if the repository points at a repository manager, {@code false} if the
558 * repository is just serving static contents.
559 * @return This builder for chaining, never {@code null}.
560 */
561 public Builder setRepositoryManager( boolean repositoryManager )
562 {
563 this.repositoryManager = repositoryManager;
564 if ( prototype != null )
565 {
566 delta( REPOMAN, this.repositoryManager, prototype.isRepositoryManager() );
567 }
568 return this;
569 }
570
571 }
572
573 }