incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jus...@apache.org
Subject svn commit: r1179454 - in /sling/trunk/contrib/scripting/java: pom.xml src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java
Date Wed, 05 Oct 2011 21:35:44 GMT
Author: justin
Date: Wed Oct  5 21:35:44 2011
New Revision: 1179454

URL: http://svn.apache.org/viewvc?rev=1179454&view=rev
Log:
SLING-2237 - initial implementation of @Inject support

Modified:
    sling/trunk/contrib/scripting/java/pom.xml
    sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java
    sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java

Modified: sling/trunk/contrib/scripting/java/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/java/pom.xml?rev=1179454&r1=1179453&r2=1179454&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/java/pom.xml (original)
+++ sling/trunk/contrib/scripting/java/pom.xml Wed Oct  5 21:35:44 2011
@@ -23,7 +23,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>11</version>
+        <version>12</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 
@@ -55,8 +55,9 @@
                         <Private-Package>
                             org.apache.sling.scripting.java.impl
                         </Private-Package>
-                        <ScriptEngine-Name>${pom.name}</ScriptEngine-Name>
-                        <ScriptEngine-Version>${pom.version}</ScriptEngine-Version>
+                        <ScriptEngine-Name>${project.name}</ScriptEngine-Name>
+                        <ScriptEngine-Version>${project.version}</ScriptEngine-Version>
+                        <Export-Package>javax.inject</Export-Package>
                     </instructions>
                 </configuration>
             </plugin>
@@ -123,5 +124,10 @@
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <version>1</version>
+        </dependency>
     </dependencies>
 </project>

Modified: sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java?rev=1179454&r1=1179453&r2=1179454&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java
(original)
+++ sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/JavaScriptEngineFactory.java
Wed Oct  5 21:35:44 2011
@@ -238,7 +238,8 @@ public class JavaScriptEngineFactory
 
             wrapper = new ServletWrapper(servletConfig,
                                          ioProvider,
-                                         scriptName);
+                                         scriptName,
+                                         scriptHelper);
             this.ioProvider.getServletCache().addWrapper(scriptName, wrapper);
 
             return wrapper;

Modified: sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java?rev=1179454&r1=1179453&r2=1179454&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java
(original)
+++ sling/trunk/contrib/scripting/java/src/main/java/org/apache/sling/scripting/java/impl/ServletWrapper.java
Wed Oct  5 21:35:44 2011
@@ -17,8 +17,16 @@
 
 package org.apache.sling.scripting.java.impl;
 
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 
+import javax.inject.Inject;
 import javax.servlet.Servlet;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
@@ -27,6 +35,7 @@ import javax.servlet.UnavailableExceptio
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.sling.api.scripting.SlingScriptHelper;
 import org.apache.sling.commons.classloader.DynamicClassLoader;
 import org.apache.sling.commons.compiler.CompilationResult;
 import org.apache.sling.commons.compiler.CompilerMessage;
@@ -54,10 +63,18 @@ public class ServletWrapper {
     /** The path to the servlet. */
     private final String sourcePath;
 
+    private final SlingScriptHelper scriptHelper;
+
     /** Flag for handling modifications. */
     private volatile long lastModificationTest = 0L;
 
-    /** The compiled and instantiated servlet. */
+    /** The compiled class. */
+    private volatile Class<?> theServletClass;
+
+    /**
+     * The compiled and instantiated servlet. This field may be null in which case a new
servlet
+     * instance is created per request.
+     */
     private volatile Servlet theServlet;
 
     /** Flag handling an unavailable exception. */
@@ -71,11 +88,13 @@ public class ServletWrapper {
      */
     public ServletWrapper(final ServletConfig config,
                           final SlingIOProvider ioProvider,
-                          final String servletPath) {
+                          final String servletPath,
+                          final SlingScriptHelper scriptHelper) {
         this.config = config;
         this.ioProvider = ioProvider;
         this.sourcePath = servletPath;
         this.className = CompilerUtil.mapSourcePath(this.sourcePath).substring(1).replace('/',
'.');
+        this.scriptHelper = scriptHelper;
     }
 
     /**
@@ -87,6 +106,7 @@ public class ServletWrapper {
     public void service(HttpServletRequest request,
                          HttpServletResponse response)
     throws Exception {
+        Servlet servlet = null;
         try {
             if ((available > 0L) && (available < Long.MAX_VALUE)) {
                 if (available > System.currentTimeMillis()) {
@@ -116,7 +136,7 @@ public class ServletWrapper {
                 throw compileException;
             }
 
-            final Servlet servlet = getServlet();
+             servlet = getServlet();
 
             // invoke the servlet
             if (servlet instanceof SingleThreadModel) {
@@ -140,6 +160,10 @@ public class ServletWrapper {
                 (HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                  ex.getMessage());
             logger.error("Java servlet {} is unavailable.", this.sourcePath);
+        } finally {
+            if (servlet != null && theServlet == null) {
+                servlet.destroy();
+            }
         }
     }
 
@@ -165,10 +189,8 @@ public class ServletWrapper {
      * Check if the used classloader is still valid
      */
     private boolean checkReload() {
-        final Servlet servlet = this.theServlet;
-        final Class<?> servletClass  = servlet != null ? servlet.getClass() : null;
-        if ( servletClass != null && servletClass.getClassLoader() instanceof DynamicClassLoader
) {
-            return !((DynamicClassLoader)servletClass.getClassLoader()).isLive();
+        if ( theServletClass != null && theServletClass.getClassLoader() instanceof
DynamicClassLoader ) {
+            return !((DynamicClassLoader)theServletClass.getClassLoader()).isLive();
         }
         return false;
     }
@@ -187,12 +209,72 @@ public class ServletWrapper {
                 }
             }
         }
+
+        if (theServlet == null && theServletClass != null) {
+            final Servlet servlet = (Servlet) theServletClass.newInstance();
+            servlet.init(this.config);
+
+            injectFields(servlet);
+
+            return servlet;
+        }
+
         return theServlet;
     }
 
