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;
28
29 import java.util.Map;
30 import java.util.concurrent.ConcurrentHashMap;
31
32 import org.apache.http.annotation.Contract;
33 import org.apache.http.annotation.ThreadingBehavior;
34 import org.apache.http.auth.AuthScope;
35 import org.apache.http.auth.Credentials;
36 import org.apache.http.client.CredentialsProvider;
37 import org.apache.http.util.Args;
38
39 /**
40  * Default implementation of {@link CredentialsProvider}.
41  *
42  * @since 4.0
43  */

44 @Contract(threading = ThreadingBehavior.SAFE)
45 public class BasicCredentialsProvider implements CredentialsProvider {
46
47     private final ConcurrentHashMap<AuthScope, Credentials> credMap;
48
49     /**
50      * Default constructor.
51      */

52     public BasicCredentialsProvider() {
53         super();
54         this.credMap = new ConcurrentHashMap<AuthScope, Credentials>();
55     }
56
57     @Override
58     public void setCredentials(
59             final AuthScope authscope,
60             final Credentials credentials) {
61         Args.notNull(authscope, "Authentication scope");
62         credMap.put(authscope, credentials);
63     }
64
65     /**
66      * Find matching {@link Credentials credentials} for the given authentication scope.
67      *
68      * @param map the credentials hash map
69      * @param authscope the {@link AuthScope authentication scope}
70      * @return the credentials
71      *
72      */

73     private static Credentials matchCredentials(
74             final Map<AuthScope, Credentials> map,
75             final AuthScope authscope) {
76         // see if we get a direct hit
77         Credentials creds = map.get(authscope);
78         if (creds == null) {
79             // Nope.
80             // Do a full scan
81             int bestMatchFactor  = -1;
82             AuthScope bestMatch  = null;
83             for (final AuthScope current: map.keySet()) {
84                 final int factor = authscope.match(current);
85                 if (factor > bestMatchFactor) {
86                     bestMatchFactor = factor;
87                     bestMatch = current;
88                 }
89             }
90             if (bestMatch != null) {
91                 creds = map.get(bestMatch);
92             }
93         }
94         return creds;
95     }
96
97     @Override
98     public Credentials getCredentials(final AuthScope authscope) {
99         Args.notNull(authscope, "Authentication scope");
100         return matchCredentials(this.credMap, authscope);
101     }
102
103     @Override
104     public void clear() {
105         this.credMap.clear();
106     }
107
108     @Override
109     public String toString() {
110         return credMap.toString();
111     }
112
113 }
114