10 Replies Latest reply on Jan 17, 2007 4:57 AM by starksm64

    Bean definition as value add problem (JBMICROCONT-28)

    alesj

       

      <bean bean="xxx">
       <property name="blah">
       <bean bean="yyy">
      ...
      


      How to actually add this bean into KernelDeployment?

      As I can see this is currently the only way we are setting BeanMD into KernelDeployment:
       AbstractKernelDeployment deployment = (AbstractKernelDeployment) parent;
       AbstractBeanMetaData bean = (AbstractBeanMetaData) child;
       List<BeanMetaDataFactory> beans = deployment.getBeanFactories();
       if (beans == null)
       {
       beans = new ArrayList<BeanMetaDataFactory>();
       deployment.setBeanFactories(beans);
       }
       beans.add(bean);
      




        • 1. Re: Bean definition as value add problem (JBMICROCONT-28)

          getBeanFactories() should return both beans
          it should affectively be:

          <bean name="xxx">
           <property name="blah">
           <inject bean="yyy"/>
          
          <bean name="yyy">
          


          Additionally, it should be possible to not have a name
          for the internal bean which would translate

          <bean name="xxx">
           <property name="blah">
           <bean/>
          


          to something like

          <bean name="xxx">
           <property name="blah">
           <inject bean="GUID"/>
          
          <bean name="GUID">
          


          Of cource, GUID (globally unique id) could be more meaningul
          in some cases e.g. above xxx$blah for the simple property injection above.

          • 2. Re: Bean definition as value add problem (JBMICROCONT-28)
            alesj

            Probably a simple

             public List<BeanMetaData> getBeans()
             {
             List<BeanMetaData> allBeans = new ArrayList<BeanMetaData>();
             addBeans(this, allBeans);
             return allBeans;
             }
            
             protected void addBeans(MetaDataVisitorNode current, List<BeanMetaData> list)
             {
             for(Iterator<? extends MetaDataVisitorNode> children = current.getChildren(); children != null && children.hasNext();)
             {
             MetaDataVisitorNode next = children.next();
             if (next instanceof BeanMetaDataFactory)
             {
             list.addAll(((BeanMetaDataFactory) next).getBeans());
             }
             else
             {
             addBeans(next, list);
             }
             }
             if (current instanceof BeanMetaData)
             {
             list.add((BeanMetaData) current);
             }
             }
            


            will do. ;-)

            I also made ClassLoaderMetaData as BeanMetaDataFactory.

            • 3. Re: Bean definition as value add problem (JBMICROCONT-28)
              alesj

               

              "adrian@jboss.org" wrote:

              Additionally, it should be possible to not have a name
              for the internal bean which would translate


              Where to set the name?

              Since I only know in MetaDataVisitor.initialVisit() if BeanMetaData is a child MD (visitorStack is not empty) and what are its previous nodes.
              But that is too 'late' - since I already need a name in AbstractKernelControllerContext instatiation.

              I can set the name before - still in MD construction - but I would be unaware of parent-child relationship (also allowing null name on root bean) and property-parent_name (to create a meaningful name).

              • 4. Re: Bean definition as value add problem (JBMICROCONT-28)

                This has nothing to do with the intitalVisit()
                which is invoked when you register the context.

                This is about constructing multiple contexts from a single BeanMetaData.

                The code should be in AbstractBeanMetaData::getBeans();

                Some thing like (psuedo code)

                public List<BeanMetaData> getBeans()
                {
                 if (noNestedBeans)
                 return Collections.singletonList(this);
                 else
                 {
                 List<BeanMetaData> result;
                 result.add(deepCloneBeanMetaData()); // Don't modify what the user gives us
                 for (BeanMetaData nested : nestedBeans)
                 {
                 generateGUIDIfNoName();
                 replaceWithInjection();
                 result.add(whatWasReplaced);
                 }
                 return result;
                 }
                }
                


                • 5. Re: Bean definition as value add problem (JBMICROCONT-28)
                  alesj

                   


                  result.add(deepCloneBeanMetaData()); // Don't modify what the user gives us


                  Probably need writing the whole deepClone stuff for meta data?


                  generateGUIDIfNoName()


                  Ok, but the name then cannot be obtained from previous nodes information.


                  replaceWithInjection();


                  Why replacing it with injection?
                  What's the issue with current impl - with plain dependency - which is similar to injection?
                  Ok, if I set the name, then I must at least deep clone it?

                  • 6. Re: Bean definition as value add problem (JBMICROCONT-28)

                     

                    "alesj" wrote:


                    generateGUIDIfNoName()


                    Ok, but the name then cannot be obtained from previous nodes information.


                    Why not (the above is pseudo code that ignores at lot the impl details)?
                    You needs the previous node so you do setValue(injection);

                    When it is not a property, I'd suggest using something like
                    OuterBeanName$N where N is the number as you iterate through
                    the metadata.



                    replaceWithInjection();


                    Why replacing it with injection?
                    What's the issue with current impl - with plain dependency - which is similar to injection?
                    Ok, if I set the name, then I must at least deep clone it?


                    Because it is an injection. You are saying inject the value of
                    this bean into the outer bean once the bean is fully installed.
                    See the original examples I posted.

                    • 7. Re: Bean definition as value add problem (JBMICROCONT-28)
                      starksm64

                      So did we end up supporting this anonymous inner bean syntax? Its a bit tedious to have to reference another bean when the bean really is a contained entity with a lifecycle bound to the bean into which its being injected.

                      • 8. Re: Bean definition as value add problem (JBMICROCONT-28)
                        alesj

                        This is done half way.
                        No cloning at the moment.
                        But you can define inner beans, with a full bean name.
                        And they can be referenced from other beans.

                        • 9. Re: Bean definition as value add problem (JBMICROCONT-28)
                          starksm64

                          I could actually use the wildcard support to use the javabean schema if the javabean schema supported non-default constructors like this:

                           <bean name="DsXmlDataSourceTemplateInfo"
                           class="org.jboss.profileservice.management.plugins.BasicDeploymentTemplateInfo">
                           <constructor>
                           <parameter>DsXmlDataSourceTemplate</parameter>
                           <parameter>A template for *-ds.xml deployments</parameter>
                           </constructor>
                           <property name="properties">
                           <set>
                           <javabean xmlns="urn:jboss:javabean:1.0"
                           class="org.jboss.test.javabean.support.SimpleBean">
                           <constructor>
                           <property>jndi-name</property>
                           <property>the jndi name to bind the DataSource under</parameter>
                           </constructor>
                           <property name="manadatory">true</property>
                           </javabean>
                           </set>
                           </property>
                           </bean>
                          


                          I'm going to take a look at adding that support. I'll make this a urn:jboss:javabean:2.0 version schema.


                          • 10. Re: Bean definition as value add problem (JBMICROCONT-28)
                            starksm64

                            support for javabean ctors is working:

                            <javabean xmlns="urn:jboss:javabean:2.0"
                             class="org.jboss.test.javabean.support.SimpleBean">
                             <!--
                             public SimpleBean(Object anObject, String string, Byte byte1,
                             Boolean boolean1, Character character, Short short1,
                             Integer anInt, Long long1, Float float1, Double double1,
                             Date date, BigDecimal bigDecimal, BigInteger bigInteger,
                             byte abyte, boolean aboolean, char achar, short ashort,
                             int anint2, long along, float afloat, double adouble,
                             Number number, String overloadedProperty, String xyz, String abc)
                             -->
                             <constructor>
                             <!-- The name is not used for parameter matching, its just for info -->
                             <property name="anObject">anObjectValue</property>
                             <property name="AString">StringValue</property>
                             <property name="AByte">12</property>
                             <property name="ABoolean">true</property>
                             <property name="ACharacter">x</property>
                             <property name="AShort">123</property>
                             <property name="anInt">1234</property>
                             <property name="ALong">12345</property>
                             <property name="AFloat">3.14</property>
                             <property name="ADouble">3.14e12</property>
                             <property name="ADate">Jan 01 00:00:00 CET 2001</property>
                             <property name="ABigDecimal">12e4</property>
                             <property name="ABigInteger">123456</property>
                             <property name="abyte">12</property>
                             <property name="aboolean">true</property>
                             <property name="achar">y</property>
                             <property name="ashort">123</property>
                             <property name="anint">1234</property>
                             <property name="along">12345</property>
                             <property name="afloat">3.14</property>
                             <property name="adouble">3.14e12</property>
                             <property name="ANumber" class="java.lang.Long">12345</property>
                             <property name="overloadedProperty">StringValue</property>
                             <property name="XYZ">XYZ</property>
                             <property name="abc">abc</property>
                             </constructor>
                            </javabean>
                            


                            I'm not able to check these changes in currently though as svn seems to still be down from the upgrade effort.