You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2010/02/28 20:10:13 UTC

svn commit: r917255 - in /roller/trunk: weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ weblogger-business/src/main/java/org/apache/roller/weblogger/util/ weblogger-business/src/main/resources/org/apache/roller/weblogger/c...

Author: snoopdave
Date: Sun Feb 28 19:10:13 2010
New Revision: 917255

URL: http://svn.apache.org/viewvc?rev=917255&view=rev
Log:
Theme reloading for development
https://issues.apache.org/jira/browse/ROL-1847

Thanks for the patch, Greg!

Modified:
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManager.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManagerImpl.java
    roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/util/I18nMessages.java
    roller/trunk/weblogger-business/src/main/resources/org/apache/roller/weblogger/config/roller.properties
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java
    roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
    roller/trunk/weblogger-web/src/test/resources/roller-custom.properties

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/SharedThemeFromDir.java Sun Feb 28 19:10:13 2010
@@ -207,7 +207,7 @@
         setName(themeMetadata.getName());
         setDescription(themeMetadata.getName());
         setAuthor(themeMetadata.getAuthor());
-        setLastModified(new Date());
+        setLastModified(null);
         setEnabled(true);
         
         // load resource representing preview image
@@ -254,6 +254,10 @@
                 // add it to templates list
                 addTemplate(theme_template);
             }
+            
+         // Set Last Modified
+			setLastModified(new Date(templateFile.lastModified()));
+			
         }
         
         // go through static resources and add them to the theme
@@ -273,6 +277,14 @@
             
             // add it to the theme
             setResource(resourcePath, new SharedThemeResourceFromDir(resourcePath, resourceFile));
+        
+            // Set Last Modified
+			Date lstModified = new Date(resourceFile.lastModified());
+			if (getLastModified() == null
+					|| lstModified.after(getLastModified())) {
+				setLastModified(lstModified);
+			}
+        
         }
         
         // go through templates and read in contents to a ThemeTemplate
@@ -308,6 +320,13 @@
 
             // add it to the theme
             addTemplate(theme_template);
+            
+            // Set Last Modified
+			Date lstModified = new Date(templateFile.lastModified());
+			if (getLastModified() == null
+					|| lstModified.after(getLastModified())) {
+				setLastModified(lstModified);
+			}
         }
     }
     

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManager.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManager.java?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManager.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManager.java Sun Feb 28 19:10:13 2010
@@ -24,60 +24,72 @@
 import org.apache.roller.weblogger.pojos.WeblogTheme;
 import org.apache.roller.weblogger.pojos.Weblog;
 
