r1029 - in xwiki/trunk/src/main/java/com/xpn/xwiki: . api render/groovy

Ludovic Dubost ludovic at users.forge.objectweb.org
Fri Apr 7 01:31:51 CEST 2006


Author: ludovic
Date: 2006-04-07 01:31:50 +0200 (Fri, 07 Apr 2006)
New Revision: 1029

Modified:
   xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/XWikiException.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/api/XWiki.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/XWikiGroovyRenderer.java
Log:
Added very powerful Groovy apis allowing to compile a groovy class with functions and instanciate it.
It can be called securely (writers of groovy apis need to have programming rights) from groovy or velocity

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java	2006-04-06 19:32:09 UTC (rev 1028)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java	2006-04-06 23:31:50 UTC (rev 1029)
@@ -34,6 +34,7 @@
 import com.xpn.xwiki.api.Document;
 import com.xpn.xwiki.api.User;
 import com.xpn.xwiki.cache.api.XWikiCacheService;
+import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
 import com.xpn.xwiki.cache.impl.OSCacheService;
 import com.xpn.xwiki.doc.XWikiAttachment;
 import com.xpn.xwiki.doc.XWikiDocument;
@@ -49,6 +50,7 @@
 import com.xpn.xwiki.plugin.XWikiPluginManager;
 import com.xpn.xwiki.render.XWikiRenderingEngine;
 import com.xpn.xwiki.render.XWikiVelocityRenderer;
+import com.xpn.xwiki.render.groovy.XWikiGroovyRenderer;
 import com.xpn.xwiki.stats.api.XWikiStatsService;
 import com.xpn.xwiki.stats.impl.SearchEngineRule;
 import com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl;
@@ -84,6 +86,7 @@
 import org.securityfilter.filter.URLPatternMatcher;
 import org.exoplatform.container.RootContainer;
 import org.exoplatform.container.PortalContainer;
+import org.codehaus.groovy.control.CompilationFailedException;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
@@ -103,6 +106,8 @@
 import java.util.*;
 import java.util.zip.ZipOutputStream;
 
+import groovy.lang.GroovyClassLoader;
+
 public class XWiki implements XWikiDocChangeNotificationInterface, XWikiInterface {
     private static final Log log = LogFactory.getLog(XWiki.class);
 
@@ -3393,5 +3398,14 @@
             pref = Param("xwiki.editor", "");
         return pref.toLowerCase();
     }
+
+    public Object parseGroovyFromString(String script, XWikiContext context) throws XWikiException {
+        return ((XWikiGroovyRenderer) getRenderingEngine().getRenderer("groovy")).parseGroovyFromString(script, context);
+    }
+
+    public Object parseGroovyFromPage(String fullname, XWikiContext context) throws XWikiException {
+        return parseGroovyFromString(context.getWiki().getDocument(fullname, context).getContent(), context);
+    }
+
 }
 

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/XWikiException.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/XWikiException.java	2006-04-06 19:32:09 UTC (rev 1028)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/XWikiException.java	2006-04-06 23:31:50 UTC (rev 1029)
@@ -64,6 +64,7 @@
     public static final int MODULE_XWIKI_APP = 11;
     public static final int MODULE_XWIKI_EXPORT = 12;
     public static final int MODULE_XWIKI_DIFF = 13;
+    public static final int MODULE_GROOVY = 14;
 
     public static final int MODULE_PLUGIN_LASZLO = 21;
 
@@ -186,6 +187,8 @@
     public static final int ERROR_XWIKI_STORE_HIBERNATE_DELETING_LINKS = 13013;
     public static final int ERROR_XWIKI_STORE_HIBERNATE_LOADING_BACKLINKS = 13014;
 
