6 Replies Latest reply on Sep 5, 2011 6:52 AM by anonym365451

    Internationalisation does not work in nested composite component

      Hello everybody,

       

      I want to have own composite components. The texts should come from property files.

      I can use rich components within my components without any problem using +cc.resourceBundleMap+.

      e.g.

      {code}

       

      <rich:popupPanel id="myNestedRichPopupPanel"

              modal="true"

              resizeable="false"

              style="margin-left:6px;margin-right:6px;"

              width="300"

              onmaskclick="#{rich:component('myNestedRichPopupPanel')}.hide()">

              <f:facet name="header">

                  <!-- cc.attrs.header -->

                  <h:outputText value="#{cc.resourceBundleMap.headerText}" />

              </f:facet>

              <f:facet name="controls">

                  <h:outputLink value="#"

                      onclick="#{rich:component('myNestedRichPopupPanel')}.hide(); return false;">

                          X

                      </h:outputLink>

              </f:facet>

              <composite:insertChildren/>

              <br/>

              Additional text inside the popup:<br/>

              <h:outputText value="#{cc.resourceBundleMap.contentText}"/>

          </rich:popupPanel>

      {code}

       

       

      But if a pass a value to another of my components the value seems to be ignored. It is not set within my component bean.

       

      {code}

      <composite:implementation>

          <h:commandButton value="Open own composite component with nested rich:popupPanel">

              <rich:componentControl event="click" target="myNestedPopupPanel"

                  operation="show" />

          </h:commandButton>

          <br/>

          <my:popupPanel id="myNestedPopupPanel" header="#{cc.resourceBundleMap.headerText}">

              <composite:insertChildren/>

              <br/>

              Additional text inside the popup:<br/>

              <h:outputText value="#{cc.resourceBundleMap.contentText}"/>

          </my:popupPanel>

          ...

      {code}

       

      MyPopupPanel is as follows:

       

      The component definition:

      {code}

      <composite:interface componentType="MyPopupPanel">

          <composite:attribute name="header" required="true" type="java.lang.String" />

      </composite:interface>

       

      <composite:implementation>

          <rich:popupPanel id="#{cc.id}"

              modal="true"

              resizeable="false"

              style="margin-left:6px;margin-right:6px;"

              width="#{cc.width}"

              onmaskclick="#{rich:component(cc.id)}.hide()">

              <f:facet name="header">

                  <!-- cc.attrs.header -->

                  <h:outputText value="#{cc.header}" />

              </f:facet>

              <f:facet name="controls">

                  <h:outputLink value="#"

                      onclick="#{rich:component(cc.id)}.hide(); return false;">

                          X

                      </h:outputLink>

              </f:facet>

              <composite:insertChildren/>

          </rich:popupPanel>

      </composite:implementation>

      {code}

       

      The java class:

      {code}

      @FacesComponent(value="MyPopupPanel")

      public class RESUIPopupPanel extends UIComponentBase {

          private String header = "Default header text from Java class (should not appear)";

          //private String header = null;

       

          /**

           *

           */

          public RESUIPopupPanel() {

          }

       

          @Override

          public String getFamily() {

              return "javax.faces.NamingContainer";

          }

         

          public int getWidth() {

              return 350;

          }

       

          ... getter/setter of header

      }

      {code}

       

      A war file is attached. Sources should be included there.

      The index.xhtml page shows three buttons.

      The first button opens a popup as I want to implement it: a custom component nested within a surrounding custom component. There the header of the popup is not overwritten as expected.

      The second button opens a popup whose header is set to a hard coded text without usage of a property file.

      The third button opens a rich:popup instead of my own.

       

      Does anybody know what is wrong here?

       

      I am using richfaces 4.0.0 tested on tomcat7 and weblogic 10.3.5.

        • 1. Re: Internationalisation does not work in nested composite component

          I simplyfied my code to reproduce the problem.

          It does not work if the nested component interface has a component type.

           

          The index.xhtml contains only <my:test/>.

           

          test.xhtml:

          {code}

          <composite:interface>

          </composite:interface>

           

          <composite:implementation>

              This is text output in test.xhtml:<br/>

              <h:outputText value="#{cc.resourceBundleMap.headerText}"/>

              <br/><br/>

              Here the nested component:<br/>

              <my:popupPanel header="#{cc.resourceBundleMap.headerText}">

              </my:popupPanel>

          </composite:implementation>

          {code}

           

          This is the popupPanel.xhtml:

          {code}

          <composite:interface componentType="MyPopupPanel">

              <composite:attribute name="header"/>

          </composite:interface>

           

          <composite:implementation>

              This text should be the value of the attribute:

              <h:outputText value="#{cc.header}" />

          </composite:implementation>

          {code}

           

          My Java class:

          {code}

          @FacesComponent(value="MyPopupPanel")

          public class RESUIPopupPanel extends UIComponentBase {

              private String header = "Default header text from Class (should not appear)";

           

              // simple getter/setter...

          }

          {code}

           

          This is the output of my page:

          {code}

          This is text output in test.xhtml:

          This is my header text from properties file

           

          Here the nested component:

          This text should be the value of the attribute: Default header text from Class (should not appear)

          {code}

           

          Can anybody tell me, what's wrong here?

          • 2. Re: Internationalisation does not work in nested composite component

            The issue has nothing to do with internationalisation but with using EL within my component:

             

            {code:xml}

            <composite:implementation>

                Here the nested component (with hard written text):<br/>

                <my:popupPanel header="This is hard written text">

                </my:popupPanel>

                <br/><br/>

                Here the nested component (with text from variable):<br/>

                <c:set var="myText" value="This is text from variable"></c:set>

                <my:popupPanel header="#{myText}">

                </my:popupPanel>

            </composite:implementation>

            {code}

             

            If I pass hard written text to the attribute it is shown correctly (first popupPanel).

            If I pass text from a variable than the text is not set in my component bean (second popupPanel).

             

            Any help out there?

             

            regards,

             

            Tommy

            • 3. Re: Internationalisation does not work in nested composite component

              Now things work in my little example.

               

              I added a h:form to my page. With that I got an exception:

               

              javax.servlet.ServletException: Komponenten-ID j_idt6:j_idt8:j_idt11 wurde bereits in der Ansicht gefunden.

              javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)

              root cause

              java.lang.IllegalStateException: Komponenten-ID j_idt6:j_idt8:j_idt11 wurde bereits in der Ansicht gefunden.
                   com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)

               

              Richfaces prints out a complete trace of the component structure which helped me to find out which component was wrong.

              With that help I found out that I should give an ID to _all_ of my elements including outputText.

               

              The following does not work in my nested component:

               

               

              <composite:interface componentType="MyPopupPanel">

              </composite:interface>

               

              <composite:implementation>

                  Hello World

              </composite:implementation>

               

              The following does work:

               

               

              <composite:interface componentType="MyPopupPanel">

              </composite:interface>

               

              <composite:implementation>

                  <h:outputText id="text2#{cc.id}" value="Hello World" />

              </composite:implementation>

               

              I have to create an individual ID because the component is used more than once.

               

              I will integrate the solution into my greater application and let you all know.

              Maybe I will file a bug. I think that RichFaces should generate IDs successfully by itself for the Hello World-Example.

              • 4. Re: Internationalisation does not work in nested composite component

                the 'solution' results into another bug that I will put into JIRA.

                 

                A simple <div> inside my component is converted into a JSF element. RichFaces ist not able to generate unique ID's for these elements.

                So an exception does occur:

                 

                javax.servlet.ServletException: Komponenten-ID j_idt6:j_idt8:j_idt10 wurde bereits in der Ansicht gefunden.

                javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)

                root cause

                java.lang.IllegalStateException: Komponenten-ID j_idt6:j_idt8:j_idt10 wurde bereits in der Ansicht gefunden.

                com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)

                 

                 

                Attached a WAR file with my HelloWorld-Example.

                I run it within eclipse with Tomcat 7.0 and Mojarra 2.1.2 on Windows7_64Bit.

                 

                Attached also the logging in eclipse (complete exception stack trace and richfaces component structure output).

                • 5. Re: Internationalisation does not work in nested composite component

                  I added bug

                  https://issues.jboss.org/browse/RF-11122

                   

                  Here some more explanation about my application:

                   

                  index.xhtml uses composite component my:simpleLevel1 (found in resources\myJSFComponents\simpleLevel1.xhtml).

                  simpleLevel1 uses composite component my:simpleLevel2 twice (found in resources\myJSFComponents\simpleLevel2.xhtml).

                  simpleLevel2 is a composite component with a component bean (com.tsystems.res.SimpleLevel2ComponentBean extends UIComponentBase).

                  The implementation of simpleLevel2 is:

                   

                  <composite:implementation>

                      <div>

                          <h:outputText value="Hallo Welt"/>

                      </div>

                  </composite:implementation>

                   

                  So this <div> should be shown twice on the page but the exception occurs as mentioned earlier.

                   

                  I hope this helps to reproduce and fix the problem.

                  • 6. Re: Internationalisation does not work in nested composite component

                    Hello outside,

                     

                    I don't know if someone followed my discussion with myself.

                     

                    Today I found a workaround to the original intension of my question as titled.

                    First I wanted to use property files with composite components that can lay in the same directory as the component and can have the same name.

                    Usage with <h:outputText value="#{cc.resourceBundleMap.myKey}" />

                    With that I only get the content of the default localed property file.

                    There must be a bug in the Mojarra JSF implementation that I use (v2.1.2).

                     

                    A workaround is to use the property file mechanism the common way. Put property files somewhere in the classpath and use f:loadBundle.

                    I'm sad, because the possibility putting the files directly to the component I like much better (all is at one place). But I have to live with that.

                     

                    regards,

                     

                    Thomas

                    1 of 1 people found this helpful