You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ar...@apache.org on 2011/08/08 22:19:25 UTC

svn commit: r1155077 - in /myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src: main/java/org/apache/myfaces/trinidadinternal/skin/ main/java/org/apache/myfaces/trinidadinternal/style/util/ main/java/org/apache/myfaces/trinidadinternal/style/xml...

Author: arobinson74
Date: Mon Aug  8 20:19:24 2011
New Revision: 1155077

URL: http://svn.apache.org/viewvc?rev=1155077&view=rev
Log:
Update for adding @agent support for tablets

Added:
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentProperties.java   (with props)
Modified:
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/NameUtils.java
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
    myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeEqualsTest.java

Added: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentProperties.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentProperties.java?rev=1155077&view=auto
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentProperties.java (added)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentProperties.java Mon Aug  8 20:19:24 2011
@@ -0,0 +1,73 @@
+package org.apache.myfaces.trinidadinternal.skin;
+
+import java.util.Arrays;
+import java.util.Set;
+
+import org.apache.myfaces.trinidad.context.Version;
+
+
+/**
+ * Container to hold "@agent" properties like {@link Version}and "touchScreen"
+ * capabilities.
+ */
+public final class AgentProperties
+{
+  public AgentProperties(Set<Version> versions,
+                         Set<String> capabilityTouchScreen)
+  {
+    if (versions == null)
+      throw new NullPointerException("versions must be non-null");
+
+    if (capabilityTouchScreen == null)
+      throw new NullPointerException("capabilityTouchScreen must be non-null");
+
+    _versions = versions;
+    _capabilityTouchScreen = capabilityTouchScreen;
+    _hashCode = _versions.hashCode() * 37 + _capabilityTouchScreen.hashCode();
+  }
+
+  public Set<Version> getVersions()
+  {
+    return _versions;
+  }
+
+  public Set<String> getCapabilityTouchScreen()
+  {
+    return _capabilityTouchScreen;
+  }
+
+  @Override
+  public boolean equals(Object o)
+  {
+    if (o == this)
+      return true;
+    else if (!(o instanceof AgentProperties))
+      return false;
+    else
+    {
+      AgentProperties otherAgentProperties = (AgentProperties) o;
+      return _versions.equals(otherAgentProperties._versions) &&
+        _capabilityTouchScreen.equals(otherAgentProperties._capabilityTouchScreen);
+    }
+
+  }
+
+  @Override
+  public String toString()
+  {
+    StringBuilder builder = new StringBuilder();
+    builder.append("versions: ").append(Arrays.toString(_versions.toArray()));
+    builder.append(" touchScreen: ").append(Arrays.toString(_capabilityTouchScreen.toArray()));
+    return builder.toString();
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return _hashCode;
+  }
+
+  private final Set<Version> _versions;
+  private final Set<String> _capabilityTouchScreen;
+  private final int _hashCode;
+}

Propchange: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/AgentProperties.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java Mon Aug  8 20:19:24 2011
@@ -20,6 +20,7 @@ package org.apache.myfaces.trinidadinter
 
 import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -37,9 +38,9 @@ import org.apache.myfaces.trinidadintern
 import org.apache.myfaces.trinidadinternal.style.xml.parse.PropertyNode;
 import org.apache.myfaces.trinidadinternal.util.nls.LocaleUtils;
 
- /** As the Skin css file is parsed, methods in this class are called to
-  * build up a SkinStyleSheetNode.
-  */
+/** As the Skin css file is parsed, methods in this class are called to
+ * build up a SkinStyleSheetNode.
+ */
 public class SkinCSSDocumentHandler
 {
 
@@ -242,7 +243,7 @@ public class SkinCSSDocumentHandler
   private CompleteSelectorNode _createCompleteSelectorNode(
     String                     selector,
     List<PropertyNode>         propertyNodeList,
-    Map<Integer, Set<Version>> selectorAgentVersions,
+    Map<Integer, AgentProperties> selectorAgentsProperties,
     int[]                      selectorPlatforms,
     Set<String>                selectorAccProperties)
   {
@@ -269,7 +270,7 @@ public class SkinCSSDocumentHandler
         selector,
         propertyNodeList,
         direction,
-        selectorAgentVersions,
+        selectorAgentsProperties,
         selectorPlatforms,
         selectorAccProperties);
   }
