You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ma...@apache.org on 2010/02/10 16:45:49 UTC

svn commit: r908546 - in /myfaces/trinidad/branches/matzewTrinidad2002: trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/ trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/ trinidad-api/src/main/java/org/apache/myfaces/trini...

Author: matzew
Date: Wed Feb 10 15:45:48 2010
New Revision: 908546

URL: http://svn.apache.org/viewvc?rev=908546&view=rev
Log:
solved missing conflicts by hand;
merged in those changes from Trunk to this new branch;

Added:
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/TrinidadRenderingConstants.java
Modified:
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java
    myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java Wed Feb 10 15:45:48 2010
@@ -29,7 +29,6 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Properties;
 
 import javax.el.ELContext;
@@ -41,6 +40,7 @@
 import javax.faces.component.ContextCallback;
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
 import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.context.FacesContext;
@@ -68,6 +68,7 @@
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.render.ExtendedRenderer;
 import org.apache.myfaces.trinidad.render.LifecycleRenderer;
+import org.apache.myfaces.trinidad.util.CollectionUtils;
 import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
 
 
@@ -109,8 +110,6 @@
   static public final FacesBean.Type TYPE = _createType();
   static public final PropertyKey ID_KEY =
     TYPE.registerKey("id", String.class, PropertyKey.CAP_NOT_BOUND);
-  static private final PropertyKey _GENERATED_ID_KEY =
-    TYPE.registerKey("_genId", String.class, PropertyKey.CAP_NOT_BOUND);
   static public final PropertyKey RENDERED_KEY =
     TYPE.registerKey("rendered", Boolean.class, Boolean.TRUE);
   static public final PropertyKey BINDING_KEY =
@@ -307,22 +306,15 @@
 
   // ------------------------------------------------------------- Properties
 
-  @Override
-  public String getClientId(FacesContext context)
+  /**
+   * Calculates the clientId for the component
+   */
+  private String _calculateClientId(FacesContext context)
   {
-    // NOTE - client ids cannot be cached because the generated
-    // value has to be dynamically calculated in some cases (UIData)
-
+    // the clientId is always at least the id of the current component
+    // our implementation of getId() guarantees that this always
+    // returns a non-null value
     String clientId = getId();
-    if (clientId == null)
-    {
-      clientId = (String) getProperty(_GENERATED_ID_KEY);
-      if (clientId == null)
-      {
-        clientId = context.getViewRoot().createUniqueId();
-        setProperty(_GENERATED_ID_KEY, clientId);
-      }
-    }
 
     // Search for an ancestor that is a naming container
     UIComponent containerComponent = getParent();
@@ -354,13 +346,67 @@
     return clientId;
   }
 
