13 Replies Latest reply on Dec 2, 2008 7:05 PM by alesj

    Injecting a field value

    dmlloyd

      I'd like to inject the value of a static constant field as a bean property value. Is this possible to do? Am I just not seeing the right tag/

      Thanks.

        • 1. Re: Injecting a field value
          dmlloyd

          ...and, I also would need to know the programmatic equivalent as well. Though I am starting to suspect that there is no support for this currently.

          • 2. Re: Injecting a field value
            alesj

             

            "david.lloyd@jboss.com" wrote:
            Though I am starting to suspect that there is no support for this currently.

            You would be wrong. ;-)
            I might even be offended as you doubt us. :-)

            See constants usage:
            - http://anonsvn.jboss.org/repos/jbossas/projects/demos/microcontainer/trunk/ioc/src/main/resources/META-INF/access-mode-beans.xml

            • 3. Re: Injecting a field value
              dmlloyd

              Ah, I see why it wasn't obvious at first. So does that mean that any bean which I want to pull constants from has to be managed?

              • 4. Re: Injecting a field value
                alesj

                 

                "david.lloyd@jboss.com" wrote:
                So does that mean that any bean which I want to pull constants from has to be managed?

                It's all about beans.
                Unless we had special constants treatment,
                how else do you expect us to pull stuff from? :-)

                But I guess this can be done generic:
                - simply add constants handling bean
                - value-factory usage
                - use similar mechanism we use for field access.

                • 5. Re: Injecting a field value
                  dmlloyd

                  It just seems a little odd - I want to pull a static field so why do I need an object instance? Unless access-mode="FIELDS" implicitly grabs the class instead?

                  • 6. Re: Injecting a field value
                    alesj

                     

                    "david.lloyd@jboss.com" wrote:
                    Unless access-mode="FIELDS" implicitly grabs the class instead?

                    Grabs class how?

                    We don't have any special static handling (via xml or BMDB).
                    OO != static. ;-)
                    And I don't see why we should have any special treatment,
                    the example I provided you is not a huge penalty.

                    But you can do all this static mojo via BeanInfo.

                    • 7. Re: Injecting a field value
                      alesj

                       

                      "alesj" wrote:

                      We don't have any special static handling (via xml or BMDB).

                      Apart from constructor::factory.

                      • 8. Re: Injecting a field value
                        dmlloyd

                        Consider the case where a constructor takes an enum or an enum-like object - object identity is significant, but there may or may not be a way to get the value from a factory method. The object would be known publicly only because it is declared as a public constant. The most obvious mechanism to me is a ValueMetaData that is comprised of a class and a field name.

                        Make sense?

                        • 9. Re: Injecting a field value
                          alesj

                          A simpler use case would be constants in an interface. ;-)

                          • 10. Re: Injecting a field value
                            dmlloyd

                            Exactly...

                            • 11. Re: Injecting a field value
                              alesj

                               

                              "david.lloyd@jboss.com" wrote:
                              The most obvious mechanism to me is a ValueMetaData that is comprised of a class and a field name.

                              The most obvious is value-factory:
                               <bean name="ConstantsProvider" class="org.jboss.demos.ioc.access.ConstantsProvider">
                               <constructor>
                               <parameter>org.jboss.demos.ioc.access.IConstants</parameter>
                               </constructor>
                               </bean>
                              
                               <bean name="XConstUser2" class="org.jboss.demos.ioc.access.XConstUser">
                               <property name="x"><value-factory bean="ConstantsProvider" method="getConstant" parameter="X_INT_VALUE"/></property>
                               </bean>
                              
                              public class ConstantsProvider
                              {
                               private KernelConfigurator configurator;
                               private String className;
                               private ClassInfo classInfo;
                              
                               public ConstantsProvider()
                               {
                               }
                              
                               public ConstantsProvider(String className)
                               {
                               this.className = className;
                               }
                              
                               @Inject(bean = KernelConstants.KERNEL_CONFIGURATOR_NAME)
                               public void setConfigurator(KernelConfigurator configurator)
                               {
                               this.configurator = configurator;
                               }
                              
                               public void create() throws Throwable
                               {
                               if (configurator == null)
                               throw new IllegalArgumentException("Null configurator");
                              
                               if (className != null)
                               classInfo = configurator.getClassInfo(className, getClass().getClassLoader());
                               }
                              
                               public Object getConstant(String constantName) throws Throwable
                               {
                               if (classInfo == null)
                               throw new IllegalArgumentException("Cannot execute constant lookup on null class info.");
                              
                               return getConstant(classInfo, constantName);
                               }
                              
                               public Object getConstant(String className, String constantName) throws Throwable
                               {
                               ClassInfo classInfo = configurator.getClassInfo(className, getClass().getClassLoader());
                               return getConstant(classInfo, constantName);
                               }
                              
                               protected Object getConstant(ClassInfo classInfo, String constantName) throws Throwable
                               {
                               if (constantName == null)
                               throw new IllegalArgumentException("Null constant name");
                              
                               FieldInfo field = classInfo.getDeclaredField(constantName);
                               if (field == null)
                               throw new IllegalArgumentException("No such constant: " + constantName + ", class info: " + classInfo);
                              
                               return field.get(null);
                               }
                              }
                              


                              I can add this as part of Kernel,
                              probably next to BeanMetaDataBuilder.

                              • 12. Re: Injecting a field value
                                dmlloyd

                                Ah, I get it. One thing though - shouldn't the class be loaded from the classloader of the deployment? If you have just one ConstantsProvider for all deployements and it's just using its own classloader, one would think there might be problems when it is used by another deployment.

                                • 13. Re: Injecting a field value
                                  alesj

                                  Sure.
                                  I never said this was _not_ pseudo code. :-)
                                  But I think you get my drift.