Creating MapBinder with Annotation and supplying a value

967 views
Skip to first unread message

GuptaJi

unread,
Apr 19, 2010, 2:44:24 PM4/19/10
to google-guice
Hi,

I am relatively new to Guice but I have read the documentation well.
I am looking for a way to create a map binder in my module with an
annotation. Creating with an annotation is easy enough by supplying
AnnotationName.class as the fourth parameter in newBinder(). My
requirements need the annotation to be supplied with a value so that
it is possible to use something like:
@AnnotationName(AnEnum.someValue).

Is it even possible to do something like what I am describing?

Thanks a lot for your help.

Cheers,
GuptaJi

--
You received this message because you are subscribed to the Google Groups "google-guice" group.
To post to this group, send email to google...@googlegroups.com.
To unsubscribe from this group, send email to google-guice...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-guice?hl=en.

Fred Faber

unread,
Apr 19, 2010, 7:58:17 PM4/19/10
to google...@googlegroups.com
Basically you need to be able to reference an instance of your annotation in your binding.

You can do this by implementing your annotation:

class AnnotationNameImpl implements @AnnotationName {
 ....
}

and then you can instantiate an instance in your binding:

bind(...).annotatedWith(new AnnotationNameImpl(AnEnum.someValue));

I bet you could also develop a simple service that would allow you do do:

class YourModule {
  ....

 @AnnotationName(AnEnum.someValue)
 private static final String annotatedString = null;

  protected void configure() {
     Annotation annotation = 
         AnnotationReader.readAnnotationFrom(getClass(), "annotatedString");
     bind(....)
  }
}

-Fred

GuptaJi

unread,
Apr 20, 2010, 12:05:16 AM4/20/10
to google-guice
Hi Fred,

I tried what you had suggested but still no luck. I am trying to use
the method:
MapBinder.newMapBinder(Binder binder, Class<K> keyType, Class<V>
valueType, Annotation annotation) ;

If I pass the AnnotationImpl object as the fourth parameter, the map
inject elsewhere contains no value. However, if I modify the
Annotation to be without value, it works fine. (I did remove the value
method from AnnotationImpl and at the point of injection).

Any ideas on what I might be doing wrong?

Thanks,
GuptaJi
> > google-guice...@googlegroups.com<google-guice%2Bunsubscribe@google­groups.com>
> > .
> > For more options, visit this group at
> >http://groups.google.com/group/google-guice?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups "google-guice" group.
> To post to this group, send email to google...@googlegroups.com.
> To unsubscribe from this group, send email to google-guice...@googlegroups.com.
> For more options, visit this group athttp://groups.google.com/group/google-guice?hl=en.- Hide quoted text -
>
> - Show quoted text -

Fred Faber

unread,
Apr 20, 2010, 12:09:53 AM4/20/10
to google...@googlegroups.com
GuptaJi,

What does your implementation of your Annotation look like?  The javadoc has a unique contract that you might want to browse to be sure your class is in accord w/ it.

-Fred

GuptaJi

unread,
Apr 20, 2010, 1:23:12 AM4/20/10
to google-guice
Hi Fred,

I tried my best to follow the documentation provided on Annotation
when defining the implementation for my custom annotation. Here is
the class that I created. Hopefully you can spot something I missed.
For testing I have used a String value instead of Enum that I
eventually wish to use (if I ever get this to work). The annotation
has only one field.

public class RegistrarImpl implements Registrar{

public String theValue;

public RegistrarImpl(String value){
theValue = value;
}

public String value(){
return theValue;
}

public Class<? extends Annotation> annotationType() {
return Registrar.class;
}

public boolean equal(Object obj){
if (obj instanceof Registrar){
return theValue.equals(
((Registrar)obj).value());
}

return false;
}

public int hashCode(){
return value().hashCode();
}
}


It is quite strpublic class RegistrarImpl implements Registrar{

public String theValue;

public RegistrarImpl(String value){
theValue = value;
}

public String value(){
return theValue;
}

public Class<? extends Annotation> annotationType() {
return Registrar.class;
}

public boolean equal(Object obj){
if (obj instanceof Registrar){
return theValue.equals(
((Registrar)obj).value());
}

return false;
}

public int hashCode(){
return value().hashCode();
}

}

I find it quite strange that passing the class Registrar.class as the
fourth parameter to the newBinder method matches it to the annotation
with the value provided.
@Inject(optional=true)
public void registerAll (@Registrar ("100") Map<String, Object> aMap)
{

theMap.putAll(aMap);
}