@@ -293,7 +294,7 @@ public class SkinCSSDocumentHandler
     {
       // we add to the ssNodeList in this method.
       int direction = completeSelectorNode.getDirection();
-      Map<Integer, Set<Version>> agentVersions = completeSelectorNode.getAgentVersions();
+      Map<Integer, AgentProperties> agentsProperties = completeSelectorNode.getAgentsProperties();
       int[] platforms = completeSelectorNode.getPlatforms();
       Set<String> accProperties = completeSelectorNode.getAccessibilityProperties();
 
@@ -306,7 +307,7 @@ public class SkinCSSDocumentHandler
       for (int i = skinStyleSheetNodes.size() - 1; i >= 0 && !match; --i)
       {
         SkinStyleSheetNode ssNode = skinStyleSheetNodes.get(i);
-        match = ssNode.matches(direction, agentVersions, platforms, accProperties);
+        match = ssNode.matches(direction, agentsProperties, platforms, accProperties);
         if (match)
           ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
       }
@@ -315,7 +316,7 @@ public class SkinCSSDocumentHandler
       {
        // no matching stylesheet node found, so create a new one
         SkinStyleSheetNode ssNode =
-         new SkinStyleSheetNode(namespaceMap, direction, agentVersions, platforms, accProperties);
+         new SkinStyleSheetNode(namespaceMap, direction, agentsProperties, platforms, accProperties);
         ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
         skinStyleSheetNodes.add(ssNode);
       }
@@ -345,48 +346,7 @@ public class SkinCSSDocumentHandler
       
       if (_AT_AGENT.equals(type))
       {
-        _selectorAgents = new HashMap<Integer, Set<Version>>();
-
-        for (int i=0; i < typeArray.length; i++)
-        {
-          // TODO: support min-version and max-version
-          // parse the agent versions. Examples:
-          // @agent ie and (version:6)
-          // @agent ie and (version:6.*)
-          // @agent ie and (version:5.0.*)
-          // @agent ie and (version:5.*) and (version:6)
-          
-          String[] sections = _WHITESPACE_PATTERN.split(typeArray[i].trim(), 2);
-          
-          // currently the type must be first
-          if (sections.length == 0)
-          {
-            throw new IllegalArgumentException("Invalid @agent string: " + typeArray[i]);
-          }
-          int agentInt = NameUtils.getBrowser(sections[0]);
-          if (agentInt != TrinidadAgent.APPLICATION_UNKNOWN)
-          {
-            Set<Version> versions = new HashSet<Version>();
-            _selectorAgents.put(agentInt, versions);
-            
-            if (sections.length == 2)
-            {
-              Matcher m = _AND_MEDIA_PROPERTY_SPLITTER.matcher(sections[1]);
-              
-              while (m.find())
-              {
-                String propName = m.group(1);
-                String version = m.group(2);
-                
-                if (!"version".equals(propName))
-                {
-                  throw new IllegalArgumentException("Invalid @agent property name: " + propName);
-                }
-                versions.add(new Version(version, "*"));
-              }
-            }
-          }
-        }
+        _parseAgentRule(typeArray);
       }
       else if (_AT_PLATFORM.equals(type))
       {
@@ -434,7 +394,166 @@ public class SkinCSSDocumentHandler
       }
     }
   }