-
 /**
  * Manager interface for accessing Theme related objects.
  */
 public interface ThemeManager {
-    
-    /**
-     * Initialize the theme system.
-     *
-     * @throws InitializationException If there is a problem during initialization.
-     */
-    public void initialize() throws InitializationException;
-    
-    
-    /**
-     * Get the Theme object with the given id.
-     *
-     * @return Theme The Theme object with the given id.
-     * @throws ThemeNotFoundException If the named theme cannot be found.
-     * @throws WebloggerException If there is some kind of fatal backend error.
-     **/
-    public SharedTheme getTheme(String id)
-        throws ThemeNotFoundException, WebloggerException;
-    
-    
-    /**
-     * Get the WeblogTheme for a given weblog.
-     *
-     * @param weblog The weblog to get the theme for.
-     * @return WeblogTheme The theme to be used for the given weblog.
-     * @throws WebloggerException If there is some kind of fatal backend error.
-     */
-    public WeblogTheme getTheme(Weblog weblog)
-        throws WebloggerException;
-    
-    
-    /**
-     * Get a list of all theme names that are currently enabled.
-     * This list is ordered alphabetically by default.
-     *
-     * @return List A list of Theme objects which are enabled.
-     */
-    public List getEnabledThemesList();
-    
-    
-    /**
-     * Import all the contents for a Theme into a weblog.
-     *
-     * @param weblog The weblog to import the theme into.
-     * @param theme The theme that should be imported.
-     *
-     * @throws WebloggerException If there is some kind of error in saving.
-     */
-    public void importTheme(Weblog website, SharedTheme theme) 
-        throws WebloggerException;
-    
+
+	/**
+	 * Initialize the theme system.
+	 * 
+	 * @throws InitializationException
+	 *             If there is a problem during initialization.
+	 */
+	public void initialize() throws InitializationException;
+
+	/**
+	 * Get the Theme object with the given id.
+	 * 
+	 * @return Theme The Theme object with the given id.
+	 * @throws ThemeNotFoundException
+	 *             If the named theme cannot be found.
+	 * @throws WebloggerException
+	 *             If there is some kind of fatal backend error.
+	 **/
+	public SharedTheme getTheme(String id) throws ThemeNotFoundException,
+			WebloggerException;
+
+	/**
+	 * Get the WeblogTheme for a given weblog.
+	 * 
+	 * @param weblog
+	 *            The weblog to get the theme for.
+	 * @return WeblogTheme The theme to be used for the given weblog.
+	 * @throws WebloggerException
+	 *             If there is some kind of fatal backend error.
+	 */
+	public WeblogTheme getTheme(Weblog weblog) throws WebloggerException;
+
+	/**
+	 * Get a list of all theme names that are currently enabled. This list is
+	 * ordered alphabetically by default.
+	 * 
+	 * @return List A list of Theme objects which are enabled.
+	 */
+	public List getEnabledThemesList();
+
+	/**
+	 * Import all the contents for a Theme into a weblog.
+	 * 
+	 * @param weblog
+	 *            The weblog to import the theme into.
+	 * @param theme
+	 *            The theme that should be imported.
+	 * 
+	 * @throws WebloggerException
+	 *             If there is some kind of error in saving.
+	 */
+	public void importTheme(Weblog website, SharedTheme theme)
+			throws WebloggerException;
+
+	/**
+	 * This is a development only method which reloads theme data from themes
+	 * stored on the filesystem in the webapp /themes/ directory.
+	 * 
+	 * @param reloadTheme
+	 *            the reload theme
+	 * 
+	 * @return true, if reloaded theme from disk
+	 */
+	public boolean reLoadThemeFromDisk(String reloadTheme);
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManagerImpl.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManagerImpl.java?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManagerImpl.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/business/themes/ThemeManagerImpl.java Sun Feb 28 19:10:13 2010
@@ -360,4 +360,40 @@
         return themes;
     }
     
+	/**
+	 * @see ThemeManager#reLoadThemeFromDisk(String)
+	 */
+	public boolean reLoadThemeFromDisk(String reloadTheme) {
+
+		boolean reloaded = false;
+
+		try {
+
+			Theme theme = new SharedThemeFromDir(this.themeDir + File.separator
+					+ reloadTheme);
+
+			if (theme != null) {
+
+				Theme loadedTheme = (Theme) themes.get(theme.getId());
+
+				if (loadedTheme != null
+						&& theme.getLastModified()
+								.after(loadedTheme.getLastModified())) {
+					themes.remove(theme.getId());
+					themes.put(theme.getId(), theme);
+					reloaded = true;
+				}
+
+			}
+
+		} catch (Throwable unexpected) {
+			// shouldn't happen, so let's learn why it did
+			log.error("Problem reloading theme " + reloadTheme, unexpected);
+		}
+
+		return reloaded;
+
+	}
+
+    
 }

Modified: roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/util/I18nMessages.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/util/I18nMessages.java?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/util/I18nMessages.java (original)
+++ roller/trunk/weblogger-business/src/main/java/org/apache/roller/weblogger/util/I18nMessages.java Sun Feb 28 19:10:13 2010
@@ -18,6 +18,9 @@
 
 package org.apache.roller.weblogger.util;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.text.MessageFormat;
 import java.util.Collections;
 import java.util.HashMap;
@@ -32,7 +35,7 @@
 /**
  * A utility class for handling i18n messaging.
  */
-public final class I18nMessages {
+public class I18nMessages {
     
     private static final Log log = LogFactory.getLog(I18nMessages.class);
     
@@ -157,4 +160,74 @@
         }
     }
     
