Author: [email protected]
Date: Wed Aug 10 10:10:43 2011
New Revision: 1303

Log:
[AMDATUOPENSOCIAL-55] Refactored Guice injector servlet registration, making it 
easier to understand

Added:
   
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServletImpl.java
Removed:
   
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorService.java
   
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServiceImpl.java
Modified:
   
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
   
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServlet.java
   
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/ShindigRegistrationServiceImpl.java

Modified: 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
==============================================================================
--- 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
  (original)
+++ 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/osgi/Activator.java
  Wed Aug 10 10:10:43 2011
@@ -15,38 +15,36 @@
  */
 package org.amdatu.opensocial.shindig.osgi;
 
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import org.amdatu.core.config.templates.ConfigTemplateManager;
-import org.amdatu.core.tenant.Tenant;
-import org.amdatu.opensocial.gadgetmanagement.GadgetStorageProvider;
-import org.amdatu.opensocial.gadgetmanagement.OpenSocialContainer;
-import org.amdatu.opensocial.shindig.OAuthModule;
-import org.amdatu.opensocial.shindig.ShindigService;
-import org.amdatu.opensocial.shindig.SocialApiModule;
-import org.amdatu.opensocial.shindig.module.ConfigurationAdminGuiceModule;
-import org.amdatu.opensocial.shindig.module.OAuthModuleImpl;
-import org.amdatu.opensocial.shindig.module.SocialApiModuleImpl;
-import org.amdatu.opensocial.shindig.persistence.AppDataServiceImpl;
-import org.amdatu.opensocial.shindig.persistence.OAuthStoreImpl;
-import org.amdatu.opensocial.shindig.service.GuiceInjectorService;
-import org.amdatu.opensocial.shindig.service.GuiceInjectorServiceImpl;
-import org.amdatu.opensocial.shindig.service.ShindigOpenSocialContainerImpl;
-import org.amdatu.opensocial.shindig.service.ShindigRegistrationServiceImpl;
-import 
org.amdatu.opensocial.shindig.service.TenantHostnameDispatchExtenderFilter;
-import org.amdatu.web.dispatcher.DispatchExtenderFilter;
-import org.amdatu.web.dispatcher.DispatcherService;
-import org.amdatu.web.httpcontext.HttpContextManagerService;
-import org.amdatu.web.httpcontext.ResourceProvider;
-import org.amdatu.web.resource.ResourceSupport;
-import org.apache.felix.dm.DependencyActivatorBase;
-import org.apache.felix.dm.DependencyManager;
-import org.apache.shindig.gadgets.oauth.OAuthStore;
-import org.apache.shindig.social.opensocial.spi.AppDataService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.service.log.LogService;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.amdatu.core.config.templates.ConfigTemplateManager;
+import org.amdatu.core.tenant.Tenant;
+import org.amdatu.opensocial.gadgetmanagement.GadgetStorageProvider;
+import org.amdatu.opensocial.gadgetmanagement.OpenSocialContainer;
+import org.amdatu.opensocial.shindig.OAuthModule;
+import org.amdatu.opensocial.shindig.ShindigService;
+import org.amdatu.opensocial.shindig.SocialApiModule;
+import org.amdatu.opensocial.shindig.module.ConfigurationAdminGuiceModule;
+import org.amdatu.opensocial.shindig.module.OAuthModuleImpl;
+import org.amdatu.opensocial.shindig.module.SocialApiModuleImpl;
+import org.amdatu.opensocial.shindig.persistence.AppDataServiceImpl;
+import org.amdatu.opensocial.shindig.persistence.OAuthStoreImpl;
+import org.amdatu.opensocial.shindig.service.ShindigOpenSocialContainerImpl;
+import org.amdatu.opensocial.shindig.service.ShindigRegistrationServiceImpl;
+import 
org.amdatu.opensocial.shindig.service.TenantHostnameDispatchExtenderFilter;
+import org.amdatu.web.dispatcher.DispatchExtenderFilter;
+import org.amdatu.web.dispatcher.DispatcherService;
+import org.amdatu.web.httpcontext.HttpContextManagerService;
+import org.amdatu.web.httpcontext.ResourceProvider;
+import org.amdatu.web.resource.ResourceSupport;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.shindig.gadgets.oauth.OAuthStore;
+import org.apache.shindig.social.opensocial.spi.AppDataService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.log.LogService;
 
 /**
  * This is the OSGi activator for this Shindig application bundle.
@@ -111,22 +109,7 @@
                 
.add(createServiceDependency().setService(LogService.class).setRequired(true))
                 
.add(createConfigurationDependency().setPid(ShindigService.SHINDIG_CONFIG_PID).setPropagate(true)));
 
-        // Create the Guice injector servlet
-        manager.add(
-            createComponent()
-                .setInterface(GuiceInjectorService.class.getName(), null)
-                .setImplementation(GuiceInjectorServiceImpl.class)
-                .setCallbacks("_init", "start", "stop", "_destroy")
-                
.add(createServiceDependency().setService(LogService.class).setRequired(true))
-                
.add(createServiceDependency().setService(SocialApiModule.class).setRequired(true))
-                
.add(createServiceDependency().setService(OAuthModule.class).setRequired(true))
-                .add(
-                    
createServiceDependency().setService(ConfigurationAdminGuiceModule.class,
-                        "(" + Constants.SERVICE_PID + "=" + 
ShindigService.SHINDIG_CONFIG_PID + ")")
-                        .setRequired(true)));
-
         // Register the Shindig registration service
-
         // Provide context and alias information for resources
         Dictionary<String, Object> properties = new Hashtable<String, 
Object>();
         properties.put(DispatcherService.CONTEXT_ID_KEY, CONTEXTID);
@@ -142,10 +125,7 @@
                 .setImplementation(ShindigRegistrationServiceImpl.class)
                 
.add(createServiceDependency().setService(DispatcherService.class).setRequired(true))
                 
.add(createServiceDependency().setService(HttpContextManagerService.class).setRequired(true))
-                // .add(createServiceDependency().setService(HttpContext.class,
-                // "(" + HttpContextManagerService.CONTEXT_ID_KEY + "=" + 
CONTEXTID + ")").setRequired(true))
                 
.add(createServiceDependency().setService(LogService.class).setRequired(true))
-                
.add(createServiceDependency().setService(GuiceInjectorService.class).setRequired(true))
                 
.add(createServiceDependency().setService(SocialApiModule.class).setRequired(true))
                 
.add(createServiceDependency().setService(OAuthModule.class).setRequired(true))
                 .add(

Modified: 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServlet.java
==============================================================================
--- 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServlet.java
    (original)
+++ 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServlet.java
    Wed Aug 10 10:10:43 2011
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 package org.amdatu.opensocial.shindig.service;
+
+import javax.servlet.Servlet;
 
 /**
  * This interface enables dependencies on the availability of the Guice 
injector servlet using service dependencies.
@@ -23,6 +25,6 @@
  * 
  * @author ivol
  */
