// Path: src/main/java/jp/eisbahn/oauth2/server/models/ClientCredential.java
// public class ClientCredential {
// 
// 	private String clientId;
// 	private String clientSecret;
// 
// 	/**
// 	 * Initialize this instance with arguments.
// 	 * @param clientId The client ID.
// 	 * @param clientSecret The client secret string.
// 	 */
// 	public ClientCredential(String clientId, String clientSecret) {
// 		super();
// 		this.clientId = clientId;
// 		this.clientSecret = clientSecret;
// 	}
// 
// 	/**
// 	 * Retrieve the client ID.
// 	 * @return The client ID.
// 	 */
// 	public String getClientId() {
// 		return clientId;
// 	}
// 
// 	/**
// 	 * Retrieve the client secret.
// 	 * @return The client secret.
// 	 */
// 	public String getClientSecret() {
// 		return clientSecret;
// 	}
// 
// }
// 
// Path: src/main/java/jp/eisbahn/oauth2/server/models/Request.java
// public interface Request {
// 
// 	/**
// 	 * Retrieve the parameter value specified by the parameter name
// 	 * from the request.
// 	 * @param name The parameter name.
// 	 * @return The value against the name.
// 	 */
// 	public String getParameter(String name);
// 
// 	/**
// 	 * Retrieve all parameter names and values from the request as a Map instance.
// 	 * @return  The map instance which has all parameter names and values.
// 	 */
// 	public Map<String, String> getParameterMap();
// 	
// 	/**
// 	 * Retrieve the request header value from the request.
// 	 * @param name The header's name.
// 	 * @return The value against the name.
// 	 */
// 	public String getHeader(String name);
// 
// }
// 
// Path: src/main/java/jp/eisbahn/oauth2/server/utils/Util.java
// public class Util {
// 
// 	/**
// 	 * Decode the URL encoded string.
// 	 * @param source The URL encoded string.
// 	 * @return The decoded original string.
// 	 */
// 	public static String decodeParam(String source) {
// 		try {
// 			return URLDecoder.decode(source, "UTF-8");
// 		} catch (UnsupportedEncodingException e) {
// 			throw new IllegalStateException(e);
// 		}
// 	}
// 
// 	/**
// 	 * Decode the BASE64 encoded string.
// 	 * @param source The BASE64 string.
// 	 * @return The decoded original string.
// 	 */
// 	public static String decodeBase64(String source) {
// 		try {
// 			return new String(Base64.decodeBase64(source), "UTF-8");
// 		} catch (UnsupportedEncodingException e) {
// 			throw new IllegalStateException(e);
// 		}
// 	}
// 
// 	/**
// 	 * Encode the object to JSON format string.
// 	 * @param source The object that you want to change to JSON string.
// 	 * @return The JSON encoded string.
// 	 * @throws IllegalStateException If the translation failed.
// 	 */
// 	public static String toJson(Object source) {
// 		try {
// 			ObjectMapper mapper = new ObjectMapper();
// 			return mapper.writeValueAsString(source);
// 		} catch (JsonGenerationException e) {
// 			throw new IllegalStateException(e);
// 		} catch (JsonMappingException e) {
// 			throw new IllegalStateException(e);
// 		} catch (IOException e) {
// 			throw new IllegalStateException(e);
// 		}
// 	}
// 
// }


import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jp.eisbahn.oauth2.server.models.ClientCredential;
import jp.eisbahn.oauth2.server.models.Request;
import jp.eisbahn.oauth2.server.utils.Util;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package jp.eisbahn.oauth2.server.fetcher.clientcredential;



/**
 * This implementation provides a client credential information
 * from a request header or request parameters
 * 
 * @author Yoichiro Tanaka
 *
 */
public class ClientCredentialFetcherImpl implements ClientCredentialFetcher {

	private static final Pattern REGEXP_BASIC =
			Pattern.compile("^\\s*(Basic)\\s+(.*)$");

