fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/**
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the Common Development and Distribution License
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (the License). You may not use this file except in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the License at
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * https://opensso.dev.java.net/public/CDDLv1.0.html or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * opensso/legal/CDDLv1.0.txt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * permission and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Header Notice in each file and include the License file
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * at opensso/legal/CDDLv1.0.txt.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below the CDDL Header,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * with the fields enclosed by brackets [] replaced by
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * your own identifying information:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * "Portions Copyrighted [year] [name of copyright owner]"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * $Id: ClientDetectionDefaultImpl.java,v 1.5 2008/06/25 05:41:32 qcheng Exp $
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortepackage com.iplanet.services.cdm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteimport com.iplanet.am.util.AMClientDetector;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteimport com.sun.identity.shared.debug.Debug;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteimport java.util.Iterator;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteimport javax.servlet.http.HttpServletRequest;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/**
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The <code>ClientDetectionInterface</code> interface needs to be implemented
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by services and applications serving multiple clients, to determine the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * client from which the request has originated. This interface detects the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * client type from the client request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * @supported.all.api
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortepublic class ClientDetectionDefaultImpl implements ClientDetectionInterface {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protected static Debug debug = Debug.getInstance("amClientDetection");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protected static DefaultClientTypesManager defCTM =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (DefaultClientTypesManager)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte AMClientDetector.getClientTypesManagerInstance();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
/**
* Creates a client detection default implementation instance.
*/
public ClientDetectionDefaultImpl() {
}
/**
* This is the method used by the interface to set the client-type.
* <code>ClientDetectionDefaultImpl</code> currently uses the following
* algorithm.
*
* <pre>
* if userAgent equals a known user-agent then
* compare userAgent length and store the longest match
* if clientType not found
* return the default clientType
* </pre>
*
* @param request
* The calling object passes in the
* <code>HTTPServletRequest</code>.
* @return The string corresponding to the client type.
* @throws ClientDetectionException
* if a default client type cannot be found
*/
public String getClientType(HttpServletRequest request)
throws ClientDetectionException {
String httpUA = request.getHeader("user-agent");
String clientType = null;
int prevClientUALen = 0;
if (debug.messageEnabled()) {
debug.message("UserAgent : httpUA is : " + httpUA);
debug.message("Looking in UA/PartialMatch Maps");
}
Client clientInstance = null;
if ((clientInstance = defCTM.getFromUserAgentMap(httpUA)) != null) {
//
// Perf: We wont have to iterate thro' all clients
//
clientType = clientInstance.getClientType();
if (debug.messageEnabled()) {
debug.message("Perf: from UA Map: " + clientType);
}
return clientType;
} else
if ((clientType = defCTM.getPartiallyMatchedClient(httpUA)) != null)
{
if (debug.messageEnabled()) {
debug.message("Perf: from PartialMatch Map: " + clientType);
}
return clientType;
}
// Iterate through Clients, find and save the longest match
int i = 0;
Iterator knownClients = ClientsManager.getAllInstances();
while (knownClients.hasNext()) {
clientInstance = (Client) knownClients.next();
i++;
String curClientUA = clientInstance.getProperty("userAgent");
if (curClientUA != null) {
if (debug.messageEnabled()) {
debug.message("(" + i + ") Client user-agent = "
+ curClientUA + " :: clientType = "
+ clientInstance.getClientType());
}
if (userAgentCheck(httpUA, curClientUA)) {
// We have a match
String curClientType = clientInstance
.getProperty("clientType");
// Check length
int curClientUALen = curClientUA.length();
if (curClientUALen > prevClientUALen) {
clientType = curClientType;
prevClientUALen = curClientUALen;
if (debug.messageEnabled()) {
debug.message("Longest user-agent match client " +
"type = " + clientType);
}
}
}
}
}
// If we don't have a single match, get the default clientType
if (clientType == null) {
clientType = Client.getDefaultInstance().getProperty("clientType");
if (debug.messageEnabled()) {
debug.message("Default client type = " + clientType);
}
} else {
//
// Found a partial map - add it so our Map,
// so our next search is faster
//
defCTM.addToPartialMatchMap(httpUA, clientType);
}
// If we can't get the default clientType
if (clientType == null) {
debug.message("Unable to obtain default client type");
throw new ClientDetectionException(CDMBundle
.getString("null_clientType"));
}
if (debug.messageEnabled()) {
debug.message("Returning client type : " + clientType);
}
return clientType;
}
/**
* This method contains the algorithm used to compare the
* <CODE>HTTPServletRequest</CODE>
* user-agent versus the <CODE>Client</CODE> user-agent.
*
* @param httpUA
* The HTTPServletRequest user-agent
* @param clientUA
* The Client userAgent
* @return True or false if they match
*/
protected boolean userAgentCheck(String httpUA, String clientUA) {
if ((httpUA == null) || (clientUA == null)) {
return false;
}
if ((httpUA.equalsIgnoreCase(clientUA))
|| (httpUA.indexOf(clientUA) > -1)) {
return true;
} else {
return false;
}
}
}