You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by vt...@apache.org on 2005/02/22 03:23:05 UTC

svn commit: r154765 - in incubator/directory/authx/trunk/script: ./ src/java/org/apache/authx/script/ src/java/org/apache/authx/script/groovy/ src/java/org/apache/authx/script/xml/ src/test/org/apache/authx/script/groovy/

Author: vtence
Date: Mon Feb 21 18:23:01 2005
New Revision: 154765

URL: http://svn.apache.org/viewcvs?view=rev&rev=154765
Log:
Implemented class loading mechanism for groovy scripts

Added:
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptClassLoader.java   (with props)
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/GroovyScriptClassLoader.java   (with props)
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/SmartCachingScriptClassLoader.java   (with props)
    incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/
    incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/GroovyScriptClassLoaderTest.java   (with props)
    incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/SmartCachingScriptClassLoaderTest.java   (with props)
    incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/greeting.groovy   (with props)
Removed:
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptInterpretationException.java
Modified:
    incubator/directory/authx/trunk/script/project.xml
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/RealmBuilder.java
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptingException.java
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/Dom4JRealmBuilder.java
    incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/ReverseBuildingContext.java

Modified: incubator/directory/authx/trunk/script/project.xml
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/project.xml?view=diff&r1=154764&r2=154765
==============================================================================
--- incubator/directory/authx/trunk/script/project.xml (original)
+++ incubator/directory/authx/trunk/script/project.xml Mon Feb 21 18:23:01 2005
@@ -43,5 +43,25 @@
             <artifactId>xml-apis</artifactId>
             <version>1.0.b2</version>
         </dependency>
+        <!-- Groovy -->
+        <dependency>
+            <groupId>groovy</groupId>
+            <artifactId>groovy</artifactId>
+            <version>1.0-beta-8</version>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm</artifactId>
+            <version>1.5.2</version>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm-util</artifactId>
+            <version>1.5.2</version>
+            <properties>
+                <gump.project>asm</gump.project>
+                <gump.id>asm-util</gump.id>
+            </properties>
+        </dependency>
     </dependencies>
 </project>

Modified: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/RealmBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/RealmBuilder.java?view=diff&r1=154764&r2=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/RealmBuilder.java (original)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/RealmBuilder.java Mon Feb 21 18:23:01 2005
@@ -23,5 +23,5 @@
  */
 public interface RealmBuilder
 {
-    void buildRealm( MutableRealm realm ) throws Exception;
+    void buildRealm( MutableRealm realm );
 }

Added: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptClassLoader.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptClassLoader.java?view=auto&rev=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptClassLoader.java (added)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptClassLoader.java Mon Feb 21 18:23:01 2005
@@ -0,0 +1,11 @@
+package org.apache.authx.script;
+
+import org.apache.authx.script.ScriptingException;
+
+import java.net.URL;
+import java.io.IOException;
+
+public interface ScriptClassLoader
+{
+    Class loadClass( URL scriptURL ) throws IOException, ScriptingException;
+}

Propchange: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptClassLoader.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptingException.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptingException.java?view=diff&r1=154764&r2=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptingException.java (original)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/ScriptingException.java Mon Feb 21 18:23:01 2005
@@ -18,12 +18,11 @@
 
 import org.apache.authx.AuthXException;
 
