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