+
+  /**
+   * Parses <code>types</code> string of the "@agent" rule for "version" and "touchScreen" 
+   * properties that are stored in an {@link AgentProperties}.
+   * @param typeArray tokenization by agents
+   * @see #_parseAgentProperties
+   * @see #_initAtRuleTargetTypes
+   */
+  private void _parseAgentRule(String[] typeArray)
+  {
+    // tracks matches on agent and properties.  
+    _selectorAgents = new HashMap<Integer, AgentProperties>();   
+    
+    Set<String> globalCapabilityTouchScreen = new HashSet<String>();
+    Set<Version> globalVersions = new HashSet<Version>();
+    
+    // Parsing agent types takes 2 passes to resovle the agent data.  
+    // 1) Identify agent properties that apply to all agents and 
+    //    parse agent types that are targeted at a specific agent
+    // 2) Apply global properties collected in the first pass to to 
+    //    all agents.
+    
+    // pass #1 - parse agent types
+    for (int i=0; i < typeArray.length; i++)
+    {
+      // TODO: support min-version and max-version
+      
+      String agentType =  typeArray[i].trim();
+       
+      // Check to see if the agent name is missing from the section.  These 
+      // rules are applied to all agents.
+      // @agent (touchScreen)                              /* all tablet agents, single and multiple touch */
+      // @agent (touchScreen:none)                         /* all desktop agents */ 
+      // @agent (touchScreen:single) and (version:multipe) /* all tablet agents, single and multiple touch */
+
+      Matcher m = _GLOBAL_MEDIA_PROPERTY_SPLITTER.matcher(agentType);
+      if (m.find() && m.start() == 0)  
+      {
+        // section[1] has no agent but matches property syntax
+        _parseAgentProperties(globalCapabilityTouchScreen, globalVersions, m.reset());
+        continue;  // continue to the next agent type condition
+      }
+      
+      // parse the agent versions. Examples:
+      // @agent ie and (version:6)
+      // @agent ie and (version:6.*)
+      // @agent ie and (version:5.0.*)
+      // @agent ie and (version:5.*) and (version:6), webkit and (version:5.0.*)
  
+      String[] sections = _WHITESPACE_PATTERN.split(agentType, 2);   
+      // currently the type must be first
+      if (sections.length == 0)
+      {
+        throw new IllegalArgumentException("Invalid @agent string: " + typeArray[i]);
+      }
+
+      int agentInt = NameUtils.getBrowser(sections[0]);
+      if (agentInt == TrinidadAgent.APPLICATION_UNKNOWN) 
+        throw new IllegalArgumentException("Invalid agent name in @agent string: " + typeArray[i]);        
+      
+      Set<String> capabilityTouchScreen = new HashSet<String>();
+      Set<Version> versions = new HashSet<Version>();      
+
+      // Match on agent. An empty AgentProperties instance by agent id 
+      // (no version and no touch capabilities) still indicates a match 
+      // on the agent browser.
+      _selectorAgents.put(agentInt, new AgentProperties(versions, capabilityTouchScreen));
+        
+      // The 2nd section when an agent name is provided are properties: 
+      // " and (version:6) and (version:5.0.*) and (touchScreen)".
+      if (sections.length == 2)
+      {
+        m = _AND_MEDIA_PROPERTY_SPLITTER.matcher(sections[1]);
+        if (!m.find())
+          throw new IllegalArgumentException("Invalid agent property syntax in @agent string: " + sections[1]);         
+        _parseAgentProperties(capabilityTouchScreen, versions, m.reset());
+      } 
+    } // end for typesArray
+    
+    // pass #2 - apply global properties to all agents
+    if (!globalCapabilityTouchScreen.isEmpty() || !globalVersions.isEmpty())
+    {
+      int[] allBrowsers = NameUtils.getAllBrowsers();
+      for (int agentInt: allBrowsers) 
+      {
+        AgentProperties agentProps = _selectorAgents.get(agentInt);
+        if (agentProps != null)
+        {
+          // add global propertie to existing agent properties
+          agentProps.getVersions().addAll(globalVersions);
+          agentProps.getCapabilityTouchScreen().addAll(globalCapabilityTouchScreen);
+        }
+        else
+        {
+          // add global properties to agent selectors for specific agent
+          _selectorAgents.put(agentInt, new AgentProperties(globalVersions, globalCapabilityTouchScreen));
+        }
+      } // end for all browsers
+    } // has global properties
+  }
+
+  /**
+   * Uses the regexp matcher to parse agent properties and append to the 
+   * capability and version sets passed in the actual parameter.
+   * 
+   * @param capabilityTouchScreen "touchScreen" agent properties
+   * @param versions "version" agent properties
+   * @param m reset agent matcher
+   * @see #_parseAgentRule
+   */
+  private void _parseAgentProperties(Set<String> capabilityTouchScreen,
+                                     Set<Version> versions, Matcher m)
+  {
+    while (m.find())
+    {
+      String propName = m.group(1);
+      String propValue = m.group(2);
+
+      if ("version".equals(propName))
+      {
+        if (propValue != null)
+          versions.add(new Version(propValue.trim(), "*"));
+        else
+          _LOG.warning("INVALID_AGENT_PROPERTY", new Object[]
+            { propName, propValue });
+      }
+      else if (TrinidadAgent.CAP_TOUCH_SCREEN.getCapabilityName().equals(propName))
+      {
+        String[] capTouchArray;
+        if (propValue != null)
+        {
+          String capValue = propValue.trim();
+          if (this._ALL_TOUCH_CAPABILITIES.contains(capValue))
+            capTouchArray = new String[]
+                { capValue };
+          else
+          {
+            _LOG.warning("INVALID_AGENT_PROPERTY", new Object[]
+                { propName, capValue });
+            capTouchArray = new String[]
+                { };
+          }
+        }
+        else
+        {
+          capTouchArray = _AFFIRMATIVE_TOUCH_CAPABILITIES;
+        }
+
+        Set<String> capTouchValues =
+          new HashSet<String>(Arrays.<String>asList(capTouchArray));
+        capabilityTouchScreen.addAll(capTouchValues);
+      }
+      else
+      {
+        //throw new IllegalArgumentException("Invalid @agent property name: " + propName);
+        _LOG.warning("INVALID_AGENT_PROPERTY", new Object[] { propName, propValue });
+      }
+    } // end while
+  }
+
   // Copies Integers from a List of Integers into an int array
   private int[] _getIntArray(List <Integer> integerList)
   {
@@ -535,17 +654,17 @@ public class SkinCSSDocumentHandler
     return mergedProperties;
   }
 