	/**
	 * Fetch a client credential sent from the client as a request header
	 * or request parameters. First, this method attempts to fetch it from
	 * the Authorization request header. For instance, it is expected as the
	 * format "Basic [Base64 encoded]". The encoded value actually has two
	 * parameter "Client ID" and "Client secret" delimited by ":" character.
	 * If it does not exist, this method attempt to fetch it from request
	 * parameter named "client_id" and "client_secret".
	 * 
	 * @param request The request object.
	 * @return The client credential information.
	 */
	@Override
	public ClientCredential fetch(Request request) {
		String header = request.getHeader("Authorization");
		if (header != null) {
			Matcher matcher = REGEXP_BASIC.matcher(header);
			if (matcher.find()) {
// Path: src/main/java/jp/eisbahn/oauth2/server/models/ClientCredential.java
// public class ClientCredential {
// 
// 	private String clientId;
// 	private String clientSecret;
// 
// 	/**
// 	 * Initialize this instance with arguments.
// 	 * @param clientId The client ID.
// 	 * @param clientSecret The client secret string.
// 	 */
// 	public ClientCredential(String clientId, String clientSecret) {
// 		super();
// 		this.clientId = clientId;
// 		this.clientSecret = clientSecret;
// 	}
// 
// 	/**
// 	 * Retrieve the client ID.
// 	 * @return The client ID.
// 	 */
// 	public String getClientId() {
// 		return clientId;
// 	}
// 
// 	/**
// 	 * Retrieve the client secret.
// 	 * @return The client secret.
// 	 */
// 	public String getClientSecret() {
// 		return clientSecret;
// 	}
// 
// }
// 
// Path: src/main/java/jp/eisbahn/oauth2/server/models/Request.java
// public interface Request {
// 
// 	/**
// 	 * Retrieve the parameter value specified by the parameter name
// 	 * from the request.
// 	 * @param name The parameter name.
// 	 * @return The value against the name.
// 	 */
// 	public String getParameter(String name);
// 
// 	/**
// 	 * Retrieve all parameter names and values from the request as a Map instance.
// 	 * @return  The map instance which has all parameter names and values.
// 	 */
// 	public Map<String, String> getParameterMap();
// 	
// 	/**
// 	 * Retrieve the request header value from the request.
// 	 * @param name The header's name.
// 	 * @return The value against the name.
// 	 */
// 	public String getHeader(String name);
// 
// }
// 
// Path: src/main/java/jp/eisbahn/oauth2/server/utils/Util.java
// public class Util {
// 
// 	/**
// 	 * Decode the URL encoded string.
// 	 * @param source The URL encoded string.
// 	 * @return The decoded original string.
// 	 */
// 	public static String decodeParam(String source) {
// 		try {
// 			return URLDecoder.decode(source, "UTF-8");
// 		} catch (UnsupportedEncodingException e) {
// 			throw new IllegalStateException(e);
// 		}
// 	}
// 
// 	/**
// 	 * Decode the BASE64 encoded string.
// 	 * @param source The BASE64 string.
// 	 * @return The decoded original string.
// 	 */
// 	public static String decodeBase64(String source) {
// 		try {
// 			return new String(Base64.decodeBase64(source), "UTF-8");
// 		} catch (UnsupportedEncodingException e) {
// 			throw new IllegalStateException(e);
// 		}
// 	}
// 
// 	/**
// 	 * Encode the object to JSON format string.
// 	 * @param source The object that you want to change to JSON string.
// 	 * @return The JSON encoded string.
// 	 * @throws IllegalStateException If the translation failed.
// 	 */
// 	public static String toJson(Object source) {
// 		try {
// 			ObjectMapper mapper = new ObjectMapper();
// 			return mapper.writeValueAsString(source);
// 		} catch (JsonGenerationException e) {
// 			throw new IllegalStateException(e);
// 		} catch (JsonMappingException e) {
// 			throw new IllegalStateException(e);
// 		} catch (IOException e) {
// 			throw new IllegalStateException(e);
// 		}
// 	}
// 
// }


// Path: src/main/java/jp/eisbahn/oauth2/server/fetcher/clientcredential/ClientCredentialFetcherImpl.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jp.eisbahn.oauth2.server.models.ClientCredential;
import jp.eisbahn.oauth2.server.models.Request;
import jp.eisbahn.oauth2.server.utils.Util;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */

package jp.eisbahn.oauth2.server.fetcher.clientcredential;



/**
 * This implementation provides a client credential information
 * from a request header or request parameters
 * 
 * @author Yoichiro Tanaka
 *
 */
public class ClientCredentialFetcherImpl implements ClientCredentialFetcher {

	private static final Pattern REGEXP_BASIC =
			Pattern.compile("^\\s*(Basic)\\s+(.*)$");

	/**
	 * Fetch a client credential sent from the client as a request header
	 * or request parameters. First, this method attempts to fetch it from
	 * the Authorization request header. For instance, it is expected as the
	 * format "Basic [Base64 encoded]". The encoded value actually has two
	 * parameter "Client ID" and "Client secret" delimited by ":" character.
	 * If it does not exist, this method attempt to fetch it from request
	 * parameter named "client_id" and "client_secret".
	 * 
	 * @param request The request object.
	 * @return The client credential information.
	 */
	@Override
	public ClientCredential fetch(Request request) {
		String header = request.getHeader("Authorization");
		if (header != null) {
			Matcher matcher = REGEXP_BASIC.matcher(header);
			if (matcher.find()) {
				String decoded = Util.decodeBase64(matcher.group(2));