r1089 - in xwiki/trunk: . lib src/main/java/com/xpn/xwiki/cache/impl src/main/java/com/xpn/xwiki/plugin/image src/main/java/com/xpn/xwiki/render src/main/java/com/xpn/xwiki/render/groovy

Ludovic Dubost ludovic at users.forge.objectweb.org
Mon Jul 24 14:12:56 CEST 2006


Author: ludovic
Date: 2006-07-24 14:12:56 +0200 (Mon, 24 Jul 2006)
New Revision: 1089

Added:
   xwiki/trunk/lib/groovy-all-1.0-jsr-06.jar
   xwiki/trunk/lib/oscache-2.3.2.jar
   xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCachedObject.java
Removed:
   xwiki/trunk/lib/groovy-all-1.0-jsr-05.jar
   xwiki/trunk/lib/oscache-2.2.jar
Modified:
   xwiki/trunk/build.xml
   xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheCache.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheService.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/render/XWikiRenderingEngine.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/GroovyTemplateEngine.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/XWikiGroovyRenderer.java
Log:
Fixed memory leaks in Groovy scripting. 
Memory consumption should be reduced while running groovy scripts
But still flushCache is needed to completely flush the groovy execution cache.
A hack was needed to cleanup the Groovy MetaClassRegistry on flushCache

Modified: xwiki/trunk/build.xml
===================================================================
--- xwiki/trunk/build.xml	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/build.xml	2006-07-24 12:12:56 UTC (rev 1089)
@@ -85,7 +85,7 @@
       includes="hibernate-3.0.3.jar" />
 
     <fileset id="libs.main.fileset" dir="${lib.dir}"
-      includes="c3p0-0.8.4.5.jar,cglib-2.1.jar,dom4j-1.6.jar,ehcache-1.1.jar,hibernate-tools-2.1.3.jar,mysql-connector-java-3.1.7-bin.jar,hsqldb-1.7.3.jar,odmg-3.0.jar,oscache-2.2.jar,concurrent.jar,jgroups-2.2.9.1.jar,swarmcache.jar,xalan-2.6.0.jar,xerces-2.4.0.jar,xml-apis-2.0.2.jar,jta.jar,antlr-2.7.5.jar,asm-1.5.3.jar,asm-util-1.5.3.jar,
+      includes="c3p0-0.8.4.5.jar,cglib-2.1.jar,dom4j-1.6.jar,ehcache-1.1.jar,hibernate-tools-2.1.3.jar,mysql-connector-java-3.1.7-bin.jar,hsqldb-1.7.3.jar,odmg-3.0.jar,oscache-2.3.2.jar,concurrent.jar,jgroups-2.2.9.1.jar,swarmcache.jar,xalan-2.6.0.jar,xerces-2.4.0.jar,xml-apis-2.0.2.jar,jta.jar,antlr-2.7.5.jar,asm-1.5.3.jar,asm-util-1.5.3.jar,
      	commons-beanutils-1.7.0.jar,commons-codec-1.3.jar,commons-collections-3.1.jar,commons-dbcp-1.2.1.jar,commons-digester-1.6.jar,commons-fileupload-1.0.jar,commons-lang-2.1.jar,commons-logging-1.0.4.jar,commons-pool-1.1.jar,commons-net-1.1.0.jar,commons-httpclient-2.0.2.jar,ecs-1.4.2.jar,oro-2.0.8.jar,log4j-1.2.8.jar,
      	org.apache.commons.jrcs.rcs.jar,
      	struts-1.2.4.jar,
@@ -94,7 +94,7 @@
      	radeox.jar,
      	portlet.jar,
      	xmlrpc-1.2.jar,
-     	groovy-all-1.0-jsr-05.jar,
+     	groovy-all-1.0-jsr-06.jar,
      	xalan-2.6.0.jar,xerces.jar-2.4.0,xml-apis-2.0.2,jimi.jar,avalon-framework-4.1.5.jar,fop-0.20.5.jar,jtidy.jar,
     	batik-all-1.6.jar,
     	ldap.jar,

Deleted: xwiki/trunk/lib/groovy-all-1.0-jsr-05.jar
===================================================================
(Binary files differ)