+	/**
+	 * Reload bundle.
+	 * 
+	 * @param key
+	 *            the key
+	 */
+	public static final void reloadBundle(Locale key) {
+
+		try {
+
+			Class type = ResourceBundle.class;
+			Field cacheList = type.getDeclaredField("cacheList");
+
+			synchronized (cacheList) {
+				cacheList.setAccessible(true);
+				((Map) cacheList.get(ResourceBundle.class)).clear();
+			}
+
+			clearTomcatCache();
+
+			// Remove cached bundle
+			messagesMap.remove(key);
+
+		} catch (Exception e) {
+			log.error("Error clearing message resource bundles", e);
+		}
+
+	}
+
+	/**
+	 * Clear tomcat cache.
+	 * 
+	 * @see com.opensymphony.xwork2.util.LocalizedTextUtil
+	 */
+	private static void clearTomcatCache() {
+
+		ClassLoader loader = Thread.currentThread().getContextClassLoader();
+		// no need for compilation here.
+		Class cl = loader.getClass();
+
+		try {
+			if ("org.apache.catalina.loader.WebappClassLoader".equals(cl
+					.getName())) {
+				clearMap(cl, loader, "resourceEntries");
+			} else {
+				if (log.isDebugEnabled()) {
+					log.debug("class loader " + cl.getName()
+							+ " is not tomcat loader.");
+				}
+			}
+		} catch (Exception e) {
+			log.warn("couldn't clear tomcat cache", e);
+		}
+	}
+
+	private static void clearMap(Class cl, Object obj, String name)
+			throws NoSuchFieldException, IllegalAccessException,
+			NoSuchMethodException, InvocationTargetException {
+		Field field = cl.getDeclaredField(name);
+		field.setAccessible(true);
+
+		Object cache = field.get(obj);
+
+		synchronized (cache) {
+			Class ccl = cache.getClass();
+			Method clearMethod = ccl.getMethod("clear");
+			clearMethod.invoke(cache);
+		}
+
+	}
 }

Modified: roller/trunk/weblogger-business/src/main/resources/org/apache/roller/weblogger/config/roller.properties
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-business/src/main/resources/org/apache/roller/weblogger/config/roller.properties?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-business/src/main/resources/org/apache/roller/weblogger/config/roller.properties (original)
+++ roller/trunk/weblogger-business/src/main/resources/org/apache/roller/weblogger/config/roller.properties Sun Feb 28 19:10:13 2010
@@ -127,6 +127,9 @@
 # The directory in which Roller will look for themes
 themes.dir=${webapp.context}
 
+# Allow theme reloading during development
+# NB remember also to always delete the style-sheet from the weblog you're using
+themes.reload.mode=false
 
 #-----------------------------------------------------------------------------
 # Feature specific settings

Modified: roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java (original)
+++ roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/PageServlet.java Sun Feb 28 19:10:13 2010
@@ -37,6 +37,7 @@
 import org.apache.roller.weblogger.business.HitCountQueue;
 import org.apache.roller.weblogger.business.referrers.IncomingReferrer;
 import org.apache.roller.weblogger.business.referrers.ReferrerQueueManager;
+import org.apache.roller.weblogger.business.themes.ThemeManager;
 import org.apache.roller.weblogger.config.WebloggerConfig;
 import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
 import org.apache.roller.weblogger.business.WebloggerFactory;
@@ -57,7 +58,7 @@
 import org.apache.roller.weblogger.ui.rendering.util.cache.WeblogPageCache;
 import org.apache.roller.weblogger.ui.rendering.util.ModDateHeaderUtil;
 import org.apache.roller.weblogger.util.BlacklistChecker;