It is almost like Guice is ignoring the value provided with the
annotation when creating the MapBinder.

Thanks,
GuptaJi

Stuart McCulloch

unread,
Apr 20, 2010, 1:33:21 AM4/20/10
to google...@googlegroups.com
On 20 April 2010 13:23, GuptaJi <pra...@gmail.com> wrote:
Hi Fred,

I tried my best to follow the documentation provided on Annotation
when defining the implementation for my custom annotation.  Here is
the class that I created.  Hopefully you can spot something I missed.
For testing I have used a String value instead of Enum that I
eventually wish to use (if I ever get this to work).  The annotation
has only one field.

public class RegistrarImpl implements Registrar{

       public String theValue;

       public RegistrarImpl(String value){
               theValue = value;
       }

       public String value(){
               return theValue;
       }

       public Class<? extends Annotation> annotationType() {
               return Registrar.class;
       }

       public boolean equal(Object obj){
               if (obj instanceof Registrar){
                       return theValue.equals(
                                       ((Registrar)obj).value());
               }

               return false;
       }

       public int hashCode(){
               return value().hashCode();
       }

^ this hashCode implementation does not match the Annotation spec:

   http://java.sun.com/javase/6/docs/api/java/lang/annotation/Annotation.html#hashCode%28%29

it should be something like:

  return ( 127 * "value".hashCode() ) ^ value().hashCode();

for your example with a single value member
 
}


It is quite strpublic class RegistrarImpl implements Registrar{

       public String theValue;

       public RegistrarImpl(String value){
               theValue = value;
       }

       public String value(){
               return theValue;
       }

       public Class<? extends Annotation> annotationType() {
               return Registrar.class;
       }

       public boolean equal(Object obj){
               if (obj instanceof Registrar){
                       return theValue.equals(
                                       ((Registrar)obj).value());
               }

               return false;
       }

       public int hashCode(){
               return value().hashCode();
       }

}

I find it quite strange that passing the class Registrar.class as the
fourth parameter to the newBinder method matches it to the annotation
with the value provided.
       @Inject(optional=true)
       public void registerAll (@Registrar ("100") Map<String, Object> aMap)
{

               theMap.putAll(aMap);
       }

It is almost like Guice is ignoring the value provided with the
annotation when creating the MapBinder.

^ if you pass in an annotation type instead of an annotation instance then
this binding will match against any instance of that annotation regardless
of the actual value

   http://code.google.com/p/google-guice/wiki/BindingAnnotations

HTH




--
Cheers, Stuart

GuptaJi

unread,
Apr 20, 2010, 11:03:55 AM4/20/10
to google-guice
Hi Stuart,

Thanks for spotting that problem. I thought I had read the
documentation well but obviously that was not the case.

After making the change you wrote about the annotation works exactly
as I expected.

Many thanks to you and Fred for your help in resolving this issue.

Cheers,
GuptaJi



On Apr 20, 1:33 am, Stuart McCulloch <mccu...@gmail.com> wrote:
> On 20 April 2010 13:23, GuptaJi <prat...@gmail.com> wrote:
>
>
>
>
>
> > Hi Fred,
>
> > I tried my best to follow the documentation provided on Annotation
> > when defining the implementation for my custom annotation.  Here is
> > the class that I created.  Hopefully you can spot something I missed.
> > For testing I have used a String value instead of Enum that I
> > eventually wish to use (if I ever get this to work).  The annotation
> > has only one field.
>
> > public class RegistrarImpl implements Registrar{
>
> >        public String theValue;
>
> >        public RegistrarImpl(String value){
> >                theValue = value;
> >        }
>
> >        public String value(){
> >                return theValue;
> >        }
>
> >        public Class<? extends Annotation> annotationType() {
> >                return Registrar.class;
> >        }
>
> >        public boolean equal(Object obj){
> >                if (obj instanceof Registrar){
> >                        return theValue.equals(
> >                                        ((Registrar)obj).value());
> >                }
>
> >                return false;
> >        }
>
> >        public int hashCode(){
> >                return value().hashCode();
> >        }
>
> ^ this hashCode implementation does not match the Annotation spec:
>
> http://java.sun.com/javase/6/docs/api/java/lang/annotation/Annotation...
> Cheers, Stuart
>
> --
> You received this message because you are subscribed to the Google Groups "google-guice" group.
> To post to this group, send email to google...@googlegroups.com.
> To unsubscribe from this group, send email to google-guice...@googlegroups.com.
> For more options, visit this group athttp://groups.google.com/group/google-guice?hl=en.- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages