You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sl...@apache.org on 2008/08/28 15:50:29 UTC

svn commit: r689820 - in /myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal: renderkit/core/ renderkit/core/xhtml/ skin/ style/ style/cache/ style/util/

Author: slessard
Date: Thu Aug 28 06:50:28 2008
New Revision: 689820

URL: http://svn.apache.org/viewvc?rev=689820&view=rev
Log:
TRINIDAD-205 : Need to avoid IE's number of CSS selectors limitation.

Modified:
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/StyleSheetRenderer.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleProvider.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
    myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java?rev=689820&r1=689819&r2=689820&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java Thu Aug 28 06:50:28 2008
@@ -18,27 +18,25 @@
  */
 package org.apache.myfaces.trinidadinternal.renderkit.core;
 
+import java.util.List;
 import java.util.Map;
-
 import java.util.concurrent.ConcurrentMap;
 
 import javax.faces.context.FacesContext;
 
 import org.apache.myfaces.trinidad.context.AccessibilityProfile;
-import org.apache.myfaces.trinidad.logging.TrinidadLogger;
-
-import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
-import org.apache.myfaces.trinidad.context.RenderingContext;
-import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.HtmlRenderer;
 import org.apache.myfaces.trinidad.context.LocaleContext;
-import org.apache.myfaces.trinidad.context.RequestContext;
+import org.apache.myfaces.trinidad.context.RenderingContext;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.skin.Icon;
 import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.HtmlRenderer;
 import org.apache.myfaces.trinidadinternal.share.config.Configuration;
 import org.apache.myfaces.trinidadinternal.skin.SkinStyleProvider;
 import org.apache.myfaces.trinidadinternal.style.StyleContext;
-import org.apache.myfaces.trinidadinternal.style.StyleProvider;
 import org.apache.myfaces.trinidadinternal.style.StyleMap;
+import org.apache.myfaces.trinidadinternal.style.StyleProvider;
 
 class StyleContextImpl implements StyleContext
 {
@@ -153,7 +151,7 @@
       return null;
     }
     
-    public String getStyleSheetURI(StyleContext context)
+    public List<String> getStyleSheetURIs(StyleContext context)
     {
       return null;
     }

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/StyleSheetRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/StyleSheetRenderer.java?rev=689820&r1=689819&r2=689820&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/StyleSheetRenderer.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/StyleSheetRenderer.java Thu Aug 28 06:50:28 2008
@@ -19,7 +19,7 @@
 package org.apache.myfaces.trinidadinternal.renderkit.core.xhtml;
 
 import java.io.IOException;
-
+import java.util.List;
 import java.util.Map;
 
 import javax.faces.component.UIComponent;
@@ -29,11 +29,9 @@
 
 import org.apache.myfaces.trinidad.bean.FacesBean;
 import org.apache.myfaces.trinidad.component.core.CoreStyleSheet;
-
 import org.apache.myfaces.trinidad.context.RenderingContext;
 import org.apache.myfaces.trinidad.skin.Skin;
 import org.apache.myfaces.trinidadinternal.renderkit.core.CoreRenderingContext;
-
 import org.apache.myfaces.trinidadinternal.style.StyleContext;
 import org.apache.myfaces.trinidadinternal.style.StyleProvider;
 