-
+import org.apache.roller.weblogger.util.I18nMessages;
 
 /**
  * Provides access to weblog pages.
@@ -72,6 +73,9 @@
     private boolean excludeOwnerPages = false;
     private WeblogPageCache weblogPageCache = null;
     private SiteWideCache siteWideCache = null;
+    
+    // Development theme reloading
+	Boolean themeReload = false;
 
     /**
      * Init method for this servlet
@@ -106,6 +110,9 @@
                 log.error("Error parsing referrer.robotCheck.userAgentPattern value '" + robotPatternStr + "'.  Robots will not be filtered. ", e);
             }
         }
+        
+        // Development theme reloading
+		themeReload = WebloggerConfig.getBooleanProperty("themes.reload.mode");
     }
 
     /**
@@ -181,6 +188,25 @@
         } else {
             cacheKey = weblogPageCache.generateKey(pageRequest);
         }
+        
+        // Development only. Reload if theme has been modified
+		if (themeReload) {
+			try {
+				ThemeManager manager = WebloggerFactory.getWeblogger().getThemeManager();
+				boolean reloaded = manager.reLoadThemeFromDisk(weblog.getEditorTheme());
+				if (reloaded) {
+					if (isSiteWide) {
+						siteWideCache.clear();
+					} else {
+						weblogPageCache.clear();
+					}
+					I18nMessages.reloadBundle(weblog.getLocaleInstance()); 
+				}
+
+			} catch (Exception ex) {
+				log.error("ERROR - reloading theme " + ex);
+			}
+		}
 
         // cached content checking
         if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) && request.getAttribute("skipCache") == null) {

Modified: roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java (original)
+++ roller/trunk/weblogger-web/src/main/java/org/apache/roller/weblogger/ui/rendering/servlets/SearchServlet.java Sun Feb 28 19:10:13 2010
@@ -34,6 +34,7 @@
 import org.apache.roller.weblogger.config.WebloggerConfig;
 import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
 import org.apache.roller.weblogger.business.WebloggerFactory;
+import org.apache.roller.weblogger.business.themes.ThemeManager;
 import org.apache.roller.weblogger.pojos.ThemeTemplate;
 import org.apache.roller.weblogger.pojos.Weblog;
 import org.apache.roller.weblogger.ui.rendering.Renderer;
@@ -43,16 +44,20 @@
 import org.apache.roller.weblogger.ui.rendering.model.SearchResultsModel;
 import org.apache.roller.weblogger.ui.rendering.util.WeblogPageRequest;
 import org.apache.roller.weblogger.ui.rendering.util.WeblogSearchRequest;
+import org.apache.roller.weblogger.ui.rendering.util.cache.SiteWideCache;
+import org.apache.roller.weblogger.ui.rendering.util.cache.WeblogPageCache;
+import org.apache.roller.weblogger.util.I18nMessages;
 import org.apache.roller.weblogger.util.cache.CachedContent;
 
 
 /**
  * Handles search queries for weblogs.
  */
-public class SearchServlet extends HttpServlet {
-    
+public class SearchServlet extends HttpServlet {    
     private static Log log = LogFactory.getLog(SearchServlet.class);
     
+    // Development theme reloading
+	Boolean themeReload = false;
     
     /**
      * Init method for this servlet
@@ -174,7 +179,25 @@
             return;
         }
 
-        
+        // Development only. Reload if theme has been modified
+		if (themeReload) {
+			try {
+				ThemeManager manager = WebloggerFactory.getWeblogger().getThemeManager();
+				boolean reloaded = manager.reLoadThemeFromDisk(weblog.getEditorTheme());
+				if (reloaded) {
+					if (WebloggerRuntimeConfig.isSiteWideWeblog(searchRequest.getWeblogHandle())) {
+						SiteWideCache.getInstance().clear();
+					} else {
+						WeblogPageCache.getInstance().clear();
+					}
+					I18nMessages.reloadBundle(weblog.getLocaleInstance()); 
+				}
+
+			} catch (Exception ex) {
+				log.error("ERROR - reloading theme " + ex);
+			}
+		}
+		
         // lookup Renderer we are going to use
         Renderer renderer = null;
         try {

Modified: roller/trunk/weblogger-web/src/test/resources/roller-custom.properties
URL: http://svn.apache.org/viewvc/roller/trunk/weblogger-web/src/test/resources/roller-custom.properties?rev=917255&r1=917254&r2=917255&view=diff
==============================================================================
--- roller/trunk/weblogger-web/src/test/resources/roller-custom.properties (original)
+++ roller/trunk/weblogger-web/src/test/resources/roller-custom.properties Sun Feb 28 19:10:13 2010
@@ -36,5 +36,14 @@
 tasks.TestTask.interval=1800
 tasks.TestTask.leaseTime=300
 
+# turn on theme reloading
+themes.reload.mode=true
+
+# turn off caching for testing/debugging
+cache.sitewide.enabled=false
+cache.weblogpage.enabled=false
+cache.weblogfeed.enabled=false
+cache.planet.enabled=false
+
 # logging - you can set Log4J properties here
 #log4j.logger.org.apache.roller.weblogger.business=DEBUG