-   /**
-    * This Class contains a SkinSelectorPropertiesNode and a rtl direction.
-    * We will use this information when creating a SkinStyleSheetNode.
-    */
+  /**
+   * This Class contains a SkinSelectorPropertiesNode and a rtl direction.
+   * We will use this information when creating a SkinStyleSheetNode.
+   */
   private static class CompleteSelectorNode
   {
     public CompleteSelectorNode(
       String                     selectorName,
       List<PropertyNode>         propertyNodes,
       int                        direction,
-      Map<Integer, Set<Version>> agentVersions,
+      Map<Integer, AgentProperties> agentsProperties,
       int[]                      platforms,
       Set<String>                accProperties
       )
@@ -554,9 +673,9 @@ public class SkinCSSDocumentHandler
       _direction = direction;
       // copy the agents and platforms because these get nulled out
       // at the end of the @rule parsing.
-      _agentVersions = agentVersions != null ?
-        new HashMap<Integer, Set<Version>>(agentVersions) :
-        new HashMap<Integer, Set<Version>>();
+      _agentsProperties = agentsProperties != null ?
+        new HashMap<Integer, AgentProperties>(agentsProperties) :
+        new HashMap<Integer, AgentProperties>();
       
       _platforms = _copyIntArray(platforms);
       
@@ -580,11 +699,11 @@ public class SkinCSSDocumentHandler
     }
 
     /**
-     * @return The versions of the agent to be supported
+     * @return The supported agent properties, "version", "touchScreen".
      */
-    public Map<Integer, Set<Version>> getAgentVersions()
+    public Map<Integer, AgentProperties> getAgentsProperties()
     {
-      return _agentVersions;
+      return _agentsProperties;
     }
     
     public int[] getPlatforms()
@@ -611,7 +730,7 @@ public class SkinCSSDocumentHandler
 
     private SkinSelectorPropertiesNode _node;
     private int _direction;  // the reading direction
-    private Map<Integer, Set<Version>> _agentVersions;
+    private Map<Integer, AgentProperties> _agentsProperties;
     private int[] _platforms;
     private Set<String> _accProperties;
   }
@@ -633,9 +752,10 @@ public class SkinCSSDocumentHandler
   private int[] _selectorPlatforms = null;
 
   // As we need to be able to have multiple versions to an agent
-  // we store a map of agents and their version sets
-  private Map<Integer, Set<Version>> _selectorAgents = null;
-
+  // we store a map of agents and their properties.  Agent properties
+  // are additional critera applied to selection (version, touchScreen).
+  private Map<Integer, AgentProperties> _selectorAgents = null;
+  
   // Stack of accessibility property sets.  While java.util.Stack has the
   // push/pop API that we want, we don't need the synchronization, so we
   // just use a LinkedList instead and pretend its a stack.
@@ -650,7 +770,20 @@ public class SkinCSSDocumentHandler
     Pattern.compile("\\s+");
   
   private static final Pattern _AND_MEDIA_PROPERTY_SPLITTER =
-    Pattern.compile("\\band\\s+\\((\\w+)\\s*:\\s*(\\S+)\\s*\\)");
+    Pattern.compile("\\band\\s+\\(([A-Za-z0-9_-]+)(?::\\s*([A-Za-z0-9.]+)\\s*)?\\s*");
+
+  private static final Pattern _GLOBAL_MEDIA_PROPERTY_SPLITTER = 
+    Pattern.compile("\\(([A-Za-z0-9_-]+)(?::\\s*([A-Za-z0-9.]+)\\s*)?\\)"); 
+  private static final String[] _AFFIRMATIVE_TOUCH_CAPABILITIES =
+    new String[]
+    { TrinidadAgent.TOUCH_SCREEN_MULTIPLE.toString(),
+      TrinidadAgent.TOUCH_SCREEN_SINGLE.toString() };
+
+  private static final HashSet<String> _ALL_TOUCH_CAPABILITIES =
+    new HashSet<String>(Arrays.<String>asList(new String[]
+        { TrinidadAgent.TOUCH_SCREEN_MULTIPLE.toString(),
+          TrinidadAgent.TOUCH_SCREEN_SINGLE.toString(),
+          TrinidadAgent.TOUCH_SCREEN_NONE.toString() }));
 }
-   
-   
+
+

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java Mon Aug  8 20:19:24 2011
@@ -24,8 +24,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.myfaces.trinidad.context.Version;
-
 /** Stores information about the .css skin file.
  * namespaceMap, a List of SkinSelectorPropertiesNodes, and direction.
  * @todo honor the namespaces that are set in the css file. For now, we ignore
@@ -43,26 +41,26 @@ class SkinStyleSheetNode
     List<SkinSelectorPropertiesNode> skinSelectorNodeList,
     Map<String, String>              namespaceMap,
     int                              direction,
-    Map<Integer, Set<Version>>       agentVersions,
+    Map<Integer, AgentProperties>    agentsProperties,
     Set<String>                      accProperties)
   {
     _skinSelectorNodeList = skinSelectorNodeList;
     _namespaceMap = namespaceMap;
     _direction = direction;
-    _agentVersions = agentVersions;
+    _agentsProperties = agentsProperties;
     _accProperties = accProperties;
   }
 
   SkinStyleSheetNode(
     Map<String, String>        namespaceMap,
     int                        direction,
-    Map<Integer, Set<Version>> agentVersions,
+    Map<Integer, AgentProperties> agentsProperties,
     int[]                      platforms,
     Set<String>                accProperties)
   {
     _namespaceMap = namespaceMap;
     _direction = direction;
-    _agentVersions = agentVersions;
+    _agentsProperties = agentsProperties;
     _platforms = platforms;
     _accProperties = accProperties;
   }
@@ -102,11 +100,11 @@ class SkinStyleSheetNode
   }
 
   /**
-   * @return a set of the supported agent versions
+   * @return a set of the supported agent properties (version, touchScreen).
    */
