001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027package org.apache.http.impl.client; 028 029import java.util.Map; 030import java.util.concurrent.ConcurrentHashMap; 031 032import org.apache.http.annotation.Contract; 033import org.apache.http.annotation.ThreadingBehavior; 034import org.apache.http.auth.AuthScope; 035import org.apache.http.auth.Credentials; 036import org.apache.http.client.CredentialsProvider; 037import org.apache.http.util.Args; 038 039/** 040 * Default implementation of {@link CredentialsProvider}. 041 * 042 * @since 4.0 043 */ 044@Contract(threading = ThreadingBehavior.SAFE) 045public class BasicCredentialsProvider implements CredentialsProvider { 046 047 private final ConcurrentHashMap<AuthScope, Credentials> credMap; 048 049 /** 050 * Default constructor. 051 */ 052 public BasicCredentialsProvider() { 053 super(); 054 this.credMap = new ConcurrentHashMap<AuthScope, Credentials>(); 055 } 056 057 @Override 058 public void setCredentials( 059 final AuthScope authscope, 060 final Credentials credentials) { 061 Args.notNull(authscope, "Authentication scope"); 062 credMap.put(authscope, credentials); 063 } 064 065 /** 066 * Find matching {@link Credentials credentials} for the given authentication scope. 067 * 068 * @param map the credentials hash map 069 * @param authscope the {@link AuthScope authentication scope} 070 * @return the credentials 071 * 072 */ 073 private static Credentials matchCredentials( 074 final Map<AuthScope, Credentials> map, 075 final AuthScope authscope) { 076 // see if we get a direct hit 077 Credentials creds = map.get(authscope); 078 if (creds == null) { 079 // Nope. 080 // Do a full scan 081 int bestMatchFactor = -1; 082 AuthScope bestMatch = null; 083 for (final AuthScope current: map.keySet()) { 084 final int factor = authscope.match(current); 085 if (factor > bestMatchFactor) { 086 bestMatchFactor = factor; 087 bestMatch = current; 088 } 089 } 090 if (bestMatch != null) { 091 creds = map.get(bestMatch); 092 } 093 } 094 return creds; 095 } 096 097 @Override 098 public Credentials getCredentials(final AuthScope authscope) { 099 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}