You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by de...@apache.org on 2017/09/17 12:30:28 UTC

[myfaces-trinidad] 05/36: TRINIDAD-1687 add a Skin api that will clear the skin file(s) and reload at runtime The api is /** * Check to see if this Skin has been marked dirty. * The only way to mark a Skin dirty is to call setDirty(true). * @return true if the Skin is marked dirty. */ abstract public boolean isDirty();

This is an automated email from the ASF dual-hosted git repository.

deki pushed a commit to branch 1.2.12.2-branch
in repository https://gitbox.apache.org/repos/asf/myfaces-trinidad.git

commit 585232b5aa1789d899d0684452778a16aa1c3771
Author: Jeanne Waldman <jw...@apache.org>
AuthorDate: Mon Jan 18 22:56:52 2010 +0000

    TRINIDAD-1687 add a Skin api that will clear the skin file(s) and reload at runtime
    The api is
      /**
       * Check to see if this Skin has been marked dirty.
       * The only way to mark a Skin dirty is to call setDirty(true).
       * @return true if the Skin is marked dirty.
       */
      abstract public boolean isDirty();
    
      /**
       * Sets the dirty flag of the Skin. Use this if you want to regenerate the skin.
       * During rendering, if isDirty is true,
       * the skin's css file will be reprocessed regardless of whether the css file has been modified
       * or if the CHECK_FILE_MODIFICATION flag was set.
       * The Skinning Framework calls setDirty(false) after the skin has been reprocessed.
       */
      abstract public void setDirty(boolean dirty);
---
 .../org/apache/myfaces/trinidad/skin/Skin.java     | 16 ++++++++
 .../trinidaddemo/SkinDirtyPhaseListener.java       | 46 +++++++++++++++++++++
 .../src/main/webapp/WEB-INF/faces-config.xml       |  6 ++-
 .../src/main/webapp/demos/panelPageSkinDemo.jspx   |  2 +-
 .../renderkit/core/StyleContextImpl.java           |  7 ++++
 .../trinidadinternal/skin/RequestSkinWrapper.java  | 11 +++++
 .../trinidadinternal/skin/SkinExtension.java       | 15 +++++++
 .../myfaces/trinidadinternal/skin/SkinImpl.java    | 31 +++++++++++++-
 .../trinidadinternal/skin/StyleSheetEntry.java     | 13 +++---
 .../trinidadinternal/style/StyleContext.java       |  1 +
 .../style/cache/FileSystemStyleCache.java          | 48 +++++++++++++++++-----
 .../trinidadinternal/resource/LoggerBundle.xrts    |  1 +
 12 files changed, 176 insertions(+), 21 deletions(-)

diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/skin/Skin.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/skin/Skin.java
index 2ec29e8..1392039 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/skin/Skin.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/skin/Skin.java
@@ -186,5 +186,21 @@ abstract public class Skin
    * @return List a List of SkinAdditions.
    */
   abstract public List<SkinAddition> getSkinAdditions ();
+  
+  /**
+   * Check to see if this Skin has been marked dirty. 
+   * The only way to mark a Skin dirty is to call setDirty(true).
+   * @return true if the Skin is marked dirty. 
+   */
+  abstract public boolean isDirty();
+
+  /**
+   * Sets the dirty flag of the Skin. Use this if you want to regenerate the skin. 
+   * During rendering, if isDirty is true, 
+   * the skin's css file will be reprocessed regardless of whether the css file has been modified 
+   * or if the CHECK_FILE_MODIFICATION flag was set. 
+   * The Skinning Framework calls setDirty(false) after the skin has been reprocessed.
+   */
+  abstract public void setDirty(boolean dirty);
     
 }
