Hi Gagandeep,

Thank you for the detailed sample code.

I tried with your module override code, but seems it does not work, there
are binding exception if I replace the DefaultGuiceModule with my new
CustomGuiceModule in web.xml.

============ Exception stack =================
2010-11-1 11:19:53 org.apache.catalina.core.StandardContext listenerStart
com.google.inject.CreationException: Guice creation errors:

1) A binding to java.util.Set<java.lang.String> annotated with
@com.google.inject.name.Named(value=org.apache.shindig.features-extended)
was already configured at
org.apache.shindig.gadgets.DefaultGuiceModule.registerFeatureHandlers(DefaultGuiceModule.java:124).
  at
org.apache.shindig.extras.ShindigExtrasGuiceModule.configureExtraFeatures(ShindigExtrasGuiceModule.java:41)

2) A binding to java.util.Set<java.lang.Object> annotated with
@com.google.inject.name.Named(value=org.apache.shindig.handlers) was already
configured at
org.apache.shindig.gadgets.DefaultGuiceModule.registerGadgetHandlers(DefaultGuiceModule.java:105).
  at
org.apache.shindig.social.core.config.SocialApiGuiceModule.configure(SocialApiGuiceModule.java:76)

2 errors
at
com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354)
 at
com.google.inject.InjectorBuilder.initializeStatically(InjectorBuilder.java:152)
at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:105)
 at com.google.inject.Guice.createInjector(Guice.java:92)
at
org.apache.shindig.common.servlet.GuiceServletContextListener.contextInitialized(GuiceServletContextListener.java:73)
 at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3972)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4467)
 at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
 at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
 at org.apache.catalina.core.StandardService.start(StandardService.java:519)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
 at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:592)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
 at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
2010-11-1 11:19:53 org.apache.catalina.core.StandardContext start

==================CustomGuiceModule=======================

protected void configure() {
    install(Modules.override(new DefaultGuiceModule()).with(new
AbstractModule() {

      @Override
      protected void configure() {
        // TODO Auto-generated method stub
      }

      @Provides
      @Singleton
      @Named("shindig.rewriters.gadget")
      protected List<GadgetRewriter> provideGadgetRewriters(
          PipelineDataGadgetRewriter pipelineRewriter,
          TemplateRewriter templateRewriter,
          AbsolutePathReferenceRewriter absolutePathRewriter,
          StyleTagExtractorContentRewriter styleTagExtractorRewriter,
          StyleAdjacencyContentRewriter styleAdjacencyRewriter,
          ProxyingContentRewriter proxyingRewriter,
          CajaContentRewriter cajaRewriter,
          SanitizingGadgetRewriter sanitizedRewriter,
          RenderingGadgetRewriter renderingRewriter,
          OpenSocialI18NGadgetRewriter i18nRewriter,
          CustomGadgetRewriter customGadgetRewriter) {
        return ImmutableList.of(pipelineRewriter, templateRewriter,
            absolutePathRewriter, styleTagExtractorRewriter,
styleAdjacencyRewriter, proxyingRewriter,
            cajaRewriter, sanitizedRewriter, renderingRewriter,
i18nRewriter, customGadgetRewriter);
      }

    }));

  }

================web.xml=====================
  <context-param>
    <param-name>guice-modules</param-name>
    <param-value>
      org.apache.shindig.common.PropertiesModule:
      org.apache.shindig.extras.CustomGuiceModule:
      org.apache.shindig.social.core.config.SocialApiGuiceModule:
      org.apache.shindig.social.sample.SampleModule:
      org.apache.shindig.gadgets.oauth.OAuthModule:
      org.apache.shindig.common.cache.ehcache.EhCacheModule:
      org.apache.shindig.sample.shiro.ShiroGuiceModule:
      org.apache.shindig.sample.container.SampleContainerGuiceModule:
      org.apache.shindig.extras.ShindigExtrasGuiceModule:
      org.apache.shindig.extras.as.ActivityStreamsGuiceModule
    </param-value>
  </context-param>

==================================
>From the exception, it says 2 binding are already configured in
DefaultGuiceModule, then they should not be configured again in other
modules, but these 2 binding are multibinding. I am curious why this would
happen.

If this kind of override module way works, it does be helpful for my case,
since I even do not need to change any code of existing Shindig code(any
modules).   Thanks.