Added: xwiki/trunk/lib/groovy-all-1.0-jsr-06.jar
===================================================================
(Binary files differ)


Property changes on: xwiki/trunk/lib/groovy-all-1.0-jsr-06.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: xwiki/trunk/lib/oscache-2.2.jar
===================================================================
(Binary files differ)

Added: xwiki/trunk/lib/oscache-2.3.2.jar
===================================================================
(Binary files differ)


Property changes on: xwiki/trunk/lib/oscache-2.3.2.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheCache.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheCache.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheCache.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -1,7 +1,9 @@
 package com.xpn.xwiki.cache.impl;
 
-import java.util.Date;
 import java.util.Properties;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Iterator;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -9,9 +11,11 @@
 import com.opensymphony.oscache.base.Cache;
 import com.opensymphony.oscache.base.EntryRefreshPolicy;
 import com.opensymphony.oscache.base.NeedsRefreshException;
+import com.opensymphony.oscache.base.CacheEntry;
 import com.opensymphony.oscache.general.GeneralCacheAdministrator;
 import com.xpn.xwiki.cache.api.XWikiCache;
 import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
+import com.xpn.xwiki.XWiki;
 
 /**
  * Copyright 2006, XpertNet SARL, and individual contributors as indicated by
@@ -44,50 +48,50 @@
 {
     private static final Log          log = LogFactory.getLog(OSCacheCache.class);
 
-    private GeneralCacheAdministrator cache;
+    private GeneralCacheAdministrator cacheAdmin;
     private String                    name;
     private int                       capacity;
 
     public OSCacheCache(Properties props)
     {
-        cache = new GeneralCacheAdministrator(props);
+        cacheAdmin = new GeneralCacheAdministrator(props);
     }
 
     public OSCacheCache(Properties props, int capacity)
     {
         this(props);
-        cache.setCacheCapacity(capacity);
+        cacheAdmin.setCacheCapacity(capacity);
         this.capacity = capacity;
     }
 
     /**
      * Provide package-private access to the underlying m_cache
      */
-    Cache getCache()
+    Cache getCacheAdmin()
     {
-        return cache.getCache();
+        return cacheAdmin.getCache();
     }
 
     public void setCapacity(int capacity)
     {
-        cache.setCacheCapacity(capacity);
+        cacheAdmin.setCacheCapacity(capacity);
         this.capacity = capacity;
     }
 
     public void flushEntry(String key)
     {
-        cache.flushEntry(key);
+        cacheAdmin.flushEntry(key);
     }
 
     public void putInCache(String key, Object obj)
     {
-        cache.putInCache(key, obj);
+        cacheAdmin.putInCache(key, obj);
         logCacheAdd(key, obj);
     }
 
     public void putInCache(String key, Object obj, EntryRefreshPolicy expiry)
     {
-        cache.putInCache(key, obj, expiry);
+        cacheAdmin.putInCache(key, obj, expiry);
         logCacheAdd(key, obj);
     }
 