@@ -88,7 +86,7 @@
     StyleProvider provider = sContext.getStyleProvider();
     if (provider != null)
     {
-      String href = provider.getStyleSheetURI(sContext);
+      List<String> hrefs = provider.getStyleSheetURIs(sContext);
 
       // If the requestMap has a skin-id, a skin's stylesheet's id and suppressStylesheet
       // is true, and the skin information matches our current skin, then it is safe
@@ -97,40 +95,45 @@
       boolean suppressStylesheet = _isSuppressStylesheet(context, arc);
       if (!suppressStylesheet)
       {
-        if (href != null)
+        if (hrefs != null && !hrefs.isEmpty())
         {
           ExternalContext externalContext = context.getExternalContext();
           String contextUri = externalContext.getRequestContextPath();
           String baseURL = contextUri + XhtmlConstants.STYLES_CACHE_DIRECTORY;
 
           String outputMode = arc.getOutputMode();
-          // =-=AEW Don't like hardcoding facet names...
-          if (XhtmlConstants.OUTPUT_MODE_PORTLET.equals(outputMode) &&
-              supportsScripting(arc))
-          {
-            writer.startElement("script", null);
-            writer.writeText("var _adfSS;if(!_adfSS){_adfSS=1;document.write(\"" +
-                          "<link rel=\\\"stylesheet\\\" "+
-                          "charset=\\\"UTF-8\\\" type=\\\"text/css\\\" " +
-                          "href=\\\"",
-              null);
-            String uri = context.getExternalContext().encodeResourceURL(baseURL+href);
-            writer.writeText(uri, null);
-            writer.writeText("\\\">\")}", null);
-            writer.endElement("script");
-          }
-          else
+          boolean asScript = XhtmlConstants.OUTPUT_MODE_PORTLET.equals(outputMode) 
+              && supportsScripting(arc);
+          
+          for (String href : hrefs)
           {
-            writer.startElement("link", null);
-            renderId(context, comp);
-            writer.writeAttribute("rel", "stylesheet", null);
-            writer.writeAttribute("charset", "UTF-8", null);
-
-            String type = provider.getContentStyleType(sContext);
-            writer.writeAttribute("type", type, null);
-
-            renderEncodedResourceURI(context, "href", baseURL + href);
-            writer.endElement("link");
+            String url = baseURL + href;
+            if (asScript)
+            {
+              writer.startElement("script", null);
+              writer.writeText("var _adfSS;if(!_adfSS){_adfSS=1;document.write(\"" +
+                            "<link rel=\\\"stylesheet\\\" "+
+                            "charset=\\\"UTF-8\\\" type=\\\"text/css\\\" " +
+                            "href=\\\"",
+                null);
+              String uri = context.getExternalContext().encodeResourceURL(url);
+              writer.writeText(uri, null);
+              writer.writeText("\\\">\")}", null);
+              writer.endElement("script");
+            }
+            else
+            {
+              writer.startElement("link", null);
+              renderId(context, comp);
+              writer.writeAttribute("rel", "stylesheet", null);
+              writer.writeAttribute("charset", "UTF-8", null);
+
+              String type = provider.getContentStyleType(sContext);
+              writer.writeAttribute("type", type, null);
+
+              renderEncodedResourceURI(context, "href", url);
+              writer.endElement("link");
+            }
           }
         }
         else

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java?rev=689820&r1=689819&r2=689820&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinStyleProvider.java Thu Aug 28 06:50:28 2008
@@ -193,11 +193,12 @@
   @Override
   protected String getTargetStyleSheetName(
     StyleContext       context,
-    StyleSheetDocument document
+    StyleSheetDocument document,
+    int                partNumber
     )
   {
     // Get the base name from the FileSystemStyleCache.
-    String name = super.getTargetStyleSheetName(context, document);
+    String name = super.getTargetStyleSheetName(context, document, partNumber);
 
     // Use the LAF's id as a prefix
     String id = _skin.getId();

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleProvider.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleProvider.java?rev=689820&r1=689819&r2=689820&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleProvider.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleProvider.java Thu Aug 28 06:50:28 2008
@@ -18,8 +18,8 @@
  */
 package org.apache.myfaces.trinidadinternal.style;
 
+import java.util.List;
 import java.util.Map;
-
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.myfaces.trinidad.skin.Icon;
@@ -60,13 +60,13 @@
   public Map<String, String> getShortStyleClasses(StyleContext context);
 
   /**
-   * Returns the URI of the CSS style sheet to use for the
+   * Returns the URIs of the CSS style sheet to use for the
    * end user environment specified via the StyleContext.
    * @param context The context which describes the end user 
    *   environment for this request
    * @return A CSS style sheet URI
    */
-  public String getStyleSheetURI(StyleContext context);
+  public List<String> getStyleSheetURIs(StyleContext context);
 
   /**
    * Returns a StyleMap object, which can be used to 

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java?rev=689820&r1=689819&r2=689820&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java Thu Aug 28 06:50:28 2008
@@ -22,6 +22,7 @@
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
@@ -154,7 +155,7 @@
   /**
    * Implementation of StyleCache.getStyleSheetURI().
    */
-  public String getStyleSheetURI(StyleContext context)
+  public List<String> getStyleSheetURIs(StyleContext context)
   {
 
     Entry entry = _getEntry(context);
@@ -162,7 +163,7 @@
     if (entry == null)
       return null;
 
-    return entry.uri;
+    return entry.uriList;
   }
 
   /**
@@ -304,10 +305,9 @@
    * @param context The StyleContext
    * @param document The StyleSheetDocument which provides the styles
    */
-  protected String getTargetStyleSheetName(
-    StyleContext       context,
-    StyleSheetDocument document
-    )
+  protected String getTargetStyleSheetName(StyleContext       context,
+                                           StyleSheetDocument document, 
+                                           int 			          partNumber)
   {
     StringBuffer buffer = new StringBuffer();
 
@@ -323,13 +323,20 @@
 
       buffer.append(contextName);
     }
+    
     if (_isCompressStyles(null))
     {
       if (baseName != null || contextName != null)
         buffer.append(_NAME_SEPARATOR);
       buffer.append(_COMPRESSED);
     }
-
+    
+    if (partNumber > 1)
+    {
+        buffer.append(_NAME_SEPARATOR);
+        buffer.append(partNumber);
+    }
+    
     buffer.append(_CSS_EXTENSION);
 
     return buffer.toString();
@@ -444,25 +451,56 @@
     Key                   key,
     boolean               checkModified)
   {
+    return _getEntryInternal(cache, key, checkModified);
+  }
+
+  private Entry _getEntryInternal(Hashtable<?, Entry> cache, Object key, boolean checkModified)
+  {
     Entry entry = cache.get(key);
     if (entry == null)
+    {
       return null;
-
-    // Make sure the entry's file exists.  If it no longer
-    // exists, we remove the entry from the cache
-    if (checkModified &&
-         (entry.uri != null) &&
-         !(new File(_targetPath, entry.uri).exists()))
+    }
+    
+    if (checkModified)
     {
-      synchronized (cache)
+      List<String> uris = entry.uriList;
+      assert uris != null;
+      assert !uris.isEmpty();
+
+      boolean valid = true;
+      List<File> existing = new ArrayList<File>(uris.size());
+      // Make sure the entry's file exists.  If it no longer
+      // exists, we remove the entry from the cache
+      for (String name : uris)
       {
-        if (cache.get(key) == entry)
-          cache.remove(key);
+        File file = new File(_targetPath, name);
+        if (file.exists())
+        {
+          existing.add(file);
+        }
+        else
+        {
+          valid = false;
+        }
       }
+      
+      if (!valid)
+      {
+        _deleteAll(existing);
+        
+        synchronized (cache)
+        {
+          if (cache.get(key) == entry)
+          {
+            cache.remove(key);
+          }
+        }
 
-      return null;
+        return null;
+      }
     }
-
+    
     return entry;
   }
 
@@ -487,32 +525,29 @@
     // info that is in the StyleContext.
     StyleNode[] styles = _getStyleContextResolvedStyles(context, document);
     if (styles == null)
+    {
       return null;
+    }
 
     // Generate the style sheet file, if it isn't already generated,
     // and return the uri.
-    String uri = _createStyleSheetFile(context,
-                                       document,
-                                       styles,
-                                       shortStyleClassMap,
-                                       namespacePrefixes,
-                                       checkModified);
+    List<String> fileNames = _createStyleSheetFile(context, document, styles,
+                                                   shortStyleClassMap, namespacePrefixes, 
+                                                   checkModified);
 
-    _LOG.fine("Finished processing stylesheet {0}", uri);
+    _LOG.fine("Finished processing stylesheets {0}", fileNames);
     
     
     // Next, get the fully resolved icons and skin properties for this context.
     // This will be those Icons and Skin Properties that match the locale, direction,
     // browser, etc -- the info that is in the StyleContext
-    ConcurrentMap<String, Icon> icons =
-      _getStyleContextResolvedIcons(context, document);
-    ConcurrentMap<Object, Object> skinProperties =
-      _getStyleContextResolvedSkinProperties(context, document);
+    ConcurrentMap<String, Icon> icons = _getStyleContextResolvedIcons(context, document);
+    ConcurrentMap<Object, Object> skinProperties = _getStyleContextResolvedSkinProperties(context, document);
 
     // Create a new entry and cache it in the "normal" cache. The "normal" cache is one
     // where the key is the Key object which is built based on information from the StyleContext,
     // like browser, agent, locale, direction.
-    Entry entry = new Entry(uri, new StyleMapImpl(), icons, skinProperties);
+    Entry entry = new Entry(fileNames, new StyleMapImpl(), icons, skinProperties);
     cache.put(key, entry);
 
     // Also, cache the new entry in the entry cache
@@ -535,28 +570,13 @@
     )
   {
     DerivationKey derivationKey = _getDerivationKey(context, document);
-    Entry entry = entryCache.get(derivationKey);
-    if (entry == null)
-      return null;
-
-    // Make sure the entry's file exists.  If the file no
-    // longer exists, we remove the entry from the entry cache.
-    if (checkModified &&
-         (entry.uri != null) &&
-         !(new File(_targetPath, entry.uri).exists()))
+    Entry entry = _getEntryInternal(entryCache, derivationKey, checkModified);
+    if (entry != null)
     {
-      synchronized (this)
-      {
-        if (entryCache.get(derivationKey) == entry)
-          entryCache.remove(derivationKey);
-      }
-
-      return null;
+      // If we've got a compatible entry, cache it
+      cache.put(key, entry);
     }
-
-    // If we've got a compatible entry, cache it
-    cache.put(key, entry);
-
+    
     return entry;
   }
 
@@ -697,7 +717,7 @@
 
   // Generates the CSS file for the specified context and styles.
   // Returns the name of the generated CSS file.
-  private String        _createStyleSheetFile(
+  private List<String> _createStyleSheetFile(
     StyleContext        context,
     StyleSheetDocument  document,
     StyleNode[]         styles,
@@ -705,89 +725,95 @@
     String[]            namespacePrefixes,
     boolean             checkModified)
   {
+	  int maxSelectorPerFile;
+	  if (TrinidadAgent.APPLICATION_IEXPLORER == context.getAgent().getAgentApplication())
+	  {
+		  maxSelectorPerFile = _MSIE_SELECTOR_LIMIT;
+	  }
+	  else
+	  {
+	    maxSelectorPerFile = styles.length;
+	  }
+	  
     // Get a name for the new style sheet
-    File outputFile = _getOutputFile(context, document);
-    String name = outputFile.getName();
-
-    // If the output file already exists, check the last modified time.
-    if (outputFile.exists())
+    File[] outputFiles = _getOutputFiles(context, document, styles.length, maxSelectorPerFile);
+    if (outputFiles[0].exists())
     {
-      if (checkModified)
+      if (_isDirty(document, outputFiles[0], checkModified))
       {
-        if (!_checkSourceModified(document, outputFile))
-          return name;
-
-        // If the output file is older than the source file, we
-        // need to regenerate the output file.  But first we
-        // need to delete the old output file before we attempt to
-        // create a new version.
-        outputFile.delete();
+        _deleteAll(outputFiles);
       }
       else
-        return name;
+      {
+        return getFileNames(outputFiles);
+      }
     }
+    
+    Skin skin = RenderingContext.getCurrentInstance().getSkin();
+    
+    // First figure out whether or not we need to compress the style classes.
+    // We don't compress the style classes if the content compression flag is disabled or
+    // if the skin is a portlet skin.
+    boolean compressStyles = _isCompressStyles(skin);
 
-    // Now, try to create the file
-    boolean created = false;
-
-    try
+    List<File> createdFiles = new ArrayList<File>(outputFiles.length);
+    for (int i = 0; i < outputFiles.length; i++)
     {
-      // Make sure the output directory exists in case it's been
-      // blown away since the creation of the cache
-      File outputDir = outputFile.getParentFile();
-      if (!outputDir.exists())
-        outputDir.mkdirs();
+      File file = outputFiles[i];
+      
+      // Now, try to create the files and get the writer to output to
+      PrintWriter writer = _getWriterToNewFile(file);
+      if (writer == null)
+      {
+        _deleteAll(createdFiles);
+        return null;
+      }
+      
+      try
+      {
+        // Write out the style sheet
+        CSSGenerationUtils.writeCSS(context, skin.getStyleSheetName(), styles, writer,
+                                    compressStyles, shortStyleClassMap, namespacePrefixes,
+                                    _STYLE_KEY_MAP, i * maxSelectorPerFile, maxSelectorPerFile);
+      }
+      finally
+      {
+        writer.close();
+      }
 
-      // If we can't create the new file, bail
-      created = outputFile.createNewFile();
+      // We never want to do anything other then read it or delete it:
+      file.setReadOnly();
     }
-    catch (IOException e)
+
+    return getFileNames(outputFiles);
+  }
+  
+  private boolean _isDirty(StyleSheetDocument document, File file, boolean checkModified)
+  {
+	  // If the output file already exists, check the last modified time.
+		return checkModified && _checkSourceModified(document, file);
+  }
+  
+  private void _deleteAll(File[] files)
+  {
+    for (File file : files)
     {
-      if (_LOG.isWarning())
-        _LOG.warning("IOEXCEPTION_CREATING_FILE", outputFile);
-        _LOG.warning(e);
+      if (file.exists())
+      {
+        file.delete();
+      }
     }
-
-    if (!created)
+  }
+  
+  private void _deleteAll(Iterable<File> files)
+  {
+    for (File file : files)
     {
-      if (_LOG.isWarning())
-        _LOG.warning("\nUnable to generate the style sheet "
-                     + outputFile.getName() + " in cache directory\n"
-                     + outputFile.getParent() + ".\n"
-                     + "Please make sure that the cache directory exists "
-                     + "and is writable.\n" );
-      return null;
+      if (file.exists())
+      {
+        file.delete();
+      }
     }
-
-    // Get the Writer to output to
-    PrintWriter out = _getWriter(outputFile);
-    if (out == null)
-      return null;
-
-    // Write out the style sheet
-    // First figure out whether or not we need to compress the style classes.
-    // We don't compress the style classes if the content compression flag is disabled or
-    // if the skin is a portlet skin.
-    Skin skin = RenderingContext.getCurrentInstance().getSkin();
-    boolean compressStyles = _isCompressStyles(skin);
-
-    CSSGenerationUtils.writeCSS(context,
-                                skin.getStyleSheetName(),
-                                styles,
-                                out,
-                                compressStyles,
-                                shortStyleClassMap,
-                                namespacePrefixes,
-                                _STYLE_KEY_MAP
-                                );
-
-    out.close();
-
-    // We never want to do anything other then read it or delete it:
-    outputFile.setReadOnly();
-
-    // Return the name of the new style sheet
-    return name;
   }
   
   // First figure out whether or not we need to compress the style classes.
@@ -812,35 +838,64 @@
 
   // Returns the name of the output file to use for the
   // style sheet associated with the specified context
-  private File _getOutputFile(
+  private File[] _getOutputFiles(
     StyleContext context,
-    StyleSheetDocument document
+    StyleSheetDocument document,
+    int selectorCount,
+    int maxSelectorPerFile
     )
   {
-    String name = getTargetStyleSheetName(context, document);
+    int fileCount = selectorCount / maxSelectorPerFile;
+    if (selectorCount % maxSelectorPerFile != 0)
+    {
+      fileCount++;
+    }
+	  
+	  File[] outputFiles = new File[fileCount];
+	  
+	  for (int i = 0; i < fileCount; i++)
+	  {
+		  String name = getTargetStyleSheetName(context, document, i + 1);
+		  outputFiles[i] = new File(_targetPath, name);
+	  }
 
-    return new File(_targetPath, name);
+	  return outputFiles;
   }
 
   // Returns the PrintWriter to use for the specified file
-  private PrintWriter _getWriter(File file)
+  private PrintWriter _getWriterToNewFile(File file)
   {
-    PrintWriter out = null;
 
     try
     {
       File parentFile = file.getParentFile();
       if (parentFile != null)
+      {
         parentFile.mkdirs();
+      }
 
-      FileOutputStream fos = new FileOutputStream(file);
-      OutputStreamWriter writer = null;
+      if (!file.createNewFile())
+      {
+        if (_LOG.isWarning())
+        {
+          _LOG.warning("\nUnable to generate the style sheet "
+                       + file.getName() + " in cache directory\n"
+                       + file.getParent() + ".\n"
+                       + "Please make sure that the cache directory exists "
+                       + "and is writable.\n" );
+        }
+        
+        return null;
+      }
+      
+      OutputStream ostream = new FileOutputStream(file);
+      
+      OutputStreamWriter writer;
 
-      // Use UTF8 encoding for output, in case font names have non-ascii
-      // characters.
+      // Use UTF8 encoding for output, in case font names have non-ascii characters.
       try
       {
-        writer = new OutputStreamWriter(fos, _UTF8_ENCODING);
+        writer = new OutputStreamWriter(ostream, _UTF8_ENCODING);
       }
       catch (UnsupportedEncodingException e)
       {
@@ -848,19 +903,21 @@
         assert false;
 
         // Just use default encoding instead
-        writer = new OutputStreamWriter(fos);
+        writer = new OutputStreamWriter(ostream);
       }
 
-      out = new PrintWriter(new BufferedWriter(writer));
+      return new PrintWriter(new BufferedWriter(writer));
     }
     catch (IOException e)
     {
       if (_LOG.isWarning())
+      {
         _LOG.warning("IOEXCEPTION_OPENNING_FILE", file);
         _LOG.warning(e);
+      }
     }
-
-    return out;
+    
+    return null;
   }
 
   // Checks to see whether the source file has been modified
@@ -938,6 +995,17 @@
 
     return v;
   }
+  
+  private static List<String> getFileNames(File[] files)
+  {
+    List<String> names = new ArrayList<String>(files.length);
+    for (File file : files)
+    {
+      names.add(file.getName());
+    }
+    
+    return Collections.unmodifiableList(names);
+  }
 
   // Create an array of all the namespace prefixes in the xss/css file. E.g., "af|" or "tr|"
   private static String[] _getNamespacePrefixes(
@@ -1083,7 +1151,7 @@
   // that start with SkinSelectors.STATE_PREFIX. The reason is that those
   // are likely to be added and removed on the client as the state changes, and
   // we don't want to require the shortened map on the client.
-  private static void _putStyleClassInShortMap(String styleClass, Map map)
+  private static void _putStyleClassInShortMap(String styleClass, Map<String, String> map)
   {
     if (styleClass != null &&
         !styleClass.startsWith(SkinSelectors.STATE_PREFIX) &&
@@ -1102,8 +1170,7 @@
     // of style classes and not the style class itself.
     return _SHORT_CLASS_PREFIX + Integer.toString(count, Character.MAX_RADIX);
   }
-
-
+  
   // Key class used for hashing style sheet URIs
   private static class Key
   {
@@ -1201,18 +1268,18 @@
   // Cache entry class
   private static class Entry
   {
-    public final String uri;
+    public final List<String> uriList;
     public final StyleMap map;
     public final ConcurrentMap<String, Icon> icons;
     public final ConcurrentMap<Object, Object> skinProperties;
 
     public Entry(
-      String uri,
+      List<String> uriList,
       StyleMap map,
       ConcurrentMap<String, Icon> icons,
       ConcurrentMap<Object, Object> skinProperties)
     {
-      this.uri = uri;
+      this.uriList = uriList;
       this.map = map;
       this.icons = icons;
       this.skinProperties = skinProperties;
@@ -1433,6 +1500,7 @@
   // Prefix to use for short style classes
   private static final String _SHORT_CLASS_PREFIX = "x";
 
+  private static final int _MSIE_SELECTOR_LIMIT = 4095;
   private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(FileSystemStyleCache.class);
 
 

Modified: myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java?rev=689820&r1=689819&r2=689820&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java (original)
+++ myfaces/trinidad/trunk/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/util/CSSGenerationUtils.java Thu Aug 28 06:50:28 2008
@@ -69,16 +69,16 @@
    * @param afSelectorMap A Map which maps the namespaced component selectors
    *   to their base names (e.g., 'af|menuPath::step' maps to 'af|menuPath A')
    */
-  public static void writeCSS(
-    StyleContext        context,
-    String              styleSheetName,
-    StyleNode[]         styles,
-    PrintWriter         out,
-    boolean             compressStyles,
-    Map<String, String> shortStyleClassMap,
-    String[]            namespacePrefixArray,
-    Map<String, String> afSelectorMap
-    )
+  public static void writeCSS(StyleContext        context,
+                              String              styleSheetName,
+                              StyleNode[]         styles,
+                              PrintWriter         out,
+                              boolean             compressStyles,
+                              Map<String, String> shortStyleClassMap,
+                              String[]            namespacePrefixArray,
+                              Map<String, String> afSelectorMap,
+                              int 				        startIndex,
+                              int					        count)
   {
     // writeCSS() attempts to produce a minimal set of style rules
     // by combining selectors with identical properties into a
@@ -103,20 +103,31 @@
     // During the second pass over the styles, we write out all matching
     // selectors for each style followed by the shared set of properties.
 
+    if (startIndex < 0)
+    {
+    	throw new IllegalArgumentException("startIndex must be positive");
+    }
+    
+    if (count <= 0)
+    {
+    	throw new IllegalArgumentException("count must be strictly positive");
+    }
+	
     // We track styles with matching properties in the following HashMap
     // which maps property strings to StyleNode[]s.
-    HashMap<String, StyleNode[]> matchingStylesMap =
-      new HashMap<String, StyleNode[]>(101);
+    HashMap<String, StyleNode[]> matchingStylesMap = new HashMap<String, StyleNode[]>(101);
 
     // We also keep an array of the property strings that we generate
     // during this pass, since we need these strings during the second
     // pass to find matching StyleNodes.
-    String[] propertyStrings = new String[styles.length];
-     // Keep track of the number of selectors written out. The reason? IE has a 4095 limit,
-     // and we want to warn when we get to that limit.
-     int numberSelectorsWritten = 0;
-
-    for (int i = 0; i < styles.length; i++)
+    String[] propertyStrings = new String[count];
+    
+    // Keep track of the number of selectors written out. The reason? IE has a 4095 limit,
+    // and we want to warn when we get to that limit.
+    int numberSelectorsWritten = 0;
+    int endIndex = startIndex + count;
+    
+    for (int i = startIndex; i < styles.length && i < endIndex; i++)
     {
       StyleNode style = styles[i];
 
@@ -133,7 +144,7 @@
         {
           // If we don't already have matching StyleNodes, add this
           // StyleNode to the map.
-          propertyStrings[i] = propertyString;
+          propertyStrings[i - startIndex] = propertyString;
           matchingStyles = new StyleNode[1];
           matchingStyles[0] = style;
         }
@@ -167,10 +178,10 @@
     // Get the baseURI up front so we don't have to recalculate it every time we find
     // a property value that contains url() and need to resolve the uri.
     String baseURI = CSSUtils.getBaseSkinStyleSheetURI(styleSheetName);
-    for (int i = 0; i < styles.length; i++)
+    for (int i = startIndex; i < styles.length && i < endIndex; i++)
     {
       StyleNode style = styles[i];
-      String propertyString = propertyStrings[i];
+      String propertyString = propertyStrings[i - startIndex];
 
       // We only write out styles for which we have a property string.
       // All other entries correspond to styles which don't have selectors -