+    public static final int ERROR_XWIKI_GROOVY_COMPILE_FAILED = 14001;
+    
     public static final int ERROR_LASZLO_INVALID_XML = 21001;
     public static final int ERROR_LASZLO_INVALID_DOTDOT = 21002;
 

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/api/XWiki.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/api/XWiki.java	2006-04-06 19:32:09 UTC (rev 1028)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/api/XWiki.java	2006-04-06 23:31:50 UTC (rev 1029)
@@ -32,6 +32,7 @@
 import com.sun.image.codec.jpeg.JPEGImageEncoder;
 import com.xpn.xwiki.XWikiContext;
 import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.render.groovy.XWikiGroovyRenderer;
 import com.xpn.xwiki.doc.XWikiDocument;
 import com.xpn.xwiki.objects.meta.MetaClass;
 import com.xpn.xwiki.stats.api.XWikiStatsService;
@@ -44,7 +45,11 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.*;
+import java.lang.*;
+import java.lang.Object;
 
+import groovy.lang.GroovyClassLoader;
+
 public class XWiki extends Api {
     private com.xpn.xwiki.XWiki xwiki;
 
@@ -990,5 +995,20 @@
     public String getEditorPreference() {
         return xwiki.getEditorPreference(context);
     }
+
+    public Object parseGroovyFromString(String script) throws XWikiException {
+        if (checkProgrammingRights())
+          return xwiki.parseGroovyFromString(script, context);
+        else
+          return null;
+    }
+
+    public Object parseGroovyFromPage(String fullname) throws XWikiException {
+        XWikiDocument doc = xwiki.getDocument(fullname, context);
+        if (xwiki.getRightService().hasProgrammingRights(doc, context))
+         return parseGroovyFromString(doc.getContent());
+        else
+         return null;
+    }
 }
 

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-04-06 19:32:09 UTC (rev 1028)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/render/groovy/XWikiGroovyRenderer.java	2006-04-06 23:31:50 UTC (rev 1029)
@@ -1,31 +1,32 @@
-/*
- * 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
- * @author slauriere
- */
+/*
+ * 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
+ * @author slauriere
+ */
 
 package com.xpn.xwiki.render.groovy;
 
 import groovy.text.Template;
 import groovy.lang.Writable;
+import groovy.lang.GroovyClassLoader;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -52,6 +53,8 @@
 public class XWikiGroovyRenderer implements XWikiRenderer {
     private static final Log log = LogFactory.getLog(com.xpn.xwiki.render.groovy.XWikiGroovyRenderer.class);
     private XWikiCache cache;
+    private XWikiCache classCache;
+    private final GroovyClassLoader gcl = new GroovyClassLoader();
 
     public XWikiGroovyRenderer() {
     }
@@ -59,35 +62,44 @@
 
     public void flushCache() {
         if (cache!=null)
-         cache.flushAll();
+            cache.flushAll();
+        if (classCache!=null)
+            classCache.flushAll();
     }
 
     public Map prepareContext(XWikiContext context) {
-            if (cache==null) {
-                 cache = context.getWiki().getCacheService().newCache(100);
-            }
+        prepareCache(context);
 
-            Map gcontext = (Map) context.get("gcontext");
-            if (gcontext==null) {
-                gcontext = new HashMap();
-                gcontext.put("xwiki", new XWiki(context.getWiki(), context));
-                gcontext.put("request", context.getRequest());
-                gcontext.put("response", context.getResponse());
-                gcontext.put("context", new Context(context));
+        Map gcontext = (Map) context.get("gcontext");
+        if (gcontext==null) {
+            gcontext = new HashMap();
+            gcontext.put("xwiki", new XWiki(context.getWiki(), context));
+            gcontext.put("request", context.getRequest());
+            gcontext.put("response", context.getResponse());
+            gcontext.put("context", new Context(context));
 
 
-                // Put the Grrovy Context in the context
-                // so that includes can use it..
-                context.put("gcontext", gcontext);
-                //add XWikiMessageTool to the context
-                if (context.get("msg") != null)
-                	gcontext.put("msg", context.get("msg"));
-                else
-                	context.getWiki().prepareResources(context);                
-            }
-            return gcontext;
+            // Put the Grrovy Context in the context
+            // so that includes can use it..
+            context.put("gcontext", gcontext);
+            //add XWikiMessageTool to the context
+            if (context.get("msg") != null)
+                gcontext.put("msg", context.get("msg"));
+            else
+                context.getWiki().prepareResources(context);
         }
+        return gcontext;
+    }
 
+    private void prepareCache(XWikiContext context) {
+        if (cache==null) {
+            cache = context.getWiki().getCacheService().newCache(100);
+        }
+        if (classCache==null) {
+            classCache = context.getWiki().getCacheService().newCache(100);
+        }
+    }
+
     public String evaluate(String content, String name, Map gcontext) {
         GroovyTemplateEngine engine = new GroovyTemplateEngine();
         Template template = null;
@@ -122,7 +134,7 @@
             String text;
 
             XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING, XWikiException.ERROR_XWIKI_RENDERING_GROOVY_EXCEPTION,
-                                                        "Error while parsing groovy page {0}", e, args);
+                    "Error while parsing groovy page {0}", e, args);
             title = xe.getMessage();
             text = com.xpn.xwiki.XWiki.getFormEncoded(xe.getFullMessage());
 