-public interface GuiceInjectorServlet {
+public interface GuiceInjectorServlet extends Servlet {
 
 }

Added: 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServletImpl.java
==============================================================================
--- (empty file)
+++ 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/GuiceInjectorServletImpl.java
        Wed Aug 10 10:10:43 2011
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu 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.amdatu.opensocial.shindig.service;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.amdatu.opensocial.shindig.OAuthModule;
+import org.amdatu.opensocial.shindig.SocialApiModule;
+import org.amdatu.opensocial.shindig.module.ConfigurationAdminGuiceModule;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.shindig.common.servlet.GuiceServletContextListener;
+import org.osgi.service.log.LogService;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.Stage;
+import com.google.inject.tools.jmx.Manager;
+
+/**
+ * This class covers a rather complicated problem using Guice. Guice-based 
servlets require the "Guice injector" to
+ * be created before they are registered. The Guice injector should be 
associated with that same servlet context, so
+ * to make that so a servlet should be registered. Usually you do not have 
control when a servlet is
+ * actually initialized.
+ * This service covers this tricky stuff. This is what will happen:
+ * -1- First this GuiceInjectorService is created, which contains some 
dependencies on Guice modules. The service is
+ * registered with the GuiceInjectorService interface, so it will not register 
any servlet yet.
+ * -2- The ShindigRegistrationService has a dependency on this 
GuiceInjectorService. In its init() method it will
+ * first create a HTTP context.
+ * -3- The ShindigRegistrationService will now register the 
GuiceInjectorService as servlet, using the HTTP context
+ * it just created
+ * -4- By registration of this service as Servlet, the init(ServletConfig) 
will be invoked which creates the Guice
+ * injector and associates it with the servlet context.
+ * -5- When the Guice injector is registered, this service is registered as 
GuiceInjectorServlet service.
+ * -6- The ShindigRegistrationService continues to register filters and 
Servlets (whiteboard style), but all with a
+ * service dependency on the GuiceInjectorServlet. This ensures that the Guice 
injector is initialized and bound to
+ * the servlet context before it is created.
+ * 
+ * @author ivol
+ * 
+ */
+public class GuiceInjectorServletImpl implements GuiceInjectorServlet {
+    /**
+     * This a path to a fake servlet used to initialize the Guice context. 
This servlet is registered *before* all
+     * other Servlets and it activates a common HttpContext in its 
ServletConfig method. So all other Servlets
+     * could find the Guice injector stored by this fake servlet.
+     */
+    public static final String SERVLET_ALIAS = 
"/this/is/the/guice/injector/servlet";
+
+    // Service dependencies
+    private volatile LogService m_logService;
+    private volatile SocialApiModule m_socialApiModule;
+    private volatile OAuthModule m_oAuthModule;
+    private volatile ConfigurationAdminGuiceModule 
m_shindigConfigurationModule;
+    private volatile DependencyManager m_dependencyManager;
+
+    // Instance variables
+    private boolean m_jmxInitialized;
+    private Component m_serviceComponent;
+    
+    public GuiceInjectorServletImpl() {
+    }
+    
+    public void setLogService(LogService logService) {
+        m_logService = logService;
+    }
+
+    public void setSocialApiModule(SocialApiModule socialApiModule) {
+        m_socialApiModule = socialApiModule;
+    }
+
+    public void setoAuthModule(OAuthModule oAuthModule) {
+        m_oAuthModule = oAuthModule;
+    }
+
+    public void setShindigConfigurationModule(ConfigurationAdminGuiceModule 
shindigConfigurationModule) {
+        m_shindigConfigurationModule = shindigConfigurationModule;
+    }
+
+    public void setDependencyManager(DependencyManager dependencyManager) {
+        m_dependencyManager = dependencyManager;
+    }
+
+    public ServletConfig getServletConfig() {
+        return null;
+    }
+
+    public String getServletInfo() {
+        return null;
+    }
+
+    public void init(final ServletConfig config) throws ServletException {
+        Injector injector = createGuiceInjector();
+        ServletContext context = config.getServletContext();
+        context.setAttribute(GuiceServletContextListener.INJECTOR_ATTRIBUTE, 
injector);
+        registerService();
+    }
+
+    private void registerService() {
+        // This registers ourselves as GuiceInjectorServlet. Note that the 
activator explicitly
+        // does not register the service with the GuiceInjectorServlet 
interface since we want
+        // postpone the availability of the service until the Guice injector 
is initialized.
+        m_serviceComponent = m_dependencyManager.createComponent()
+                .setInterface(GuiceInjectorServlet.class.getName(), null)
+                .setImplementation(this)
+                .setCallbacks("_init", "start", "stop", "_destroy");
+        m_dependencyManager.add(m_serviceComponent);
+    }
+
+    public void service(final ServletRequest arg0, final ServletResponse arg1) 
throws ServletException, IOException {
+    }
+
+    public void destroy() {
+        removeService();
+    }
+
+    private void removeService() {
+        m_dependencyManager.remove(m_serviceComponent);
+    }
+
+    /**
+     * @return a newly created Guice injector which is shared between all 
Shindig servlets using a common HttpContext
+     */
+    private Injector createGuiceInjector() {
+        String[] moduleNames = getGuiceModules();
+        List<Module> modules = new ArrayList<Module>();
+        if (moduleNames != null) {
+            // First add the properties module
+            modules.add(m_shindigConfigurationModule);
+
+            // Now add all Guice-injected modules
+            for (String moduleName : moduleNames) {
+                try {
+                    moduleName = moduleName.trim();
+                    if (moduleName.length() > 0) {
+                        ClassLoader cl = Module.class.getClassLoader();
+                        Module moduleInstance = (Module) 
cl.loadClass(moduleName).newInstance();
+                        modules.add(moduleInstance);
+                    }
+                }
+                catch (InstantiationException e) {
+                    m_logService.log(LogService.LOG_ERROR, "Could not create 
Guice module", e);
+                }
+                catch (ClassNotFoundException e) {
+                    m_logService.log(LogService.LOG_ERROR, "Could not create 
Guice module", e);
+                }
+                catch (IllegalAccessException e) {
+                    m_logService.log(LogService.LOG_ERROR, "Could not create 
Guice module", e);
+                }
+                catch (ClassCastException e) {
+                    m_logService.log(LogService.LOG_ERROR, "Could not create 
Guice module", e);
+                }
+            }
+
+            // Add our own oAuth module
+            modules.add(m_oAuthModule);
+
+            // Finally add our own social API module
+            modules.add(m_socialApiModule);
+        }
+        Injector injector = Guice.createInjector(Stage.PRODUCTION, modules);
+        injector.injectMembers(this);
+        try {
+            if (!m_jmxInitialized) {
+                Manager.manage("ShindigGuiceContext", injector);
+                m_jmxInitialized = true;
+            }
+        }
+        catch (Exception e) {
+            // Ignore errors
+        }
+        return injector;
+    }
+
+    private String[] getGuiceModules() {
+        return new String[] {
+            "org.apache.shindig.gadgets.DefaultGuiceModule",
+            "org.apache.shindig.extras.ShindigExtrasGuiceModule",
+            "org.apache.shindig.common.cache.ehcache.EhCacheModule"};
+    }
+}

Modified: 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/ShindigRegistrationServiceImpl.java
==============================================================================
--- 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/ShindigRegistrationServiceImpl.java
  (original)
+++ 
trunk/amdatu-opensocial/opensocial-shindig/src/main/java/org/amdatu/opensocial/shindig/service/ShindigRegistrationServiceImpl.java
  Wed Aug 10 10:10:43 2011
@@ -15,39 +15,42 @@
  */
 package org.amdatu.opensocial.shindig.service;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Properties;
-
-import javax.servlet.Filter;
-import javax.servlet.Servlet;
-
-import org.amdatu.opensocial.shindig.ShindigService;
-import org.amdatu.opensocial.shindig.osgi.Activator;
-import org.amdatu.web.dispatcher.DispatcherService;
-import org.amdatu.web.httpcontext.ResourceProvider;
-import org.apache.felix.dm.Component;
-import org.apache.felix.dm.DependencyManager;
-import org.apache.shindig.auth.AuthenticationServletFilter;
-import org.apache.shindig.gadgets.servlet.ConcatProxyServlet;
-import org.apache.shindig.gadgets.servlet.GadgetRenderingServlet;
-import org.apache.shindig.gadgets.servlet.JsServlet;
-import org.apache.shindig.gadgets.servlet.MakeRequestServlet;
-import org.apache.shindig.gadgets.servlet.OAuthCallbackServlet;
-import org.apache.shindig.gadgets.servlet.ProxyServlet;
-import org.apache.shindig.gadgets.servlet.RpcServlet;
-import org.apache.shindig.protocol.DataServiceServlet;
-import org.apache.shindig.protocol.JsonRpcServlet;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.service.log.LogService;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+
+import org.amdatu.opensocial.shindig.OAuthModule;
+import org.amdatu.opensocial.shindig.ShindigService;
+import org.amdatu.opensocial.shindig.SocialApiModule;
+import org.amdatu.opensocial.shindig.module.ConfigurationAdminGuiceModule;
+import org.amdatu.opensocial.shindig.osgi.Activator;
+import org.amdatu.web.dispatcher.DispatcherService;
+import org.amdatu.web.httpcontext.ResourceProvider;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.shindig.auth.AuthenticationServletFilter;
+import org.apache.shindig.gadgets.servlet.ConcatProxyServlet;
+import org.apache.shindig.gadgets.servlet.GadgetRenderingServlet;
+import org.apache.shindig.gadgets.servlet.JsServlet;
+import org.apache.shindig.gadgets.servlet.MakeRequestServlet;
+import org.apache.shindig.gadgets.servlet.OAuthCallbackServlet;
+import org.apache.shindig.gadgets.servlet.ProxyServlet;
+import org.apache.shindig.gadgets.servlet.RpcServlet;
+import org.apache.shindig.protocol.DataServiceServlet;
+import org.apache.shindig.protocol.JsonRpcServlet;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.log.LogService;
 
 /**
  * This service manages construction/destruction and 
registration/deregistration of
@@ -81,8 +84,10 @@
     private volatile BundleContext m_bundleContext;
     private volatile LogService m_logService;
     private volatile DependencyManager m_dependencyManager;
-    private volatile GuiceInjectorService m_guiceInjectorService;
-
+    private volatile OAuthModule m_OAuthModule;
+    private volatile ConfigurationAdminGuiceModule 
m_shindigConfigurationModule;
+    private volatile SocialApiModule m_socialApiModule;
+    
     // Other instance variables
     private List<Component> m_registeredServletComponents = new 
ArrayList<Component>();
 
@@ -180,13 +185,20 @@
         }
     }
 
-    private void registerInjectorServlet() {
+    private void registerInjectorServlet() {
+        GuiceInjectorServletImpl guiceInjectorServlet = new 
GuiceInjectorServletImpl();
+        guiceInjectorServlet.setDependencyManager(m_dependencyManager);
+        guiceInjectorServlet.setLogService(m_logService);
+        guiceInjectorServlet.setoAuthModule(m_OAuthModule);
+        
guiceInjectorServlet.setShindigConfigurationModule(m_shindigConfigurationModule);
+        guiceInjectorServlet.setSocialApiModule(m_socialApiModule);
+        
         Properties servletProperties = new Properties();
-        servletProperties.put(DispatcherService.ALIAS_KEY, 
GuiceInjectorServiceImpl.SERVLET_ALIAS);
+        servletProperties.put(DispatcherService.ALIAS_KEY, 
GuiceInjectorServletImpl.SERVLET_ALIAS);
         servletProperties.put(DispatcherService.CONTEXT_ID_KEY, 
Activator.CONTEXTID);
 
         Component servletComponent = m_dependencyManager.createComponent()
-            .setImplementation(m_guiceInjectorService)
+            .setImplementation(guiceInjectorServlet)
             .setInterface(Servlet.class.getName(), servletProperties);
         m_dependencyManager.add(servletComponent);
         m_registeredServletComponents.add(servletComponent);
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits

Reply via email to