You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ck...@apache.org on 2009/09/30 20:54:22 UTC
svn commit: r820386 [1/2] - in /myfaces/commons/trunk: ./
myfaces-commons-agent/ myfaces-commons-agent/src/
myfaces-commons-agent/src/main/ myfaces-commons-agent/src/main/java/
myfaces-commons-agent/src/main/java/org/
myfaces-commons-agent/src/main/jav...
Author: ckormos
Date: Wed Sep 30 18:54:21 2009
New Revision: 820386
URL: http://svn.apache.org/viewvc?rev=820386&view=rev
Log:
applied patch for [MFCOMMONS-11] - New agent detection module (Thanks to Marius Petoi)
Added:
myfaces/commons/trunk/myfaces-commons-agent/
myfaces/commons/trunk/myfaces-commons-agent/pom.xml (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/
myfaces/commons/trunk/myfaces-commons-agent/src/main/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java (with props)
myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentImpl.java (with props)
Modified:
myfaces/commons/trunk/pom.xml
Added: myfaces/commons/trunk/myfaces-commons-agent/pom.xml
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/pom.xml?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/pom.xml (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/pom.xml Wed Sep 30 18:54:21 2009
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.myfaces.commons</groupId>
+ <artifactId>commons12</artifactId>
+ <version>1.0.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>myfaces-commons-agent</artifactId>
+ <packaging>jar</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+ <name>Apache MyFaces Commons Agent Detection</name>
+ <description>MyFaces Commons Agent Detection provides and API obtaining information about the agent accessing a JSF application</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.myfaces.core</groupId>
+ <artifactId>myfaces-api</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <!-- Install in the repository a "-javadoc.jar" file -->
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.4</version>
+ <executions>
+ <execution>
+ <id>attach-javadoc</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <!-- Install in the repository a "-sources.jar" file -->
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-source</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Propchange: myfaces/commons/trunk/myfaces-commons-agent/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/pom.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,95 @@
+/*
+ * 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.commons.agent;
+
+import java.util.Map;
+
+/**
+ * The Agent interface describes the client that is making the request that will display
+ * the rendered output.
+ * <p>
+ * Implementations that provide the set of capabilities must clearly define the names
+ * of these capabilities and their values.
+ * </p>
+ * <p/>
+ * Capability names that are implementation private must be defined so using appropriate
+ * naming schemes. Trinidad private capability names are prefixed using "-adfinternal-xxx",
+ * and such capability names (and their values) may change at anytime
+ * (and not guaranteed to be supported in future releases).
+ * <p/>
+ */
+
+public interface Agent {
+
+ /**
+ * @return return the Type of Agent. Returns <code>TYPE_UNKNOWN</code> if not available.
+ * <br>E.g. desktop, pda, phone
+ */
+ public String getType();
+
+ /**
+ * @return return the canonical name of the agent (browser application).
+ * Returns <code>null</code> if not available.
+ * <br>E.g. gecko, ie, opera, pocketie
+ */
+ public String getAgentName();
+
+ /**
+ * @return return the version number of the agent (browser application).
+ * Return <code>null</code> if not available.
+ */
+ public String getAgentVersion();
+
+ /**
+ * @return return the canonical name for the platform. Returns <code>null</code> if not available.
+ * <br>E.g ppc, series60, windows, mac, linux, solaris
+ */
+ public String getPlatformName();
+
+ /**
+ * @return return the version number for the platform.
+ * Returns <code>null</code> if not available.
+ */
+ public String getPlatformVersion();
+
+ /**
+ * @return return a canonical name for the Hardware make and Model. Re
+ * turns <code>null</code> if not available.
+ * <br>E.g nokia6600, sonyericssonP900, nokai3650i
+ */
+ public String getHardwareMakeModel();
+
+
+ /**
+ * @return Map of capability names and their values for the current client request.
+ * <br>Some of the available capability names are:
+ * <br><i>height</i>- provides the screen height in pixels of the Agent as an Integer.
+ * <br><i>width</i>- provides the screen width in pixels of the Agent as an Integer.
+ * <br><i>dom</i>- provides the DOM API support of the agent as a String.
+ * Possible values are: <i>level2</i>, <i>level1</i>, <i>form</i>, and <i>none</i>.
+ * <br><i>frames</i>- returns a Boolean value signifying whether or not the Agent
+ * supports frames.
+ * <br><i>accessKeys</i>- returns a Boolean value signifying whether or not the Agent
+ * supports accessKeys.
+ */
+ // See CapabilityMap for why this takes Object as a key instead
+ // of String, at least for now
+ public Map<Object, Object> getCapabilities();
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/Agent.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,220 @@
+/*
+ * 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.commons.agent;
+
+import org.apache.myfaces.commons.agent.impl.AgentFactoryImpl;
+
+/**
+ * Class which contains all constants related to the detection of the agent
+ */
+public class AgentConstants {
+
+ /**
+ * Prevent instantiation of constants class
+ */
+ private AgentConstants() {
+ }
+
+ /**
+ * The factory used for creating an agent.
+ * <p/>
+ * TODO: see whether it is ok to put the factory here.
+ */
+ public static final AgentFactory FACTORY = AgentFactoryImpl.getInstance();
+
+ /**
+ * Constant for an unknown element (type, platform, etc).
+ */
+ public static final String UNKNOWN = "unknown";
+
+ /**
+ * Constant for telnet device type
+ */
+ public static final String TYPE_TELNET = "telnet";
+
+ /**
+ * Constant for desktop devices
+ */
+ public static final String TYPE_DESKTOP = "desktop";
+
+ /**
+ * Constant for hand-held sized devices (Pocket-PC, Palm)
+ */
+ public static final String TYPE_PDA = "pda";
+
+ /**
+ * Constant for Phone sized devices
+ */
+ public static final String TYPE_PHONE = "phone";
+
+ /**
+ * Constant for windows platform
+ */
+ public static final String PLATFORM_WINDOWS = "windows";
+
+ /**
+ * Constant for linux platform
+ */
+ public static final String PLATFORM_LINUX = "linux";
+
+ /**
+ * Constant for MacOS platform
+ */
+ public static final String PLATFORM_MACOS = "mac";
+
+ /**
+ * Constant for Mac platform
+ *
+ * @deprecated
+ */
+ @Deprecated
+ public static final String PLATFORM_MAC = PLATFORM_MACOS;
+
+ /**
+ * Constant for iPhone platform
+ */
+ public static final String PLATFORM_IPHONE = "iphone";
+
+ /**
+ * Constant for plam platform
+ */
+ public static final String PLATFORM_PALM = "palm";
+
+ /**
+ * Constant for solaris platform
+ */
+ public static final String PLATFORM_SOLARIS = "solaris";
+
+ /**
+ * Constant for pocket pc platform
+ */
+ public static final String PLATFORM_PPC = "ppc";
+
+ /**
+ * Constant for blackberry platform
+ */
+ public static final String PLATFORM_BLACKBERRY = "blackberry";
+
+ /**
+ * /** Constant for Nokia S60 platform
+ */
+ public static final String PLATFORM_NOKIA_S60 = "nokia_s60";
+
+ /**
+ * Constant for generic PDA device browser
+ */
+ public static final String PLATFORM_GENERICPDA = "genericpda";
+
+ /**
+ * Constant for Konqueror agent
+ */
+ public static final String AGENT_KONQUEROR = "konqueror";
+
+ /**
+ * Constant for Internet Explorer agent
+ */
+ public static final String AGENT_IE = "ie";
+
+ /**
+ * Constant for Gecko agent. Used for all Gecko based agents like Mozilla,
+ * Netscape 6+
+ */
+ public static final String AGENT_GECKO = "gecko";
+
+ /**
+ * Constant for email agent. Used for all email agents like Outlook 2007 and
+ * Thunderbird
+ */
+ public static final String AGENT_EMAIL = "email";
+
+ /**
+ * Constant for Apple Webkit agent. Used for all Webkit based agent like
+ * Safari
+ */
+ public static final String AGENT_WEBKIT = "webkit";
+
+ /**
+ * Constant for BlackBerry Browser agent. (Note the distinction from the
+ * BlackBerry platform. The BlackBerry Browser agent runs on the BlackBerry
+ * platform. It is possible for other agents to run on the BlackBerry
+ * platform.)
+ */
+ public static final String AGENT_BLACKBERRY = "blackberry";
+
+ /**
+ * Constant for Symbian Nokia S60 agent. Used for Nokia Series 60 3rd
+ * Edition or later
+ */
+ public static final String AGENT_NOKIA_S60 = "nokia_s60";
+
+ /**
+ * Constant for basic HTML (without JavaScript) Browser agent.
+ */
+ public static final String AGENT_GENERICPDA = "genericpda";
+
+ /**
+ * Name Constant for Netfront agent
+ */
+ public static final String AGENT_NETFRONT = "netfront";
+
+ /**
+ * Name Constant for Netscape agent. Used only for Netscape versions that
+ * are not Gecko based such as Netscape 4.7
+ */
+ public static final String AGENT_NETSCAPE = "netscape";
+
+ /**
+ * Name Constant for Palm Webpro agent //@TODO: Check: Isn't webpro same as
+ * netfront access
+ */
+ public static final String AGENT_WEBPRO = "webpro";
+
+ /**
+ * Name constant for ICE browser agent
+ */
+ public static final String AGENT_ICE_BROWSER = "icebrowser";
+
+ /**
+ * Name Constant for Pixo agent //@TODO: Check: Are we still supporting
+ * Pixo??
+ */
+ public static final String AGENT_PIXO = "pixo";
+
+ /**
+ * Name Constant for OracleAS Wireless. //@TODO: Check: Do we still have to
+ * support this??
+ */
+ public static final String AGENT_PTG = "ptg";
+
+ /**
+ * Name Constant for Blazer agent
+ */
+ public static final String AGENT_BLAZER = "blazer";
+
+ /**
+ * Name Constant for Xiino agent
+ */
+ public static final String AGENT_XIINO = "xiino";
+
+ /**
+ * Name Constant for Palm Web clipping (Elaine) agent
+ */
+ public static final String AGENT_ELAINE = "elaine";
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentConstants.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,46 @@
+/*
+ * 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.commons.agent;
+
+import org.apache.myfaces.commons.agent.Agent;
+
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * Factory to create Agent. Allows implementations to plug in their own agent
+ * detection, without having to override RequestContext.
+ * //@todo: Right now this not public API, but will be when adf faces cofiguration is sorted out
+ */
+
+public interface AgentFactory {
+ /**
+ * @param facesContext
+ * @return Agent for the current request/context
+ */
+ public Agent createAgent(FacesContext facesContext);
+
+ /**
+ * @param headerMap
+ * @return
+ */
+ public Agent createAgent(Map<String, String> headerMap);
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/AgentFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,55 @@
+/*
+ * 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.commons.agent;
+
+
+/**
+ * Class which declares all constants used as capability keys.
+ */
+public class CapabilityConstants {
+
+ /**
+ * Prevent instantiation of constants class
+ */
+ private CapabilityConstants() {
+ }
+
+ static public final CapabilityKey CAP_WIDTH = CapabilityKey
+ .getCapabilityKey("width", true);
+
+ static public final CapabilityKey CAP_HEIGHT = CapabilityKey
+ .getCapabilityKey("height", true);
+
+ static public final CapabilityKey CAP_IS_JDEV_JAVASCRIPT_VE = CapabilityKey
+ .getCapabilityKey("-adfinternal-isJDevJavascriptVE", true);
+
+ static public final CapabilityKey CAP_IS_JDEV_VE = CapabilityKey
+ .getCapabilityKey("-adfinternal-isJDevVE", true);
+
+ /**
+ * If this capability flag is true, it means that the request is from an
+ * agent that is running in a narrow-screen PDA. Trinidad optimizes its
+ * rendering for narrow-screen PDAs to reduce the overall width of the page
+ * rendered.
+ */
+ static public final CapabilityKey CAP_NARROW_SCREEN = CapabilityKey
+ .getCapabilityKey("narrowScreen", true);
+
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityConstants.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,134 @@
+/*
+ * 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.commons.agent;
+
+import java.util.HashMap;
+
+/**
+ * Key for capability Pretty much an impl similar to uix of AgentCapabilityKey
+ * -- added method getKeyAt (and required storage units) -- remove getKeyCount
+ * as ...
+ */
+public final class CapabilityKey {
+
+ private CapabilityKey(String capabilityName, int index) {
+ if (capabilityName == null)
+ throw new NullPointerException();
+
+ if (index < 0)
+ throw new IllegalArgumentException();
+
+ _capName = capabilityName.intern();
+ _capIndex = index;
+ _capKeyNames.put(_capName, this);
+
+ if (_keys.length < _capIndex) {
+ CapabilityKey[] newKeys = new CapabilityKey[_keys.length
+ + DEFAULT_SIZE];
+ System.arraycopy(_keys, 0, newKeys, 0, _keys.length);
+ }
+
+ _keys[_capIndex] = this;
+ }
+
+ /**
+ * Create a new CapabilityKey. If an key with name already exists returns
+ * the pre-created CapabilityKey
+ *
+ * @param capabilityName
+ */
+ public static CapabilityKey getCapabilityKey(String capabilityName,
+ boolean createIfNull) {
+ if (capabilityName == null)
+ return null;
+
+ Object key = _capKeyNames.get(capabilityName);
+ if ((createIfNull) && (key == null))
+ key = _createKey(capabilityName);
+
+ return ((CapabilityKey) key);
+ }
+
+ /**
+ * @param capabilityName
+ * @return CapabilityKey for the capability name
+ */
+ public static CapabilityKey getCapabilityKey(String capabilityName) {
+ return getCapabilityKey(capabilityName, false);
+ }
+
+ /**
+ * @return capability name
+ */
+ public String getCapabilityName() {
+ return _capName;
+ }
+
+ /**
+ * @return capability key index
+ */
+ public int getIndex() {
+ return _capIndex;
+ }
+
+ /**
+ * @param index
+ * @return CapabilityKey with the specified index
+ */
+ public static CapabilityKey getKeyAt(int index) {
+ if (index >= 0 && index <= _count)
+ return _keys[index];
+
+ // just return null if out of range
+ return null;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return _capIndex;
+ }
+
+ synchronized private static Object _createKey(String capabilityName) {
+ Object key = _capKeyNames.get(capabilityName);
+ if (key == null) {
+ key = new CapabilityKey(capabilityName, _count++);
+ }
+ return key;
+ }
+
+ @Override
+ public String toString() {
+ return _capName;
+ }
+
+ private String _capName;
+ private int _capIndex = 0;
+
+ static final private int DEFAULT_SIZE = 50;
+
+ static private HashMap<String, CapabilityKey> _capKeyNames = new HashMap<String, CapabilityKey>();
+ static private CapabilityKey[] _keys = new CapabilityKey[DEFAULT_SIZE];
+ private static int _count = 0;
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityKey.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,345 @@
+/*
+ * 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.commons.agent;
+
+import java.util.Set;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.AbstractMap;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * Pretty much the same Impl of UIX CapabilityMap, with following changes
+ * -- Actually a map implementation now
+ * -- added support to get Entries (To support a map interface)
+ * -- Also this impl assumes that the number of keys **will** change (increase) after init.
+ */
+// FIXME -= Simon Lessard =-
+// This is another map that can accept both String and another type as keys.
+// Shouldn't we force type safety with a single key type ?
+// -= Adam Winer =-
+// This, supports Strings and CapabilityKey. In theory, using
+// CapabilityKey is faster, which lets our built-in renderers
+// execute faster. A fair question is whether this is a real
+// issue. At the moment, however, it is definitely the case
+// that we are using CapabilityKey inside our code, and yet we
+// haven't made the plunge to require everyone to use
+// CapabilityKey on Agent (or make CapabilityKey public).
+public class CapabilityMap extends AbstractMap<Object, Object> implements Cloneable {
+
+ private CapabilityMap() {
+ }
+
+ public CapabilityMap(Object[][] keyValuesArr) {
+
+ int arrayCount = keyValuesArr.length;
+ CapabilityKey[][] keyArrays = new CapabilityKey[arrayCount][];
+
+ for (int arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++) {
+ keyArrays[arrayIndex] = new CapabilityKey[
+ keyValuesArr[arrayIndex] == null ? 0 : (keyValuesArr[arrayIndex].length >> 1)];
+ }
+
+ //Get All the Keys
+ //determine how many keys we need. The keys list/count could change hence
+ //need to find max key index.
+ int maxKeyIndex = 0;
+ for (int arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++) {
+ Object[] keyValues = keyValuesArr[arrayIndex];
+ CapabilityKey[] keys = keyArrays[arrayIndex];
+ int keyCount = keys.length;
+
+ for (int i = 0; i < keyCount; i++) {
+ keys[i] = (CapabilityKey) keyValues[i << 1];
+ maxKeyIndex = _max(keys[i].getIndex(), maxKeyIndex);
+ }
+ }
+
+ _indexedValues = new Object[maxKeyIndex + 1];
+ for (int arrayIndex = 0; arrayIndex < arrayCount; arrayIndex++) {
+ Object[] keyValues = keyValuesArr[arrayIndex];
+ CapabilityKey[] keys = keyArrays[arrayIndex];
+ int keyCount = keys.length;
+
+ for (int i = 0; i < keyCount; i++) {
+ _indexedValues[keys[i].getIndex()] = keyValues[(i << 1) + 1];
+ }
+ }
+ }
+
+
+ /**
+ * @param capKey
+ * @return value object for the capability
+ */
+ public Object getCapability(CapabilityKey capKey) {
+ int keyIndex = capKey.getIndex();
+
+ if (keyIndex < _indexedValues.length)
+ return _indexedValues[keyIndex];
+
+ return null;
+ }
+
+ /**
+ * @param capabilities
+ * @return returns a new capability map that merges key/values of the provided map
+ */
+ public CapabilityMap merge(Map<Object, Object> capabilities) {
+ if ((capabilities == null) || (capabilities.isEmpty()))
+ return this;
+
+ return merge(_getMapAsArray(capabilities));
+ }
+
+
+ /**
+ * @param capabilities
+ * @return
+ */
+ //Doing this as current Impl. uses this method
+ public CapabilityMap merge(Object[] capabilities) {
+ // could simply do this but .....
+ // new CapabilitiesImpl (new Object[][] {_getCapabilitiesAsArray(),
+ // capabilities});
+
+ if ((capabilities == null) || (capabilities.length <= 0))
+ return this;
+
+ int maxKeyIndex = _indexedValues.length;
+ Object[] capKeys = new Object[capabilities.length >> 1];
+ Object[] capValues = new Object[capabilities.length >> 1];
+ for (int i = 0, j = 0; i < capabilities.length - 1; i++) {
+ CapabilityKey capKey = (CapabilityKey) capabilities[i++];
+ capKeys[j] = capKey;
+ capValues[j++] = capabilities[i];
+ maxKeyIndex = _max(capKey.getIndex(), maxKeyIndex);
+ }
+
+ //new structures
+ Object[] indexedValues = new Object[maxKeyIndex + 1];
+
+ //Copy the values
+ System.arraycopy(_indexedValues, 0, indexedValues, 0, _indexedValues.length);
+ for (int i = 0; i < capKeys.length; i++) {
+ CapabilityKey capKey = (CapabilityKey) capKeys[i];
+ int keyIndex = capKey.getIndex();
+ indexedValues[keyIndex] = capValues[i];
+ }
+
+ CapabilityMap newImpl = new CapabilityMap();
+ newImpl._indexedValues = indexedValues;
+ return newImpl;
+ }
+
+ //Implementation of Map Methods
+ /**
+ * @param key
+ * @return
+ */
+ @Override
+ public Object get(Object key) {
+ if (key == null)
+ return null;
+
+ if (key instanceof CapabilityKey)
+ return getCapability((CapabilityKey) key);
+
+ return _get(key.toString());
+ }
+
+ /**
+ * @param key
+ * @param value
+ * @return
+ */
+ @Override
+ public Object put(Object key, Object value) {
+ return new UnsupportedOperationException();
+ }
+
+ /**
+ * @return
+ */
+ @Override
+ public Set<Map.Entry<Object, Object>> entrySet() {
+ if (_entrySet == null)
+ _createEntrySet();
+
+ return _entrySet;
+ }
+
+ @Override
+ public Object clone() {
+ try {
+ CapabilityMap that = (CapabilityMap) super.clone();
+ that._indexedValues = _indexedValues.clone();
+ that._entrySet = null;
+ return that;
+ }
+ catch (CloneNotSupportedException cnse) {
+ assert false;
+ return null;
+ }
+ }
+
+ private Object _get(String key) {
+ //key == null should be done before
+ CapabilityKey key0 = null;
+ Object value = null;
+ key0 = CapabilityKey.getCapabilityKey(key);
+ if (key0 != null)
+ value = getCapability(key0);
+
+ return value;
+ }
+
+
+ synchronized private void _createEntrySet() {
+ if (_entrySet == null) {
+ HashSet<Map.Entry<Object, Object>> hs =
+ new HashSet<Map.Entry<Object, Object>>();
+ Iterator<Object> iter = new KeyIterator();
+ while (iter.hasNext()) {
+ CapabilityKey capKey = (CapabilityKey) iter.next();
+ Object value = getCapability(capKey);
+ CEntry ce = new CEntry(capKey.getCapabilityName(), value);
+ hs.add(ce);
+ }
+ //Don't allow clear(), remove(), etc etc on the map
+ _entrySet = Collections.unmodifiableSet(hs);
+ }
+ }
+
+
+ private int _max(int value1, int value2) {
+ return (value1 > value2 ? value1 : value2);
+ }
+
+
+ private Object[] _getMapAsArray(Map<Object, Object> capabilities) {
+ Object[] caps = new Object[capabilities.size() * 2];
+ int i = 0;
+ for (Map.Entry<Object, Object> entry : capabilities.entrySet()) {
+ Object key = entry.getKey();
+ CapabilityKey capKey = key instanceof CapabilityKey
+ ? (CapabilityKey) key
+ : CapabilityKey.getCapabilityKey((String) key);
+ caps[i++] = capKey;
+ caps[i++] = entry.getValue();
+ }
+ return caps;
+ }
+
+
+ //KeyIterator
+ private class KeyIterator implements Iterator<Object> {
+ public KeyIterator() {
+ _setNext();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasNext() {
+ if (_next != null)
+ return true;
+ return false;
+ }
+
+ public Object next() {
+ if (_next == null)
+ _setNext();
+
+ if (_next != null) {
+ CapabilityKey next = _next;
+ _setNext();
+ return next;
+ }
+
+ throw new NoSuchElementException();
+ }
+
+ private void _setNext() {
+ _next = null;
+ for (int i = _current; i < _indexedValues.length; i++) {
+ if (_indexedValues[i] != null) {
+ _next = CapabilityKey.getKeyAt(i);
+ _current = ++i;
+ break;
+ }
+ }
+ }
+
+ private int _current = 0;
+ private CapabilityKey _next = null;
+
+ }
+
+
+ //Map Entry
+ static private class CEntry implements Entry<Object, Object> {
+
+ private Object key;
+ private Object value;
+
+ CEntry(Object key, Object value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (!(o instanceof CEntry))
+ return false;
+
+ CEntry ce = (CEntry) o;
+ return ((ce.key == key || ce.key.equals(key)) &&
+ (value == null ? ce.value == null : ce.value.equals(value)));
+ }
+
+ public Object getKey() {
+ return key;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public Object setValue(Object newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int hashCode() {
+ return key.hashCode() ^ (value == null ? 0 : value.hashCode());
+ }
+ }
+
+
+ private Object[] _indexedValues;
+ private Set<Map.Entry<Object, Object>> _entrySet;
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityMap.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,76 @@
+/*
+ * 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.commons.agent;
+
+import org.apache.myfaces.commons.agent.CapabilityKey;
+
+import java.util.HashMap;
+
+public class CapabilityValue {
+ //AdfFacesAgent (the old Agent) uses Objects constants for
+ //capability values, and the code base uses identity comaprison
+ //to check for a capability value.
+
+ //With the new Agent, the values are in a file and are string objects.
+ //So one way of making the identity comparison still work is to perform
+ //an string.intern() on the values read from the file.
+
+ //Also string values need to be retained, as need to support
+ //clients accessing the Agent Api (RequestContext object constants
+ //are internal impl)
+
+ //This is a poor man's quick substitute for string.intern().
+ //Later, need to refine this properly.
+ //Based on key, can know the value type object. Need metadata info on key
+
+ public final static Object getCapabilityValue(CapabilityKey key,
+ Object value) {
+ if (value instanceof String) {
+ String stringValue = (String) value;
+ if (stringValue.length() == 0)
+ return null;
+ if (Character.isDigit(stringValue.charAt(0))) {
+ try {
+ return Integer.valueOf(stringValue);
+ }
+ catch (NumberFormatException nfe) {
+ }
+ }
+
+ if ("true".equals(value))
+ return Boolean.TRUE;
+ else if ("false".equals(value))
+ return Boolean.FALSE;
+ }
+
+ return _getValue(value);
+ }
+
+ synchronized static private Object _getValue(Object value) {
+ Object cValue = _values.get(value);
+ if (cValue != null)
+ return cValue;
+
+ _values.put(value, value);
+ return value;
+ }
+
+ private static HashMap<Object, Object> _values = new HashMap<Object, Object>(32);
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/CapabilityValue.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,33 @@
+/*
+ * 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.commons.agent;
+
+/**
+ * Class that declares all constants used by the detection agent.
+ */
+public final class XhtmlAgentConstants {
+
+ // This class is only a container for constants, therefore it should not be instantiated
+ private XhtmlAgentConstants() {
+ }
+
+ // Maximum width of a narrow-screen PDA device in pixels
+ public static final int NARROW_SCREEN_PDA_MAX_WIDTH = 240;
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/XhtmlAgentConstants.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java?rev=820386&view=auto
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java (added)
+++ myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java Wed Sep 30 18:54:21 2009
@@ -0,0 +1,900 @@
+/*
+ * 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.commons.agent.impl;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import static org.apache.myfaces.commons.agent.AgentConstants.*;
+import org.apache.myfaces.commons.agent.*;
+
+/**
+ * Default MyFaces implementation of AgentFactory.
+ */
+public class AgentFactoryImpl implements AgentFactory {
+
+ /**
+ * Unique instance of this factory.
+ */
+ private static AgentFactory _instance;
+
+ /**
+ * Factory is a singleton, therefore make constructor public.
+ */
+ private AgentFactoryImpl() {
+ }
+
+ /**
+ * @return the unique instance of this <code>AgentFactory</code>
+ */
+ public static AgentFactory getInstance() {
+ if (_instance == null) {
+ _instance = new AgentFactoryImpl();
+ }
+ return _instance;
+ }
+
+ public Agent createAgent(Map<String, String> headerMap) {
+ // this method primarily exists for use during testing
+
+ AgentImpl agent = new AgentImpl();
+ _populateAgentImpl(null, headerMap, agent);
+ return agent;
+ }
+
+ public Agent createAgent(FacesContext facesContext) {
+ AgentImpl agent = new AgentImpl();
+
+ // Get the RequestHeaderMap to help populate the agent
+ Map<String, String> 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<String, String> 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(TYPE_PDA);
+ agent.setAgent(AGENT_GENERICPDA);
+ agent.setAgentVersion("1"); // Version does not matter
+ agent.setPlatform(PLATFORM_GENERICPDA);
+ }
+
+ private void _populateUnknownAgentImpl(String userAgent, AgentImpl agent) {
+ // Log warning message that we are setting the agent entry to unknown
+ // attributes
+ // TODO: _LOG.warning("UNKNOWN_AGENT_ATTRIBUTES_CREATE_WITH_UNKNOWN",
+ // userAgent);
+ agent.setAgent(UNKNOWN);
+ agent.setType(UNKNOWN);
+ agent.setAgentVersion(UNKNOWN);
+ agent.setPlatform(UNKNOWN);
+ agent.setPlatformVersion(UNKNOWN);
+ agent.setMakeModel(UNKNOWN);
+ }
+
+ // 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(TYPE_TELNET);
+ versionStartIndex = "OracleJDevMobile_ITS".length() + 1;
+ } else if (pdaIndex > -1) {
+
+ agentObj.setType(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(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(TYPE_PDA);
+ agentObj.setAgent(AGENT_IE);
+ agentObj.setAgentVersion(version);
+ agentObj.setPlatform(PLATFORM_PPC);
+
+ boolean narrowScreenDevice = false;
+
+ if (uaPixels != null && uaPixels.length() > 0) {
+ // UA-pixels is defined as <width>x<height>
+ // 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) {
+ // TODO: _LOG.fine(ex);
+ }
+ }
+
+ if (width != null && height != null) {
+ agentObj.__addRequestCapability(CapabilityConstants.CAP_WIDTH,
+ width);
+ agentObj.__addRequestCapability(CapabilityConstants.CAP_HEIGHT,
+ height);
+
+ if (width.intValue() < XhtmlAgentConstants.NARROW_SCREEN_PDA_MAX_WIDTH) {
+ narrowScreenDevice = true;
+ }
+ } else {
+ // TODO:
+ // _LOG.fine("When creating the Agent, the UA-pixels value \"{0}\" could not be parsed.",
+ // uaPixels);
+ }
+ } else {
+ narrowScreenDevice = true;
+ }
+
+ if (narrowScreenDevice) {
+ agentObj.__addRequestCapability(
+ CapabilityConstants.CAP_NARROW_SCREEN, Boolean.TRUE);
+ } else {
+ agentObj.__addRequestCapability(
+ CapabilityConstants.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<model>/<version> where <model> 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<model>/<version>; this returns the
+ // BlackBerry<model> (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(TYPE_PDA);
+ agentObj.setAgent(AGENT_BLACKBERRY);
+ agentObj.setAgentVersion(version);
+ agentObj.setPlatform(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(CapabilityConstants.CAP_NARROW_SCREEN,
+ Boolean.FALSE);
+ }
+
+ /**
+ * returns the data for the Palm Web Pro browser request
+ */
+ private void _populatePalmWebBrowserProAgentImpl(String agent,
+ AgentImpl agentObj) {
+ agentObj.setType(TYPE_PDA);
+ agentObj.setAgent(AGENT_WEBPRO);
+
+ int start = agent.indexOf("WebPro/");
+
+ if (start > -1) {
+ agentObj.setAgentVersion(_getVersion(agent, start + 6));
+ }
+
+ agentObj.setPlatform(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(TYPE_PHONE);
+ agentObj.setAgent(AGENT_PTG);
+ agentObj.setAgentVersion(version);
+ }
+
+ /**
+ * returns the AgentEntry for the Palm
+ */
+ private void _populatePalmAgentImpl(String userAgent, AgentImpl agentObj) {
+ agentObj.setType(TYPE_PDA);
+
+ if (userAgent.indexOf("Blazer") != -1)
+ agentObj.setAgent(AGENT_BLAZER);
+ else if (userAgent.indexOf("Xiino") != -1)
+ agentObj.setAgent(AGENT_XIINO);
+
+ agentObj.setPlatform(PLATFORM_PALM);
+
+ }
+
+ /**
+ * returns the AgentEntry for the Ice brwoser
+ */
+ private void _populateIceAgentImpl(String agent, AgentImpl agentObj) {
+ int slashIndex = agent.indexOf('/');
+ agentObj.setType(TYPE_DESKTOP);
+ agentObj.setAgent(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(TYPE_PHONE);
+ agentObj.setAgent(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(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(TYPE_DESKTOP);
+ agentObj.setAgent(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(PLATFORM_WINDOWS);
+ } else if (agent.indexOf("Mac", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_MACOS);
+ } else if (agent.indexOf("Linux", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_LINUX);
+ } else if (agent.indexOf("Sun", paren) > 0) {
+ agentObj.setPlatform(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(TYPE_PDA);
+ agentObj.setAgent(AGENT_GENERICPDA);
+ agentObj.setPlatform(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(TYPE_DESKTOP);
+ agentObj.setAgent(AGENT_GECKO);
+
+ int operaIndex = agent.indexOf("Opera/");
+ int firstSpace = agent.indexOf(" ");
+ 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(PLATFORM_WINDOWS);
+ } else if (agent.indexOf("Mac", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_MACOS);
+ } else if (agent.indexOf("Linux", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_LINUX);
+ } else if (agent.indexOf("Sun", paren) > 0) {
+ agentObj.setPlatform(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) {
+ agentObj.setPlatform(PLATFORM_IPHONE);
+ } else if (agent.indexOf("iPod") > 0) {
+ // At the moment, the iPod touch version of this browser matches
+ // iPhone's
+ agentObj.setPlatform(PLATFORM_IPHONE);
+ } else if (agent.indexOf("Win") > 0) {
+ // At the moment, this includes Safari and Google Chrome
+ agentObj.setPlatform(PLATFORM_WINDOWS);
+ } else if (agent.indexOf("Linux") > 0) {
+ // At the moment, this includes Android
+ agentObj.setPlatform(PLATFORM_LINUX);
+ } else if (agent.indexOf("Mac") > 0) {
+ // At the moment, this includes Safari
+ agentObj.setPlatform(PLATFORM_MACOS);
+ }
+
+ String version = _getVersion(agent, start);
+ agentObj.setType(TYPE_DESKTOP);
+ if ((agent.indexOf("Symbian") > -1) || (agent.indexOf("Nokia") > -1)) {
+ agentObj.setAgent(AGENT_NOKIA_S60);
+ agentObj.setPlatform(AGENT_NOKIA_S60);
+ } else {
+ agentObj.setAgent(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 paren = agent.indexOf('(');
+ agentObj.setType(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(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(TYPE_DESKTOP);
+ agentObj.setAgent(AGENT_KONQUEROR);
+ agentObj.setAgentVersion(_getVersion(agent, agent
+ .lastIndexOf('/')));
+ } 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(TYPE_PDA);
+ agentObj.setAgent(AGENT_ELAINE);
+ agentObj.setAgentVersion(_getVersion(agent, palmIndex));
+ agentObj.setPlatform(PLATFORM_PALM);
+ }
+ } else {
+ agentObj.setAgent(AGENT_IE);
+ agentObj.setAgentVersion(_getVersion(agent, ieIndex + 4));
+ }
+ } else {
+ agentObj.setAgent(AGENT_NETSCAPE);
+ agentObj
+ .setAgentVersion(_getVersion(agent, agent.indexOf('/')));
+ }
+
+ // try to determine the OS, if unknown
+ if (agentObj.getPlatformName() == null) {
+ // 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(PLATFORM_WINDOWS);
+ } else if (agent.indexOf("Mac", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_MACOS);
+ } else if (agent.indexOf("Linux", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_LINUX);
+ } else if (agent.indexOf("Sun", paren) > 0) {
+ agentObj.setPlatform(PLATFORM_SOLARIS);
+ }
+ }
+
+ if (isJDevVE) {
+ agentObj.__addRequestCapability(
+ CapabilityConstants.CAP_IS_JDEV_VE, Boolean.TRUE);
+ if (isJDevJSVE) {
+ agentObj.__addRequestCapability(
+ CapabilityConstants.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(TYPE_DESKTOP);
+
+ agentObj.setAgent(AGENT_EMAIL);
+ agentObj.setAgentVersion("0.0");
+ agentObj.setPlatform(UNKNOWN);
+ agentObj.setPlatformVersion(UNKNOWN);
+ agentObj.setMakeModel(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.
+ * <p/>
+ * 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 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";
+}
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange: myfaces/commons/trunk/myfaces-commons-agent/src/main/java/org/apache/myfaces/commons/agent/impl/AgentFactoryImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain