/* * 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 org.apache.myfaces.trinidadinternal.agent; import java.util.Collections; import java.util.Map; import javax.faces.context.FacesContext; import org.apache.myfaces.trinidad.context.Agent; import org.apache.myfaces.trinidad.logging.TrinidadLogger; import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.TrinidadRenderingConstants; /** * Trinidad implementation of AgentFactory. */ public class AgentFactoryImpl implements AgentFactory { public Agent createAgent(Map headerMap) { // this method primarily exists for use during testing AgentImpl agent = new AgentImpl(); _populateAgentImpl(null, headerMap,agent); return agent; } @SuppressWarnings("unchecked") public Agent createAgent(FacesContext facesContext) { AgentImpl agent = new AgentImpl(); // Get the RequestHeaderMap to help populate the agent Map headerMap; if (facesContext != null) { headerMap = facesContext.getExternalContext().getRequestHeaderMap(); } else { headerMap = Collections.emptyMap(); } //TODO: Add declarative and extensible means for populating AgentImpl object // the RequestHeaderMap helps populate the agent _populateAgentImpl(facesContext, headerMap, agent); return agent; } // The headerMap is the RequestHeaderMap from the externalContext. It is // consulted to correctly populate the agent private void _populateAgentImpl( FacesContext facesContext, Map headerMap, AgentImpl agent) { String userAgent = headerMap.get("User-Agent"); String isEmail = null; if (facesContext != null) isEmail = facesContext.getExternalContext().getRequestParameterMap(). get(_EMAIL_PARAM); if ("true".equals(isEmail)) { _populateEmailAgentImpl(agent); return; } if ((userAgent != null) && userAgent.startsWith("PTG")) { _populateIaswAgentImpl(userAgent, headerMap.get(_IASW_DEVICE_HINT_PARAM),agent); return; } String accept = headerMap.get("Accept"); // See if the agent wants WML - if so, we're talking WAP. if ((accept != null) && accept.regionMatches(true, 0, "vnd.wap.wml", 0, 11)) { _populateWAPAgentImpl(agent); return; } if (userAgent == null) { _populateUnknownAgentImpl(null, agent); return; } //the useragent string for telnet and PDA design time will start with //OracleJDevMobile because in each of these cases we know we have an //exact match in the device repository for the agent name. This is //because the jdev design time and ITS runtime have access to the same //device repository as the Trinidad runtime //The PDA DT useragent string will be: OracleJDevMobile/PDA/[agentName] //The telnet DT and RT useragent string will be: //OracleJDevMobile/ITS/[agentName] if (userAgent.startsWith("OracleJDevMobile")) { _populateJDevMobileAgentImpl(userAgent,agent); return; } if (userAgent.startsWith("OracleITS")) { _populateTelnetAgentImpl(userAgent,agent); return; } if (userAgent.startsWith("Pixo-Browser")) { _populatePixoAgentImpl(userAgent,agent); return; } if (userAgent.startsWith("ICE Browser")) { _populateIceAgentImpl(userAgent,agent); return; } // Web Pro //userAgent = "Mozilla/4.76 (compatible; MSIE 6.0; U; Windows 95; PalmSource; PalmOS; WebPro; Tungsten Proxyless 1.1 320x320x16)"; if ( (userAgent.indexOf( "WebPro") != -1 && userAgent.indexOf("Palm")!= -1)|| userAgent.indexOf("Blazer/3.") != -1) { _populatePalmWebBrowserProAgentImpl(userAgent,agent); return; } /* //Commenting - Confirm this pattern fornBlazer before uncommenting //and remove the Blazer 3.0 check in the previous if if (((userAgent.indexOf("Blazer/4.") != -1) || (userAgent.indexOf("Blazer 3.") != -1)) && ((userAgent.indexOf("Palm") != -1))) { return _getPalmBlazerAgentEntry(userAgent); } */ //PPC 02 //userAgent = "Mozilla/2.0 (compatible; MSIE 3.02; Windows CE; PPC; 240x320)"; // PPC 03 //userAgent = "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"; if (userAgent.indexOf("Windows CE") != -1) { // for PocketPC and Windows Mobile, try to grab the header UA-pixels to // determine width/height String uaPixels = headerMap.get("UA-pixels"); _populatePocketPCAgentImpl(userAgent,uaPixels,agent); return; } // This needs to be before check for mozilla! if ((userAgent.indexOf("PalmOS") != -1) || (userAgent.indexOf("Blazer") != -1) || (userAgent.indexOf("Xiino") != -1)) { _populatePalmAgentImpl(userAgent,agent); return; } if ((userAgent.indexOf("AppleWebKit") != -1) || (userAgent.indexOf("Safari") != -1)) { _populateSafariAgentImpl(userAgent,agent); return; } if(userAgent.startsWith("BlackBerry")) { _populateBlackberryAgentImpl(userAgent,agent); return; } if (userAgent.indexOf("Opera") > -1) { _populateOperaAgentImpl(userAgent,agent); return; } // Generic Mobile Browser Detection // The user agent signature varies depending on the // device manufacturer and carrier. Use case insensitive // string matching. // Some of the browsers listed below support higher capabilities // than basic HTML browser capabilities. However, those browsers // are treated as basic HTML browser here for maximam compatibility // and performance. // We do not support WAP1.X browsers (WML). String userAgentLowercase = userAgent.toLowerCase(); if ((userAgentLowercase.indexOf("wap1.") < 0) && (userAgentLowercase.indexOf("wap2.") > -1 || userAgentLowercase.indexOf("up.browser") > -1 || userAgentLowercase.indexOf("nokia") > -1 || userAgentLowercase.startsWith("mot-") || userAgentLowercase.indexOf("symbian") > -1 || userAgentLowercase.indexOf("sonyeri") > -1 || userAgentLowercase.indexOf("netfront/") > -1 || userAgentLowercase.startsWith("samsang-") || userAgentLowercase.startsWith("lg-") || userAgentLowercase.indexOf("obigo") > -1|| userAgentLowercase.indexOf("vodafone") > -1 || userAgentLowercase.indexOf("kddi") > -1 || userAgentLowercase.indexOf("openwave") > -1)) { _populateGenericPDAAgentImpl(userAgent,agent); return; } // Gecko and Mozilla tests should be placed following more specific // uiser-agent test. if (userAgent.indexOf("Gecko/") != -1) { _populateGeckoAgentImpl(userAgent,agent); return; } // must check for gecko before checking for mozilla: else if (userAgent.startsWith("Mozilla")) { _populateMozillaAgentImpl(userAgent,agent); return; } _populateUnknownAgentImpl(userAgent, agent); } private void _populateGenericPDAAgentImpl(String userAgent, AgentImpl agent) { // Generic PDA browser agent.setType(Agent.TYPE_PDA); agent.setAgent(Agent.AGENT_GENERICPDA); agent.setAgentVersion("1"); // Version does not matter agent.setPlatform(Agent.PLATFORM_GENERICPDA); } private void _populateUnknownAgentImpl(String userAgent, AgentImpl agent) { // Log warning message that we are setting the agent entry to unknown attributes _LOG.warning("UNKNOWN_AGENT_ATTRIBUTES_CREATE_WITH_UNKNOWN", userAgent); agent.setAgentEntryToNULL(); } //populates the agent entry for DT access for either Telnet or PDA //for jdev mobile there are two user agent strings possible: //1. OracleJDevMobile_PDA(DeviceName:[name of device]) //2. OracleJDevMobile_ITS(DeviceName:[name of device]) private void _populateJDevMobileAgentImpl(String agent,AgentImpl agentObj) { //the form of JDEVMobile user agent string will be: //OracleJDevMobile_[PDA or ITS]/[version](DeviceName:[device name];[capability1]:[capability 1 value];...) boolean returnUnknownAgentObj = false; int itsIndex = agent.indexOf("ITS"); int pdaIndex = agent.indexOf("PDA"); int versionStartIndex = -1; if (itsIndex > -1) { agentObj.setType(Agent.TYPE_TELNET); versionStartIndex = "OracleJDevMobile_ITS".length()+1; } else if (pdaIndex > -1) { agentObj.setType(Agent.TYPE_PDA); versionStartIndex = "OracleJDevMobile_PDA".length()+1; } else { returnUnknownAgentObj = true; } //Now find the name of the device if (!returnUnknownAgentObj){ int versionEndIndex = agent.indexOf("("); String version = agent.substring(versionStartIndex,versionEndIndex); agentObj.setAgentVersion(version); //parse agentName int agentNameStartIndex = agent.indexOf(":",versionEndIndex) +1; //find end of agentName (ie. when we see a semicolon int agentNameEndIndex = agentNameStartIndex; for (;agent.charAt(agentNameEndIndex)!=';' && agent.charAt(agentNameEndIndex) !=')'; agentNameEndIndex++); String agentName = agent.substring(agentNameStartIndex,agentNameEndIndex); agentObj.setAgent(agentName); if (agent.charAt(agentNameEndIndex) == ')') return; //now parse remaining request specific capabilities int capabilityNameStartIndex; int capabilityNameEndIndex; int capabilityValueStartIndex; int capabilityValueEndIndex = agentNameEndIndex; while(agent.charAt(capabilityValueEndIndex)!= ')') { capabilityNameStartIndex = capabilityValueEndIndex + 1; capabilityNameEndIndex = agent.indexOf(":",capabilityNameStartIndex); String capabilityName = agent.substring(capabilityNameStartIndex,capabilityNameEndIndex); capabilityValueStartIndex = capabilityNameEndIndex +1; capabilityValueEndIndex = agent.indexOf(";",capabilityValueStartIndex); if (capabilityValueEndIndex == -1) { capabilityValueEndIndex = agent.indexOf(")",capabilityValueEndIndex); } String capabilityValue = agent.substring(capabilityValueStartIndex,capabilityValueEndIndex); agentObj.__addRequestCapability(CapabilityKey.getCapabilityKey(capabilityName,true),capabilityValue); } } if (returnUnknownAgentObj) { _populateUnknownAgentImpl(agent, agentObj); } } private void _populateTelnetAgentImpl(String agent,AgentImpl agentObj) { //the form of an ITS user agent will be //OracleITS/[version](DeviceName:[device name];[capability1]:[capability 1 value];...) agentObj.setType(Agent.TYPE_TELNET); int versionStartIndex = "OracleITS".length() +1; int versionEndIndex = agent.indexOf("("); String version = agent.substring(versionStartIndex,versionEndIndex); agentObj.setAgentVersion(version); //parse agentName int agentNameStartIndex = agent.indexOf(":",versionEndIndex) +1; //find end of agentName (ie. when we see a semicolon int agentNameEndIndex = agentNameStartIndex; for (;agent.charAt(agentNameEndIndex)!=';' && agent.charAt(agentNameEndIndex) !=')'; agentNameEndIndex++); String agentName = agent.substring(agentNameStartIndex,agentNameEndIndex); agentObj.setAgent(agentName); if (agent.charAt(agentNameEndIndex) == ')') return; //now parse remaining request specific capabilities int capabilityNameStartIndex; int capabilityNameEndIndex; int capabilityValueStartIndex; int capabilityValueEndIndex = agentNameEndIndex; while(agent.charAt(capabilityValueEndIndex)!= ')') { capabilityNameStartIndex = capabilityValueEndIndex + 1; capabilityNameEndIndex = agent.indexOf(":",capabilityNameStartIndex); String capabilityName = agent.substring(capabilityNameStartIndex,capabilityNameEndIndex); capabilityValueStartIndex = capabilityNameEndIndex +1; capabilityValueEndIndex = agent.indexOf(";",capabilityValueStartIndex); if (capabilityValueEndIndex == -1) { capabilityValueEndIndex = agent.indexOf(")",capabilityValueEndIndex); } String capabilityValue = agent.substring(capabilityValueStartIndex,capabilityValueEndIndex); agentObj.__addRequestCapability(CapabilityKey.getCapabilityKey(capabilityName,true),capabilityValue); } } /** * populates data from a PocketPC IE request */ private void _populatePocketPCAgentImpl(String agent,String uaPixels,AgentImpl agentObj) { int start = agent.indexOf("MSIE"); String version = null; if (start > -1) { version = _getVersion(agent, start + "MSIE".length()); } agentObj.setType(Agent.TYPE_PDA); agentObj.setAgent(Agent.AGENT_IE); agentObj.setAgentVersion(version); agentObj.setPlatform(Agent.PLATFORM_PPC); boolean narrowScreenDevice = false; if(uaPixels != null && uaPixels.length() > 0) { // UA-pixels is defined as x // UA-pixels was proposed here // http://www.watersprings.org/pub/id/draft-mutz-http-attributes-00.txt // and it is used by Pocket IE and IE Mobile; see // http://blogs.msdn.com/iemobile/archive/2006/08/03/Detecting_IE_Mobile.aspx Integer width = null; Integer height = null; String[] parts = uaPixels.split("x"); if(parts.length == 2) { try { width = new Integer(parts[0]); height = new Integer(parts[1]); } catch(NumberFormatException ex) { _LOG.fine(ex); } } if(width != null && height != null) { agentObj.__addRequestCapability(TrinidadAgent.CAP_WIDTH,width); agentObj.__addRequestCapability(TrinidadAgent.CAP_HEIGHT,height); if (width.intValue() < TrinidadRenderingConstants.NARROW_SCREEN_PDA_MAX_WIDTH) { narrowScreenDevice = true; } } else { _LOG.fine("When creating the Agent, the UA-pixels value \"{0}\" could not be parsed.", uaPixels); } } else { narrowScreenDevice = true; } if (narrowScreenDevice) { agentObj.__addRequestCapability(TrinidadAgent.CAP_NARROW_SCREEN, Boolean.TRUE); } else { agentObj.__addRequestCapability(TrinidadAgent.CAP_NARROW_SCREEN, Boolean.FALSE); } } /** * populates data from a Blackberry browser request */ private void _populateBlackberryAgentImpl(String agent,AgentImpl agentObj) { // the User-Agent string for the BlackBerry Browser starts with // BlackBerry/ where is the BlackBerry // model, e.g. for the BlackBerry browser 4.1.0 on // the BlackBerry 8700 device, the User-Agent string begins with // BlackBerry8700/4.1.0 int start = agent.indexOf("BlackBerry"); String version = null; String makeModel = null; if (start > -1) { // find the first /, which occurs before the version number int slashLoc = agent.indexOf('/',start); if(slashLoc > -1) { // see the note above about how the User-Agent starts with // BlackBerry/; this returns the // BlackBerry (e.g. BlackBerry8700), which we will // use as the Agent hardwareMakeModel makeModel = agent.substring(start,slashLoc); // _getVersion assumes the location of the slash is passed in, // and starts looking for the version at the NEXT character version = _getVersion(agent, slashLoc); } } // note that the agent and platform are both BLACKBERRY // this is because it is the BlackBerry Browser running on the // BlackBerry device agentObj.setType(Agent.TYPE_PDA); agentObj.setAgent(Agent.AGENT_BLACKBERRY); agentObj.setAgentVersion(version); agentObj.setPlatform(Agent.PLATFORM_BLACKBERRY); agentObj.setMakeModel(makeModel); // Most of BlackBerry devices' widths are more than 240px, so // don't consider BlackBerry as a narrow-screen PDA. agentObj.__addRequestCapability(TrinidadAgent.CAP_NARROW_SCREEN, Boolean.FALSE); } /** * returns the data for the Palm Web Pro browser request */ private void _populatePalmWebBrowserProAgentImpl(String agent,AgentImpl agentObj) { agentObj.setType(Agent.TYPE_PDA); agentObj.setAgent(TrinidadAgent.AGENT_WEBPRO); int start = agent.indexOf("WebPro/"); if (start > -1) { agentObj.setAgentVersion(_getVersion(agent, start + 6)); } agentObj.setPlatform(Agent.PLATFORM_PALM); } /** * returns the data for the Palm blazer browser request */ /* //comment for now private AgentEntry _getPalmBlazerAgentEntry(String agent) { AgentEntry entry = new AgentEntry(); entry._type = TYPE_PDA; entry._agent = AdfFacesAgent.AGENT_BLAZER; //balzer 3 has "Blazer 3..." and 4.0 has Blazer 4/.... int start = agent.indexOf("Blazer"); if (start > -1) { entry._agentVersion = _getVersion(agent, start + 6); } entry._platform = Agent.PLATFORM_PALM; return entry; } */ /** * returns the AgentEntry for ias wireless */ private void _populateIaswAgentImpl(String agent, String wirelessType,AgentImpl agentObj) { // map device hint to agent type if (wirelessType == null) { _populateUnknownAgentImpl(agent, agentObj); return; } String version = _getVersion(agent, agent.indexOf('/')); agentObj.setType(Agent.TYPE_PHONE); agentObj.setAgent(TrinidadAgent.AGENT_PTG); agentObj.setAgentVersion(version); } /** * returns the AgentEntry for the Palm */ private void _populatePalmAgentImpl(String userAgent,AgentImpl agentObj) { agentObj.setType(Agent.TYPE_PDA); if (userAgent.indexOf("Blazer") != -1) agentObj.setAgent(TrinidadAgent.AGENT_BLAZER); else if (userAgent.indexOf("Xiino") != -1) agentObj.setAgent(TrinidadAgent.AGENT_XIINO); agentObj.setPlatform(Agent.PLATFORM_PALM); } /** * returns the AgentEntry for the Ice brwoser */ private void _populateIceAgentImpl(String agent,AgentImpl agentObj) { int slashIndex = agent.indexOf('/'); agentObj.setType(Agent.TYPE_DESKTOP); agentObj.setAgent(TrinidadAgent.AGENT_ICE_BROWSER); agentObj.setAgentVersion(_getVersion(agent, slashIndex)); agentObj.setPlatform(_getJavaOS(agent, slashIndex)); } /** * returns the AgentEntry for the Pixo Microbrowser */ private void _populatePixoAgentImpl(String agent,AgentImpl agentObj) { agentObj.setType(Agent.TYPE_PHONE); agentObj.setAgent(TrinidadAgent.AGENT_PIXO); agentObj.setAgentVersion(_getVersion(agent, agent.indexOf('/'))); } /** * Returns an AgentEntry for a WML client. */ private void _populateWAPAgentImpl(AgentImpl agentObj) { //TODO: Add generic wmlbrowser when wml browsers are supported // Generic WML support agentObj.setType(Agent.TYPE_PHONE); } /** * Returns an AgentEntry for the browsers that use the Gecko Layout Engine. */ private void _populateGeckoAgentImpl(String agent,AgentImpl agentObj) { //Identifying an Gecko Based agent as Gecko (and not Mozilla, Netscape, Firefox) //could be an issue //E.g User-Agent String //Mozilla/5.0 (Windows; U; Win 9x 4.90; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0 //For Gecko based agents // - Gecko uses Date string as a version number // - Mozilla uses the revision number as the version number rv:x.x.x // - Each vendor has a version number (like firefox/1.0, Netscape/7.0) // Mozilla revision : Gecko Version // 1.0.1 : 20020826 // 1.1 : 20020826 // 1.2.1 : 20021130 //Currently (in UIX 2.2 base agent Impl) // - All Gecko Based agents are identified as Gecko // - But PPR capability is determined is based on the Mozilla version number (rv:x.x.x) // - For Major version , for Gecko, always "1" is returned //so stricly speaking all capabilities are not based on the layout engine. //New Impl. // - Still using Gecko as the identifier for all gecko based agents // - Still returning date string as version number of Gecko. But this can get messy to use // by the applications. The version number could change everyday and may not be the same for // different platforms. (An alternate option is to return version number of Mozilla // that would be equivalent to current browser for Gecko-based browsers) // - But assumes PPR Support in all Gecko versions. //Change 2008-05-13: // We need the rv to support @agent versioning in CSS as the date makes no sense, // so look for the rv:, not the Gecko build date agentObj.setType(Agent.TYPE_DESKTOP); agentObj.setAgent(Agent.AGENT_GECKO); int start = agent.indexOf("rv:"); if (start >= 0) { agentObj.setAgentVersion(_getVersion(agent, start + 2)); } else { int geckoIndex = agent.indexOf("Gecko/"); agentObj.setAgentVersion(agent.substring(geckoIndex+6, // skip over 'Gecko/' geckoIndex+14)); // always 8 chars length } int paren = agent.indexOf('('); if (paren >= 0) { // try to determine the OS if (agent.indexOf("Win", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_WINDOWS); } else if (agent.indexOf("Mac", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_MACOS); } else if (agent.indexOf("Linux", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_LINUX); } else if (agent.indexOf("Sun", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_SOLARIS); } } } /** * Returns an AgentEntry for the Opera browser. */ private void _populateOperaAgentImpl(String agent,AgentImpl agentObj) { int start = agent.indexOf("Opera Mini"); if (start > -1) { // Opera Mini supports JavaScript. However, generic PDA capability // will be assigned to maximize the compatibility until fully certified. start = agent.indexOf('/', start); String version = _getVersion(agent, start); agentObj.setAgentVersion(version); agentObj.setType(Agent.TYPE_PDA); agentObj.setAgent(Agent.AGENT_GENERICPDA); agentObj.setPlatform(Agent.PLATFORM_GENERICPDA); } // For performance reasons, consider Opera Mobile as a generic PDA-browser // so just return. It will be handle by _populateGenricPDAImpl(). else if (agent.indexOf("MOT-") != -1 || agent.indexOf("Nokia") != -1) { return; } else { agentObj.setType(Agent.TYPE_DESKTOP); agentObj.setAgent(Agent.AGENT_OPERA); int operaIndex = agent.indexOf("Opera/"); int firstSpace = agent.indexOf(" "); // Opera Mobile running in HTC if (agent.indexOf("HTC-") != -1 || agent.indexOf("HTC_") != -1 || agent.indexOf("XV6850") != -1) { firstSpace = agent.indexOf(" ", operaIndex); } if (operaIndex >= 0 && firstSpace >=0 ) { agentObj.setAgentVersion(agent.substring(operaIndex + 6,firstSpace)); } int paren = agent.indexOf('('); if (paren >= 0) { // try to determine the OS if (agent.indexOf("Win", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_WINDOWS); } else if (agent.indexOf("Mac", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_MACOS); } else if (agent.indexOf("Linux", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_LINUX); } else if (agent.indexOf("Sun", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_SOLARIS); } } } } /** * returns the AgentEntry for Safari */ private void _populateSafariAgentImpl(String agent, AgentImpl agentObj) { int start = agent.indexOf("AppleWebKit"); if (start < 0) { start = agent.indexOf("Safari"); } if (start >= 0) { start = agent.indexOf('/', start); } if (agent.indexOf("iPhone") > 0) { // iPhone is a member of the iOS platform: agentObj.setPlatform(Agent.PLATFORM_IPHONE); } else if (agent.indexOf("iPad") > 0) { // iPad is a member of the iOS platform: agentObj.setPlatform(Agent.PLATFORM_IPHONE); } else if (agent.indexOf("iPod") > 0) { // iPod is a member of the iOS platform: agentObj.setPlatform(Agent.PLATFORM_IPHONE); } else if (agent.indexOf("Win") > 0) { // At the moment, this includes Safari and Google Chrome agentObj.setPlatform(Agent.PLATFORM_WINDOWS); } else if (agent.indexOf("Linux") > 0) { // At the moment, this includes Android agentObj.setPlatform(Agent.PLATFORM_LINUX); } else if (agent.indexOf("Mac") > 0) { // At the moment, this includes Safari agentObj.setPlatform(Agent.PLATFORM_MACOS); } String version = _getVersion(agent, start); agentObj.setType(Agent.TYPE_DESKTOP); if ((agent.indexOf("Symbian") > -1) || (agent.indexOf("Nokia") > -1)) { agentObj.setAgent(Agent.AGENT_NOKIA_S60); agentObj.setPlatform(Agent.AGENT_NOKIA_S60); } else { agentObj.setAgent(Agent.AGENT_WEBKIT); } agentObj.setAgentVersion(version); } /** * Returns an AgentEntry for the "Mozilla" family of browsers - which * most at least pretend to be. */ private void _populateMozillaAgentImpl(String agent,AgentImpl agentObj) { int ieTridentIndex = -1; int paren = agent.indexOf('('); agentObj.setType(Agent.TYPE_DESKTOP); //Is this default realli okay??? These days Mobile agents also use Mozilla/xx.xx // No section to qualify the agent; assume Mozilla/Netscape if (paren == -1) { agentObj.setAgent(TrinidadAgent.AGENT_NETSCAPE); agentObj.setAgentVersion(_getVersion(agent, agent.indexOf('/'))); } else { paren = paren + 1; boolean isJDevVE = agent.indexOf("JDeveloper", paren) > 0; boolean isJDevJSVE = agent.indexOf("JDeveloper JS", paren) > 0; if (agent.indexOf("Konqueror", paren) >= 0) { agentObj.setType(Agent.TYPE_DESKTOP); agentObj.setAgent(Agent.AGENT_KONQUEROR); agentObj.setAgentVersion(_getVersion(agent, agent.lastIndexOf('/'))); } else if ((ieTridentIndex = agent.indexOf("Trident", paren)) > -1) { agentObj.setAgent(Agent.AGENT_IE); // As of IE8, the Trident version is the most reliable method to find the // maximum capabilities of IE. The IE WebBrowser Control by default is in IE7 // compatability - MSIE 7.0; // As of IE11, the "MSIE" token no loger exists. //Trident/4.0 -> IE8 //Trident/5.0 -> IE9 //Trident/6.0 -> IE10 //Trident/7.0 -> IE11 Double ieTridentVersion = Double.valueOf(_getVersion(agent, ieTridentIndex + "Trident/".length() - 1)); agentObj.setAgentVersion(String.valueOf(ieTridentVersion + 4.0)); } else if (agent.startsWith("compatible", paren)) { int ieIndex = agent.indexOf("MSIE", paren); if (ieIndex < 0) { // check for Palm int palmIndex = agent.indexOf("Elaine", paren); if (palmIndex > 0) { agentObj.setType(Agent.TYPE_PDA); agentObj.setAgent(TrinidadAgent.AGENT_ELAINE); agentObj.setAgentVersion(_getVersion(agent, palmIndex)); agentObj.setPlatform(Agent.PLATFORM_PALM); } } else { agentObj.setAgent(Agent.AGENT_IE); agentObj.setAgentVersion(_getVersion(agent, ieIndex + 4)); } } else { agentObj.setAgent(TrinidadAgent.AGENT_NETSCAPE); agentObj.setAgentVersion(_getVersion(agent, agent.indexOf('/'))); } // try to determine the OS, if unknown if (agentObj.getPlatformName() == null || agentObj.getPlatformName().equals(Agent.PLATFORM_UNKNOWN)) { // Hack: treat the JDeveloper agent as Windows, // so that we assume IE 6.0 Windows capabilities if ((agent.indexOf("Win", paren) > 0) || isJDevVE) { agentObj.setPlatform(Agent.PLATFORM_WINDOWS); } else if (agent.indexOf("Mac", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_MACOS); } else if (agent.indexOf("Linux", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_LINUX); } else if (agent.indexOf("Sun", paren) > 0) { agentObj.setPlatform(Agent.PLATFORM_SOLARIS); } } if (isJDevVE) { agentObj.__addRequestCapability(TrinidadAgent.CAP_IS_JDEV_VE, Boolean.TRUE); if (isJDevJSVE) { agentObj.__addRequestCapability(TrinidadAgent.CAP_IS_JDEV_JAVASCRIPT_VE, Boolean.TRUE); } } } } /** * Returns an AgentEntry for the email agents like Outlook 2007 and * Thunderbird */ private void _populateEmailAgentImpl(AgentImpl agentObj) { agentObj.setType(Agent.TYPE_DESKTOP); agentObj.setAgent(Agent.AGENT_EMAIL); agentObj.setAgentVersion("0.0"); agentObj.setPlatform(Agent.AGENT_UNKNOWN); agentObj.setPlatformVersion(Agent.PLATFORM_VERSION_UNKNOWN); agentObj.setMakeModel(Agent.MAKE_MODEL_UNKNOWN); } /** * Returns the version contained within a string starting * at a certain location. The version will contain only numeric * parts separated by dots (.). * @param base the string to pull the version from * @param start the index of the character BEFORE the version * @return the version string */ private String _getVersion(String base, int start) { // start should be the character BEFORE the version portion // (typically a slash character after the agent name) if (start < 0) { return null; } int end = base.length(); start = start + 1; for (int i = start; i < end; i++) { // Find the last non-numeric character; that'll // mark the end of the version char ch = base.charAt(i); if ((ch != '.') && ((ch < '0') || (ch > '9'))) { return base.substring(start, i); } } return base.substring(start); } /** * Parse the OS string returned from java.System. *

* Currently, only checks for Windows */ private String _getJavaOS(String base, int start) { if (start < 0) { return null; } // check for Windows if (base.regionMatches(start, "Windows", 0, base.length() - start)) { return Agent.PLATFORM_WINDOWS; } return null; } static private final String _EMAIL_PARAM = "org.apache.myfaces.trinidad.agent.email"; static final private String _IASW_DEVICE_HINT_PARAM = "X-Oracle-Device.Class"; static final private TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(AgentFactoryImpl.class); }