diff --git a/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/SkinDirtyPhaseListener.java b/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/SkinDirtyPhaseListener.java
new file mode 100644
index 0000000..684da26
--- /dev/null
+++ b/trinidad-examples/trinidad-demo/src/main/java/org/apache/myfaces/trinidaddemo/SkinDirtyPhaseListener.java
@@ -0,0 +1,46 @@
+package org.apache.myfaces.trinidaddemo;
+
+import javax.faces.event.PhaseEvent;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+
+import org.apache.myfaces.trinidad.context.RenderingContext;
+import org.apache.myfaces.trinidad.context.RequestContext;
+
+/**
+ * This class is used in panelPageSkinDemo.jspx. It sets the Skin to dirty so that if you
+ * change a skin css file it gets picked up immediately without the need to set the web.xml
+ * CHECK_FILE_MODIFICATION flag.
+ */
+public class SkinDirtyPhaseListener
+  implements PhaseListener
+{
+  public SkinDirtyPhaseListener()
+  {
+    super();
+  }
+
+  public void afterPhase(PhaseEvent phaseEvent)
+  {
+  }
+
+  public void beforePhase(PhaseEvent phaseEvent)
+  {
+    // Add event code here...
+    System.out.println("***PhaseTracker: Before Phase: " + phaseEvent.getPhaseId());
+    RenderingContext rContext = RenderingContext.getCurrentInstance();
+    if (rContext != null)
+    {
+      System.out.println("Set Skin to dirty");
+      rContext.getSkin().setDirty(true);
+    }
+    else
+      System.out.println("rContext in _beforePhase is null!");
+
+  }
+
+  public PhaseId getPhaseId()
+  {
+    return PhaseId.ANY_PHASE;
+  }
+}
diff --git a/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml b/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
index 0a91f2f..4c32694 100644
--- a/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
+++ b/trinidad-examples/trinidad-demo/src/main/webapp/WEB-INF/faces-config.xml
@@ -3065,5 +3065,9 @@
     <managed-bean-class>org.apache.myfaces.trinidaddemo.DemoAccessibilityProfileBean</managed-bean-class>
     <managed-bean-scope>session</managed-bean-scope>
   </managed-bean>
-
+  <managed-bean>
+    <managed-bean-name>skinDirty</managed-bean-name>
+    <managed-bean-class>org.apache.myfaces.trinidaddemo.SkinDirtyPhaseListener</managed-bean-class>
+    <managed-bean-scope>request</managed-bean-scope>
+  </managed-bean>
 </faces-config>
diff --git a/trinidad-examples/trinidad-demo/src/main/webapp/demos/panelPageSkinDemo.jspx b/trinidad-examples/trinidad-demo/src/main/webapp/demos/panelPageSkinDemo.jspx
index 07b4ac2..ad6632b 100644
--- a/trinidad-examples/trinidad-demo/src/main/webapp/demos/panelPageSkinDemo.jspx
+++ b/trinidad-examples/trinidad-demo/src/main/webapp/demos/panelPageSkinDemo.jspx
@@ -24,7 +24,7 @@
           xmlns:trh="http://myfaces.apache.org/trinidad/html"
           xmlns:tr="http://myfaces.apache.org/trinidad">
   <jsp:directive.page contentType="text/html;charset=utf-8"/>
-  <f:view>
+  <f:view beforePhase="#{skinDirty.beforePhase}">
     <trh:html>
       <trh:head title="Skin Demo">
         <!-- the beach skin is defined in beach.css. If you want to add your own
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
index 7c7ebdd..9eb7305 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
@@ -132,6 +132,13 @@ class StyleContextImpl implements StyleContext
       context.getExternalContext().getInitParameter(Configuration.CHECK_TIMESTAMP_PARAM);
     return "true".equals(checkTimestamp);
   }
+  /*
+   * checks to see if the Skin is dirty by calling skin.isDirty()
+   */
+  public boolean isDirty()
+  {
+    return _arc.getSkin().isDirty();
+  }
 
   public boolean disableStandardsMode()
   {
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/RequestSkinWrapper.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/RequestSkinWrapper.java
index ba1cfef..6106c2d 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/RequestSkinWrapper.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/RequestSkinWrapper.java
@@ -312,6 +312,17 @@ public class RequestSkinWrapper extends Skin implements DocumentProviderSkin
 
     return ((DocumentProviderSkin)_skin).getStyleSheetDocument(styleContext);
   }