+
+  @Override
+  public String getClientId(FacesContext context)
+  {
+    return _calculateClientId(context);
+/* TODO put back in when we fix all of the clientID caching issues
+    String clientId = _clientId;
+    
+    if (clientId == null)
+    {
+      clientId = _calculateClientId(context);
+      
+      if (_usesFacesBeanImpl)
+        _clientId = clientId;
+    }
+    else
+    {
+      assert clientId.equals(_calculateClientId(context)) :
+      "cached client id " + _clientId + " for " + this + " doesn't match client id:" + _calculateClientId(context);
+    }
+    return clientId;
+*/
+  }
+
   /**
-   * Gets the identifier for the component.
+   * Gets the identifier for the component.  This implementation
+   * never returns a null id.
    */
   @Override
   public String getId()
   {
-    return (String) getProperty(ID_KEY);
+    // determine whether we can use the optimized code path or not
+    if (_usesFacesBeanImpl)
+    {
+      // optimized path
+
+      // make sure that we always have an id
+      if (_id == null)
+      {
+        _id = FacesContext.getCurrentInstance().getViewRoot().createUniqueId();        
+      }
+
+      return _id;
+    }
+    else
+    {
+      // unoptimized path
+      FacesBean facesBean = getFacesBean();
+
+      String id = (String)facesBean.getProperty(ID_KEY);
+
+      // make sure that we always have an id
+      if (id == null)
+      {
+        id = FacesContext.getCurrentInstance().getViewRoot().createUniqueId();
+
+        facesBean.setProperty(ID_KEY, id);
+      }
+
+      return id;
+    }
   }
 
   /**
@@ -375,15 +421,35 @@
   @Override
   public void setId(String id)
   {
-    // =-=AEW Currently, setId() assumes that resetting to
-    // the same value *is not* short-circuited.
-    _validateId(id);
-    // If we're setting the ID to null, don't discard
-    // the _GENERATED_ID
-    if (id != null)
-      setProperty(_GENERATED_ID_KEY, null);
+    _clientId = null;
+
+    FacesBean facesBean = getFacesBean();
+
+    // if we are using a FacesBeanImpl, then the FacesBean will
+    // delegate all calls to set the id back to us and we can store
+    // the value localy.  Otehrwise,w e need to store it in
+    // the FacesBean
+    if (_usesFacesBeanImpl)
+    {
+      // only validate if the id has actually changed
+      if ((_id == null) || !_id.equals(id))
+      {
+        _validateId(id);
+        _id = id;
 
-    setProperty(ID_KEY, id);
+        // if we're a NamingContainer then changing our id will invalidate the clientIds of all
+        // of our children
+        if ((_clientId != null) && (this instanceof NamingContainer))
+        {
+          clearCachedClientIds(this);
+        }
+      }      
+    }
+    else
+    {
+      _validateId(id);
+      facesBean.setProperty(ID_KEY, id);      
+    }
   }
 
   @Override
@@ -590,7 +656,8 @@
   {
     if (_children == null)
       return 0;
-    return getChildren().size();
+    else
+      return getChildren().size();
   }
 
   /**
@@ -612,9 +679,11 @@
   {
     if (facetName == null)
       throw new NullPointerException();
+
     if (_facets == null)
       return null;
-    return getFacets().get(facetName);
+    else
+      return getFacets().get(facetName);
   }
 
   /**
@@ -628,7 +697,8 @@
   {
     if (_facets == null)
       return _EMPTY_STRING_ITERATOR;
-    return _facets.keySet().iterator();
+    else
+      return _facets.keySet().iterator();
   }
 
   @Override
@@ -1812,11 +1882,39 @@
     String rendererType)
   {
     FacesBean oldBean = _facesBean;
-    _facesBean = createFacesBean(rendererType);
+    FacesBean newBean = createFacesBean(rendererType);;
+
     if (oldBean != null)
-      _facesBean.addAll(oldBean);
+      newBean.addAll(oldBean);
+
+    _attributes = new ValueMap(newBean);
+
+    _facesBean = newBean;
+
+    // determine whether it is ok to store the attributes locally.  We cache the result since
+    // this can be a little involved
+    boolean usesFacesBeanImpl = false;
+
+    if (newBean instanceof UIXFacesBeanImpl)
+      usesFacesBeanImpl = true;
+    else
+    {
+      // handle the wrapped case
+      FacesBean currImpl = newBean;
 
-    _attributes = new ValueMap(_facesBean);
+      while (currImpl instanceof FacesBeanWrapper)
+      {
+        currImpl = ((FacesBeanWrapper)currImpl).getWrappedBean();
+
+        if (currImpl instanceof UIXFacesBeanImpl)
+        {
+          usesFacesBeanImpl = true;
+          break;
+        }
+      }
+    }
+
+    _usesFacesBeanImpl = usesFacesBeanImpl;
   }
 
   private FacesBean                _facesBean;
@@ -1825,6 +1923,10 @@
   private Map<String, UIComponent> _facets;
   private UIComponent              _parent;
 
+  private String                   _id;
+  private String                   _clientId;
+  private boolean                  _usesFacesBeanImpl;
+
   // Cached instance of the Renderer for this component.
   // The instance will be re-retrieved in encodeBegin()
   private transient Renderer _cachedRenderer = _UNDEFINED_RENDERER;
@@ -1836,11 +1938,9 @@
   //        So commented out, is that ok? If so, this attribute should be deleted
   //private transient boolean _initialStateMarked;
 
-  private static final Iterator<String> _EMPTY_STRING_ITERATOR =
-    new EmptyIterator<String>();
-
+  private static final Iterator<String> _EMPTY_STRING_ITERATOR = CollectionUtils.emptyIterator();
   private static final Iterator<UIComponent> _EMPTY_UICOMPONENT_ITERATOR =
-    new EmptyIterator<UIComponent>();
+    CollectionUtils.emptyIterator();
 
   static private final ThreadLocal<StringBuilder> _STRING_BUILDER =
                                                           ThreadLocalUtils.newRequestThreadLocal();
@@ -1893,25 +1993,6 @@
   {
   }
 
-  private static class EmptyIterator<T> implements Iterator<T>
-  {
-    public boolean hasNext()
-    {
-      return false;
-    }
-
-    public T next()
-    {
-      throw new NoSuchElementException();
-    }
-
-    public void remove()
-    {
-      throw new UnsupportedOperationException();
-    }
-
-  }
-
   static private final LifecycleRenderer _UNDEFINED_LIFECYCLE_RENDERER =
                                                 new ExtendedRendererImpl();
   static private final Renderer _UNDEFINED_RENDERER = new RendererImpl();

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/render/CoreRenderer.java Wed Feb 10 15:45:48 2010
@@ -103,7 +103,7 @@
 
   /**
    * <p>
-   * Called before rendering the current component's children in order to set
+   * Called before rendering the current comopnent's children in order to set
    * up any special context.
    * </p>
    * <p>If <code>setupEncodingContext</code> succeeds then
@@ -118,25 +118,47 @@
   public void setupEncodingContext(
     FacesContext     context,
     RenderingContext rc,
-    UIXComponent     component)
+    UIComponent      component)
   {
+    // TODO Remove after one release
+    if (component instanceof UIXComponent)
+      setupEncodingContext(context, rc, (UIXComponent)component);
+
   }
 
+  // TODO Remove after one release
+  @Deprecated
   public void setupEncodingContext(
-    FacesContext     context,
-    RenderingContext rc,
-    UIComponent      component)
+    @SuppressWarnings("unused") FacesContext context,
+    @SuppressWarnings("unused") RenderingContext rc,
+    @SuppressWarnings("unused") UIXComponent component)
   {
-    // temporary hack to change UIComponent.  Once the change has propagated through, we will
-    // remove the UIXComponent version.
-    // We need to support UIComponents so that we can use CoreRenderers against non-UIXComponents
-    if (component instanceof UIXComponent)
-      setupEncodingContext(context, rc, (UIXComponent)component);
   }
 
   /**
    * <p>
-   * Called after rendering the current component's children in order to tear
+   * Called before rendering the current component's children in order to set
+   * up any special context.
+   * </p>
+   * <p>If <code>setupChildrenEncodingContext</code> succeeds then
+   * <code>tearDownChildrenEncodingContext</code> will be called for the same component.
+   * </p>
+   * <p>The default implementation does nothing</p>
+   * @param context FacesContext for this request
+   * @param rc RenderingContext for this encoding pass
+   * @param component Component to encode using this Renderer
+   * @see #tearDownChildrenEncodingContext
+   */
+  public void setupChildrenEncodingContext(
+    @SuppressWarnings("unused") FacesContext context,
+    @SuppressWarnings("unused") RenderingContext rc,
+    @SuppressWarnings("unused") UIComponent component)
+  {
+  }
+
+  /**
+   * <p>
+   * Called after rendering the current component in order to tear
    * down any special context.
    * </p>
    * <p>
@@ -146,26 +168,48 @@
    * <p>The default implementation does nothing</p>
    * @param context FacesContext for this request
    * @param rc RenderingContext for this encoding pass
-   * @ param component Component to encode using this Renderer
+   * @param component Component to encode using this Renderer
    * @see #setupEncodingContext
    */
   public void tearDownEncodingContext(
     FacesContext     context,
     RenderingContext rc,
-    UIXComponent     component)
+    UIComponent     component)
   {
+    // TODO Remove after one release
+    if (component instanceof UIXComponent)
+      tearDownEncodingContext(context, rc, (UIXComponent)component);
   }
 
+  // TODO Remove after one release
+  @Deprecated
   public void tearDownEncodingContext(
-    FacesContext     context,
-    RenderingContext rc,
-    UIComponent      component)
+    @SuppressWarnings("unused") FacesContext context,
+    @SuppressWarnings("unused") RenderingContext rc,
+    @SuppressWarnings("unused") UIXComponent     component)
+  {
+  }
+
+  /**
+   * <p>
+   * Called after rendering the current component's children in order to tear
+   * down any special context.
+   * </p>
+   * <p>
+   * <code>tearDownChildrenEncodingContext</code> will be called on the component if
+   * <code>setupChildrenEncodingContext</code> succeeded.
+   * </p>
+   * <p>The default implementation does nothing</p>
+   * @param context FacesContext for this request
+   * @param rc RenderingContext for this encoding pass
+   * @param component Component to encode using this Renderer
+   * @see #setupChildrenEncodingContext
+   */
+  public void tearDownChildrenEncodingContext(
+    @SuppressWarnings("unused") FacesContext context,
+    @SuppressWarnings("unused") RenderingContext rc,
+    @SuppressWarnings("unused") UIComponent component)
   {
-    // temporary hack to change UIComponent.  Once the change has propagated through, we will
-    // remove the UIXComponent version.
-    // We need to support UIComponents so that we can use CoreRenderers against non-UIXComponents
-    if (component instanceof UIXComponent)
-      tearDownEncodingContext(context, rc, (UIXComponent)component);
   }
 
   //
@@ -250,6 +294,7 @@
    * Coerces an object into a resource URI, calling the view-handler.
    * @deprecated use toResourceUri
    */
+  @Deprecated
   static public String toUri(Object o)
   {
     return toResourceUri(FacesContext.getCurrentInstance(),o);

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/CollectionUtils.java Wed Feb 10 15:45:48 2010
@@ -26,11 +26,13 @@
 import java.lang.reflect.Array;
 
 import java.util.AbstractQueue;
+import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.ConcurrentModificationException;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -42,6 +44,7 @@
 import java.util.RandomAccess;
 import java.util.Set;
 
+import org.apache.myfaces.trinidad.component.CompositeIterator;
 import org.apache.myfaces.trinidad.context.Version;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 
@@ -145,6 +148,28 @@
     return _asSet(a, true);
   }
 