@@ -137,7 +149,7 @@
             return content;
 
         if (!context.getWiki().getRightService().hasProgrammingRights(contentdoc, context))
-             return content;
+            return content;
 
         Map gcontext = null;
         try {
@@ -153,7 +165,7 @@
                 if (previousdoc!=null)
                     gcontext.put("doc", previousdoc);
                 if (previouswriter!=null)
-                    gcontext.put("out", previouswriter);    
+                    gcontext.put("out", previouswriter);
             }
 
         } finally {
@@ -166,11 +178,11 @@
         if ((param!=null)&&(!param.trim().equals(""))) {
             String[] params = StringUtils.split(param, "|");
             for (int i=0;i<params.length;i++) {
-              String[] rparam = StringUtils.split(params[i], "=");
-              if (rparam.length==1)
-                  unnamedparams.add(params[i]);
-              else
-                  namedparams.put(rparam[0], rparam[1]);
+                String[] rparam = StringUtils.split(params[i], "=");
+                if (rparam.length==1)
+                    unnamedparams.add(params[i]);
+                else
+                    namedparams.put(rparam[0], rparam[1]);
             }
         }
 
@@ -192,7 +204,7 @@
                 }
             }
             if (i>0)
-             result.append(",");
+                result.append(",");
             result.append("\"");
             result.append(value.replaceAll("\"","\\\\\""));
             result.append("\"");
@@ -210,14 +222,14 @@
     private void addGroovyMacros(StringBuffer result, XWikiContext context) {
         Object macroAdded = context.get("groovyMacrosAdded");
         if (macroAdded==null) {
-          context.put("groovyMacrosAdded", "1");
-          String inclDocName = context.getWiki().getXWikiPreference("macros_groovy", context);
+            context.put("groovyMacrosAdded", "1");
+            String inclDocName = context.getWiki().getXWikiPreference("macros_groovy", context);
             try {
                 XWikiDocument doc = context.getWiki().getDocument(inclDocName, context);
                 result.append(doc.getContent());
             } catch (XWikiException e) {
                 if (log.isErrorEnabled())
-                log.error("Impossible to load groovy macros doc " + inclDocName);
+                    log.error("Impossible to load groovy macros doc " + inclDocName);
             }
         }
     }
@@ -236,4 +248,25 @@
         return result.toString();
     }
 
+    public Object parseGroovyFromString(String script, XWikiContext context) throws XWikiException {
+        prepareCache(context);
+        try {
+            Class gc;
+            try {
+                gc = (Class) classCache.getFromCache(script);
+            }
+            catch (XWikiCacheNeedsRefreshException e) {
+                gc = gcl.parseClass(script);
+                classCache.putInCache(script, gc);
+            } finally {
+                classCache.cancelUpdate(script);
+            }
+
+            return gc.newInstance();
+        } catch (Exception e) {
+            throw new XWikiException(XWikiException.MODULE_GROOVY,
+                    XWikiException.ERROR_XWIKI_GROOVY_COMPILE_FAILED,
+                    "Failed compiling groovy script", e);
+        }
+    }
 }





More information about the Xwiki-notifications mailing list