+/**
+ * TODO: Need to think about exception strategy for the script package.
+ */
 public class ScriptingException extends AuthXException
 {
-    public ScriptingException()
-    {
-    }
-
     public ScriptingException( String message )
     {
         super( message );

Added: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/GroovyScriptClassLoader.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/GroovyScriptClassLoader.java?view=auto&rev=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/GroovyScriptClassLoader.java (added)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/GroovyScriptClassLoader.java Mon Feb 21 18:23:01 2005
@@ -0,0 +1,60 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.authx.script.groovy;
+
+import groovy.lang.GroovyClassLoader;
+import org.apache.authx.script.ScriptingException;
+import org.apache.authx.script.ScriptClassLoader;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class GroovyScriptClassLoader implements ScriptClassLoader
+{
+    private final ClassLoader m_classLoader;
+
+    public GroovyScriptClassLoader()
+    {
+        this( Thread.currentThread().getContextClassLoader() );
+    }
+
+    public GroovyScriptClassLoader( ClassLoader classLoader )
+    {
+        m_classLoader = classLoader;
+    }
+
+    public Class loadClass( URL scriptURL ) throws IOException, ScriptingException
+    {
+        GroovyClassLoader groovyLoader = new GroovyClassLoader( m_classLoader );
+        return loadGroovyClass( groovyLoader, scriptURL );
+    }
+
+    private Class loadGroovyClass( GroovyClassLoader groovyLoader, URL scriptURL )
+            throws IOException, ScriptingException
+    {
+        try
+        {
+            return groovyLoader.parseClass( scriptURL.openStream(),
+                    scriptURL.getFile() );
+        }
+        catch ( CompilationFailedException e )
+        {
+            throw new ScriptingException( e );
+        }
+    }
+}
\ No newline at end of file

Propchange: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/GroovyScriptClassLoader.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/SmartCachingScriptClassLoader.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/SmartCachingScriptClassLoader.java?view=auto&rev=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/SmartCachingScriptClassLoader.java (added)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/SmartCachingScriptClassLoader.java Mon Feb 21 18:23:01 2005
@@ -0,0 +1,115 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.authx.script.groovy;
+
+import org.apache.authx.script.ScriptClassLoader;
+import org.apache.authx.script.ScriptingException;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SmartCachingScriptClassLoader
+{
+    private final ScriptClassLoader m_delegate;
+    private final Map m_classCache;
+
+    public SmartCachingScriptClassLoader( ScriptClassLoader delegate )
+    {
+        this.m_delegate = delegate;
+        m_classCache = new HashMap();
+    }
+
+    public Class loadClass( URL scriptUrl ) throws IOException, ScriptingException
+    {
+        return cacheHit( scriptUrl )
+                ? loadScriptFromCache( scriptUrl )
+                : loadAndCacheScript( scriptUrl );
+    }
+
+    private boolean cacheHit( URL scriptURL ) throws IOException
+    {
+        if ( !foundCacheEntry( scriptURL ) )
+        {
+            return false;
+        }
+
+        CacheEntry entry = getCacheEntry( scriptURL );
+        return !entry.isOutOfDate( lastModificationTime( scriptURL ) );
+    }
+
+    private boolean foundCacheEntry( URL scriptURL )
+    {
+        return m_classCache.containsKey( key( scriptURL ) );
+    }
+
+    private CacheEntry getCacheEntry( URL scriptURL )
+    {
+        return ( CacheEntry ) m_classCache.get( key( scriptURL ) );
+    }
+
+    private Object key( URL scriptURL )
+    {
+        return scriptURL.toExternalForm();
+    }
+
+    private long lastModificationTime( URL scriptURL ) throws IOException
+    {
+        URLConnection urlConnection = scriptURL.openConnection();
+        return urlConnection.getLastModified();
+    }
+
+    private Class loadAndCacheScript( URL scriptURL ) throws IOException,
+            ScriptingException
+    {
+        Class clazz = m_delegate.loadClass( scriptURL );
+        CacheEntry entry = new CacheEntry( clazz,
+                lastModificationTime( scriptURL ) );
+        m_classCache.put( key( scriptURL ), entry );
+        return clazz;
+    }
+
+    private Class loadScriptFromCache( URL scriptURL )
+    {
+        CacheEntry entry = getCacheEntry( scriptURL );
+        return entry.getScriptClass();
+    }
+
+    private static class CacheEntry
+    {
+        private final Class scriptClass;
+        private final long loadTime;
+
+        public CacheEntry( Class scriptClass, long loadTime )
+        {
+            this.scriptClass = scriptClass;
+            this.loadTime = loadTime;
+        }
+
+        public Class getScriptClass()
+        {
+            return scriptClass;
+        }
+
+        public boolean isOutOfDate( long lastModified )
+        {
+            return loadTime < lastModified;
+        }
+    }
+}

Propchange: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/groovy/SmartCachingScriptClassLoader.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/Dom4JRealmBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/Dom4JRealmBuilder.java?view=diff&r1=154764&r2=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/Dom4JRealmBuilder.java (original)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/Dom4JRealmBuilder.java Mon Feb 21 18:23:01 2005
@@ -28,7 +28,6 @@
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
 
-import java.io.IOException;
 import java.io.Reader;
 import java.util.Iterator;
 import java.util.List;
@@ -76,7 +75,7 @@
         m_monitor = monitor;
     }
 
-    public void buildRealm( MutableRealm realm ) throws IOException
+    public void buildRealm( MutableRealm realm )
     {
         addUsers( realm, m_root.elements( "user" ) );
     }

Modified: incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/ReverseBuildingContext.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/ReverseBuildingContext.java?view=diff&r1=154764&r2=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/ReverseBuildingContext.java (original)
+++ incubator/directory/authx/trunk/script/src/java/org/apache/authx/script/xml/ReverseBuildingContext.java Mon Feb 21 18:23:01 2005
@@ -16,7 +16,7 @@
  */
 package org.apache.authx.script.xml;
 
-import org.apache.authx.script.ScriptInterpretationException;
+import org.apache.authx.script.ScriptingException;
 import org.apache.authx.script.xml.builder.AbstractElementBuilder;
 import org.dom4j.Element;
 
@@ -47,7 +47,7 @@
     public Object buildFrom( Element e )
     {
         ElementBuilder builder = lookupBuilder( e );
-        if (builder == null) throw new ScriptInterpretationException( "Don't know how to handle element: " + e.getName());
+        if (builder == null) throw new ScriptingException( "Don't know how to handle element: " + e.getName() );
 
         return builder.buildFrom( e );
     }

Added: incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/GroovyScriptClassLoaderTest.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/GroovyScriptClassLoaderTest.java?view=auto&rev=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/GroovyScriptClassLoaderTest.java (added)
+++ incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/GroovyScriptClassLoaderTest.java Mon Feb 21 18:23:01 2005
@@ -0,0 +1,49 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.authx.script.groovy;
+
+import junit.framework.TestCase;
+
+import java.net.URL;
+
+public class GroovyScriptClassLoaderTest extends TestCase
+{
+    private GroovyScriptClassLoader m_groovyClassLoader;
+
+    protected void setUp() throws Exception
+    {
+        m_groovyClassLoader = new GroovyScriptClassLoader();
+    }
+
+    public void testCanLoadAClassFromAGroovyScript() throws Throwable
+    {
+        URL scriptURL = getClass().getResource( "greeting.groovy" );
+        Class groovyClass = m_groovyClassLoader.loadClass( scriptURL );
+        Object greeter = groovyClass.newInstance();
+
+        assertEquals( "Hola!", greeter.toString() );
+    }
+
+    public void testReloadsClassesEveryTime() throws Exception
+    {
+        URL scriptURL = getClass().getResource( "greeting.groovy" );
+        Class clazz1 = m_groovyClassLoader.loadClass( scriptURL );
+        Class clazz2 = m_groovyClassLoader.loadClass( scriptURL );
+
+        assertNotSame( clazz1, clazz2 );
+    }
+}
\ No newline at end of file

Propchange: incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/GroovyScriptClassLoaderTest.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/SmartCachingScriptClassLoaderTest.java
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/SmartCachingScriptClassLoaderTest.java?view=auto&rev=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/SmartCachingScriptClassLoaderTest.java (added)
+++ incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/SmartCachingScriptClassLoaderTest.java Mon Feb 21 18:23:01 2005
@@ -0,0 +1,72 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.authx.script.groovy;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URL;
+
+public class SmartCachingScriptClassLoaderTest extends TestCase
+{
+    private SmartCachingScriptClassLoader scriptClassLoader;
+
+    public static void main( String[] args )
+    {
+        junit.textui.TestRunner.run( SmartCachingScriptClassLoaderTest.class );
+    }
+
+    protected void setUp() throws Exception
+    {
+        scriptClassLoader = new SmartCachingScriptClassLoader( new GroovyScriptClassLoader() );
+    }
+
+    public void testClassesAreRetrievedFromCacheIfScriptHasNotChanged()
+            throws Exception
+    {
+        URL scriptURL = getClass().getResource( "greeting.groovy" );
+        Class firstHit = scriptClassLoader.loadClass( scriptURL );
+        Class secondHit = scriptClassLoader.loadClass( scriptURL );
+        assertSame( firstHit, secondHit );
+    }
+
+    public void testClassesAreReloadedIfScriptWasChanged() throws Exception
+    {
+        URL scriptURL = getClass().getResource( "greeting.groovy" );
+        Class firstHit = scriptClassLoader.loadClass( scriptURL );
+        touch( scriptURL );
+        Class secondHit = scriptClassLoader.loadClass( scriptURL );
+        assertNotSame( firstHit, secondHit );
+    }
+
+    /**
+     * There has to be a better way to do a touch. The thing is
+     * File.setLastModified( long time ) does not seem to work on my windoze
+     * box. That would have been perfect.
+     */
+    private void touch( URL scriptURL ) throws IOException
+    {
+        File script = new File( scriptURL.getFile() );
+        Writer writer = new FileWriter( script, true );
+        writer.write( " " );
+        writer.close();
+    }
+
+}

Propchange: incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/SmartCachingScriptClassLoaderTest.java
------------------------------------------------------------------------------
    svn:executable = *

Added: incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/greeting.groovy
URL: http://svn.apache.org/viewcvs/incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/greeting.groovy?view=auto&rev=154765
==============================================================================
--- incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/greeting.groovy (added)
+++ incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/greeting.groovy Mon Feb 21 18:23:01 2005
@@ -0,0 +1,7 @@
+class GroovyGreeting
+{
+    String toString()
+    {
+        return "Hola!"
+    }
+}
\ No newline at end of file

Propchange: incubator/directory/authx/trunk/script/src/test/org/apache/authx/script/groovy/greeting.groovy
------------------------------------------------------------------------------
    svn:executable = *