+  /**
+   * Returns an unmodifiable versions of the Set of Enums.  If the contents of the set are known
+   * to be unmodifiable by the caller in any way, the set itself will be retured, otherwise an
+   * unmodifiable copy of the Set will be returned.
+   * @param s Set to get the tamper-proof version of
+   * @return An unmodifiable tamper-proof version of the set
+   */
+  public static <E extends Enum<E>> Set<E> unmodifiableCopyOfEnumSet(Set<E> s)
+  {
+    Class<? extends Set> copyClass = s.getClass();
+
+    if ((_EMPTY_SET == copyClass) || (_SINGLETON_SET == copyClass))
+    {
+      // these classes are already unmodifiable, so just return
+      return s;
+    }
+    else
+    {
+      return Collections.unmodifiableSet(EnumSet.copyOf(s));
+    }
+  }
+
   private static <T> Set<T> _asSet(T[] a, boolean makeImmutable)
   {
     int count = (a != null) ? a.length : 0;
@@ -184,6 +209,23 @@
     return outSet;
   }
 
+  /**
+   * Given two disjoint sets, returns a live composition of the two Sets that maintains
+   * the disjoint invariant.  If both Sets are Serializable, the returned
+   * implementation will be Serializable as well.  The returned Set implementation is
+   * not thread safe.
+   * @param primarySet The Set that adds will be applied to
+   * @param secondarySet The other Set
+   * @return The composition of the two disjoint Sets
+   * @throws NullPointerException of primarySet or secondarySet are <code>null</code>
+   */
+  public static <T> Set<T> compositeSet(Set<T> primarySet, Set<T> secondarySet)
+  {
+    if ((primarySet instanceof Serializable) && (secondarySet instanceof Serializable))
+      return new SerializableFixedCompositeSet(primarySet, secondarySet);
+    else
+      return new FixedCompositeSet(primarySet, secondarySet);
+  }
 
   /**
    * Returns a Collection based on the passed in Collection <code>c</code>,
@@ -412,7 +454,273 @@
       return getDelegate().toString();
     }
   }
+
+  /**
+   * Note: Requires contents to be disjoint!
+   * @param <E>
+   */
+  protected abstract static class CompositeCollection<E> implements Collection<E>
+  {
+    protected abstract Collection<E> getPrimaryDelegate();
+    protected abstract Collection<E> getSecondaryDelegate();
+
+    public int size()
+    {
+      return getPrimaryDelegate().size() + getSecondaryDelegate().size();
+    }
+
+    public boolean isEmpty()
+    {
+      return getPrimaryDelegate().isEmpty() || getSecondaryDelegate().isEmpty();
+    }
+
+    public boolean contains(Object o)
+    {
+      return getPrimaryDelegate().contains(o) || getSecondaryDelegate().contains(o);
+    }
+
+    public Iterator<E> iterator()
+    {
+      return new CompositeIterator(getPrimaryDelegate().iterator(),
+                                   getSecondaryDelegate().iterator());
+    }
+
+    public Object[] toArray()
+    {
+      int size = size();
+      
+      Object[] out = new Object[size];
+      
+      int i = 0;
+      for (Object currObject : this)
+      {
+        out[i] = currObject;
+        
+        i++;
+        
+        if (i == size)
+          break;
+      }
+      
+      return out;
+    }
+
+    public <T> T[] toArray(T[] outArray)
+    {
+      int collectionSize = size();
+      int arraySize = outArray.length;
+      
+      // size isn't big enough, so need a new array
+      if (collectionSize > arraySize)
+      {
+        outArray = (T[])Array.newInstance(outArray.getClass().getComponentType(),
+                                          collectionSize);
+      }
+
+      Iterator<E> iterator = this.iterator();
+      
+      for (int i = 0; i < collectionSize; i++)
+      {
+        if (!iterator.hasNext())
+          break;
+        
+        outArray[i] = (T)iterator.next();
+      }
+      
+      return outArray;
+    }
+
+    public boolean add(E e)
+    {
+      return getPrimaryDelegate().add(e);
+    }
+
+    public boolean remove(Object o)
+    {
+      boolean removed = getPrimaryDelegate().remove(0);
+      
+      if (!removed)
+        removed = getSecondaryDelegate().remove(0);
+      
+      return removed;
+    }
+
+    public boolean containsAll(Collection<?> c)
+    {
+      // find all of the items in both the collection and the primary delegate
+      
+      Set<Object> intersection = new HashSet<Object>(getPrimaryDelegate());
+      intersection.retainAll(c);
+            
+      if (intersection.size() == c.size())
+      {
+        // the primary delegate contained all of the items, so we're done
+        return true;
+      }
+      else
+      {
+        // compute the set of items we still haven't match in order to check against the
+        // secondary delegate
+        Set<Object> remainder = new HashSet<Object>(c);
+        remainder.removeAll(intersection);
+        
+        return getSecondaryDelegate().containsAll(remainder);
+      }
+    }
+
+    public boolean addAll(Collection<? extends E> c)
+    {
+      // determine the result ahead of time
+      boolean changed = !containsAll(c);
+      
+      // make sure that the collections maintain disjointness
+      getSecondaryDelegate().removeAll(c);
+      getPrimaryDelegate().addAll(c);
+      
+      return changed;
+    }
+
+    public boolean removeAll(Collection<?> c)
+    {
+      return getPrimaryDelegate().removeAll(c) || getSecondaryDelegate().removeAll(c);
+    }
+
+    public boolean retainAll(Collection<?> c)
+    {
+      return getPrimaryDelegate().retainAll(c) || getSecondaryDelegate().retainAll(c);
+    }
+
+    public void clear()
+    {
+      getPrimaryDelegate().clear();
+      getSecondaryDelegate().clear();
+    }
+    
+    @Override
+    public String toString()
+    {
+      return super.toString() + 
+             "[primary:" + 
+             getPrimaryDelegate() +
+             ", secondary:" +
+             getSecondaryDelegate() +
+             "]";
+    }
+  }
+  
+  /**
+   * Note: Requires contents to be disjoint!
+   * @param <E>
+   */
+  protected abstract static class CompositeSet<E> extends CompositeCollection<E> implements Set<E>
+  {
+    @Override
+    protected abstract Set<E> getPrimaryDelegate();
     
+    @Override
+    protected abstract Set<E> getSecondaryDelegate();
+
+    /**
+     * Implement Set-defined equals behavior 
+     */
+    @Override
+    public boolean equals(Object o)
+    {
+      if (o == this)
+        return true;
+      else if (!(o instanceof Set))
+        return false;
+      else
+      {
+        Collection other = (Collection) o;
+
+        if (other.size() != size())
+        {
+          return false;
+        }
+        else
+        {
+          // since the sizes are the same, if we contain all of the other collection's
+          // elements, we are identical
+          try
+          {
+            return containsAll(other);
+          }
+          catch(NullPointerException npe)
+          {
+            // optional NullPointerException that containsAll is allowed to throw
+            return false;
+          }
+          catch(ClassCastException npe)
+          {
+            // optional ClassCastException that containsAll is allowed to throw
+            return false;
+          }
+        }
+      }
+    }
+
+    /**
+     * Implement Set-defined equals behavior 
+     */
+    @Override
+    public int hashCode()
+    {
+      // Set defines hashCode() as additive based on the contents
+      return getPrimaryDelegate().hashCode() + getSecondaryDelegate().hashCode();
+    }
+  }
+  
+  /**
+   * Concrete Composite Set that takes the two sets to compose
+   */
+  private static class FixedCompositeSet<E> extends CompositeSet<E>
+  {
+    FixedCompositeSet(Set<E> primarySet, Set<E> secondarySet)
+    {
+      if (primarySet == null)
+        throw new NullPointerException();
+
+      if (secondarySet == null)
+        throw new NullPointerException();
+      
+      assert Collections.disjoint(primarySet, secondarySet) : "Composed Sets not disjoint";
+      
+      _primarySet   = primarySet;
+      _secondarySet = secondarySet;
+    }
+
+    @Override
+    protected Set<E> getPrimaryDelegate()
+    {
+      return _primarySet;
+    }
+    
+    @Override
+    protected Set<E> getSecondaryDelegate()
+    {
+      return _secondarySet;
+    }
+    
+    private final Set<E> _primarySet;
+    private final Set<E> _secondarySet;
+  }
+
+  /**
+   * Serializable version of FixedCompositeSet
+   * @param <E>
+   */
+  private static final class SerializableFixedCompositeSet<E> extends FixedCompositeSet<E>
+                                                              implements Serializable
+  {
+    SerializableFixedCompositeSet(Set<E> primarySet, Set<E> secondarySet)
+    {
+      super(primarySet, secondarySet);
+    }
+
+    private static final long serialVersionUID = 0L;
+  }
+
   private static class SerializableCollection<E> extends DelegatingCollection<E>
                                                  implements Serializable
   {
@@ -633,6 +941,7 @@
   private final static class CheckedSerializationMap<K, V> extends DelegatingMap<K,V>
                                                            implements Serializable
   {
+
     public CheckedSerializationMap(Map<K, V> delegate)
     {
       if (delegate == null)
@@ -965,6 +1274,8 @@
   private static final Class<? extends List> _CHECKED_LIST;
   private static final Class<? extends List> _UNMODIFIABLE_LIST;
   private static final Class<? extends List> _SYNCHRONIZED_LIST;
+  private static final Class<? extends Set> _EMPTY_SET = Collections.emptySet().getClass();
+  private static final Class<? extends Set> _SINGLETON_SET = Collections.singleton(null).getClass();
   private static final Queue _EMPTY_QUEUE = new EmptyQueue();
   private static final Iterator _EMPTY_ITERATOR = new EmptyIterator();
   private static final Iterator _EMPTY_LIST_ITERATOR = new EmptyListIterator();
@@ -980,7 +1291,7 @@
     _UNMODIFIABLE_LIST = Collections.unmodifiableList(dummyList).getClass();
     _SYNCHRONIZED_LIST = Collections.synchronizedList(dummyList).getClass();
   }
-  
+
   private static final TrinidadLogger _LOG = 
                                         TrinidadLogger.createTrinidadLogger(CollectionUtils.class);
 

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-api/src/main/java/org/apache/myfaces/trinidad/webapp/ResourceServlet.java Wed Feb 10 15:45:48 2010
@@ -208,7 +208,7 @@
     connection.setDoInput(true);
     connection.setDoOutput(false);
 
-    _setHeaders(connection, response);
+    _setHeaders(connection, response, loader);
 
     InputStream in = connection.getInputStream();
     OutputStream out = response.getOutputStream();
@@ -529,11 +529,12 @@
    */
   private void _setHeaders(
     URLConnection       connection,
-    HttpServletResponse response)
+    HttpServletResponse response,
+    ResourceLoader      loader)
   {
     String resourcePath;
     URL    url;
-    String contentType  = connection.getContentType();
+    String contentType  = ResourceLoader.getContentType(loader, connection);
 
     if (contentType == null || "content/unknown".equals(contentType))
     {
@@ -550,26 +551,26 @@
       else
         contentType = getServletContext().getMimeType(resourcePath);
 
-      // The resource has an file extension we have not 
+      // The resource has an file extension we have not
       // included in the case statement above
       if (contentType == null)
       {
-        _LOG.warning("ResourceServlet._setHeaders(): " +  
+        _LOG.warning("ResourceServlet._setHeaders(): " +
                      "Content type for {0} is NULL!\n" +
                      "Cause: Unknown file extension",
                      resourcePath);
       }
     }
-    
+
     if (contentType != null)
     {
-      response.setContentType(contentType);    
+      response.setContentType(contentType);
       int contentLength = connection.getContentLength();
 
       if (contentLength >= 0)
         response.setContentLength(contentLength);
     }
-    
+
     long lastModified;
     try
     {
@@ -669,7 +670,6 @@
   // cutting back just to be safe.)
   public static final long ONE_YEAR_MILLIS = 31363200000L;
 
-  
   private static final Class[] _DECORATOR_SIGNATURE =
                                   new Class[]{ResourceLoader.class};
 

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java Wed Feb 10 15:45:48 2010
@@ -114,34 +114,37 @@
 
   public boolean checkStylesModified()
   {
+    FacesContext context = FacesContext.getCurrentInstance();
+    String checkTimestamp =
+      context.getExternalContext().getInitParameter(Configuration.CHECK_TIMESTAMP_PARAM);
+
+    // in production stage we don't want TRUE here;
+    // a WARNING will be triggered by the ViewHandlerImpl.java
+    return "true".equals(checkTimestamp);
+  }
 
+  /*
+   * checks to see if the Skin is dirty by calling skin.isDirty()
+   */
+  public boolean isDirty()
+  {
     if (Beans.isDesignTime())
     {
       // In Design Time mode, if we have a skin-id on the request scope,
-      // then this means we want to check if the skin css files are modified.
-      // This is an alternative to the initParam (CHECK_TIMESTAMP_PARAM) which
-      // is set in web.xml. Design Time cannot set the web.xml file.
+      // then this means the Design Time wants the skin to regenerate. To do this,
+      // we say the skin is dirtys
       FacesContext context = FacesContext.getCurrentInstance();
       Object requestSkinId = 
         ((CoreRenderingContext) _arc).getRequestMapSkinId(context);
-
       if (requestSkinId != null)
       {
+        // set the skin to dirty as well for double insurance, like if someone checks the 
+        // skin directly to see if it is dirty.
+        _arc.getSkin().setDirty(true); 
         return true;
       }
     }
-
-    // TODO: similar code is present in the ViewHanlder;
-    // this needs to be factored out into a common util.
-    // See TRINIDAD-1662
-    
-    FacesContext context = FacesContext.getCurrentInstance();
-    String checkTimestamp =
-      context.getExternalContext().getInitParameter(Configuration.CHECK_TIMESTAMP_PARAM);
-
-    // in production stage we don't want TRUE here;
-    // a WARNING will be triggered by the ViewHandlerImpl.java
-    return "true".equals(checkTimestamp);
+    return _arc.getSkin().isDirty();
   }
 
   public boolean disableStandardsMode()

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java Wed Feb 10 15:45:48 2010
@@ -111,16 +111,6 @@
   public void setupEncodingContext(
     FacesContext     context,
     RenderingContext rc,
-    UIXComponent     component)
-  {
-    // temp hack
-    setupEncodingContext(context, rc, (UIComponent)component);
-  }
-
-  @Override
-  public void setupEncodingContext(
-    FacesContext     context,
-    RenderingContext rc,
     UIComponent      component)
   {
     String formName = getClientId(context, component);
@@ -439,16 +429,6 @@
   public void tearDownEncodingContext(
     FacesContext     context,
     RenderingContext rc,
-    UIXComponent     component)
-  {
-    // temp hack
-    tearDownEncodingContext(context, rc, (UIComponent)component);
-  }
-
-  @Override
-  public void tearDownEncodingContext(
-    FacesContext     context,
-    RenderingContext rc,
     UIComponent      component)
   {
     // Clear out the form name property

Added: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/TrinidadRenderingConstants.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/TrinidadRenderingConstants.java?rev=908546&view=auto
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/TrinidadRenderingConstants.java (added)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/TrinidadRenderingConstants.java Wed Feb 10 15:45:48 2010
@@ -0,0 +1,231 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.myfaces.trinidadinternal.renderkit.core.xhtml;
+
+import org.apache.myfaces.trinidadinternal.renderkit.core.CoreRenderKit;
+
+/**
+ * Class that contains misc constants used by several renderers.
+ * Class contains details about events, parameters and other useful stuff. 
+ */
+public final class TrinidadRenderingConstants
+{
+  private TrinidadRenderingConstants(){}
+  
+  // Input components
+  public static final String AUTOSUBMIT_EVENT = "autosub";
+
+  // Mobile dateField and LovField
+  // "picker" events and types
+  public static final String DATE_EVENT   = "date";
+  public static final String CANCEL_EVENT = "cancel";
+  public static final String TYPE_POST    = "post";
+
+  // NavigationBar
+  public static final String GOTO_EVENT = "goto";
+
+  // HideShow
+  public static final String HIDE_EVENT = "hide";
+  public static final String SHOW_EVENT = "show";
+
+  // HGrid
+  public static final int INCOMPLETE_DATA_SET = -1;
+  
+  // SortableHeader
+  public static final String SORT_EVENT = "sort";
+
+  // Poll
+  public static final String POLL_EVENT = "poll";
+
+  // Chart Drill down
+  public static final String CHART_DRILL_DOWN_EVENT = "chartDrillDown";
+
+  /**
+   * Constant for the value of the "value" event parameter when
+   * the user is asking to see all rows.
+   */
+  public static final String VALUE_SHOW_ALL = "all";
+
+  //
+  // Context Property Names
+  //
+  /**
+   * String rendering property for the name of the current form bean.
+   */
+  public static final String FORM_NAME_PROPERTY   = "formName";
+
+  /**
+   * Key used to store the initialFocus on the RenderingContext
+   * under the UIConstants.MARLIN_NAMESPACE. initialFocus is an attribute
+   * of body and is an id indicating the component
+   * which should have the initial focus.
+   */
+  public static final Object INITIAL_FOCUS_CONTEXT_PROPERTY = "initialFocus";
+  
+  //
+  // parameter names
+  //
+  public static final String PARTIAL_PARAM         = "partial";
+  public static final String PARTIAL_TARGETS_PARAM = "partialTargets";
+  public static final String SIZE_PARAM            = "size";
+  public static final String SOURCE_PARAM          = "source";
+  public static final String STATE_PARAM           = "state";
+  public static final String TYPE_PARAM            = "type";
+  public static final String VALUE_PARAM           = "value";
+  public static final String TARGETITEM_PARAM      = "targetItem";
+
+  //
+  // parameter values
+  //
+  // calendar, mobile dateField params
+  public static final String EVENT_PARAM          = "event";
+  public static final String LOC_PARAM            = "loc";
+  public static final String MAX_VALUE_PARAM      = "maxValue";
+  public static final String MIN_VALUE_PARAM      = "minValue";
+  public static final String MONTH_PARAM          = "month";
+  public static final String SCROLLED_VALUE_PARAM = "scrolledValue";
+  public static final String YEAR_PARAM           = "year";
+  
+  //
+  // Named Children
+  //
+  public static final String PATH_STAMP_CHILD = "pathStamp";
+
+  // MAX_VALUE_ATTR
+  public static final int MAX_VALUE_UNKNOWN = -1;
+
+  // MESSAGE_TYPE_ATTR
+  /**
+   * Message type if the associated message is informational.
+   */
+  public static final String MESSAGE_TYPE_INFO = "info";
+
+  /**
+   * Message type if the associated message is a warning.
+   */
+  public static final String MESSAGE_TYPE_WARNING = "warning";
+
+  /**
+   * Message type if the associated message is an error.
+   */
+  public static final String MESSAGE_TYPE_ERROR = "error";
+
+  /**
+   * Message type if the associated message is a confirmation.
+   */
+  public static final String MESSAGE_TYPE_CONFIRMATION = "confirmation";
+
+  /**
+   * Message type if the page layout messageType is processing.
+   */
+  public static final String MESSAGE_TYPE_PROCESSING = "processing";
+  
+  /**
+   * Message type if there is no type of message.
+   */
+  public static final String MESSAGE_TYPE_NONE = "none";
+  
+  // SORTABLE_ATTR
+  /**
+   * Sortable value if the table column is sortable and is currently
+   * sorted with ascending values down the column.
+   */
+  public static final String SORTABLE_ASCENDING = "ascending";
+
+  /**
+   * Sortable value if the table column is sortable and is currently
+   * sorted with descending values down the column.
+   */
+  public static final String SORTABLE_DESCENDING = "descending";
+
+  /**
+   * The default text used for a secret field.
+   * When working with password fields, compare the value submitted
+   * with this value. If they are the same, then the user did not modify
+   * the field.
+   */
+  public static final String SECRET_FIELD_DEFAULT_VALUE = "******";
+
+  // ORIENTATION_ATTR
+  /**
+   * Value to indicate orientation is vertical (currently used by BreadCrumbs)
+   */
+  public final static String ORIENTATION_VERTICAL="vertical";
+
+  public static final String SELECTED_KEY = "selected";
+
+  // ===================== End of copy from UIConstants =======================
+
+  public static final String STYLES_CACHE_DIRECTORY = "/adf/styles/cache/";
+  public static final String OUTPUT_MODE_PORTLET = org.apache.myfaces.trinidad.render.XhtmlConstants.FACET_PORTLET;
+  
+  //
+  // Copied from BaseDesktopConstants
+  //
+  public static final String BASE_DESKTOP_ID = "base.desktop";
+
+  //
+  // Copied from XhtmlLafConstants
+  //
+  public static final String APACHE_TRINIDAD_DESKTOP = 
+    "org.apache.myfaces.trinidad.desktop";
+  public static final String APACHE_TRINIDAD_PDA = 
+    "org.apache.myfaces.trinidad.pda";
+  public static final String APACHE_TRINIDAD_PORTLET = 
+    CoreRenderKit.OUTPUT_MODE_PORTLET;
+
+  // skin family names constants
+  public static final String CASABLANCA_SKIN_FAMILY = "casablanca";
+  public static final String MINIMAL_SKIN_FAMILY = "minimal";
+
+  public static final String COLOR_PALETTE_TRANSPARENT_ICON_NAME = "cpt.gif";
+  
+  // 'xc' stands for uiX Composite
+  // -= Simon =-
+  // FIXME: Should it be renamed to remove UIX reference?
+  public static final String COMPOSITE_ID_EXTENSION = "__xc_";
+  
+  // context property to indicate that form elements are repeated and the
+  // data needs to be kept in sync
+  public static final Object REPEAT_PROPERTY = new Object();
+
+  //Constants for Non JavaScript browser support
+  public static final String NO_JS_PARAMETER_KEY = "_parameterkey";
+  public static final String NO_JS_INPUT_IMAGE_KEY = "_inputImagekey";
+  public static final String MULTIPLE_VALUE_PARAM = "multipleValueParam";
+  public static final String NO_JS_PARAMETER_KEY_BUTTON = "Go";
+  public static final String NO_JS_PARAMETER_BACK_BUTTON = "Back";
+  public static final String NO_JS_PARAMETER_NEXT_BUTTON = "Next";
+  
+  public static final String NON_JS_BROWSER = "_noJavaScript";
+  public static final String NON_JS_BROWSER_TRUE = "true";
+  public static final String NON_JS_DETAIL_DISCLOSED_ICON = "-";
+  public static final String NON_JS_DETAIL_UNDISCLOSED_ICON = "+";
+  public static final String NON_JS_ASC_ICON = "v";
+  public static final String NON_JS_DESC_ICON = "^";
+  
+  // Maximum width of a narrow-screen PDA device in pixels
+  public static final int NARROW_SCREEN_PDA_MAX_WIDTH = 240; 
+  
+  // The name of the hidden parameter that stores the value of the 
+  // request-header, UA-pixels. This hidden paramter is rendered only 
+  // for windows mobile.
+  public static final String WINDOWS_MOBILE_UAPIXELS = "uapixels";
+
+}
\ No newline at end of file

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinCSSDocumentHandler.java Wed Feb 10 15:45:48 2010
@@ -19,13 +19,17 @@
 package org.apache.myfaces.trinidadinternal.skin;
 
 import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.ArrayList;
+import java.util.Locale;
 import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.LinkedList;
 
 import org.apache.myfaces.trinidad.context.Version;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
@@ -110,6 +114,7 @@
        CompleteSelectorNode node =
          _createCompleteSelectorNode(selector,
                                      _propertyNodeList,
++                                     _locales,
                                      _agentAtRuleMatcher,
                                      _selectorPlatforms,
                                      _getSelectorAccProperties());
@@ -187,6 +192,10 @@
       {
         _parseCustomAtRule(_AT_PLATFORM, atRule);
       }
+      else if (atRule.startsWith(_AT_LOCALE))
+      {
+        _parseCustomAtRule(_AT_LOCALE, atRule);
+      }
       else if (atRule.startsWith(_AT_ACC_PROFILE))
       {
         _parseCustomAtRule(_AT_ACC_PROFILE, atRule);
@@ -202,8 +211,8 @@
    */
   private void _parseCustomAtRule(String type, String atRule)
   {
-    // get the @agent agents, they are deliminated by commas
-    // parse out the content
+    // get the @agent agents, @platform platforms or the @locale locales 
+    // they are deliminated by commas parse out the content
     // save the atRule type, so the document handler code can get to it.
     // run this through parser again
     String content = _getAtRuleContent(atRule);
@@ -226,6 +235,8 @@
       _agentAtRuleMatcher = null;
     else if (_AT_PLATFORM.equals(type))
       _selectorPlatforms = null;
+    else if (_AT_LOCALE.equals(type))
+      _locales = null;
     else if (_AT_ACC_PROFILE.equals(type))
     {
       assert(!_selectorAccPropertiesStack.isEmpty());
@@ -240,6 +251,7 @@
   private CompleteSelectorNode _createCompleteSelectorNode(
     String                     selector,
     List<PropertyNode>         propertyNodeList,
+    Set<Locale>                locales,
     AgentAtRuleMatcher         agentMatcher,
     int[]                      selectorPlatforms,
     Set<String>                selectorAccProperties)
@@ -266,6 +278,7 @@
       new CompleteSelectorNode(
         selector,
         propertyNodeList,
+        locales,
         direction,
         agentMatcher,
         selectorPlatforms,
@@ -293,6 +306,7 @@
       int direction = completeSelectorNode.getDirection();
       AgentAtRuleMatcher agentMatcher = completeSelectorNode.getAgentMatcher();
       int[] platforms = completeSelectorNode.getPlatforms();
+      Set<Locale> locales = completeSelectorNode.getLocales();
       Set<String> accProperties = completeSelectorNode.getAccessibilityProperties();
 
       // loop through the skinStyleSheetNodeList to find a match
@@ -304,7 +318,8 @@
       for (int i = skinStyleSheetNodes.size() - 1; i >= 0 && !match; --i)
       {
         SkinStyleSheetNode ssNode = skinStyleSheetNodes.get(i);
-        match = ssNode.matches(direction, agentMatcher, platforms, accProperties);
+        match = ssNode.matches(direction, agentMatcher, platforms, locales, accProperties);
+
         if (match)
           ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
       }
@@ -313,7 +328,7 @@
       {
         // no matching stylesheet node found, so create a new one
         SkinStyleSheetNode ssNode =
-         new SkinStyleSheetNode(namespaceMap, direction, agentMatcher, platforms, accProperties);
+         new SkinStyleSheetNode(namespaceMap, direction, locales, agentMatcher, platforms, accProperties);
         ssNode.add(completeSelectorNode.getSkinSelectorPropertiesNode());
         skinStyleSheetNodes.add(ssNode);
       }
@@ -324,7 +339,7 @@
   /**
    * Initialized at rule target types.
    * 
-   * @param type type of the at rule. _AT_AGENT, _AT_PLATFORM, or _AT_ACC_PROFILE
+   * @param type type of the at rule. _AT_AGENT, _AT_PLATFORM, _AT_ACC_PROFILE or _AT_LOCALE
    * @param atRule - the atRule string
    */
   private void _initAtRuleTargetTypes(
@@ -359,6 +374,15 @@
         
         _selectorPlatforms = _getIntArray(list);
       }
+      else if (_AT_LOCALE.equals(type))
+      {
+        _locales = new HashSet<Locale>();
+        for (int i = 0; i < typeArray.length; i++)
+        {
+          Locale locale = LocaleUtils.getLocaleForIANAString(typeArray[i].replace('_', '-').trim());
+          _locales.add(locale);
+        }
+      }
       else if (_AT_ACC_PROFILE.equals(type))
       {
         // The number of profile properties is always going to be
@@ -501,6 +525,7 @@
     public CompleteSelectorNode(
       String                     selectorName,
       List<PropertyNode>         propertyNodes,
+      Set<Locale>                locales,
       int                        direction,
       AgentAtRuleMatcher         agentMatcher,
       int[]                      platforms,
@@ -514,6 +539,8 @@
       // at the end of the @rule parsing.
       _agentMatcher = agentMatcher;
       _platforms = _copyIntArray(platforms);
+      _locales = ((locales != null) ? new HashSet<Locale>(locales)
+            :Collections.<Locale>emptySet());
       
       if (accProperties != null)
       {
@@ -551,6 +578,11 @@
       return _platforms;
     }
 
+    public Set<Locale> getLocales()
+    {
+      return _locales;
+    }
+
     public Set<String> getAccessibilityProperties()
     {
       return _accProperties;
@@ -572,12 +604,14 @@
     private final int _direction;  // the reading direction
     private final AgentAtRuleMatcher _agentMatcher;
     private final int[] _platforms;
+    private final Set<Locale> _locales; 
     private final Set<String> _accProperties;
   }
 
-  private static String _AT_AGENT = "@agent";
-  private static String _AT_PLATFORM = "@platform";
-  private static String _AT_ACC_PROFILE = "@accessibility-profile";
+  private static final String _AT_AGENT = "@agent";
+  private static final String _AT_PLATFORM = "@platform";
+  private static final String _AT_LOCALE = "@locale";
+  private static final String _AT_ACC_PROFILE = "@accessibility-profile";
 
   // below are properties that we set and reset
   // as the methods of this documentHandler get called.
@@ -594,6 +628,9 @@
   // matches the current Agent against the allowed agents
   private AgentAtRuleMatcher _agentAtRuleMatcher = null;
 
+  // the locales of the selectors parsed in this document.
+  private Set<Locale> _locales = 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.

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleSheetNode.java Wed Feb 10 15:45:48 2010
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
 
@@ -41,11 +42,13 @@
     List<SkinSelectorPropertiesNode> skinSelectorNodeList,
     Map<String, String>              namespaceMap,
     int                              direction,
+    Set<Locale>                      locales,
     AgentAtRuleMatcher               agentMatcher,
     Set<String>                      accProperties)
   {
     _skinSelectorNodeList = skinSelectorNodeList;
     _namespaceMap = namespaceMap;
+    _locales = locales;
     _direction = direction;
     _agentMatcher = agentMatcher;
     _platforms     = null;
@@ -55,12 +58,14 @@
   SkinStyleSheetNode(
     Map<String, String>        namespaceMap,
     int                        direction,
+    Set<Locale>                locales,
     AgentAtRuleMatcher         agentMatcher,
     int[]                      platforms,
     Set<String>                accProperties)
   {
     _namespaceMap = namespaceMap;
     _direction = direction;
+    _locales = locales;
     _agentMatcher = agentMatcher;
     _platforms = platforms;
     _accProperties = accProperties;
@@ -113,6 +118,11 @@
     return _platforms;
   }
 
+  public Set<Locale> getLocales()
+  {
+    return _locales;
+  }
+
   public Set<String> getAcessibilityProperties()
   {
     return _accProperties;
@@ -122,6 +132,7 @@
     int                        direction,
     AgentAtRuleMatcher         agentMatcher,
     int[]                      platforms,
+    Set<Locale>                locales,
     Set<String>                accProperties)
   {
     if (direction == _direction)
@@ -133,10 +144,13 @@
         boolean platformsMatch = _intArraysEqual(platforms, _platforms);
         if (platformsMatch)
         {
-          boolean accMatch = _setsEqual(accProperties, _accProperties);
-
-          if (accMatch)
-            return true;
+          boolean localeMatch = _setsEqual(locales, _locales);
+          if (localeMatch)
+          {
+            boolean accMatch = _setsEqual(accProperties, _accProperties);
+            if (accMatch)
+             return true;
+          }
         }
       }
     }
@@ -167,5 +181,6 @@
   private final int _direction; // reading direction
   private final AgentAtRuleMatcher _agentMatcher;
   private final int[] _platforms;
+  private final Set<Locale> _locales;
   private final Set<String> _accProperties;
 }

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNode.java Wed Feb 10 15:45:48 2010
@@ -25,12 +25,10 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 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.AgentAtRuleMatcher;
 import org.apache.myfaces.trinidadinternal.style.util.ModeUtils;
@@ -43,8 +41,12 @@
  * Private implementation of StyleSheetNode. A StyleSheetNode has StyleNodes for particular
  * browsers, direction, versions, platforms and mode.  In addition, the StyleSheetNode
  * provides access to IconNodes representing the icons which were defined within
- * the context of this style sheet.
- *
+ * the context of this style sheet. StyleSheetNodes are contained in StyleSheetDocuments.
+ * And a StyleSheetNode is created for both .xss skin files and .css files.
+ * .xss skin files create StyleSheetNodes via StyleSheetNodeParser
+ * .css skin files create StyleSheetNodes via SkinStyleSheetParserUtils
+ * @see StyleSheetNodeParser
+ * @see org.apache.myfaces.trinidadinternal.skin.SkinStyleSheetParserUtils
  * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/style/xml/parse/StyleSheetNode.java#0 $) $Date: 10-nov-2005.18:58:46 $
  */
 public class StyleSheetNode
@@ -57,7 +59,7 @@
     StyleNode[] styles,
     Collection<IconNode> icons,
     Collection<SkinPropertyNode> skinProperties,
-    Locale[] locales,
+    Set<Locale> locales,
     int direction,
     AgentAtRuleMatcher agentMatcher,
     int[] platforms,
@@ -86,8 +88,7 @@
     // locales, browsers, versions, platforms order does not matter, so these are Sets.
     if (locales != null)
     {
-      Set<Locale> localesSet = _copyLocaleArrayToSet(locales);
-      _locales = Collections.unmodifiableSet(localesSet);
+      _locales = Collections.unmodifiableSet(locales);
     }
     else
       _locales = Collections.emptySet();
@@ -331,6 +332,9 @@
 
     int match = 0;
 
+    if (_locales.contains(locale))
+        return _LOCALE_EXACT_MATCH;
+
     for (Locale tmpLocale : _locales)
     {
       if (tmpLocale.getLanguage().equals(locale.getLanguage()))

Modified: myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java?rev=908546&r1=908545&r2=908546&view=diff
==============================================================================
--- myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java (original)
+++ myfaces/trinidad/branches/matzewTrinidad2002/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetNodeParser.java Wed Feb 10 15:45:48 2010
@@ -21,12 +21,10 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
 
@@ -41,11 +39,14 @@
 import org.apache.myfaces.trinidadinternal.style.StyleConstants;
 import org.apache.myfaces.trinidadinternal.style.util.NameUtils;
 import org.apache.myfaces.trinidadinternal.style.xml.XMLConstants;
+import org.apache.myfaces.trinidadinternal.util.nls.LocaleUtils;
 import org.xml.sax.Attributes;
 import org.xml.sax.SAXParseException;
 
 /**
- * NodeParser for style sheet nodes
+ * NodeParser for style sheet nodes. This class is thread-safe since it is created each time 
+ * with newInstance(). Therefore we do not synchronize.
+ * This parses the XSS file and creates a StyleSheetNode object.
  * @version $Name:  $ ($Revision: adfrt/faces/adf-faces-impl/src/main/java/oracle/adfinternal/view/faces/style/xml/parse/StyleSheetNodeParser.java#0 $) $Date: 10-nov-2005.18:58:47 $
  */
 public class StyleSheetNodeParser extends BaseNodeParser
@@ -66,9 +67,9 @@
     _direction = NameUtils.getDirection(attrs.getValue(DIRECTION_ATTR));
     _mode = NameUtils.getMode(attrs.getValue(MODE_ATTR));
     _browsers = _initBrowsers(attrs.getValue(BROWSERS_ATTR));
-    _initVersions(attrs.getValue(VERSIONS_ATTR));
-    _initPlatforms(attrs.getValue(PLATFORMS_ATTR));
-    _initAccessibilityProperties(attrs.getValue(ACC_PROFILE_ATTR));
+    _versions = _initVersions(attrs.getValue(VERSIONS_ATTR));
+    _platforms = _initPlatforms(attrs.getValue(PLATFORMS_ATTR));
+    _accProperties = _initAccessibilityProperties(attrs.getValue(ACC_PROFILE_ATTR));
   }
 
   /**
@@ -84,8 +85,7 @@
     StyleNode[] styles = null;
     if (_styles != null)
     {
-      styles = new StyleNode[_styles.size()];
-      _styles.copyInto(styles);
+      styles = _styles.toArray(new StyleNode[_styles.size()]);
     }
     // Do not create an agentMatcher if there are no browsers or versions to compare against.
     // This way a styleSheetNode will match any browser if it hasn't specified a specific browser.
@@ -136,52 +136,32 @@
     if (child instanceof StyleNode)
     {
       if (_styles == null)
-        _styles = new Vector<StyleNode>();
+        _styles = new ArrayList<StyleNode>();
 
-      _styles.addElement((StyleNode)child);
+      _styles.add((StyleNode)child);
     }
   }
 
-  // Converts a string to a locale
-  private Locale _getLocale(String str)
-  {
-    // Language only
-    int length = str.length();
-    if (length == 2)
-      return new Locale(str, "");
-
-    // Locale and country
-    if ((length == 5) && (str.charAt(2) == '_'))
-      return new Locale(str.substring(0, 2), str.substring(3, 5));
-
-    // We don't handle variants at the moment...
-
-    return null;
-  }
-
   // Initialize locales
-  private void _initLocales(String localeAttr)
+  private Set<Locale> _initLocales(String localeAttr)
   {
-    if (localeAttr == null)
-      return;
-
-    // -= Simon Lessard =-
-    // TODO: Check if synchronization is really needed.
-    Vector<Locale> locales = new Vector<Locale>();
     Iterator<String> tokens = _getTokens(localeAttr);
+    
+    if (tokens == null)
+      return Collections.emptySet();
+    
+    Set<Locale> locales = new HashSet<Locale>();
+    
     while (tokens.hasNext())
     {
-      Locale locale = _getLocale(tokens.next());
+      String localeString = tokens.next();
+      // TODO: check if the replace of _ with - is really necessary. Also see RequestContextImpl.getFormattingLocale()
+      Locale locale = LocaleUtils.getLocaleForIANAString(localeString.replace('_', '-').trim());
 
       if (locale != null)
-        locales.addElement(locale);
-    }
-
-    if (locales != null)
-    {
-      _locales = new Locale[locales.size()];
-      locales.copyInto(_locales);
+        locales.add(locale);
     }
+    return locales;
   }
 
   // Initialize browsers
@@ -205,16 +185,13 @@
   }
 
   // Initialize version
-  private void _initVersions(String versionAttr)
+  private Version[] _initVersions(String versionAttr)
   {
     Iterator<String> versions = _getTokens(versionAttr);
     if (versions == null)
-      return;
-
-    // -= Simon Lessard =-
-    // TODO: Check if synchronization is really needed.
-    
-    Vector<Version> v = new Vector<Version>();
+      return null;
+  
+    List<Version> v = new ArrayList<Version>();
     while (versions.hasNext())
     {
       String version = versions.next();
@@ -224,19 +201,17 @@
       }
     }
     
-    _versions = v.toArray(new Version[v.size()]);
+    return v.toArray(new Version[v.size()]);
   }
 
   // Initialize platforms
-  private void _initPlatforms(String platformAttr)
+  private int[] _initPlatforms(String platformAttr)
   {
     Iterator<String> platforms = _getTokens(platformAttr);
     if (platforms == null)
-      return;
+      return null;
 
-    // -= Simon Lessard =-
-    // TODO: Check if synchronization is really needed.
-    Vector<Integer> v = new Vector<Integer>();
+    List<Integer> v = new ArrayList<Integer>();
     while (platforms.hasNext())
     {
       String platformName = platforms.next();
@@ -247,18 +222,18 @@
         platform = StyleSheetNode.__OS_UNIX;
 
       if (platform != TrinidadAgent.OS_UNKNOWN)
-        v.addElement(platform);
+        v.add(platform);
     }
 
-    _platforms = _getIntegers(v);
+    return _getIntegers(v);
   }
 
   // Initialize accessibility profile properties
-  private void _initAccessibilityProperties(String accProfileAttr)
+  private Set<String> _initAccessibilityProperties(String accProfileAttr)
   {
     Iterator<String> tokens = _getTokens(accProfileAttr);
     if (tokens == null)
-      return;
+      return Collections.emptySet();
 
     // The number of accessibility properties is always small - typically
     // just 1.  Use a small initial capacity.
@@ -278,11 +253,11 @@
       }
     }
     
-    _accProperties = props;
+    return props;
   }
 
-  // Copies Integers from a Vector into an int array
-  private int[] _getIntegers(Vector<Integer> v)
+  // Copies Integers from a List into an int array
+  private int[] _getIntegers(List<Integer> v)
   {
     int count = v.size();
 
@@ -292,7 +267,7 @@
     int[] array = new int[count];
 
     for (int i = 0; i < count; i++)
-      array[i] = v.elementAt(i).intValue();
+      array[i] = v.get(i).intValue();
 
     return array;
   }
@@ -306,10 +281,8 @@
     return (Arrays.asList(XMLUtils.parseNameTokens(attr))).iterator();
   }
 
-  // -= Simon Lessard =-
-  // TODO: Check if synchronization is really needed.
-  private Vector<StyleNode> _styles;
-  private Locale[]          _locales;
+  private List<StyleNode> _styles;
+  private Set<Locale>       _locales;
   private int               _direction;
   private int               _mode;
   private List<TrinidadAgent.Application> _browsers;