+    private void injectFields(Servlet servlet) {
+        for (Field field : theServletClass.getDeclaredFields()) {
+            if (field.isAnnotationPresent(Inject.class)) {
+                field.setAccessible(true);
+                try {
+                    Type type = field.getGenericType();
+                    if (type instanceof Class) {
+                        Class<?> injectedClass = (Class<?>) type;
+                        if (injectedClass.isInstance(scriptHelper)) {
+                            field.set(servlet, scriptHelper);
+                        } else if (injectedClass.isArray()) {
+                            Object[] services = scriptHelper.getServices(injectedClass.getComponentType(),
null);
+                            Object arr = Array.newInstance(injectedClass.getComponentType(),
services.length);
+                            for (int i = 0; i < services.length; i++) {
+                                Array.set(arr, i, services[i]);
+                            }
+                            field.set(servlet, arr);
+                        } else {
+                            field.set(servlet, scriptHelper.getService(injectedClass));
+                        }
+                    } else if (type instanceof ParameterizedType) {
+                        ParameterizedType ptype = (ParameterizedType) type;
+                        if (ptype.getActualTypeArguments().length != 1) {
+                            logger.warn("Field {} of {} has more than one type parameter.",
field.getName(), sourcePath);
+                            continue;
+                        }
+                        Class<?> collectionType = (Class<?>) ptype.getRawType();
+                        if (!(collectionType.equals(Collection.class) ||
+                                collectionType.equals(List.class))) {
+                            logger.warn("Field {} of {} was not an injectable collection
type.", field.getName(), sourcePath);
+                            continue;
+                        }
+                        
+                        Class<?> serviceType = (Class<?>) ptype.getActualTypeArguments()[0];
+                        Object[] services = scriptHelper.getServices(serviceType, null);
+                        field.set(servlet, Arrays.asList(services));
+                    } else {
+                        logger.warn("Field {} of {} was not an injectable type.", field.getName(),
sourcePath);
+                    }
+                } catch (IllegalArgumentException e) {
+                    logger.error(String.format("Unable to inject into field %s of %s.", field.getName(),
sourcePath), e);
+                } catch (IllegalAccessException e) {
+                    logger.error(String.format("Unable to inject into field %s of %s.", field.getName(),
sourcePath), e);
+                } finally {
+                    field.setAccessible(false);
+                }
+            }
+        }
+    }
+
     /**
-     * Compile the servlet java class
-     * and instantiate the servlet
+     * Compile the servlet java class. If the compiled class has
+     * injected fields, don't create an instance of it.
      */
     private void compile()
     throws Exception {
@@ -209,12 +291,14 @@ public class ServletWrapper {
             if ( errors != null && errors.size() > 0 ) {
                 throw CompilerException.create(errors, this.sourcePath);
             }
-            if ( result.didCompile() || this.theServlet == null ) {
+            if ( result.didCompile() || this.theServletClass == null ) {
                 destroy();
-                final Class<?> servletClass = result.loadCompiledClass(this.className);
-                final Servlet servlet = (Servlet) servletClass.newInstance();
-                servlet.init(this.config);
+                this.theServletClass = result.loadCompiledClass(this.className);
+            }
 
+            if ( !hasInjectedFields(this.theServletClass) ) {
+                final Servlet servlet = (Servlet) theServletClass.newInstance();
+                servlet.init(this.config);
                 this.theServlet = servlet;
             }
         } catch (final Exception ex) {
@@ -226,6 +310,15 @@ public class ServletWrapper {
         }
     }
 
+    private static boolean hasInjectedFields(Class<?> clazz) {
+        for (Field field : clazz.getDeclaredFields()) {
+            if (field.isAnnotationPresent(Inject.class)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /** Compiler exception .*/
     protected final static class CompilerException extends ServletException {
 



Mime
View raw message