Thanks,

Kevin Zhang (凯峰)
Gtalk:   [email protected]
Blog:    http://www.zhangkf.com
Twitter: http://twitter.com/zhangkf


On Mon, Nov 1, 2010 at 12:31 AM, Gagandeep Singh <[email protected]>wrote:

> Hi Kai
>
>
> On Sun, Oct 31, 2010 at 5:38 PM, Kai Feng Zhang <[email protected]>wrote:
>
>> Hey Gagandeep,
>>
>> Thank you, it seems your solution is cool thing with more flexibility.
>>
>> What I am asking is to *append* a rewriter to current rewriters list from
>> DefaultGuiceModule, b/c I think the existing rewriters are good enough for
>> my case. And as I know, DefaultGuiceModule does a lot of things (installing
>> different modules etc), but not only install RewriterModule for binding
>> rewiters.
>>
>
> Your module (say MyGuiceModule) would look like:
> class MyGuiceModule extends AbstractModule {
>   public void configure() {
>     install(Modules.override(new DefaultGuiceModule()).with(new
> MySpecialModule()));
>   }
> }
>
> This will provide everything that DefaultGuiceModule already does. In
> addition, it will provide the bindings you specifically provided in
> MySpecialModule and override these when they conflict with ones provided
> by DefaultGuiceModule.
> Take a look at 
> Modules.override<http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/util/Modules.html#override(com.google.inject.Module...)>documentation.
>
>  As far as appending a rewriter to existing list is concerned, can't help
> you much there.
> This sample code:
>     class T {
>       public final String name;
>       public T(String name) {
>         this.name = name;
>       }
>     }
>
>     class A extends AbstractModule {
>       @Override
>       protected void configure() {
>         bind(T.class).annotatedWith(Names.named("hello")).toInstance(new
> T("hello"));
>       }
>     }
>     class B extends AbstractModule {
>       @Override
>       protected void configure() {
>       }
>
>       @Provides @Named("hello") @Inject
>       public T provideBuffalo(@Named("hello") T helloT) {
>         return new T("buffalo");
>       }
>     }
>
>     Injector injector = Guice.createInjector(Modules.override(new
> A()).with(new B()));
>     T h = injector.getInstance(Key.get(T.class, Names.named("hello")));
>     assertEquals("buffalo", h.name);
>
> throws StackOverflowException, because guice is trying to access the same
> @Named("hello")that its trying to provide.
> So you'l have to enumerate the rewriters you need to append your rewriter
> to again in your module.
>
>
>> So I think replace DefaultGuiceModule with custom module class in web.xml
>> maybe not enough, you still need to do other same work as DefaultGuiceModule
>> in your module.Please note that RewriterModule installed in
>> DefaultGuiceModule is not configured in web.xml.
>>
>> Any comments? Thanks a lot.
>>
>> Thanks,
>>
>> Kevin Zhang (凯峰)
>> Gtalk:   [email protected]
>> Blog:    http://www.zhangkf.com
>> Twitter: http://twitter.com/zhangkf
>>
>>
>> On Sat, Oct 30, 2010 at 10:28 AM, Gagandeep singh 
>> <[email protected]>wrote:
>>
>>> Hi Kai, Paul
>>>
>>> You are both right :) The order of rewriters matters.
>>>
>>> I have a patch<
>>> http://codereview.appspot.com/2058042/diff/123001/java/gadgets/src/main/java/org/apache/shindig/gadgets/rewrite/RewriteModule.java
>>> >
>>>
>>> (which
>>> JohnH has been reviewing and providing ideas for) which does something
>>> similar. The idea is, we create a map binder from container + flow id ->
>>> *
>>> provider* of list of rewriters.
>>> And we provide the list of rewriters similarly to how we providing
>>> currently. Since we add provider of rewriter list, we can provide a
>>> different list without having to add it to the map binder separately (map
>>> binder will cry if you add same key twice).
>>> Any new binding can be added to map binder in the custom module.
>>>
>>> The way ppl can override this is, in your new module, you again provide a
>>> new list of rewriters. And then you override the DefaultGuiceModule with
>>> your module.
>>>
>>> Say you were providing a default list of GadgetRewriters in
>>> DefaultGuiceModule:
>>> @Named("gadget.rewriters") List<GadgetRewriter> provideDef(Rewriter1 r1)
>>> {
>>> }
>>>
>>> and you want to change this list of provide Rewriter2 as well. You create
>>> your module called MyModule and provide:
>>> @Named("gadget.rewriters") List<GadgetRewriter> provideDef(Rewriter1 r1,
>>> Rewriter2 r2) {
>>> }
>>>
>>> And then early on in the code, you override default guice module with
>>> your
>>> module:
>>> Modules.override(new GuiceModule()).with(new MyModule());
>>>
>>> I think your facing the problem because maybe web.xml does not allow you
>>> to
>>> override a module with a new one. And when 2 modules provide same
>>> binding,
>>> guice dies.
>>> A quick solution for your case would be to change web.xml to provide your
>>> module in place of DefaultGuiceModule, and change your module to
>>> install DefaultGuiceModule after overriding it with your rewriter list.
>>> Something like:
>>>
>>> web.xml:
>>>  <context-param>
>>>    <param-name>guice-modules</param-name>
>>>    <param-value>
>>>      org.apache.shindig.common.PropertiesModule:
>>>      org.apache.shindig.gadgets.*MyGuiceModule*:
>>>      org.apache.shindig.social.core.config.SocialApiGuiceModule:
>>> ......
>>>
>>> MyGuiceModule.java:
>>> protected void configure() {
>>>  Modules.override(new DefaultGuiceModule()).with(new AbstractModule() {
>>>    protected void configure() {
>>>    }
>>>    @Provides @Named("gadget.rewriters") List<GadgetRewriter>
>>>     ....
>>>  }
>>> }
>>>
>>> I hope im making sense.
>>>
>>> On Fri, Oct 29, 2010 at 5:52 PM, Paul Lindner <[email protected]> wrote:
>>>
>>> > I think this is a good idea, however I'm concerned that the ordering of
>>> > Rewriters may be important.
>>> >
>>> > I'm guessing that we could make a SortedSet if we had a Comparable<>
>>> > implementation of all rewriters.
>>> >
>>> > On Fri, Oct 29, 2010 at 1:23 AM, Kai Feng Zhang <[email protected]>
>>> > wrote:
>>> >
>>> > > I found a possible solution to extend Shindig rewriter capability,
>>> using
>>> > > multibinding in Guice.
>>> > >
>>> > > Please see:
>>> > >
>>> > >
>>> >
>>> http://google-guice.googlecode.com/svn/trunk/latest-javadoc/com/google/inject/multibindings/Multibinder.html
>>> > >
>>> > > I created a jira for this, see
>>> > > https://issues.apache.org/jira/browse/SHINDIG-1456
>>> > >
>>> > >
>>> > >
>>> > > On Fri, Oct 29, 2010 at 3:02 PM, Kai Feng Zhang <[email protected]>
>>> > > wrote:
>>> > >
>>> > > > Hi,
>>> > > >
>>> > > > I'd like to add a custom rewriter into Shindig, with requirement of
>>> no
>>> > > need
>>> > > > to change Shindig rendering gadget server side code directly. I
>>> want to
>>> > > add
>>> > > > it as a new feature in extras, so when this feature is required by
>>> > > gadget,
>>> > > > the custom rewriter will do some special work when rendering gadget
>>> at
>>> > > > server side.
>>> > > >
>>> > > > But I checked Shindig code, RewriteModule @Provides all predefined
>>> > > > rewriters with @Named("shindig.rewriters.gadget") , and
>>> > > > then GadgetRewritersProvider will provide all rewriters as per the
>>> same
>>> > > > @Name when rendering gadget.
>>> > > >
>>> > > > If I create a new Module in shindig extras, and @Provides custom
>>> > rewriter
>>> > > > with same @Name, and startup server, there will be error saying the
>>> > same
>>> > > > @Name is configured already by RewriteModule.
>>> > > >
>>> > > > Can anyone please help if there is some way to append such a
>>> rewriter
>>> > > > without touching any existing Shindig gadget rendering code? Or
>>> that is
>>> > > the
>>> > > > only way to extend a new rewriter for gadget rendering?
>>> > > >
>>> > > > Thanks a lot!
>>> > > >
>>> > >
>>> >
>>> >
>>> >
>>> > --
>>> > Paul Lindner -- [email protected] -- linkedin.com/in/plindner
>>> >
>>>
>>
>>
>

Reply via email to