Hi, I extended one of the servlets (JsonRpcServlet [0]) handling the Shindig calls (/social/rpc/*) just for testing. The new servlet is called XWikiShindigServlet (see complete class code at the bottom).
XWikiShindigServlet initializes the XWiki Context and container components similar to XWiki GWT and REST services. (see class code at bottom) Should this be enough or the resulted context has to be passed further along from call to call until reaches PersonServiceXW [1] ? And, in PersonServiceXW can I still use @Requirement DocumentAccessBridge to access the component, or do I have to use the XWiki context like in XWikiServiceImpl [2], with calls like, for example: XWikiDocument doc = context.getWiki().getDocument(fullName, context); Note: there are about other 7 servlets in Shindig, some of them use a GadgetContext [3] object as context. I didn't look closely to all of them how they work. The approximate inverted call stack I'm looking at looks like this: org.xwiki.opensocial.social.XWikiShindigServlet.doPost(HttpServletRequest, HttpServletResponse) org.apache.shindig.protocol.JsonRpcServlet.doPost(HttpServletRequest, HttpServletResponse) org.apache.shindig.protocol.JsonRpcServlet.dispatchBatch(JSONArray, Map<String, FormDataItem>, HttpServletRequest, HttpServletResponse, SecurityToken) org.apache.shindig.protocol.JsonRpcServlet.getHandler(JSONObject, HttpServletRequest) org.apache.shindig.protocol.DefaultHandlerRegistry.getRpcHandler(JSONObject) org.apache.shindig.protocol.DefaultHandlerRegistry.RpcInvocationWrapper.execute(Map<String, FormDataItem>, SecurityToken, BeanConverter) org.apache.shindig.protocol.DefaultHandlerRegistry.RpcInvocationHandler.execute(JSONObject, Map<String, FormDataItem>, SecurityToken, BeanConverter) org.apache.shindig.social.opensocial.service.PersonHandler.get(SocialRequestItem) org.xwiki.opensocial.social.spi.internal.PersonServiceXW.getPerson(UserId, Set<String>, SecurityToken) [0] - https://svn.apache.org/repos/asf/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java [1] - https://svn.xwiki.org/svnroot/xwiki/sandbox/gsoc/opensocial/xwiki-social-opensocial/src/main/java/org/xwiki/opensocial/social/spi/internal/PersonServiceXW.java [2] - http://svn.xwiki.org/svnroot/xwiki/platform/web/trunk/gwt/src/main/java/com/xpn/xwiki/gwt/api/server/XWikiServiceImpl.java [3] - http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/gadgets/src/main/java/org/apache/shindig/gadgets/GadgetContext.java public class XWikiShindigServlet extends JsonRpcServlet { private XWikiContext context; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { try { this.context = initializeXWikiContext(req, resp); super.doGet(req, resp); } finally { if (context != null) { cleanupContainerComponents(); } } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { try { this.context = initializeXWikiContext(req, resp); super.doPost(req, resp); } finally { if (context != null) { cleanupContainerComponents(); } } } private XWikiContext initializeXWikiContext(HttpServletRequest req, HttpServletResponse resp) throws XWikiException, ServletException { XWikiEngineContext engine = new XWikiServletContext(getServletContext()); XWikiRequest request = new XWikiServletRequest(req); XWikiResponse response = new XWikiServletResponse(resp); XWikiContext context = Utils.prepareContext("", request, response, engine); // Initialize the Container component which is the new way of transporting the Context in the new // component architecture. initializeContainerComponent(context); return context; } private void initializeContainerComponent(XWikiContext context) throws ServletException { // Initialize the Container fields (request, response, session). // Note that this is a bridge between the old core and the component architecture. // In the new component architecture we use ThreadLocal to transport the request, // response and session to components which require them. ServletContainerInitializer containerInitializer = (ServletContainerInitializer) Utils.getComponent(ServletContainerInitializer.class); try { containerInitializer.initializeRequest(context.getRequest().getHttpServletRequest(), context); containerInitializer.initializeResponse(context.getResponse().getHttpServletResponse()); containerInitializer.initializeSession(context.getRequest().getHttpServletRequest()); } catch (ServletContainerException e) { throw new ServletException("Failed to initialize request/response or session", e); } } private void cleanupContainerComponents() { Container container = (Container) Utils.getComponent(Container.class); Execution execution = (Execution) Utils.getComponent(Execution.class); // We must ensure we clean the ThreadLocal variables located in the Container and Execution // components as otherwise we will have a potential memory leak. container.removeRequest(); container.removeResponse(); container.removeSession(); execution.removeContext(); } } Thanks, Anamaria On Mon, Aug 10, 2009 at 4:28 PM, Anamaria Stoica <anam.sto...@gmail.com>wrote: > > > On Mon, Aug 10, 2009 at 2:51 PM, Vincent Massol <vinc...@massol.net>wrote: > >> >> On Aug 10, 2009, at 1:31 PM, Sergiu Dumitriu wrote: >> >> > Vincent Massol wrote: >> >> On Aug 10, 2009, at 12:41 PM, Sergiu Dumitriu wrote: >> >> >> >>> Anamaria Stoica wrote: >> >>>> It looks like you can bind an instance to type in Guice. This is >> >>>> done either >> >>>> with Instance Bindings, >> >>>> @Provides Methods or Provider Bindings, depending on the complexity >> >>>> of the >> >>>> class. >> >>>> (http://code.google.com/p/google-guice/wiki/Bindings) >> >>>> >> >>>> All bindings are defined in a class that extends AbstractModule, >> >>>> this would >> >>>> be >> >>>> XWSocialModule in my code ( >> >>>> >> https://svn.xwiki.org/svnroot/xwiki/sandbox/gsoc/opensocial/xwiki-social-opensocial/src/main/java/org/xwiki/opensocial/social/XWSocialModule.java >> ) >> >>>> . >> >>>> >> >>>> >> >>>> These modules are then passed as arguments to >> >>>> Guice.createInjector(), which >> >>>> builds the injector. >> >>>> In my application, the injector is build by >> >>>> GuiceServletContextListener ( >> >>>> >> http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/GuiceServletContextListener.java >> ) >> >>>> This servlet takes the context parameters defined in my web.xml; >> >>>> these are: >> >>>> >> >>>> <context-param> >> >>>> <param-name>guice-modules</param-name> >> >>>> <param-value> >> >>>> org.apache.shindig.common.PropertiesModule: >> >>>> org.apache.shindig.gadgets.DefaultGuiceModule: >> >>>> org.apache.shindig.gadgets.oauth.OAuthModule: >> >>>> org.apache.shindig.common.cache.ehcache.EhCacheModule: >> >>>> org.xwiki.opensocial.social.XWSocialModule >> >>>> </param-value> >> >>>> </context-param> >> >>>> >> >>>> <listener> >> >>>> >> >>>> <listener- >> >>>> class>org.xwiki.container.servlet.XWikiServletContextListener</ >> >>>> listener-class> >> >>>> </listener> >> >>>> >> >>>> Now, all I need to do is bind the instance of PersonServiceXW after >> >>>> it has >> >>>> been initialized by XWiki's Component Manager. >> >>>> The binding will be done in XWSocialModule, using one of the >> >>>> instance >> >>>> binding methods (Instance Bindings, >> >>>> @Provides Methods or Provider Bindings). >> >>>> >> >>>> My questions are: >> >>>> 1. How do I make sure PersonServiceXW has been initialized already >> >>>> by the >> >>>> XWiki CM before binding it for Guice ? >> >>> List GuiceServletContextListener AFTER XWikiServletContextListener >> >>> in >> >>> web.xml. The servlet spec specifies that listeners are called in the >> >>> order they are encountered in web.xml, and >> >>> XWikiServletContextListener >> >>> is the one that starts our component manager. >> >> >> >> For the future: we should not use other servlet context listener >> >> other >> >> than the xwiki one. We need it to init the CM but once this is done >> >> everything else should be done with it. >> >> >> >> So ideally you should instead create an EventListener that listen for >> >> the application start event and initizalize shindig in there rather >> >> than use an environment-specific servlet context listener. >> > >> > I'm not sure, but I think that Shindig works this way, there's nothing >> > we can do about it. >> >> Just checked >> >> http://svn.apache.org/repos/asf/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/servlet/GuiceServletContextListener.java >> >> It doesn't do much, just init Guice in a few lines. > > > The important part is creating the injector: > > Injector injector = Guice.createInjector(Stage.PRODUCTION, modules); > > I don't know how setting/registering the context part works though. > > >> >> >> Thanks >> -Vincent >> >> >> -Vincent >> >> >> >>>> 2. How do I get the initialized PersonServiceXW instance from >> >>>> XWSocialModule? >> >>> com.xpn.xwiki.web.Utils.getComponent(PersonServiceXW.class) >> _______________________________________________ >> devs mailing list >> devs@xwiki.org >> http://lists.xwiki.org/mailman/listinfo/devs >> > > _______________________________________________ devs mailing list devs@xwiki.org http://lists.xwiki.org/mailman/listinfo/devs