@@ -95,7 +99,7 @@
     {
         try
         {
-            return cache.getFromCache(key);
+            return cacheAdmin.getFromCache(key);
         }
         catch (NeedsRefreshException e)
         {
@@ -107,7 +111,7 @@
     {
         try
         {
-            return cache.getFromCache(key, refeshPeriod);
+            return cacheAdmin.getFromCache(key, refeshPeriod);
         }
         catch (NeedsRefreshException e)
         {
@@ -117,12 +121,28 @@
 
     public void cancelUpdate(String key)
     {
-        cache.cancelUpdate(key);
+        cacheAdmin.cancelUpdate(key);
     }
 
     public void flushAll()
     {
-        cache.flushAll(new Date());
+        cacheAdmin.flushAll();
+        Cache cache = cacheAdmin.getCache();
+
+        // Make sure we clean-up and finalize cached objects
+        Map map = (Map) XWiki.getPrivateField(cache, "cacheMap");
+        Iterator it = map.values().iterator();
+        while (it.hasNext()) {
+            try {
+                CacheEntry centry = (CacheEntry)it.next();
+                Object obj = centry.getContent();
+                if (obj instanceof XWikiCachedObject) {
+                    ((XWikiCachedObject)obj).finalize();
+                }
+            } catch (Throwable throwable) {
+            }
+        }
+        XWiki.callPrivateMethod(cache, "clear");
     }
 
     /**
@@ -131,7 +151,7 @@
      */
     public int getNumberEntries()
     {
-        return cache.getCache().getNbEntries();
+        return cacheAdmin.getCache().getNbEntries();
     }
 
     public void setName(String name)

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheService.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheService.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/OSCacheService.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -15,7 +15,6 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import com.opensymphony.oscache.base.AbstractCacheAdministrator;
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.cache.api.XWikiCache;
 import com.xpn.xwiki.cache.api.XWikiCacheService;

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCacheListener.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -1,7 +1,5 @@
 package com.xpn.xwiki.cache.impl;
 
-import javax.servlet.http.HttpServletRequestWrapper;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -13,7 +11,6 @@
 import com.xpn.xwiki.XWiki;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.doc.XWikiDocument;
-import com.xpn.xwiki.web.XWikiServletRequest;
 
 /*
  * Copyright 2006, XpertNet SARL, and individual contributors as indicated

Added: xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCachedObject.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCachedObject.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/cache/impl/XWikiCachedObject.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -0,0 +1,12 @@
+package com.xpn.xwiki.cache.impl;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ldubost
+ * Date: 24 juil. 2006
+ * Time: 03:09:34
+ * To change this template use File | Settings | File Templates.
+ */
+public interface XWikiCachedObject {
+    public void finalize() throws Throwable;
+}

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -36,9 +36,6 @@
 
 import javax.imageio.ImageIO;
 
-import com.opensymphony.oscache.base.Cache;
-import com.opensymphony.oscache.base.Config;
-import com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.cache.api.XWikiCache;

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/render/XWikiRenderingEngine.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/render/XWikiRenderingEngine.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/render/XWikiRenderingEngine.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -1,251 +1,264 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author ludovic
- * @author sdumitriu
- */
-
-package com.xpn.xwiki.render;
-
-import java.util.*;
-
-import com.xpn.xwiki.XWiki;
-import com.xpn.xwiki.XWikiContext;
-import com.xpn.xwiki.XWikiException;
-import com.xpn.xwiki.web.XWikiRequest;
-import com.xpn.xwiki.cache.api.XWikiCache;
-import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
-import com.xpn.xwiki.doc.XWikiDocument;
-import com.xpn.xwiki.monitor.api.MonitorPlugin;
-import com.xpn.xwiki.render.groovy.XWikiGroovyRenderer;
-import com.xpn.xwiki.util.Util;
-
-public class XWikiRenderingEngine {
-
-    private List renderers = new ArrayList();
-    private HashMap renderermap = new LinkedHashMap();
-    private XWikiCache cache = null;
-
-    public XWikiRenderingEngine(XWiki xwiki, XWikiContext context) throws XWikiException {
-        if (xwiki.Param("xwiki.render.macromapping", "0").equals("1"))
-            addRenderer("mapping", new XWikiMacrosMappingRenderer(xwiki, context));
-        // addRenderer(new XWikiJSPRenderer());
-        if (xwiki.Param("xwiki.render.velocity", "1").equals("1"))
-            addRenderer("velocity", new XWikiVelocityRenderer());
-        if (xwiki.Param("xwiki.render.groovy", "1").equals("1"))
-            addRenderer("groovy", new XWikiGroovyRenderer());
-        if (xwiki.Param("xwiki.render.plugin", "1").equals("1"))
-            addRenderer("plugin", new XWikiPluginRenderer());
-
-        // The first should not removePre
-        // The last one should removePre
-        if (xwiki.Param("xwiki.render.wiki", "1").equals("1"))
-            addRenderer("wiki", new XWikiRadeoxRenderer(false));
-
-        // if (xwiki.Param("xwiki.render.wiki2", "1").equals("1"))
-        // addRenderer("wiki2", new XWikiWikiParser2Renderer(false));
-
-        if (xwiki.Param("xwiki.render.wikiwiki", "0").equals("1")) {
-            addRenderer("xwiki", new XWikiWikiBaseRenderer(true, true));
-        } else {
-            addRenderer("xwiki", new XWikiWikiBaseRenderer(false, true));
-        }
-
-        try {
-        	String capacity = xwiki.Param("xwiki.render.cache.capacity");
-			if (capacity != null) {
-				cache = xwiki.getCacheService().newCache(Integer.parseInt(capacity));
-			} else {
-				cache = xwiki.getCacheService().newCache();
-			}
-        } catch (Exception e) {
-			e.printStackTrace();        
-        }
-    }
-
-    public void addRenderer(String name, XWikiRenderer renderer) {
-        renderers.add(renderer);
-        renderermap.put(name, renderer);
-    }
-    
-    public XWikiRenderer getRenderer(String name) {
-		return (XWikiRenderer) renderermap.get(name);
-	}
-
-	public List getRendererList() {
-		return (List) ((ArrayList) renderers).clone();
-	}
-
-	public List getRendererNames() {
-		return new LinkedList(renderermap.keySet());
-	}
-	
-	protected XWikiRenderer removeRenderer(String name) {
-		XWikiRenderer result = (XWikiRenderer) renderermap.remove(name);
-		if (result != null) {
-			renderers.remove(result);
-		}
-		return result;
-	}
-	
-    public String renderDocument(XWikiDocument doc, XWikiContext context) throws XWikiException {
-           return renderText(doc.getTranslatedContent(context), doc, context);
-    }
-
-    public String renderDocument(XWikiDocument doc, XWikiDocument includingdoc, XWikiContext context) throws XWikiException {
-        return renderText(doc.getTranslatedContent(context), includingdoc, context);
-    }
-
-    public String renderText(String text, XWikiDocument includingdoc, XWikiContext context) {
-        return renderText(text, includingdoc, includingdoc, context);
-    }
-
-    public void addToCached(String key, XWikiContext context) {
-        List cached = (ArrayList) context.get("render_cached");
-        if (cached==null) {
-            cached = new ArrayList();
-            context.put("render_cached", cached);
-        }
-        cached.add(key);
-    }
-
-    public void addToRefreshed(String key, XWikiContext context) {
-        List cached = (ArrayList) context.get("render_refreshed");
-        if (cached==null) {
-            cached = new ArrayList();
-            context.put("render_refreshed", cached);
-        }
-        cached.add(key);
-    }
-
-    public String renderText(String text, XWikiDocument contentdoc, XWikiDocument includingdoc, XWikiContext context) {
-        String key = getKey(text, contentdoc, includingdoc, context);
-        synchronized (key) {
-            try {
-                XWikiRenderingCache cacheObject = null;
-                try {
-                    cacheObject = (XWikiRenderingCache) cache.getFromCache(key);
-                } catch (XWikiCacheNeedsRefreshException e2) {
-                    cache.cancelUpdate(key);
-                }
-                if (cacheObject!=null) {
-                    XWikiRequest request = context.getRequest();
-                    boolean refresh = (request!=null) && ("1".equals(request.get("refresh")));
-                    if ((cacheObject.isValid()&&(!refresh))) {
-                        addToCached(key, context);
-                        return cacheObject.getContent();
-                    } else {
-                        addToRefreshed(key, context);
-                    }
-                }
-            } catch (Exception e) {
-            }
-
-            MonitorPlugin monitor  = Util.getMonitorPlugin(context);
-            try {
-                // Start monitoring timer
-                if (monitor!=null)
-                    monitor.startTimer("rendering");
-
-                XWikiDocument doc = context.getDoc();
-                XWikiDocument cdoc = context.getDoc();
-
-                // Let's call the beginRendering loop
-                context.getWiki().getPluginManager().beginRendering(context);
-
-                String content = text;
-
-                // Which is the current idoc and sdoc
-                XWikiDocument idoc = (XWikiDocument) context.get("idoc");
-                XWikiDocument sdoc = (XWikiDocument) context.get("sdoc");
-                // We put the including and security doc in the context
-                // It will be needed to verify programming rights
-                context.put("idoc", includingdoc);
-                context.put("sdoc", contentdoc);
-
-                try {
-
-                    for (int i=0;i<renderers.size();i++)
-                        content = ((XWikiRenderer)renderers.get(i)).render(content, contentdoc, includingdoc, context);
-                } finally {
-                    // Remove including doc or set the previous one
-                    if (idoc==null)
-                        context.remove("idoc");
-                    else
-                        context.put("idoc", idoc);
-
-                    // Remove security doc or set the previous one
-                    if (sdoc==null)
-                        context.remove("sdoc");
-                    else
-                        context.put("sdoc", sdoc);
-
-                    // Let's call the endRendering loop
-                    context.getWiki().getPluginManager().endRendering(context);
-                }
-
-                try {
-                    int cacheDuration = context.getCacheDuration();
-                    if (cacheDuration>0) {
-                        XWikiRenderingCache cacheObject = new XWikiRenderingCache(key, content, cacheDuration, new Date());
-                        cache.putInCache(key, (Object)cacheObject);
-                    }
-                } catch (Exception e) {}
-                return content;
-            }
-            finally {
-                if (monitor!=null)
-                    monitor.endTimer("rendering");
-            }
-        }
-    }
-
-    private String getKey(String text, XWikiDocument contentdoc, XWikiDocument includingdoc, XWikiContext context) {
-        return ((context==null) ? "xwiki" : context.getDatabase()) + "-"
-                + ((contentdoc==null) ? "" : contentdoc.getDatabase() + ":" + contentdoc.getFullName()) + "-"
-                + ((includingdoc==null) ? "" : includingdoc.getDatabase() + ":" + includingdoc.getFullName()) + "-"
-                + ((context.getRequest()==null) ? "" : context.getRequest().getQueryString())
-                + "-" + text.hashCode();
-    }
-
-    public void flushCache() {
-        for (int i=0;i<renderers.size();i++)
-           ((XWikiRenderer)renderers.get(i)).flushCache();
-        cache.flushAll();
-    }
-
-    public String convertMultiLine(String macroname, String params, String data, String allcontent, XWikiVirtualMacro macro, XWikiContext context) {
-        String language = macro.getLanguage();
-        XWikiRenderer renderer = (XWikiRenderer) renderermap.get(language);
-        if (renderer==null)
-            return allcontent;
-        else
-            return renderer.convertMultiLine(macroname, params, data, allcontent, macro, context);
-    }
-
-    public String convertSingleLine(String macroname, String params, String allcontent, XWikiVirtualMacro macro, XWikiContext context) {
-        String language = macro.getLanguage();
-        XWikiRenderer renderer = (XWikiRenderer) renderermap.get(language);
-        if (renderer==null)
-            return allcontent;
-        else
-            return renderer.convertSingleLine(macroname, params, allcontent, macro, context);
-    }
-
-}
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author ludovic
+ * @author sdumitriu
+ */
+
+package com.xpn.xwiki.render;
+
+import java.util.*;
+
+import com.xpn.xwiki.XWiki;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.web.XWikiRequest;
+import com.xpn.xwiki.cache.api.XWikiCache;
+import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
+import com.xpn.xwiki.cache.api.XWikiCacheService;
+import com.xpn.xwiki.doc.XWikiDocument;
+import com.xpn.xwiki.monitor.api.MonitorPlugin;
+import com.xpn.xwiki.render.groovy.XWikiGroovyRenderer;
+import com.xpn.xwiki.util.Util;
+
+public class XWikiRenderingEngine {
+
+    private List renderers = new ArrayList();
+    private HashMap renderermap = new LinkedHashMap();
+    private XWikiCache cache;
+
+    public XWikiRenderingEngine(XWiki xwiki, XWikiContext context) throws XWikiException {
+
+        if (xwiki.Param("xwiki.render.macromapping", "0").equals("1"))
+            addRenderer("mapping", new XWikiMacrosMappingRenderer(xwiki, context));
+        // addRenderer(new XWikiJSPRenderer());
+        if (xwiki.Param("xwiki.render.velocity", "1").equals("1"))
+            addRenderer("velocity", new XWikiVelocityRenderer());
+        if (xwiki.Param("xwiki.render.groovy", "1").equals("1")) {
+            addRenderer("groovy", new XWikiGroovyRenderer());
+        }
+        if (xwiki.Param("xwiki.render.plugin", "1").equals("1"))
+            addRenderer("plugin", new XWikiPluginRenderer());
+
+        // The first should not removePre
+        // The last one should removePre
+        if (xwiki.Param("xwiki.render.wiki", "1").equals("1"))
+            addRenderer("wiki", new XWikiRadeoxRenderer(false));
+
+        // if (xwiki.Param("xwiki.render.wiki2", "1").equals("1"))
+        // addRenderer("wiki2", new XWikiWikiParser2Renderer(false));
+
+        if (xwiki.Param("xwiki.render.wikiwiki", "0").equals("1")) {
+            addRenderer("xwiki", new XWikiWikiBaseRenderer(true, true));
+        } else {
+            addRenderer("xwiki", new XWikiWikiBaseRenderer(false, true));
+        }
+
+        initCache(context);
+    }
+
+    public void initCache(XWikiContext context) {
+        int iCapacity = 100;
+        try {
+        String capacity = context.getWiki().Param("xwiki.render.cache.capacity");
+        if (capacity != null)
+            iCapacity = Integer.parseInt(capacity);
+        } catch (Exception e) {}
+        initCache(iCapacity, context);
+    }
+
+    public void initCache(int iCapacity, XWikiContext context) {
+        XWikiCacheService cacheService = context.getWiki().getCacheService();
+        cache = cacheService.newCache(iCapacity);
+    }
+
+    public XWikiCache getCache() {
+        return cache;
+    }
+
+    public void addRenderer(String name, XWikiRenderer renderer) {
+        renderers.add(renderer);
+        renderermap.put(name, renderer);
+    }
+
+    public XWikiRenderer getRenderer(String name) {
+		return (XWikiRenderer) renderermap.get(name);
+	}
+
+	public List getRendererList() {
+		return (List) ((ArrayList) renderers).clone();
+	}
+
+	public List getRendererNames() {
+		return new LinkedList(renderermap.keySet());
+	}
+
+	protected XWikiRenderer removeRenderer(String name) {
+		XWikiRenderer result = (XWikiRenderer) renderermap.remove(name);
+		if (result != null) {
+			renderers.remove(result);
+		}
+		return result;
+	}
+
+    public String renderDocument(XWikiDocument doc, XWikiContext context) throws XWikiException {
+           return renderText(doc.getTranslatedContent(context), doc, context);
+    }
+
+    public String renderDocument(XWikiDocument doc, XWikiDocument includingdoc, XWikiContext context) throws XWikiException {
+        return renderText(doc.getTranslatedContent(context), includingdoc, context);
+    }
+
+    public String renderText(String text, XWikiDocument includingdoc, XWikiContext context) {
+        return renderText(text, includingdoc, includingdoc, context);
+    }
+
+    public void addToCached(String key, XWikiContext context) {
+        List cached = (ArrayList) context.get("render_cached");
+        if (cached==null) {
+            cached = new ArrayList();
+            context.put("render_cached", cached);
+        }
+        cached.add(key);
+    }
+
+    public void addToRefreshed(String key, XWikiContext context) {
+        List cached = (ArrayList) context.get("render_refreshed");
+        if (cached==null) {
+            cached = new ArrayList();
+            context.put("render_refreshed", cached);
+        }
+        cached.add(key);
+    }
+
+    public String renderText(String text, XWikiDocument contentdoc, XWikiDocument includingdoc, XWikiContext context) {
+        String key = getKey(text, contentdoc, includingdoc, context);
+        synchronized (key) {
+            try {
+                XWikiRenderingCache cacheObject = null;
+                try {
+                    cacheObject = (XWikiRenderingCache) cache.getFromCache(key);
+                } catch (XWikiCacheNeedsRefreshException e2) {
+                    cache.cancelUpdate(key);
+                }
+                if (cacheObject!=null) {
+                    XWikiRequest request = context.getRequest();
+                    boolean refresh = (request!=null) && ("1".equals(request.get("refresh")));
+                    if ((cacheObject.isValid()&&(!refresh))) {
+                        addToCached(key, context);
+                        return cacheObject.getContent();
+                    } else {
+                        addToRefreshed(key, context);
+                    }
+                }
+            } catch (Exception e) {
+            }
+
+            MonitorPlugin monitor  = Util.getMonitorPlugin(context);
+            try {
+                // Start monitoring timer
+                if (monitor!=null)
+                    monitor.startTimer("rendering");
+
+                XWikiDocument doc = context.getDoc();
+                XWikiDocument cdoc = context.getDoc();
+
+                // Let's call the beginRendering loop
+                context.getWiki().getPluginManager().beginRendering(context);
+
+                String content = text;
+
+                // Which is the current idoc and sdoc
+                XWikiDocument idoc = (XWikiDocument) context.get("idoc");
+                XWikiDocument sdoc = (XWikiDocument) context.get("sdoc");
+                // We put the including and security doc in the context
+                // It will be needed to verify programming rights
+                context.put("idoc", includingdoc);
+                context.put("sdoc", contentdoc);
+
+                try {
+
+                    for (int i=0;i<renderers.size();i++)
+                        content = ((XWikiRenderer)renderers.get(i)).render(content, contentdoc, includingdoc, context);
+                } finally {
+                    // Remove including doc or set the previous one
+                    if (idoc==null)
+                        context.remove("idoc");
+                    else
+                        context.put("idoc", idoc);
+
+                    // Remove security doc or set the previous one
+                    if (sdoc==null)
+                        context.remove("sdoc");
+                    else
+                        context.put("sdoc", sdoc);
+
+                    // Let's call the endRendering loop
+                    context.getWiki().getPluginManager().endRendering(context);
+                }
+
+                try {
+                    int cacheDuration = context.getCacheDuration();
+                    if (cacheDuration>0) {
+                        XWikiRenderingCache cacheObject = new XWikiRenderingCache(key, content, cacheDuration, new Date());
+                        cache.putInCache(key, (Object)cacheObject);
+                    }
+                } catch (Exception e) {}
+                return content;
+            }
+            finally {
+                if (monitor!=null)
+                    monitor.endTimer("rendering");
+            }
+        }
+    }
+
+    private String getKey(String text, XWikiDocument contentdoc, XWikiDocument includingdoc, XWikiContext context) {
+        return ((context==null) ? "xwiki" : context.getDatabase()) + "-"
+                + ((contentdoc==null) ? "" : contentdoc.getDatabase() + ":" + contentdoc.getFullName()) + "-"
+                + ((includingdoc==null) ? "" : includingdoc.getDatabase() + ":" + includingdoc.getFullName()) + "-"
+                + ((context.getRequest()==null) ? "" : context.getRequest().getQueryString())
+                + "-" + text.hashCode();
+    }
+
+    public void flushCache() {
+        for (int i=0;i<renderers.size();i++)
+           ((XWikiRenderer)renderers.get(i)).flushCache();
+        cache.flushAll();
+    }
+
+    public String convertMultiLine(String macroname, String params, String data, String allcontent, XWikiVirtualMacro macro, XWikiContext context) {
+        String language = macro.getLanguage();
+        XWikiRenderer renderer = (XWikiRenderer) renderermap.get(language);
+        if (renderer==null)
+            return allcontent;
+        else
+            return renderer.convertMultiLine(macroname, params, data, allcontent, macro, context);
+    }
+
+    public String convertSingleLine(String macroname, String params, String allcontent, XWikiVirtualMacro macro, XWikiContext context) {
+        String language = macro.getLanguage();
+        XWikiRenderer renderer = (XWikiRenderer) renderermap.get(language);
+        if (renderer==null)
+            return allcontent;
+        else
+            return renderer.convertSingleLine(macroname, params, allcontent, macro, context);
+    }
+
+}

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/GroovyTemplateEngine.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/GroovyTemplateEngine.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/GroovyTemplateEngine.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -65,15 +65,38 @@
 */
    public class GroovyTemplateEngine extends TemplateEngine {
 
+       private class GTEClassLoader extends ClassLoader {
+           private HashMap classMap = new HashMap();
+
+           public GTEClassLoader(ClassLoader parent) {
+               super(parent);
+           }
+           protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+               Object cached = classMap.get(name);
+               if (cached!=null) return (Class) cached;
+               ClassLoader parent = getParent();
+               if (parent!=null) return parent.loadClass(name);
+               return super.loadClass(name,resolve);
+           }
+       }
+
+
    /* (non-Javadoc)
     * @see groovy.util.TemplateEngine#createTemplate(java.io.Reader)
     */
    public Template createTemplate(Reader reader) throws CompilationFailedException, ClassNotFoundException, IOException {
+       ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
+
+       try {
+           Thread.currentThread().setContextClassLoader(new GTEClassLoader(oldClassLoader));
            com.xpn.xwiki.render.groovy.GroovyTemplateEngine.SimpleTemplate template = new com.xpn.xwiki.render.groovy.GroovyTemplateEngine.SimpleTemplate();
            GroovyShell shell = new GroovyShell();
            String script = template.parse(reader);
            template.script = shell.parse(script);
            return template;
+       } finally {
+           Thread.currentThread().setContextClassLoader(oldClassLoader);
+       }
    }
 
    private static class SimpleTemplate implements Template {
@@ -82,13 +105,6 @@
        private Binding binding;
        private Map map;
 
-
-       public void finalize()
-       {
-           if (script!=null)
-               InvokerHelper.removeClass(script.getClass());
-       }
-
        /**
         * Set the binding for the template.  Keys will be converted to Strings.
         *

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/XWikiGroovyRenderer.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/XWikiGroovyRenderer.java	2006-07-20 15:51:45 UTC (rev 1088)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/XWikiGroovyRenderer.java	2006-07-24 12:12:56 UTC (rev 1089)
@@ -46,6 +46,7 @@
 import com.xpn.xwiki.api.XWiki;
 import com.xpn.xwiki.cache.api.XWikiCache;
 import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
+import com.xpn.xwiki.cache.impl.XWikiCachedObject;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.render.XWikiRenderer;
 import com.xpn.xwiki.render.XWikiVirtualMacro;
@@ -56,15 +57,37 @@
     private XWikiCache cache;
     private XWikiCache classCache;
 
+
+    private class XWikiRenderingEngineClassLoader extends ClassLoader {
+        private Map classMap = new HashMap();
+
+        public XWikiRenderingEngineClassLoader(ClassLoader parent) {
+            super(parent);
+        }
+        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            Object cached = classMap.get(name);
+            if (cached!=null) return (Class) cached;
+            ClassLoader parent = getParent();
+            if (parent!=null) return parent.loadClass(name);
+            return super.loadClass(name,resolve);
+        }
+    }
+
     public XWikiGroovyRenderer() {
     }
 
 
     public void flushCache() {
-        if (cache!=null)
+        if (cache!=null) {
             cache.flushAll();
+        }
         if (classCache!=null)
             classCache.flushAll();
+
+        GroovyTemplateEngine.flushCache();
+
+        cache = null;
+        classCache = null;
     }
 
     public Map prepareContext(XWikiContext context) {
@@ -92,16 +115,16 @@
     }
 
     public void initCache(XWikiContext context) {
-            cache = context.getWiki().getCacheService().newCache(100);
-            classCache = context.getWiki().getCacheService().newCache(100);
+            cache = context.getWiki().getCacheService().newLocalCache(100);
+            classCache = context.getWiki().getCacheService().newLocalCache(100);
     }
 
     protected void prepareCache(XWikiContext context) {
         if (cache==null) {
-            cache = context.getWiki().getCacheService().newCache(100);
+            cache = context.getWiki().getCacheService().newLocalCache(100);
         }
         if (classCache==null) {
-            classCache = context.getWiki().getCacheService().newCache(100);
+            classCache = context.getWiki().getCacheService().newLocalCache(100);
         }
     }
 
@@ -278,7 +301,7 @@
         }
     }
 
-    private class CachedGroovyClass {
+    public class CachedGroovyClass implements XWikiCachedObject {
         protected Class cl;
 
         public CachedGroovyClass(Class cl) {
@@ -289,9 +312,16 @@
             return cl;
         }
 
-        public void finalize() {
-            if (cl!=null)
-                InvokerHelper.removeClass(cl);
+        public void finalize() throws Throwable  {
+            try {
+                System.out.println("Finalizing: " + cl.toString());
+                if (cl!=null) {
+                    InvokerHelper.removeClass(cl);
+                    GroovyTemplateEngine.removeClass(cl);
+                }
+            } finally {
+                super.finalize();
+            }
         }
-    }    
+    }
 }





More information about the Xwiki-notifications mailing list