You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by an...@apache.org on 2012/03/09 03:17:26 UTC

svn commit: r1298692 [2/3] - in /myfaces/trinidad/branches/andys-skin-pregen: trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/ trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ trinidad-api/src/main/xrts/org/apache/myfaces/tri...

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationUtils.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationUtils.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerationUtils.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,79 @@
+/*
+ * 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.skin.pregen;
+
+import java.beans.Beans;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig;
+
+/**
+ * Skin pregeneration utilities.
+ */
+public final class SkinPregenerationUtils
+{
+  /**
+   * Pregenerates style sheets for the specified skin.
+   *
+   * @param context the FacesContext for the current request
+   * @param skin the non-null Skin to pregenerate
+   * @param config configuration info that determines how pregeneration
+   *   is performed.
+   */
+  public static void pregenerate(
+    FacesContext    context,
+    Skin            skin,
+    PregenConfig    config
+    )
+  {
+    assert(skin != null);
+    assert(config != null);
+
+    SkinPregenerator pregenerator = _getSkinPregenerator(context);
+    pregenerator.pregenerate(context, skin, config);
+  }
+  
+  private static SkinPregenerator _getSkinPregenerator(FacesContext context)
+  {
+    if (Beans.isDesignTime())
+    {
+      return _NOOP_PREGENERATOR;
+    }
+
+    return new AllVariantsSkinPregenerator(context);
+  }
+
+  private SkinPregenerationUtils()
+  {
+  }
+  
+  private static final SkinPregenerator _NOOP_PREGENERATOR =
+    new SkinPregenerator()
+    {
+      @Override
+      public void pregenerate(
+        FacesContext    context,
+        Skin            skin, 
+        PregenConfig    config)
+      {
+      }
+    };
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerator.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerator.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerator.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/SkinPregenerator.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,43 @@
+/*
+ * 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.skin.pregen;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig;
+
+/**
+ * Interface for objects that perform skin pregeneration.
+ */
+interface SkinPregenerator
+{
+
+  /**
+   * Pregenerate style sheets for the specified skin
+   * @param context the FacesContext for the current request
+   * @param skin the Skin to pregenerate
+   * @param config configuration info that influences pregeneration
+   */
+  public void pregenerate(
+    FacesContext context,
+    Skin         skin,
+    PregenConfig config
+    );
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/InvalidConfigException.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/InvalidConfigException.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/InvalidConfigException.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/InvalidConfigException.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,37 @@
+/*
+ * 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.skin.pregen.config;
+
+/**
+ * Exception thrown from PregenConfig.parse() if a failure occurs during
+ * parsing.
+ */
+public class InvalidConfigException extends RuntimeException
+{
+  /**
+   * Creates an InvalidConfigException with a message that is
+   * suitable for publication to the end user.
+   */
+  public InvalidConfigException(String message)
+  {
+    super(message);
+  }
+
+  private static final long serialVersionUID = 1L;
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/PregenConfig.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/PregenConfig.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/PregenConfig.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/config/PregenConfig.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,529 @@
+/*
+ * 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.skin.pregen.config;
+
+import java.util.AbstractCollection;
+import java.util.Arrays;
+import java.util.Collection;
+
+import java.util.Collections;
+import java.util.Iterator;
+
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+
+import org.apache.myfaces.trinidad.context.AccessibilityProfile;
+import org.apache.myfaces.trinidad.context.LocaleContext;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.util.EnumParseException;
+import org.apache.myfaces.trinidad.util.Enums;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent.Application;
+import org.apache.myfaces.trinidadinternal.share.nls.NullLocaleContext;
+import org.apache.myfaces.trinidadinternal.util.nls.LocaleUtils;
+
+/**
+ * Specifies configuration constraints for skin pregeneration.
+ */
+abstract public class PregenConfig
+{
+  /**
+   * Constant returned from variants accessors to indicate that
+   * all possible values of the variant should be included during
+   * pregeneration.
+   */
+  public static final Collection<?> ALL_VARIANTS =
+    new AbstractCollection() {
+    
+      @Override
+      public boolean isEmpty()
+      {
+        return false;
+      }
+  
+      @Override
+      public Iterator iterator()
+      {
+        throw new UnsupportedOperationException();
+      }
+
+      @Override
+      public int size()
+      {
+        throw new UnsupportedOperationException();
+      }
+    };
+
+  /**
+   * Returns a null/empty PregenConfig instance.
+   */
+  public static PregenConfig nullInstance()
+  {
+    return _NULL_CONFIG;    
+  }
+
+  /**
+   * Creates a PregenConfig instance that is configured based on request
+   * parmeter values.
+   * 
+   * Request parameters are documented in SkinPregenerationService class doc.
+   * 
+   * @param external the ExternalContext to use for retreving request parameter
+   *   values.
+   * @return
+   */
+  public static PregenConfig parse(ExternalContext external)
+    throws InvalidConfigException
+  {
+    return _isAllVariantsRequest(external) ?
+      new AllPregenConfig(external) :
+      new CommonPregenConfig(external);
+  }
+
+  private static boolean _isAllVariantsRequest(ExternalContext external)
+    throws InvalidConfigException
+  {
+    Collection<Variants> variants = _parseDisplayNameParam(external,
+                                                           "variants",
+                                                           Variants.class,
+                                                           Variants.COMMON);
+    
+    return variants.contains(Variants.ALL);
+  }
+
+  private static <E extends Enum> Collection<E> _parseDisplayNameParam(
+    ExternalContext external,
+    String          paramName,
+    Class<E>        enumClass, 
+    E               defaultValue
+    ) throws InvalidConfigException
+  {
+    try
+    {
+      return Enums.parseEnumRequestParameter(external,
+                                             paramName,
+                                             enumClass,
+                                             Enums.displayNameEnumParser(enumClass),
+                                             defaultValue);
+    }
+    catch (EnumParseException e)
+    {
+      String message = _getIllegalDisplayNameRequestParamMessage(paramName,
+                                                                 e.getIllegalValue(),
+                                                                 enumClass);
+      throw new InvalidConfigException(message);
+    }
+  }
+
+  private static <E extends Enum> String _getIllegalDisplayNameRequestParamMessage(
+    String   paramName,
+    String   paramValue,
+    Class<E> enumClass
+    )
+  {
+    String validValues = Enums.patternOf(enumClass,
+                                         Enums.displayNameStringProducer(enumClass));
+
+    return _LOG.getMessage("ILLEGAL_REQUEST_PARAMETER_VALUE",
+                           new Object[] {
+                             paramValue,
+                             paramName,                             
+                             validValues });
+  }
+
+  /**
+   * Returns the (non-null) platform variants to pregenerate.
+   * 
+   * The collection values correspond to TrinidadAgent.OS_* constants.
+   * 
+   * A return value of PregenConfig.ALL indicates that all platform
+   * variants should be pregenerated.
+   */
+  abstract public Collection<Integer> getPlatformVariants();
+  
+  /**
+   * Returns the (non-null) locale variants to pregenerate.
+   * 
+   * A return value of PregenConfig.ALL indicates that all locale
+   * variants should be pregenerated.
+   */
+  abstract public Collection<LocaleContext> getLocaleVariants();
+  
+  /**
+   * Returns the (non-null) reading direction variants to pregenerate.
+   * 
+   * A return value of PregenConfig.ALL indicates that both ltr and
+   * rtl variants should be pregenerated.
+   */
+  abstract public Collection<Integer> getReadingDirectionVariants();
+  
+  /**
+   * Returns the (non-null) agent application variants to pregenerate.
+   * 
+   * A return value of PregenConfig.ALL indicates that all agent application
+   * variants should be pregenerated.
+   */
+  abstract public Collection<Application> getAgentApplicationVariants();
+  
+  /**
+   * Returns the (non-null) accessibility variants to pregenerate.
+   * 
+   * A return value of PregenConfig.ALL indicates that all accessibility
+   * variants should be pregenerated.
+   */
+  abstract public Collection<AccessibilityProfile> getAccessibilityVariants();
+  
+  /**
+   * Returns the conatiner types to pregenerate.
+   */
+  abstract public Collection<ContainerType> getContainerTypes();
+
+  /**
+   * Returns the request types to pregenerate.
+   */
+  abstract public Collection<RequestType> getRequestTypes();
+  
+  /**
+   * Returns the style class types to pregenerate.
+   */
+  abstract public Collection<StyleClassType> getStyleClassTypes();
+  
+  // Utility enum class used to identify whether PregenConfig.parse() should
+  // return a PregenConfig instance that is configured for generating
+  // "common" or "all" variants.
+  public enum Variants
+  {
+    COMMON("common"),
+    ALL("all");
+    
+    Variants(String displayName)
+    {
+      _displayName = displayName;
+    }
+    
+    public String displayName()
+    {
+      return _displayName;
+    }
+    
+    public static Variants valueOfDisplayName(String displayName)
+    {
+      return Enums.stringToEnum(_displayNameMap, displayName, Variants.class);
+    }
+    
+    private final String _displayName;
+    private static final Map<String, Variants> _displayNameMap;
+    
+    static
+    {
+      _displayNameMap = Enums.createDisplayNameMap(Variants.class);
+    }
+  }
+  
+  // Enum that is used to indicate whether pregeneration should target
+  // servlet or portlet containers (or both).
+  public enum ContainerType
+  {
+    SERVLET("servlet"),
+    PORTLET("portlet");
+
+    ContainerType(String displayName)
+    {
+      _displayName = displayName;
+    }
+    
+    public String displayName()
+    {
+      return _displayName;
+    }
+    
+    public static ContainerType valueOfDisplayName(String displayName)
+    {
+      return Enums.stringToEnum(_displayNameMap, displayName, ContainerType.class);
+    }
+    
+    private final String _displayName;
+    private static final Map<String, ContainerType> _displayNameMap;
+    
+    static
+    {
+      _displayNameMap = Enums.createDisplayNameMap(ContainerType.class);
+    }    
+  }
+  
+  // Enum that is used to indicate whether pregeneration should target  
+  // secure or nonsecure request types (or both).
+  public enum RequestType
+  {
+    NONSECURE("nonsecure"),
+    SECURE("secure");
+
+    RequestType(String displayName)
+    {
+      _displayName = displayName;
+    }
+    
+    public String displayName()
+    {
+      return _displayName;
+    }
+    
+    public static RequestType valueOfDisplayName(String displayName)
+    {
+      return Enums.stringToEnum(_displayNameMap, displayName, RequestType.class);
+    }
+    
+    private final String _displayName;
+    private static final Map<String, RequestType> _displayNameMap;
+    
+    static
+    {
+      _displayNameMap = Enums.createDisplayNameMap(RequestType.class);
+    } 
+  }
+
+  // Enum that is used to indicate whether pregeneration should target
+  // compressed or uncompressed style classes (or both).
+  public enum StyleClassType
+  {
+    COMPRESSED("compressed"),
+    UNCOMPRESSED("uncompressed");
+
+    StyleClassType(String displayName)
+    {
+      _displayName = displayName;
+    }
+    
+    public String displayName()
+    {
+      return _displayName;
+    }
+    
+    public static StyleClassType valueOfDisplayName(String displayName)
+    {
+      return Enums.stringToEnum(_displayNameMap, displayName, StyleClassType.class);
+    }
+    
+    private final String _displayName;
+    private static final Map<String, StyleClassType> _displayNameMap;
+    
+    static
+    {
+      _displayNameMap = Enums.createDisplayNameMap(StyleClassType.class);
+    } 
+  }
+
+  protected PregenConfig()
+  {
+  }
+
+  // A PregenConfig implementation that derives its contextual configuration 
+  // from request parameters.
+  private static abstract class ParamPregenConfig extends PregenConfig
+  {
+    public ParamPregenConfig(ExternalContext external)
+      throws InvalidConfigException
+    {
+      _containerTypes = _parseDisplayNameParam(external,
+                                               "containerType",
+                                               ContainerType.class,
+                                               ContainerType.SERVLET);
+
+      _requestTypes = _parseDisplayNameParam(external,
+                                             "requestType",
+                                             RequestType.class,
+                                             RequestType.NONSECURE);
+      
+      _styleClassTypes = _parseDisplayNameParam(external,
+                                                "styleClassType",
+                                                StyleClassType.class,
+                                                StyleClassType.COMPRESSED);      
+    }
+    
+    @Override
+    public Collection<ContainerType> getContainerTypes()
+    {
+      return _containerTypes;
+    }
+    
+    @Override
+    public Collection<RequestType> getRequestTypes()
+    {
+      return _requestTypes;
+    }
+    
+    @Override
+    public Collection<StyleClassType> getStyleClassTypes()
+    {
+      return _styleClassTypes;
+    }
+
+    private final Collection<ContainerType>  _containerTypes;
+    private final Collection<RequestType>    _requestTypes;
+    private final Collection<StyleClassType> _styleClassTypes;
+  }
+  
+  // PregenConfig implementation that is used for pregeneration of
+  // all possible variant values.
+  private static class AllPregenConfig extends ParamPregenConfig
+  {
+    public AllPregenConfig(ExternalContext external)
+    {
+      super(external);
+    }
+
+    @Override
+    public Collection<Integer> getPlatformVariants()
+    {
+      return (Collection<Integer>)ALL_VARIANTS;
+    }
+    
+    @Override
+    public Collection<LocaleContext> getLocaleVariants()
+    {
+     return (Collection<LocaleContext>)ALL_VARIANTS;
+    }
+
+    @Override
+    public Collection<Integer> getReadingDirectionVariants()
+    {
+      return (Collection<Integer>)ALL_VARIANTS;
+    }
+
+    @Override
+    public Collection<TrinidadAgent.Application> getAgentApplicationVariants()
+    {
+      return (Collection<TrinidadAgent.Application>)ALL_VARIANTS;
+    }
+
+    @Override
+    public Collection<AccessibilityProfile> getAccessibilityVariants()
+    {
+      return (Collection<AccessibilityProfile>)ALL_VARIANTS;      
+    }
+  }
+
+  // PregenConfig implementation that is used for pregeneration of
+  // only the most common variant values.
+  private static class CommonPregenConfig extends ParamPregenConfig
+  {
+    public CommonPregenConfig(ExternalContext external)
+    {
+      super(external);
+    }
+
+    @Override
+    public Collection<Integer> getPlatformVariants()
+    {
+      return Arrays.asList(
+               TrinidadAgent.OS_ANDROID,
+               TrinidadAgent.OS_IPHONE,
+               TrinidadAgent.OS_LINUX,
+               TrinidadAgent.OS_MACOS,
+               TrinidadAgent.OS_WINDOWS);
+    }
+    
+    @Override
+    public Collection<LocaleContext> getLocaleVariants()
+    {
+     return Arrays.asList(
+              NullLocaleContext.getLeftToRightContext(),
+              NullLocaleContext.getRightToLeftContext());
+    }
+
+    @Override
+    public Collection<Integer> getReadingDirectionVariants()
+    {
+      return Arrays.asList(LocaleUtils.DIRECTION_LEFTTORIGHT);
+    }
+
+    @Override
+    public Collection<TrinidadAgent.Application> getAgentApplicationVariants()
+    {
+      return Arrays.asList(TrinidadAgent.Application.GECKO,
+                           TrinidadAgent.Application.IEXPLORER,
+                           TrinidadAgent.Application.SAFARI);
+    }
+
+    @Override
+    public Collection<AccessibilityProfile> getAccessibilityVariants()
+    {
+      return Arrays.asList(AccessibilityProfile.getDefaultInstance());      
+    }
+  }
+  
+  // Null PregenConfig implementation. Only used for error cases, to
+  // avoid null comparisons.
+  private static final class NullPregenConfig extends PregenConfig
+  {
+    @Override
+    public Collection<Integer> getPlatformVariants()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<LocaleContext> getLocaleVariants()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<Integer> getReadingDirectionVariants()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<TrinidadAgent.Application> getAgentApplicationVariants()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<AccessibilityProfile> getAccessibilityVariants()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<PregenConfig.ContainerType> getContainerTypes()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<PregenConfig.RequestType> getRequestTypes()
+    {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public Collection<PregenConfig.StyleClassType> getStyleClassTypes()
+    {
+      return Collections.emptySet();
+    }
+  }
+
+  private static final PregenConfig _NULL_CONFIG = new NullPregenConfig();
+  
+  private static final TrinidadLogger _LOG =
+    TrinidadLogger.createTrinidadLogger(PregenConfig.class);  
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleContext.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleContext.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleContext.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,244 @@
+/*
+ * 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.skin.pregen.context;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.context.AccessibilityProfile;
+import org.apache.myfaces.trinidad.context.Agent;
+import org.apache.myfaces.trinidad.context.LocaleContext;
+import org.apache.myfaces.trinidad.style.Styles;
+import org.apache.myfaces.trinidadinternal.agent.AgentNameUtil;
+import org.apache.myfaces.trinidadinternal.agent.DefaultAgent;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgentImpl;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.ContainerType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.RequestType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.StyleClassType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.variant.ApplicationAndVersion;
+import org.apache.myfaces.trinidadinternal.skin.pregen.variant.SkinVariant;
+import org.apache.myfaces.trinidadinternal.style.StyleContext;
+import org.apache.myfaces.trinidadinternal.style.StyleProvider;
+import org.apache.myfaces.trinidadinternal.style.StyleSheetNamingStrategy;
+
+/**
+ * StyleContext implementation used during skin pregeneration.
+ */
+public final class PregenStyleContext implements StyleContext
+{
+  /**
+   * Returns a StyleContext instance that can be used to retrieve the
+   * StyleSheetDocument for the specified StyleProvider.
+   * 
+   * @param provider the StyleProvider for which we'll retrieve the StyleSheetDocument
+   * @param path the generated files path
+   * @return
+   */
+  public static StyleContext documentContext(
+    FacesContext  context,
+    StyleProvider provider,
+    String        path
+    )
+  {
+    // Note: DocumentProviderSkin.getStyleSheetDocument() minimally requires
+    // the StyleContet's StyleProvider and the generated files path, so that is
+    // all that we bother with here.
+    return new PregenStyleContext(context,
+                                  provider, 
+                                  path, 
+                                  null,
+                                  false);
+  }
+
+  /**
+   * Creates a StyleContext that can be used for pregeneration
+   * of a single skin variant.
+   * 
+   * @param context the FacesContext
+   * @param provider the StyleProvider
+   * @param generatedFilesPath the root generated files path
+   * @param variant the variant of the skin to generate
+   */
+  public PregenStyleContext(
+    FacesContext           context,
+    StyleProvider          provider,
+    String                 generatedFilesPath,
+    SkinVariant            variant,
+    boolean                dirty
+    )
+  {
+    _styleProvider = provider;
+    _generatedFilesPath = generatedFilesPath;
+    _variant = variant;
+    _agent = _createTrinidadAgent(context, variant);
+    _dirty = dirty;
+  }
+  
+  @Override
+  public LocaleContext getLocaleContext()
+  {
+    return _variant.getLocaleContext();
+  }
+
+  @Override
+  public TrinidadAgent getAgent()
+  {
+    return _agent;
+  }
+
+  @Override
+  public String getGeneratedFilesPath()
+  {
+    return _generatedFilesPath;
+  }
+  
+  @Override
+  public StyleSheetNamingStrategy getNamingStrategy()
+  {
+    // Stable names are required for pregeneration in order
+    // for runtime names to match pregenerated names.
+    return StyleSheetNamingStrategy.STABLE;
+  }
+
+  @Override
+  public boolean checkStylesModified()
+  {
+    return false;
+  }
+
+  @Override
+  public boolean disableStandardsMode()
+  {
+    return false;
+  }
+
+  @Override
+  public StyleProvider getStyleProvider()
+  {
+    return getStyleProvider(false);
+  }
+
+  @Override
+  public StyleProvider getStyleProvider(boolean recompute)
+  {
+    return _styleProvider;
+  }
+
+  @Override
+  public Styles getStyles()
+  {
+    return null;
+  }
+
+  @Override
+  public AccessibilityProfile getAccessibilityProfile()
+  {
+    return _variant.getAccessibilityProfile();
+  }
+
+  @Override
+  public boolean isPortletMode()
+  {
+    return (_variant.getContainerType() == ContainerType.PORTLET);
+  }
+
+  @Override
+  public boolean isDisableStyleCompression()
+  {
+    return (_variant.getStyleClassType() == StyleClassType.UNCOMPRESSED);
+  }
+
+  @Override
+  public boolean isDirty()
+  {
+    return _dirty;
+  }
+
+  @Override
+  public boolean isRequestSecure()
+  {
+    return (_variant.getRequestType() == RequestType.SECURE);
+  }
+  
+  private static TrinidadAgent _createTrinidadAgent(
+    FacesContext          context,
+    SkinVariant           variant
+    )
+  {
+    if (variant == null)
+    {
+      // Null variant == bootstrapping case.  No need for agent access.
+      return null;
+    }
+                            
+    // In theory we should be able to create/use our own trivial TrinidadAgent
+    // implementation.  However, TrinidadAgentImpl contains all of the magic
+    // for figuring out agent capabilities.  Turns out to be easier if we
+    // just use this implementation rather than create our own.  Unfortunately,
+    // this means that we first need to jump through the hoop of translating
+    // the agent information into org.apache.myfaces.trinidad.context.Agent
+    // land.
+    Agent agent = new PregenAgent(variant.getPlatform(), variant.getApplicationAndVersion());
+
+    return new TrinidadAgentImpl(context, agent);
+  }
+  
+  private static class PregenAgent extends DefaultAgent
+  {
+    public PregenAgent(
+      int                   platform,
+      ApplicationAndVersion appAndVersion
+      )
+    {
+      assert(appAndVersion != null);
+      
+      _platformName = AgentNameUtil.getPlatformName(platform);
+      _agentName = appAndVersion.application.getAgentName();
+      _agentVersion = appAndVersion.version.toString();
+    }
+    
+    @Override
+    public String getAgentName()
+    {
+      return _agentName;  
+    }
+    
+    @Override
+    public String getAgentVersion()
+    {
+      return _agentVersion;
+    }
+    
+    @Override
+    public String getPlatformName()
+    {
+      return _platformName;
+    }
+    
+    private final String _agentName;
+    private final String _agentVersion;
+    private final String _platformName;
+  }
+
+  private final StyleProvider _styleProvider;
+  private final String        _generatedFilesPath;
+  private final SkinVariant   _variant;
+  private final TrinidadAgent _agent;
+  private final boolean       _dirty;
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleProvider.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleProvider.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/context/PregenStyleProvider.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,47 @@
+/*
+ * 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.skin.pregen.context;
+
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.skin.SkinStyleProvider;
+
+/**
+ * StyleProvider implementation used during skin pregeneration.
+ * 
+ * During skin pregeneration we periodically clear out the
+ * StyleProvider in order to free up memory.  However, when
+ * we do this, we don't want to force a re-parse of the skin
+ * definitions.  We override getClearOnDirty() to avoid this.
+ */
+public class PregenStyleProvider extends SkinStyleProvider
+{
+  public PregenStyleProvider(Skin skin, String targetDirectoryPath)
+    throws IllegalArgumentException
+  {
+    super(skin, targetDirectoryPath);
+  }
+  
+  @Override
+  protected ClearOnDirty getClearOnDirty()
+  {
+    // Only clear out cache entries - don't blow away the
+    // StyleSheetDocument and associated data.
+    return ClearOnDirty.ENTRIES;
+  }
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AccessibilityVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AccessibilityVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AccessibilityVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AccessibilityVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,144 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.ArrayList;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import org.apache.myfaces.trinidad.context.AccessibilityProfile;
+import org.apache.myfaces.trinidadinternal.style.xml.XMLConstants;
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetNode;
+
+/**
+ * Helper class for extracting @accessibility-profile rule metadata.
+ */
+final class AccessibilityVariantExtractor implements SkinVariantExtractor<AccessibilityProfile>
+{
+  public AccessibilityVariantExtractor()
+  {
+    _accProfiles = new HashSet<AccessibilityProfile>();
+    
+    // Seed with default accessibility profile. This won't show
+    // up as at @accessibility rule, but needs to be covered during
+    // pregeneration.
+    _accProfiles.add(AccessibilityProfile.getDefaultInstance());
+  }
+
+  @Override
+  public void visit(StyleSheetNode node)
+  {
+    Collection<String> accProps = node.getAccessibilityProperties();
+    
+    for (String accProp : accProps)
+    {
+      _addAccessibilityProfile(accProp);
+    }
+  }
+
+  /**
+   * Returns un unmodifiable list containing AccessibilityProfiles corresponding
+   * to all @accesibility-profile rules in the specified document.
+   */
+  public List<AccessibilityProfile> getVariants()
+  {
+    if (_accProfiles.contains(_HIGH_CONTRAST_ONLY) &&
+        _accProfiles.contains(_LARGE_FONTS_ONLY)   &&
+        !_accProfiles.contains(_HIGH_CONTRAST_LARGE_FONTS))
+    {
+      _accProfiles.add(_HIGH_CONTRAST_LARGE_FONTS);
+    }
+  
+    List<AccessibilityProfile> accProfilesList =
+      new ArrayList<AccessibilityProfile>(_accProfiles);
+  
+    return Collections.unmodifiableList(accProfilesList);
+  }
+  
+  private void _addAccessibilityProfile(String accProp)
+  {
+    AccessibilityProfile accProfile = _toAccessibilityProfile(accProp);
+
+    _accProfiles.add(accProfile);                                                               
+  }
+  
+  private static AccessibilityProfile _toAccessibilityProfile(String accProp)
+  {
+    boolean highContrast = false;
+    boolean largeFonts = false;
+    
+    if (_isHighContrast(accProp))
+    {
+      highContrast = true;
+    }
+    else if (_isLargeFonts(accProp))
+    {
+      largeFonts = true;
+    }
+    else if (_isHighContrastLargeFonts(accProp))
+    {
+      highContrast = true;
+      largeFonts = true;
+    }
+    
+    return _getAccessibilityProfile(highContrast, largeFonts);
+  }
+
+  private static boolean _isHighContrast(String accProp)
+  {
+    return XMLConstants.ACC_HIGH_CONTRAST.equals(accProp);
+  }
+  
+  private static boolean _isLargeFonts(String accProp)
+  {
+    return XMLConstants.ACC_LARGE_FONTS.equals(accProp);
+  }
+
+  private static boolean _isHighContrastLargeFonts(String accProp)
+  {
+    return ((accProp.indexOf(XMLConstants.ACC_HIGH_CONTRAST) > -1) &&
+            (accProp.indexOf(XMLConstants.ACC_LARGE_FONTS) > -1));
+  }
+
+  private static AccessibilityProfile _getAccessibilityProfile(
+    boolean highContrast,
+    boolean largeFonts
+    )
+  {
+    return AccessibilityProfile.getInstance(
+             highContrast ?
+               AccessibilityProfile.ColorContrast.HIGH :
+               AccessibilityProfile.ColorContrast.STANDARD,
+             largeFonts ?
+               AccessibilityProfile.FontSize.LARGE :
+               AccessibilityProfile.FontSize.MEDIUM);
+  }
+
+  private final Collection<AccessibilityProfile> _accProfiles;
+
+  private static final AccessibilityProfile _HIGH_CONTRAST_ONLY =
+    _getAccessibilityProfile(true, false);  
+  private static final AccessibilityProfile _LARGE_FONTS_ONLY =
+    _getAccessibilityProfile(false, true);
+  private static final AccessibilityProfile _HIGH_CONTRAST_LARGE_FONTS =
+    _getAccessibilityProfile(true, true);
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AgentVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AgentVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AgentVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/AgentVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,218 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.AbstractCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import java.util.Collections;
+import java.util.HashMap;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+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.xml.parse.StyleSheetNode;
+import org.apache.myfaces.trinidadinternal.util.Range;
+
+/**
+ * An @-rule processor for extracting @agent rule metadata.
+ */
+final class AgentVariantExtractor implements SkinVariantExtractor<ApplicationAndVersion>
+{
+  /**
+   * Creates an AgentVariantExtractor for a specified set of supported
+   * agent applications.  AgentVariantExtractor.getVariants() will only
+   * ApplicationAndVersion instances corresponding to these agent
+   * applications.  If no supported agent applications are specified,
+   * all agent applications found in the style sheet nodes will be 
+   * treated as supported.
+   */
+  public AgentVariantExtractor(
+    Collection<TrinidadAgent.Application> supportedApplications
+    )
+  {
+    _appVersionsMap =
+      new HashMap<TrinidadAgent.Application, Set<Version>>();
+    
+    _supportedApplications = _initSupportedApplications(supportedApplications);
+    
+    // Seed the map with unknown agent.  This won't appear
+    // in the skin definition, but we need to cover this case
+    // during pregeneration.
+    _addApplicationIfSupported(TrinidadAgent.Application.UNKNOWN);  
+  }
+  
+  private Collection<TrinidadAgent.Application> _initSupportedApplications(
+    Collection<TrinidadAgent.Application> supportedApplications
+    )
+  {
+    if ((supportedApplications == null) || supportedApplications.isEmpty())
+    {
+      return new AbstractCollection<TrinidadAgent.Application>() {
+        
+          @Override
+          public boolean contains(Object o)
+          {
+            return true;  
+          }
+          
+          @Override
+          public Iterator<TrinidadAgent.Application> iterator()
+          {
+            throw new UnsupportedOperationException();
+          }
+
+          @Override
+          public int size()
+          {
+            throw new UnsupportedOperationException();
+          }
+        };
+    }
+
+    return new HashSet<TrinidadAgent.Application>(supportedApplications);
+  }
+
+  @Override
+  public void visit(StyleSheetNode node)
+  {
+    AgentAtRuleMatcher agentMatcher = node.getAgentMatcher();
+    
+    if (agentMatcher != null)
+    {
+      _addApplicationVersions(agentMatcher);    
+    }
+  }
+
+  /**
+   * Returns an unmodifiable list containing ApplicationAndVersions
+   * corresponding to all processed @agent rules.
+   */
+  public List<ApplicationAndVersion> getVariants()
+  {
+    List<ApplicationAndVersion> appAndVersionsList =
+      _toAppAndVersionsList(_appVersionsMap);
+
+    return Collections.unmodifiableList(appAndVersionsList);
+  }
+  
+  private void _addApplicationVersions(AgentAtRuleMatcher agentMatcher)
+  {
+    assert(agentMatcher != null);
+    
+    Collection<TrinidadAgent.Application> nodeApplications =
+      agentMatcher.getMatchingApplications();
+      
+    for (TrinidadAgent.Application application : nodeApplications)
+    {
+
+      boolean supported = _addApplicationIfSupported(application);
+      
+      if (supported)
+      {
+        Collection<Range<Version>> versionRanges = agentMatcher.getVersionsForApplication(application);
+        _addVersions(application, versionRanges);        
+      }
+
+    }    
+  }
+  
+  private boolean _addApplicationIfSupported(TrinidadAgent.Application application)
+  {
+    if (!_supportedApplications.contains(application))
+    {
+      return false;
+    }
+
+    if (!_appVersionsMap.containsKey(application))
+    {
+      Set<Version> versions = new TreeSet<Version>();
+      
+      // Minimally, every application needs to be able
+      // to pregenerate for the unknown version case.
+      versions.add(_UNKNOWN_VERSION);
+      
+      _appVersionsMap.put(application, versions);
+    }
+    
+    return true;
+  }
+  
+  private void _addVersions(
+    TrinidadAgent.Application  application,
+    Collection<Range<Version>> versionRanges
+    )
+  {
+    Set<Version> versions = _appVersionsMap.get(application);
+    assert(versions != null);
+    
+    for (Range<Version> versionRange : versionRanges)
+    {
+      // We add the start/end points of the range to our
+      // set of versions to pregenerate.
+      
+      // Also note that from here on out we only want to
+      // deal with "concrete" versions.  If we leave version
+      // wildcards in place, we can lose information due to
+      // Version's wildcard-sensitive natural ordering (ie.
+      // a Set.add() might fail because a matching/wildcarded
+      // version is already present.)
+      versions.add(versionRange.getStart().toConcreteVersion());
+      versions.add(versionRange.getEnd().toConcreteVersion());
+    }
+  }
+
+  private static List<ApplicationAndVersion> _toAppAndVersionsList(
+    Map<TrinidadAgent.Application, Set<Version>> appVersionsMap
+    )
+  {
+    ArrayList<ApplicationAndVersion> appAndVersions = 
+      new ArrayList<ApplicationAndVersion>();
+    
+    for (TrinidadAgent.Application application : appVersionsMap.keySet())
+    {
+      Collection<Version> versions = appVersionsMap.get(application);
+      
+      for (Version version : versions)
+      {
+        appAndVersions.add(new ApplicationAndVersion(application, version));
+      }
+    }
+    
+    return appAndVersions;
+  }
+
+  // Map of application to versions that have been encountered 
+  // during processing
+  private final Map<TrinidadAgent.Application, Set<Version>> _appVersionsMap;
+  
+  // Only extract version information for these applications.
+  private final Collection<TrinidadAgent.Application> _supportedApplications;
+
+  private static final Version _UNKNOWN_VERSION = new Version("unknown");
+  
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/ApplicationAndVersion.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/ApplicationAndVersion.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/ApplicationAndVersion.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/ApplicationAndVersion.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,115 @@
+/*
+ * 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.skin.pregen.variant;
+
+import org.apache.myfaces.trinidad.context.Version;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+
+/**
+ * A convenience duple class that holds onto a TrinidadAgent.Application and
+ * Version value.
+ * 
+ * Only note of interest: the AppicationAndVersion.version is guaranteed to
+ * be concrete (ie. no wildcards).
+ */
+public final class ApplicationAndVersion implements Comparable<ApplicationAndVersion>
+{
+  public final TrinidadAgent.Application application;
+  public final Version version;
+
+  /**
+   * An instance that can be used as a placeholder for cases
+   * where the application and version are not known.
+   */
+  public static final ApplicationAndVersion UNKNOWN = 
+    new ApplicationAndVersion(
+      TrinidadAgent.Application.UNKNOWN,
+      new Version("0"));
+  
+  /**
+   * Creates an AppplicationAndVersion instance for the
+   * specified application and version.
+   * 
+   * If the Version contains wildcards, this will be replaced by a new,
+   * matching, concrete (wildcard-free) Version instance.
+   * 
+   * @param application a non-null TrinidadAgent.Application instance.
+   * @param version a non-null Version instance.
+   */
+  public ApplicationAndVersion(
+    TrinidadAgent.Application application,
+    Version version
+    )
+  {
+    assert(application != null);
+    assert(version != null);
+
+    this.application = application;
+    this.version = version.toConcreteVersion();
+  }
+  
+  @Override
+  public String toString()
+  {
+    return this.application + "v" + this.version;
+  }
+
+  @Override
+  public int compareTo(ApplicationAndVersion appAndVersion)
+  {
+    int appResult = this.application.compareTo(appAndVersion.application);
+    
+    if (appResult != 0)
+    {
+      return appResult;
+    }
+    
+    return this.version.compareTo(appAndVersion.version);
+  }
+  
+  @Override
+  public boolean equals(Object o)
+  {
+    if (this == o)
+    {
+      return true;
+    }
+    
+    if (!(o instanceof ApplicationAndVersion))
+    {
+      return false;
+    }
+    
+    ApplicationAndVersion appAndVersion = (ApplicationAndVersion)o;
+    
+    return (this.application.equals(appAndVersion.application) &&
+            this.version.equals(appAndVersion.version));
+  }
+  
+  @Override
+  public int hashCode()
+  {
+    int result = 17;
+    
+    result = 31 * result + this.application.hashCode();
+    result = 31 * result + this.version.hashCode();
+    
+    return result;
+  }
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/DirectionFilteringVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/DirectionFilteringVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/DirectionFilteringVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/DirectionFilteringVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,72 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.myfaces.trinidad.context.LocaleContext;
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetNode;
+
+/**
+ * A SkinVariantExtractor that filters LocaleContexts based on reading direction
+ */
+final class DirectionFilteringVariantExtractor implements SkinVariantExtractor<LocaleContext>
+{
+  /**
+   * Creates a filtering variant extractor.
+   * @param wrapped the LocaleContext variant extractor to filter
+   * @param rtlOnly if true, getVariants() only returns rtl LocaleContexts.
+   *        Otherwise, only ltr LocaleContexts are returned.
+   */
+  DirectionFilteringVariantExtractor(
+    SkinVariantExtractor<LocaleContext> wrapped,
+    boolean rtlOnly
+    )
+  {
+    _wrapped = wrapped;
+    _rtlOnly = rtlOnly;
+  }
+
+  @Override
+  public List<LocaleContext> getVariants()
+  {
+    List<LocaleContext> locales = _wrapped.getVariants();
+    List<LocaleContext> filteredLocales = new ArrayList<LocaleContext>(locales.size());
+      
+    for (LocaleContext locale : locales)
+    {
+      if (locale.isRightToLeft() == _rtlOnly)
+      {
+        filteredLocales.add(locale);
+      }
+    }
+      
+    return filteredLocales;
+  }
+
+  @Override
+  public void visit(StyleSheetNode styleSheet)
+  {
+    _wrapped.visit(styleSheet);
+  }
+    
+  private final SkinVariantExtractor<LocaleContext> _wrapped;
+  private final boolean _rtlOnly;
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/FixedVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/FixedVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/FixedVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/FixedVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,80 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetNode;
+
+/**
+ * Trivial SkinVariantExtractor implementation that returns a fixed
+ * value.
+ * 
+ * Used by SkinVariants in cases where the variants to pregenerate
+ * are explicitly configured.
+ */
+final class FixedVariantExtractor <T> implements SkinVariantExtractor
+{
+
+  /**
+   * Returns a SkinVariantExtractor for single value.
+   * 
+   * @param defaultValue the value that the created SkinVariantExtractor
+   *   will return from getVariants().
+   */
+  public static <T> SkinVariantExtractor<T> extractor(T defaultValue)
+  {
+    return new FixedVariantExtractor<T>(Arrays.asList(defaultValue));
+  }
+
+  /**
+   * Returns a SkinVariantExtractor for a collection of values.
+   *
+   * @param values the values that the created SkinVariantExtractor
+   *   will return from getVariants.
+   */
+  public static <T> SkinVariantExtractor<T> extractor(Collection<T> values)
+  {
+    return new FixedVariantExtractor<T>(new ArrayList<T>(values));
+  }
+
+  @Override
+  public List<T> getVariants()
+  {
+    return _values;
+  }
+
+  @Override
+  public void visit(StyleSheetNode styleSheet)
+  {
+    // This is a no-op since we're just going to return the fixed
+    // set of values that was passed into the constructor.
+  }
+
+  private FixedVariantExtractor(
+    List<T> values)
+  {
+    _values = values;
+  }
+  
+  private final List<T> _values;
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/LocaleVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/LocaleVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/LocaleVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/LocaleVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,106 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.TreeSet;
+
+import org.apache.myfaces.trinidad.context.LocaleContext;
+import org.apache.myfaces.trinidadinternal.share.nls.LocaleContextImpl;
+import org.apache.myfaces.trinidadinternal.share.nls.NullLocaleContext;
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetNode;
+
+/**
+ * An @-rule processor for extracting @locale rule metadata.
+ */
+final class LocaleVariantExtractor implements SkinVariantExtractor<LocaleContext>
+{
+  public LocaleVariantExtractor()
+  {
+    _locales = new TreeSet<Locale>(_LOCALE_COMPARATOR);
+  }
+  
+  @Override
+  public void visit(StyleSheetNode node)
+  {
+    Collection<Locale> nodeLocales = node.getLocales();
+    
+    for (Locale locale : nodeLocales)
+    {
+      _locales.add(locale);
+    }    
+  }
+
+  /**
+   * Returns un unmodifiable list containing LocaleContexts corresponding
+   * to all processed @locale rules.
+   */
+  public List<LocaleContext> getVariants()
+  {
+    List<LocaleContext> localeContexts = _toLocaleContexts(_locales);
+    return Collections.unmodifiableList(localeContexts);
+  }
+
+  // Converts from Locale to LocaleContext, from Collection -> List, and
+  // adds in entries for null locales.
+  private static List<LocaleContext> _toLocaleContexts(Collection<Locale> locales)
+  {
+    int size = locales.size() + 2;
+    List<LocaleContext> localeContexts = new ArrayList<LocaleContext>(size);
+    _addNullLocaleContexts(localeContexts);
+    _addLocaleContexts(localeContexts, locales);
+    
+    return localeContexts;
+  }
+
+  private static void _addNullLocaleContexts(Collection<LocaleContext> localeContexts)
+  {
+    localeContexts.add(NullLocaleContext.getLeftToRightContext());
+    localeContexts.add(NullLocaleContext.getRightToLeftContext());
+  }
+  
+  private static void _addLocaleContexts(
+    Collection<LocaleContext> localeContexts,
+    Collection<Locale>        locales
+    )
+  {
+    for (Locale locale : locales)
+    {
+      localeContexts.add(new LocaleContextImpl(locale));
+    }
+  }
+
+  private static final class LocaleComparator implements Comparator<Locale>
+  {
+    @Override
+    public int compare(Locale locale1, Locale locale2)
+    {
+      return locale1.toString().compareTo(locale2.toString());
+    }
+  }
+
+  private final Collection<Locale> _locales;
+
+  private static final Comparator<Locale> _LOCALE_COMPARATOR = new LocaleComparator();
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/PlatformVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/PlatformVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/PlatformVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/PlatformVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,73 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.TreeSet;
+
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetNode;
+
+ /**
+  * An @-rule processor for extracting @platform rule metadata.
+  */
+final class PlatformVariantExtractor implements SkinVariantExtractor<Integer>
+{
+   public PlatformVariantExtractor()
+   {
+     _platforms = new TreeSet<Integer>();
+   }
+
+   @Override
+   public void visit(StyleSheetNode node)
+   {
+     Collection<Integer> nodePlatforms = node.getPlatforms();
+     
+     for (Integer platform : nodePlatforms)
+     {
+       _platforms.add(platform);
+     }     
+   }
+
+  /**
+   * Returns un unmodifiable list containing platforms corresponding
+   * to all processed @platform rules.
+   */
+  public List<Integer> getVariants()
+  {
+    ArrayList<Integer> platforms = new ArrayList<Integer>(_platforms.size() + 1);
+
+    // The "unknown" platform shouldn't be found by the document search,
+    // but does need to be included during pregeneration.    
+    if (!_platforms.contains(TrinidadAgent.OS_UNKNOWN))
+    {
+      platforms.add(TrinidadAgent.OS_UNKNOWN);      
+    }
+    
+    platforms.addAll(_platforms);
+
+    return Collections.unmodifiableList(platforms);
+  }
+
+  private final Collection<Integer> _platforms;
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariant.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariant.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariant.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariant.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,98 @@
+/*
+ * 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.skin.pregen.variant;
+
+import org.apache.myfaces.trinidad.context.AccessibilityProfile;
+import org.apache.myfaces.trinidad.context.LocaleContext;
+
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.ContainerType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.RequestType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.StyleClassType;
+
+/**
+ * Represents a single unique combination of variants/properties that
+ * influence which styles are selected/included during skin generation.
+ */
+public final class SkinVariant
+{
+  /**
+   * Creates a unique skin variant.
+   */
+  public SkinVariant(
+    LocaleContext         localeContext,
+    int                   platform,
+    ApplicationAndVersion appAndVersion,
+    AccessibilityProfile  accProfile,
+    ContainerType         containerType,
+    RequestType           requestType,
+    StyleClassType        styleClassType
+    )
+  {
+    _localeContext = localeContext;
+    _platform = platform;
+    _appAndVersion = appAndVersion;
+    _accProfile = accProfile;
+    _containerType = containerType;
+    _requestType = requestType;
+    _styleClassType = styleClassType;
+  }
+  
+  public LocaleContext getLocaleContext()
+  {
+    return _localeContext;
+  }
+  
+  public int getPlatform()
+  {
+    return _platform;
+  }
+
+  public ApplicationAndVersion getApplicationAndVersion()
+  {
+     return _appAndVersion;
+  }
+  
+  public AccessibilityProfile getAccessibilityProfile()
+  {
+    return _accProfile;
+  }
+  
+  public ContainerType getContainerType()
+  {
+    return _containerType;
+  }
+  
+  public RequestType getRequestType()
+  {
+    return _requestType;
+  }
+  
+  public StyleClassType getStyleClassType()
+  {
+    return _styleClassType;
+  }
+
+  private final LocaleContext         _localeContext;
+  private final int                   _platform;
+  private final ApplicationAndVersion _appAndVersion;
+  private final AccessibilityProfile  _accProfile;
+  private final ContainerType         _containerType;
+  private final RequestType           _requestType;
+  private final StyleClassType        _styleClassType;
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariantExtractor.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariantExtractor.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariantExtractor.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariantExtractor.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,38 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.List;
+
+import org.apache.myfaces.trinidadinternal.style.util.StyleSheetVisitUtils.StyleSheetVisitor;
+
+/**
+ * StyleSheetVisitor that is used to extract variant (eg. @-rule)
+ * metadata from a skin style sheet document.
+ * 
+ * @see org.apache.myfaces.trinidadinternal.style.util.StyleSheetVisitUtils
+ */
+interface SkinVariantExtractor <T> extends StyleSheetVisitor
+{
+  /**
+   * Called after the style sheet visit to retrieve the variants
+   * that were seen.
+   */
+  public List<T> getVariants();
+}

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariants.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariants.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariants.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/pregen/variant/SkinVariants.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,289 @@
+/*
+ * 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.skin.pregen.variant;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+import java.util.List;
+
+import java.util.NoSuchElementException;
+
+import org.apache.myfaces.trinidad.context.AccessibilityProfile;
+import org.apache.myfaces.trinidad.context.LocaleContext;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent.Application;
+import org.apache.myfaces.trinidadinternal.share.nls.NullLocaleContext;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.ContainerType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.RequestType;
+import org.apache.myfaces.trinidadinternal.skin.pregen.config.PregenConfig.StyleClassType;
+import org.apache.myfaces.trinidadinternal.style.util.StyleSheetVisitUtils;
+import org.apache.myfaces.trinidadinternal.style.util.StyleSheetVisitUtils.StyleSheetVisitor;
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetDocument;
+import org.apache.myfaces.trinidadinternal.style.xml.parse.StyleSheetNode;
+import org.apache.myfaces.trinidadinternal.util.nls.LocaleUtils;
+
+/**
+ * Produces the unique combinations of variants for a skin.  These variants
+ * are exposed via iteration - ie. clients interact with this class as an 
+ * Iterable.
+ */
+public final class SkinVariants implements Iterable<SkinVariant>
+{
+  public SkinVariants(
+    StyleSheetDocument document,
+    PregenConfig       config
+    )
+  {
+    SkinVariantExtractor<Integer> platformExtractor = _getPlatformExtractor(config);
+    SkinVariantExtractor<ApplicationAndVersion> agentExtractor = _getAgentExtractor(config);
+    SkinVariantExtractor<LocaleContext> localeExtractor = _getLocaleExtractor(config);    
+    SkinVariantExtractor<AccessibilityProfile> accExtractor = _getAccessibilityExtractor(config);
+    
+    _extractVariants(document,
+                    localeExtractor,
+                    platformExtractor,
+                    agentExtractor,
+                    accExtractor);
+    
+    _localeContexts = localeExtractor.getVariants();
+    _platforms = platformExtractor.getVariants();
+    _appAndVersions = agentExtractor.getVariants();
+    _accProfiles = accExtractor.getVariants();
+
+    _containerTypes = new ArrayList<ContainerType>(config.getContainerTypes());
+    _requestTypes = new ArrayList<RequestType>(config.getRequestTypes());
+    _styleClassTypes = new ArrayList<StyleClassType>(config.getStyleClassTypes());
+  }
+
+  public Iterator<SkinVariant> iterator()
+  {
+    return new VariantsIterator();
+  }
+
+  private SkinVariantExtractor<Integer> _getPlatformExtractor(PregenConfig config)
+  {
+    Collection<Integer> platforms = config.getPlatformVariants();
+    
+    if (platforms == PregenConfig.ALL_VARIANTS)
+    {
+      return new PlatformVariantExtractor();
+    }
+
+    return (platforms.isEmpty()) ?
+      FixedVariantExtractor.extractor(TrinidadAgent.OS_UNKNOWN) :
+      FixedVariantExtractor.extractor(platforms);
+  }
+  
+  private SkinVariantExtractor<ApplicationAndVersion> _getAgentExtractor(PregenConfig config)
+  {
+    Collection<Application> agentApplications = config.getAgentApplicationVariants();
+    
+    if (agentApplications.isEmpty())
+    {
+      return FixedVariantExtractor.extractor(ApplicationAndVersion.UNKNOWN);
+    }
+    
+    if (agentApplications == PregenConfig.ALL_VARIANTS)
+    {
+      agentApplications = null;
+    }
+
+    // We need to go through AgentVariantExtractor even in the case where
+    // PregenConfig provides a fixed set of agents to pregenerate since
+    // wee need to visit style sheets to determine agent versions.
+    return new AgentVariantExtractor(agentApplications);
+  }
+
+  private SkinVariantExtractor<LocaleContext> _getLocaleExtractor(PregenConfig config)
+  {
+    SkinVariantExtractor<LocaleContext> localeExtractor;
+    Collection<LocaleContext> locales = config.getLocaleVariants();
+    
+    if (locales == PregenConfig.ALL_VARIANTS)
+    {
+      localeExtractor = new LocaleVariantExtractor();
+    }
+    else
+    {
+      if (locales.isEmpty())
+      {
+        locales = Arrays.asList(NullLocaleContext.getLeftToRightContext(),
+                                NullLocaleContext.getRightToLeftContext());
+      }
+      
+      localeExtractor = FixedVariantExtractor.extractor(locales);
+    }
+
+    return _filterDirections(localeExtractor, config);
+  }
+
+  private SkinVariantExtractor<LocaleContext> _filterDirections(
+    SkinVariantExtractor<LocaleContext> localeExtractor,
+    PregenConfig                        config
+    )
+  {
+    Collection<Integer> directions = config.getReadingDirectionVariants();
+    
+    if ((directions == PregenConfig.ALL_VARIANTS) || (directions.size() > 1))
+    {
+      return localeExtractor;
+    }
+    
+    boolean rtlOnly = directions.contains(LocaleUtils.DIRECTION_RIGHTTOLEFT);
+
+    return new DirectionFilteringVariantExtractor(localeExtractor, rtlOnly);
+  }
+  
+  private SkinVariantExtractor<AccessibilityProfile> _getAccessibilityExtractor(
+    PregenConfig config
+    )
+  {
+    Collection<AccessibilityProfile> accessibilityProfiles =
+      config.getAccessibilityVariants();
+    
+    if (accessibilityProfiles == PregenConfig.ALL_VARIANTS)
+    {
+      return new AccessibilityVariantExtractor();
+    }
+    
+    return (accessibilityProfiles.isEmpty() ?
+      FixedVariantExtractor.extractor(AccessibilityProfile.getDefaultInstance()) :
+      FixedVariantExtractor.extractor(accessibilityProfiles));
+      
+  }
+
+  private void _extractVariants(
+    StyleSheetDocument      document,
+    StyleSheetVisitor...    visitors
+    )
+  {
+    Collection<StyleSheetNode> styleSheets = document.getStyleSheetsAsCollection();
+    StyleSheetVisitor compoundVisitor = 
+      StyleSheetVisitUtils.compoundStyleSheetVisitor(Arrays.asList(visitors));
+
+    StyleSheetVisitUtils.visitStyleSheets(styleSheets, compoundVisitor);    
+  }
+
+  private class VariantsIterator implements Iterator<SkinVariant>
+  {
+    @Override
+    public boolean hasNext()
+    {
+      return ((_localeIndex < _localeContexts.size())         &&
+               (_platformIndex < _platforms.size())           &&
+               (_appAndVersionIndex < _appAndVersions.size()) &&
+               (_accProfileIndex < _accProfiles.size())       &&
+               (_containerTypeIndex < _containerTypes.size()) &&
+               (_requestTypeIndex < _requestTypes.size())     &&
+               (_styleClassTypeIndex < _styleClassTypes.size()));
+    }
+
+    @Override
+    public SkinVariant next()
+    {
+      SkinVariant variant = _getNextVariant();
+      _nextIndex();
+      
+      return variant;
+    }
+
+    @Override
+    public void remove()
+    {
+      throw new UnsupportedOperationException();
+    }
+    
+    private SkinVariant _getNextVariant()
+    {
+      if (!hasNext())
+      {
+        throw new NoSuchElementException();
+      }
+      
+      return new SkinVariant(_localeContexts.get(_localeIndex),
+                             _platforms.get(_platformIndex),
+                             _appAndVersions.get(_appAndVersionIndex),
+                             _accProfiles.get(_accProfileIndex),
+                             _containerTypes.get(_containerTypeIndex),
+                             _requestTypes.get(_requestTypeIndex),
+                             _styleClassTypes.get(_styleClassTypeIndex));
+    }
+    
+    private void _nextIndex()
+    {
+      _localeIndex++;
+        
+      if (_localeIndex == _localeContexts.size())
+      {
+        _localeIndex = 0;
+        _accProfileIndex++;
+      }
+      
+      if (_accProfileIndex == _accProfiles.size())
+      {
+        _accProfileIndex = 0;
+        _containerTypeIndex++;
+      }
+      
+      if (_containerTypeIndex == _containerTypes.size())
+      {
+        _containerTypeIndex = 0;
+        _requestTypeIndex++;
+      }
+      
+      if (_requestTypeIndex == _requestTypes.size())
+      {
+        _requestTypeIndex = 0;
+        _styleClassTypeIndex++;
+      }
+
+      if (_styleClassTypeIndex == _styleClassTypes.size())
+      {
+        _styleClassTypeIndex = 0;
+        _appAndVersionIndex++;        
+      }
+
+      if (_appAndVersionIndex == _appAndVersions.size())
+      {
+        _appAndVersionIndex = 0;
+        _platformIndex++;
+      }
+    }
+
+    private int _localeIndex = 0;
+    private int _platformIndex = 0;
+    private int _appAndVersionIndex = 0;
+    private int _accProfileIndex = 0;
+    private int _containerTypeIndex = 0;
+    private int _requestTypeIndex = 0;
+    private int _styleClassTypeIndex = 0;
+  }
+
+  private final List<LocaleContext>         _localeContexts;
+  private final List<Integer>               _platforms;
+  private final List<ApplicationAndVersion> _appAndVersions;
+  private final List<AccessibilityProfile>  _accProfiles;
+  private final List<ContainerType>         _containerTypes;
+  private final List<RequestType>           _requestTypes;
+  private final List<StyleClassType>        _styleClassTypes;
+}

Modified: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java?rev=1298692&r1=1298691&r2=1298692&view=diff
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java (original)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java Fri Mar  9 02:17:24 2012
@@ -59,4 +59,10 @@ public interface StyleContext
    * @return true if the current request is secure (an https request), false otherwise
    */
   public boolean isRequestSecure();
+  
+  /**
+   * Returns a StyleSheetNamingStrategy value that indicates how generated
+   * style sheet files should be named.
+   */
+  public StyleSheetNamingStrategy getNamingStrategy();
 }

Added: myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleSheetNamingStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleSheetNamingStrategy.java?rev=1298692&view=auto
==============================================================================
--- myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleSheetNamingStrategy.java (added)
+++ myfaces/trinidad/branches/andys-skin-pregen/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleSheetNamingStrategy.java Fri Mar  9 02:17:24 2012
@@ -0,0 +1,77 @@
+/*
+ * 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.style;
+
+import java.util.Map;
+
+import org.apache.myfaces.trinidad.util.Enums;
+
+/**
+ * Enum used by StyleSheetContext.getStyleSheetNaming() to indicate what
+ * type of names should be used for generated style file names.
+ */
+public enum StyleSheetNamingStrategy
+{
+  /**
+   * Indicates that short names should be used for generated style sheet files.
+   */
+  SHORT("short"),
+  
+  /**
+   * Indicates that stable (possibly longer) names should be used for generated
+   * style sheet files.
+   */
+  STABLE("stable");
+  
+  StyleSheetNamingStrategy(String displayName)
+  {
+    _displayName = displayName;
+  }
+
+  /**
+   * Returns the display name for this enum constant.
+   */
+  public String displayName()
+  {
+    return _displayName;
+  }
+
+  /**
+   * Performs a reverse lookup of an StyleSheetNames constant based on
+   * its display name.
+   * 
+   * @param displayName the display name of the Accessibility constant to return.
+   * @return the non-null Accessibility constant associated with the display name.
+   * @throws IllegalArgumentException if displayName does not correspond
+   *   to some Accessibility constant.
+   * @throws NullPointerException if displayName is null. 
+   */
+  public static StyleSheetNamingStrategy valueOfDisplayName(String displayName)
+  {
+    return Enums.stringToEnum(_displayNameMap, displayName, StyleSheetNamingStrategy.class);
+  }
+
+  private final String _displayName;
+  private static final Map<String, StyleSheetNamingStrategy> _displayNameMap;
+    
+  static
+  {   
+    _displayNameMap = Enums.createDisplayNameMap(StyleSheetNamingStrategy.class);
+  }
+}