+  
+  @Override
+  public boolean isDirty()
+  {
+    return _skin.isDirty();
+  }
+  @Override
+  public void setDirty(boolean dirty)
+  {
+    _skin.setDirty(dirty);
+  }
 
   // Returns request-specific map of icon names to Icons
   private Map<String, Icon> _getRequestIcons()
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinExtension.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinExtension.java
index 6f66009..3b0305c 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinExtension.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinExtension.java
@@ -548,6 +548,21 @@ public class SkinExtension extends SkinImpl
       return _fullStyleSheetDocument;
     }
   }
+  
+  /**
+   * Set the skin to be dirty. This will force the skin's css file to
+   * be reprocessed regardless of whether the css file has been modified 
+   * or if the CHECK_FILE_MODIFICATION flag was set.
+   * The Skinning Framework sets the dirty flag back to 
+   * false once it has reprocessed the skin.
+   */
+  @Override
+  public void setDirty(boolean dirty)
+  {
+    super.setDirty(dirty);
+    // also, set the base skin's dirty flag
+    getBaseSkin().setDirty(dirty);
+  }
 
   /**
    * Find the actual icon
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinImpl.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinImpl.java
index 929008b..5ecb82a 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinImpl.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/SkinImpl.java
@@ -386,6 +386,31 @@ abstract public class SkinImpl extends Skin implements DocumentProviderSkin
     SkinAddition addition = new SkinAddition(styleSheetName);
     addSkinAddition(addition);
   }
+  
+  /**
+   * Check to see if this Skin has been marked dirty. 
+   * The only way to mark a Skin dirty is to call setDirty(true).
+   * @return true if the Skin is marked dirty. 
+   * 
+   */
+  @Override
+  public boolean isDirty()
+  {
+    return _dirty;
+  }
+
+  /**
+   * Sets the dirty flag of the Skin. Use this if you want to regenerate the skin. 
+   * During rendering, if isDirty is true, 
+   * the skin's css file will be reprocessed regardless of whether the css file has been modified 
+   * or if the CHECK_FILE_MODIFICATION flag was set. 
+   * The Skinning Framework calls setDirty(false) after the skin has been reprocessed.
+   */
+   @Override
+  public void setDirty(boolean dirty)
+  {
+    _dirty = dirty;
+  }
 
   /**
    * Returns a translated value in the LocaleContext's translation Locale, or null
@@ -489,10 +514,11 @@ abstract public class SkinImpl extends Skin implements DocumentProviderSkin
   abstract protected ValueExpression getTranslationSourceValueExpression();
 
   // Checks to see whether any of our style sheets have been updated
+  // or if the skin has been marked dirty
   private boolean _checkStylesModified(
     StyleContext context
     )
-  {
+  {    
     boolean modified = false;
 
     if (_skinStyleSheet != null)
@@ -1157,6 +1183,7 @@ abstract public class SkinImpl extends Skin implements DocumentProviderSkin
   // HashMap of Skin properties
   private ConcurrentHashMap<Object, Object> _properties= new ConcurrentHashMap<Object, Object>();
 
-
+  private boolean _dirty;
+  
   private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(SkinImpl.class);
 }
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetEntry.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetEntry.java
index acd0291..b2bb2e6 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetEntry.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/skin/StyleSheetEntry.java
@@ -78,9 +78,10 @@ class StyleSheetEntry
         return null;
 
       // We either create a plain old StyleSheetEntry or a special
-      // subclass of StyleSheetEntry that can check for modifications
-      // depending on the Configuration settings
-      if (context.checkStylesModified())
+      // subclass of StyleSheetEntry that will recalculate the StyleSheetEntry
+      // if the skin is dirty or if there are file modifications
+      // and the Configuration settings say to check for file modifications.
+      if (context.checkStylesModified() || context.isDirty())
         return new CheckModifiedEntry(styleSheetName,
                                       skinStyleSheet.getDocument(),
                                       resolver);
@@ -269,8 +270,8 @@ class StyleSheetEntry
   }
 
 
-  // Subclass of StyleSheetEntry which checks for updates
-  // to the underlying style sheet files.
+  // Subclass of StyleSheetEntry which recreates the StyleSheetEntry
+  // if the skin is marked dirty (skin.isDirty()) or if the underlying source files have been modified.
   private static class CheckModifiedEntry extends StyleSheetEntry
   {
     public CheckModifiedEntry(
@@ -294,7 +295,7 @@ class StyleSheetEntry
     {
       // We would synchronize here, but at the moment synchronization
       // is provided by Skin.getStyleSheetDocument().
-      if ((_provider != null) && (_provider.hasSourceChanged()))
+      if (context.isDirty() || ((_provider != null) && (_provider.hasSourceChanged())))
       {
         // Throw away the old InputStreamProvider and StyleSheetDocument
         _provider = null;
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
index dfb1679..8f5107a 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
@@ -53,4 +53,5 @@ public interface StyleContext
   public AccessibilityProfile getAccessibilityProfile();
   public boolean isPortletMode();
   public boolean isDisableStyleCompression();
+  public boolean isDirty();
 }
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
index b21f1e0..ef9bad1 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
@@ -290,7 +290,9 @@ public class FileSystemStyleCache implements StyleProvider
     StyleSheetDocument document = null;
     Map<String, String> shortStyleClassMap = null;
     String[] namespacePrefixes = null;
-
+    RenderingContext arc = RenderingContext.getCurrentInstance();
+    Skin skin = arc.getSkin();
+    boolean isDirty = skin.isDirty();
     boolean checkModified  = context.checkStylesModified();
 
     // Synchronize while set up the _cache, _entryCache, _document, etc...
@@ -298,7 +300,7 @@ public class FileSystemStyleCache implements StyleProvider
     {
       // If checking for modified files, then check to see if the XSS or CSS
       // document has been modified.  If so, we dump our in-memory style cache.
-      if (checkModified && hasSourceDocumentChanged(context))
+      if (isDirty || (checkModified && hasSourceDocumentChanged(context)))
       {
         _cache = null;
         _entryCache = null;
@@ -356,7 +358,8 @@ public class FileSystemStyleCache implements StyleProvider
                         entryCache,
                         shortStyleClassMap,
                         namespacePrefixes,
-                        checkModified);
+                        checkModified, 
+                        isDirty);
   }
 
   private Entry _getEntry(
@@ -422,7 +425,8 @@ public class FileSystemStyleCache implements StyleProvider
     ConcurrentMap<Object, Entry> entryCache,
     Map<String, String>          shortStyleClassMap,
     String[]                     namespacePrefixes,
-    boolean                      checkModified)
+    boolean                      checkModified,
+    boolean                      isDirty)
   {
     // Next, get the fully resolved styles for this context. This will be
     // those StyleNodes that match the locale, direction, browser, portlet mode
@@ -445,7 +449,8 @@ public class FileSystemStyleCache implements StyleProvider
                                        styleNodes,
                                        shortStyleClassMap,
                                        namespacePrefixes,
-                                       checkModified);
+                                       checkModified,
+                                       isDirty);
 
     _LOG.fine("Finished processing stylesheet {0}", uris);
 
@@ -469,6 +474,11 @@ public class FileSystemStyleCache implements StyleProvider
     // Also, cache the new entry in the entry cache
     DerivationKey derivationKey = _getDerivationKey(context, document);
     entryCache.put(derivationKey, entry);
+    
+    // just in case, clear the dirty flag.
+    RenderingContext arc = RenderingContext.getCurrentInstance();
+    Skin skin = arc.getSkin();
+    skin.setDirty(false);
 
     return entry;
   }
@@ -655,17 +665,21 @@ public class FileSystemStyleCache implements StyleProvider
     StyleNode[]         styles,
     Map<String, String> shortStyleClassMap,
     String[]            namespacePrefixes,
-    boolean             checkModified)
+    boolean             checkModified,
+    boolean             isDirty)
   {
+
     // Get the current files
     List<File> outputFiles = _getOutputFiles(context, document);
 
     // If at least one output file exists, check the last modified time.
     if (!outputFiles.isEmpty())
     {
-      if (checkModified)
+      // If the skin is marked dirty, we regenerate the css even if the document's timestamp has not
+      // changed.
+      if (checkModified || isDirty)
       {
-        if (!_checkSourceModified(document, outputFiles.get(0)))
+        if (!isDirty && (checkModified && !_checkSourceModified(document, outputFiles.get(0))))
         {
           return _getFileNames(outputFiles);
         }
@@ -740,7 +754,15 @@ public class FileSystemStyleCache implements StyleProvider
     {
       if (file.exists())
       {
-        file.delete();
+        boolean success = file.delete();
+        // add warning if success is false, but continue on.
+        // I've seen the delete fail when we try to delete right after the file was created -
+        // like if the skin css file is modified and the page refreshed immediately after the
+        // app was initially run.
+        if (!success && _LOG.isWarning())
+        {
+          _LOG.warning("COULD_NOT_DELETE_FILE", file.getName());
+        }
       }
     }
   }
@@ -813,6 +835,9 @@ public class FileSystemStyleCache implements StyleProvider
       if (parentFile != null)
         parentFile.mkdirs();
 
+      // This throws a FileNotFoundException if it wasn't successfully deleted earlier, most likely
+      // due to creating, then deleting too soon after.
+      // Since the file has the hashcode in the name, it's not bad that it doesn't rewrite it.
       FileOutputStream fos = new FileOutputStream(file);
       OutputStreamWriter writer = null;
 
@@ -835,6 +860,8 @@ public class FileSystemStyleCache implements StyleProvider
     }
     catch (IOException e)
     {
+      // This might happen if we couldn't delete the css file that was already there, so we 
+      // are unable to recreate it.
       if (_LOG.isWarning())
         _LOG.warning("IOEXCEPTION_OPENNING_FILE", file);
         _LOG.warning(e);
@@ -1434,7 +1461,7 @@ public class FileSystemStyleCache implements StyleProvider
       }
 
       File outputFile = _getOutputFile(_baseFilename, _files.size() + 1);
-      // We never want to do anything other then read it or delete it:
+      // We never want to do anything other than read it or delete it:
       outputFile.setReadOnly();
 
       _files.add(outputFile);
@@ -1500,7 +1527,6 @@ public class FileSystemStyleCache implements StyleProvider
    * names do not contain html, whereas our internal style selector
    * names may. We write out the shortened version of the mapped
    * selector names to the css file.
-   * jmw.
    * @todo Need to find a better spot for this, like the skin?
    */
   private static final Map<String, String> _STYLE_KEY_MAP;
diff --git a/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts b/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
index c0c8042..f8e7a71 100644
--- a/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
+++ b/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
@@ -1076,4 +1076,5 @@ The skin {0} specified on the requestMap will be used even though the consumer''
 <!-- INVALID_LOCALE_VARIANT_HAS_SLASH  -->
 <resource key="INVALID_LOCALE_VARIANT_HAS_SLASH">Invalid variant for Locale identifier {0} - cannot contain slashes to avoid XSS attack. Will use empty string for variant.</resource>
 
+<resource key="COULD_NOT_DELETE_FILE">Could not delete the file {0}</resource>
 </resources>

-- 
To stop receiving notification emails like this one, please contact
"commits@myfaces.apache.org" <co...@myfaces.apache.org>.