-  public Map<Integer, Set<Version>> getAgentVersions()
+  public Map<Integer, AgentProperties> getAgentsProperties()
   {
-    return _agentVersions;
+    return _agentsProperties;
   }
 
   public int[] getPlatforms()
@@ -121,13 +119,13 @@ class SkinStyleSheetNode
 
   public boolean matches(
     int                        direction,
-    Map<Integer, Set<Version>> agentVersions,
+    Map<Integer, AgentProperties> agentsProperties,
     int[]                      platforms,
     Set<String>                accProperties)
   {
     if (direction == _direction)
     {
-      boolean agentsMatch = _mapsEqual(agentVersions, _agentVersions);
+      boolean agentsMatch = _mapsEqual(agentsProperties, _agentsProperties);
 
       if (agentsMatch)
       {
@@ -166,7 +164,7 @@ class SkinStyleSheetNode
   private Map<String, String> _namespaceMap;
   private List<SkinSelectorPropertiesNode> _skinSelectorNodeList;
   private int _direction; // reading direction
-  private Map<Integer, Set<Version>> _agentVersions;
+  private Map<Integer, AgentProperties> _agentsProperties;
   private int[] _platforms;
   private Set<String> _accProperties;
 }

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetParserUtils.java Mon Aug  8 20:19:24 2011
@@ -275,7 +275,7 @@ class SkinStyleSheetParserUtils
                              iconNodeList,
                              null,/*locales, not yet supported*/
                              skinSSNode.getDirection(),
-                             skinSSNode.getAgentVersions(),
+                             skinSSNode.getAgentsProperties(),
                              skinSSNode.getPlatforms(),
                              0,
                              skinSSNode.getAcessibilityProperties());

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/NameUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/NameUtils.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/NameUtils.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/NameUtils.java Mon Aug  8 20:19:24 2011
@@ -25,6 +25,7 @@ import java.util.Vector;
 
 import org.apache.myfaces.trinidad.context.Version;
 import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.skin.AgentProperties;
 import org.apache.myfaces.trinidadinternal.style.StyleContext;
 import org.apache.myfaces.trinidadinternal.style.xml.XMLConstants;
 import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetDocument;
@@ -33,7 +34,7 @@ import org.apache.myfaces.trinidadintern
 
 /**
  * Utilities for converting between variant names and ids
- * 
+ *
  * @version $Name: $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/style/util/NameUtils.java#0 $) $Date: 10-nov-2005.18:58:52 $
  */
 public class NameUtils
@@ -41,6 +42,14 @@ public class NameUtils
   private NameUtils() {}
 
   /**
+   * @return id of all supported browsers
+   */
+  public static int[] getAllBrowsers()
+  {
+    return _ALL_BROWSERS;  
+  }
+  
+  /**
    * Returns the id of the browser with the specified name
    */
   public static int getBrowser(String browserName)
@@ -642,7 +651,7 @@ public class NameUtils
    *          and the second value being the version match
    */
   private static boolean[] _isBrowserAndVersionMatch(StyleContext context,
-      StyleSheetNode[] styleSheets)
+                                                     StyleSheetNode[] styleSheets)
   {
     int browser = context.getAgent().getAgentApplication();
     Version version = new Version(context.getAgent().getAgentVersion());
@@ -653,23 +662,28 @@ public class NameUtils
 
     boolean browserMatched = false;
     Integer browserNum = Integer.valueOf(browser);
-    
+
     // If any style sheet has a non-null browser variant, we must
     // have a browser match.
     for (int i = 0; i < styleSheets.length; i++)
     {
-      if (!styleSheets[i].getAgentVersions().isEmpty())
+      if (!styleSheets[i].getAgentsProperties().isEmpty())
       {
-        Set<Version> versions = styleSheets[i].getAgentVersions().get(browserNum);
-        
-        if (versions != null)
+        AgentProperties agentProps =
+          styleSheets[i].getAgentsProperties().get(browserNum);
+        if (agentProps != null)
         {
           browserMatched = true;
-          for (Version av : versions)
+          
+          Set<Version> versions = agentProps.getVersions();
+          if (versions != null && !versions.isEmpty())
           {
-            if (av.compareTo(version) == 0)
+            for (Version av: versions)
             {
-              return new boolean[] { true, true };
+              if (av.compareTo(version) == 0)
+              {
+                return new boolean[] { true, true };
+              }
             }
           }
         }
@@ -766,6 +780,17 @@ public class NameUtils
   private static final String _BROWSER_GENERICPDA = "genericpda";
 
   private static final String _BROWSER_EMAIL = "email";
+  
+  // all supported browsers by id
+  private static final int[] _ALL_BROWSERS =
+  { TrinidadAgent.APPLICATION_NETSCAPE,
+    TrinidadAgent.APPLICATION_IEXPLORER, TrinidadAgent.APPLICATION_GECKO,
+    TrinidadAgent.APPLICATION_ICE, TrinidadAgent.APPLICATION_SAFARI,
+    TrinidadAgent.APPLICATION_BLACKBERRY,
+    TrinidadAgent.APPLICATION_NOKIA_S60,
+    TrinidadAgent.APPLICATION_GENERICPDA,
+    TrinidadAgent.APPLICATION_EMAIL };
+
   // Platform constants
   private static final String _PLATFORM_WINDOWS = "windows";
 

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java Mon Aug  8 20:19:24 2011
@@ -32,6 +32,7 @@ import java.util.StringTokenizer;
 import org.apache.myfaces.trinidad.context.AccessibilityProfile;
 import org.apache.myfaces.trinidad.context.Version;
 import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.skin.AgentProperties;
 import org.apache.myfaces.trinidadinternal.style.util.ModeUtils;
 import org.apache.myfaces.trinidadinternal.style.util.NameUtils;
 import org.apache.myfaces.trinidadinternal.style.xml.XMLConstants;
@@ -57,7 +58,7 @@ public class StyleSheetNode
     Collection<IconNode> icons,
     Locale[] locales,
     int direction,
-    Map<Integer, Set<Version>> agentVersions,
+    Map<Integer, AgentProperties> agentsProperties,
     int[] platforms,
     int mode,
     Set<String> accessibilityProperties
@@ -83,12 +84,12 @@ public class StyleSheetNode
     else
       _locales = Collections.emptySet();
 
-    if (agentVersions != null)
+    if (agentsProperties != null)
     {
-      _agentVersions = Collections.unmodifiableMap(agentVersions);
+      _agentsProperties = Collections.unmodifiableMap(agentsProperties);
     }
     else
-      _agentVersions = Collections.emptyMap();
+      _agentsProperties = Collections.emptyMap();
 
     if (platforms != null)
     {
@@ -149,12 +150,11 @@ public class StyleSheetNode
   }
 
   /**
-   * Implementation of StyleSheetNode.getAgentVersions().
-   * @return a map containing each browser type mapped to its versions set
+   * @return A map containing each browser mapped to supported properties.
    */
-  public Map<Integer, Set<Version>> getAgentVersions()
+  public Map<Integer, AgentProperties> getAgentsProperties()
   {
-    return _agentVersions;
+    return _agentsProperties;
   }
 
   /**
@@ -199,8 +199,8 @@ public class StyleSheetNode
 
     int browser = agent.getAgentApplication();
     
-    int browserAndVersionMatch = _compareBrowserAndVersion(browser, agent);
-    if (browserAndVersionMatch == 0)
+    int browserAndPropertiesMatch = _compareBrowserAndProperties(browser, agent);
+    if (browserAndPropertiesMatch == 0)
       return 0;
     int modeMatch = _compareMode(mode);
     if(modeMatch == 0)
@@ -214,7 +214,7 @@ public class StyleSheetNode
     if (accessibilityMatch == 0)
       return 0;
 
-    return (localeMatch | browserAndVersionMatch | osMatch | accessibilityMatch);
+    return (localeMatch | browserAndPropertiesMatch | osMatch | accessibilityMatch);
   }
 
   @Override
@@ -258,7 +258,7 @@ public class StyleSheetNode
     return getClass().getName() + "[" +
       "locales="   + (_locales != null ? _locales.toString() : "")    + ", " +
       "direction=" + _getDirectionString() + ", " +
-      "agentVersions="  + (_agentVersions != null ? _agentVersions.toString() : "")  + ", " +
+      "agentProperties="  + (_agentsProperties != null ? _agentsProperties.toString() : "")  + ", " +
 //      "versions="  + _versions.toString()  + ", " +
       "platforms=" + (_platforms != null ? _platforms.toString() : "") + ", " +
       "styles="    + (_styles != null ? _styles.toString() : "") + ", " +
@@ -297,7 +297,7 @@ public class StyleSheetNode
     hash = 37*hash + _mode;
     hash = 37*hash + _direction;
     hash = 37*hash + _locales.hashCode();
-    hash = 37*hash + _agentVersions.hashCode();
+    hash = 37*hash + _agentsProperties.hashCode();
     hash = 37*hash + _platforms.hashCode();
     hash = 37*hash + _styles.hashCode();
     hash = 37*hash + _accProps.hashCode();
@@ -365,42 +365,65 @@ public class StyleSheetNode
   }
 
   //Compares the browser and its version against the supported variants
-  private int _compareBrowserAndVersion(int browser, TrinidadAgent agent)
+  private int _compareBrowserAndProperties(int browser, TrinidadAgent agent)
   {
     // If we don't have a browser specified, we match anything
-    if (_agentVersions.isEmpty())
+    if (_agentsProperties.isEmpty())
       return _BROWSER_UNKNOWN_MATCH;
 
     // On the other hand, if we do have a browser specified, but
     // the client browser is not known, we don't have a match
     if (browser == TrinidadAgent.APPLICATION_UNKNOWN)
-      return 0;
+      return 0; // no-match
     
     //If we have browser exact match, compare versions
     Integer browserNum = Integer.valueOf(browser);
-    if (_agentVersions.containsKey(browserNum))
+    if (_agentsProperties.containsKey(browserNum))
     {
-      Set<Version> versions = _agentVersions.get(browserNum);
-      if (versions.isEmpty())
-        return _BROWSER_EXACT_MATCH | _VERSION_UNKNOWN_MATCH;
+      int matchResults = 0;
       
-      Version version = new Version(agent.getAgentVersion());
-        
-      for (Version av : versions)
+      AgentProperties agentProperties = _agentsProperties.get(browserNum);
+      Set<Version> versions = agentProperties.getVersions();
+
+      if (versions.isEmpty())
       {
-        if (av.compareTo(version) == 0)
+        matchResults = _BROWSER_EXACT_MATCH |_VERSION_UNKNOWN_MATCH;
+      }
+      else
+      {
+        Version version = new Version(agent.getAgentVersion());
+        
+        for (Version av : versions)
         {
-          return _BROWSER_EXACT_MATCH | _VERSION_EXACT_MATCH;
+          if (av.compareTo(version) == 0)
+          {
+            matchResults = _BROWSER_EXACT_MATCH |_VERSION_EXACT_MATCH;
+            break;
+          }
         }
+        if (matchResults == 0)  // version specified but no matchy
+          return 0;
       }
       
-      return 0;
+      String agentCapTouchScreen = (String) agent.getCapability(TrinidadAgent.CAP_TOUCH_SCREEN);
+      Set<String> capabilityTouchScreen = agentProperties.getCapabilityTouchScreen();   
+      if (capabilityTouchScreen.isEmpty())
+      {
+        matchResults |= _BROWSER_EXACT_MATCH | _CAP_TOUCH_SCREEN_UNKNOWN_MATCH;        
+      }
+      else if (capabilityTouchScreen.contains(agentCapTouchScreen))
+      {
+        matchResults |= _BROWSER_EXACT_MATCH | _CAP_TOUCH_SCREEN_EXACT_MATCH;
+      }
+      else if (matchResults == (_BROWSER_EXACT_MATCH | _VERSION_UNKNOWN_MATCH)) // no match on version or touch
+        return 0;
+      
+      return matchResults;
     }
 
-    return 0;
+    return 0; // no-match
   }
 
-
   // Compares the specified OS against the supported variants
   private int _compareOS(int os)
   {
@@ -563,7 +586,7 @@ public class StyleSheetNode
   // Integer is 3, it is APPLICATION_GECKO.
   // TODO It would be clearer to make the Integer an Enum, and to make the
   // Application constants an enum.
-  private final Map<Integer, Set<Version>>    _agentVersions;
+  private final Map<Integer, AgentProperties> _agentsProperties;
   private final Set<Integer>    _platforms;  // The platform variants
   private final int             _mode;       // The mode
   private final Set<String>     _accProps;   // Accessibility profile properties
@@ -592,7 +615,11 @@ public class StyleSheetNode
 
   // Constants for version matches - 0x000000f0 bits
   private static final int _VERSION_EXACT_MATCH     = 0x00000020;
-  private static final int _VERSION_UNKNOWN_MATCH   = 0x00000020;
+  private static final int _VERSION_UNKNOWN_MATCH   = 0x00000010;
+
+  // Constants for capability touchScreen matches - 0x000000f0 bits
+  private static final int _CAP_TOUCH_SCREEN_EXACT_MATCH     = 0x00000040;
+  private static final int _CAP_TOUCH_SCREEN_UNKNOWN_MATCH   = 0x00000030;
 
   // Constants for os matches - 0x0000000f bits
   private static final int _OS_EXACT_MATCH          = 0x00000004;

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java Mon Aug  8 20:19:24 2011
@@ -19,6 +19,7 @@
 package org.apache.myfaces.trinidadinternal.style.xml.parse;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -34,6 +35,7 @@ import org.apache.myfaces.trinidadintern
 import org.apache.myfaces.trinidadinternal.share.xml.NodeParser;
 import org.apache.myfaces.trinidadinternal.share.xml.ParseContext;
 import org.apache.myfaces.trinidadinternal.share.xml.XMLUtils;
+import org.apache.myfaces.trinidadinternal.skin.AgentProperties;
 import org.apache.myfaces.trinidadinternal.style.StyleConstants;
 import org.apache.myfaces.trinidadinternal.style.util.NameUtils;
 import org.apache.myfaces.trinidadinternal.style.xml.XMLConstants;
@@ -93,14 +95,15 @@ public class StyleSheetNodeParser extend
    }
    
     int browserCount = (_browsers != null) ? _browsers.length : 0;
-    Map<Integer, Set<Version>> browsers
-        = new HashMap<Integer, Set<Version>>(browserCount);
+    Map<Integer, AgentProperties> browsers
+        = new HashMap<Integer, AgentProperties>(browserCount);
 
    //in XSS there's now way of having multiple browsers and multiple versions
    //if encountered, we map all versions to each browser (it works for 1 browser)
    for (int i=0; i < browserCount ; i++)
    {
-     browsers.put(_browsers[i], new HashSet<Version>(versions));
+     // touchScreen capabilities are not supported in xss.  This is only a css feature.
+     browsers.put(_browsers[i], new AgentProperties(new HashSet<Version>(versions), Collections.<String>emptySet()));
    }
 
     return new StyleSheetNode(

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts Mon Aug  8 20:19:24 2011
@@ -1114,4 +1114,6 @@ The skin {0} specified on the requestMap
 <!-- SESSION_SERIALIZATION_ATTRIBUTE -->
 <resource key="SESSION_SERIALIZATION_ATTRIBUTE">Session attribute:{0}</resource>
 
+<resource key="INVALID_AGENT_PROPERTY">Not a valid @agent CSS property rule: {0}: {1}</resource>
+
 </resources>

Modified: myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeEqualsTest.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeEqualsTest.java?rev=1155077&r1=1155076&r2=1155077&view=diff
==============================================================================
--- myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeEqualsTest.java (original)
+++ myfaces/trinidad/branches/1.2-ios-branch/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeEqualsTest.java Mon Aug  8 20:19:24 2011
@@ -20,6 +20,7 @@ package org.apache.myfaces.trinidadinter
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -29,6 +30,7 @@ import java.util.Set;
 
 import junit.framework.TestCase;
 
+import org.apache.myfaces.trinidadinternal.skin.AgentProperties;
 import org.apache.myfaces.trinidad.context.Version;
 import org.apache.myfaces.trinidad.skin.Icon;
 import org.apache.myfaces.trinidadinternal.skin.icon.ContextImageIcon;
@@ -133,16 +135,16 @@ public class StyleSheetNodeEqualsTest ex
     Locale[] diffOrderLocalesArray = getDiffOrderLocalesArray();
      
     // create a browsers map
-    Map<Integer, Set<Version>> browsers = new HashMap<Integer, Set<Version>>();
-    browsers.put(1, new HashSet<Version>(Arrays.asList(new Version("5"), new Version("6"))));
-    browsers.put(2, new HashSet<Version>(Arrays.asList(new Version("7"), new Version("8"))));
-    Map<Integer, Set<Version>> anotherBrowsers = new HashMap<Integer, Set<Version>>();
-    anotherBrowsers.put(1, new HashSet<Version>(Arrays.asList(new Version("5"), new Version("6"))));
-    anotherBrowsers.put(2, new HashSet<Version>(Arrays.asList(new Version("7"), new Version("8"))));
-    Map<Integer, Set<Version>> anotherBrowsersDiffOrder
-        = new HashMap<Integer, Set<Version>>();
-    anotherBrowsersDiffOrder.put(2, new HashSet<Version>(Arrays.asList(new Version("8"), new Version("7"))));
-    anotherBrowsersDiffOrder.put(1, new HashSet<Version>(Arrays.asList(new Version("6"), new Version("5"))));
+    Map<Integer, AgentProperties> browsers = new HashMap<Integer, AgentProperties>();
+    browsers.put(1, new AgentProperties(new HashSet<Version>(Arrays.asList(new Version("5"), new Version("6"))), Collections.<String>emptySet()));
+    browsers.put(2, new AgentProperties(new HashSet<Version>(Arrays.asList(new Version("7"), new Version("8"))), Collections.<String>emptySet()));
+    Map<Integer, AgentProperties> anotherBrowsers = new HashMap<Integer, AgentProperties>();
+    anotherBrowsers.put(1, new AgentProperties(new HashSet<Version>(Arrays.asList(new Version("5"), new Version("6"))), Collections.<String>emptySet()));
+    anotherBrowsers.put(2, new AgentProperties(new HashSet<Version>(Arrays.asList(new Version("7"), new Version("8"))), Collections.<String>emptySet()));
+    Map<Integer, AgentProperties> anotherBrowsersDiffOrder
+        = new HashMap<Integer, AgentProperties>();
+    anotherBrowsersDiffOrder.put(2, new AgentProperties(new HashSet<Version>(Arrays.asList(new Version("8"), new Version("7"))), Collections.<String>emptySet()));
+    anotherBrowsersDiffOrder.put(1, new AgentProperties(new HashSet<Version>(Arrays.asList(new Version("6"), new Version("5"))), Collections.<String>emptySet()));
 
 
     int[] platforms = {2, 3, 4};