Skip navigation

I presented this demo at DevNexus 2014 in Atlanta today.  It is Reza's demo with just a pinch more Java EE thrown in.  This blog entry covers how to fully internationalize an AngularJS application with just a pinch of Java EE.

 

Reza hosts the code for this demo on his github.  The demo has a chat client and a todo list.  This blog entry only looks at the chat client, and assumes basic familiarity with AngularJS.  The content is broken up into two parts, the first part shows how to localize an Angular JS app using the locale support of Java EE.  The second part, to be published at a later date, shows how to apply Facelets templating to accomplish page modularity on top of AngularJS.

 

The first pinch of Java EE

 

Reza is using basic authentication to give the chat app a quick concept of user identity.  Java EE basic authentication is documented in the Java EE tutorial.  Assuming the app has been configured for basic authentication, any JSP or Facelets page can be an AngularJS application and take advantage of that identity with a simple EL expression.  The first inline script block of chat.jsp is the following:

 
          
  1. <script type="text/javascript">
  2. var principal = '${pageContext.request.userPrincipal.name}';
  3. </script>
          
 

Using Facelets, you can get the same effect with this code from chat.xhtml:

             
          
  1. <script type="text/javascript">
  2. var principal = '#{request.userPrincipal.name}';
  3. </script>
          
  

In both the JSP and Facelets cases, we take the name of the currently logged in user and stick it in a JavaScript top level variable.  Later, in the AngluarJS controller for this demo, controllers.js we expose that value on the controller scope: $scope.user = principal;

 

There is one other bothersome restriction when using Facelets.  It must be well formed XML.  This means you must write:

            
          
  1. <input class="textbox" placeholder="#{i18n.placeholderMessage}"
  2.       ng-model="newMessage" autofocus="autofocus" required="required" />
          
 

instead of

 
          
  1. <input class="textbox" placeholder="#{i18n.placeholderMessage}"
  2.       ng-model="newMessage" autofocus required >
          
 

If this is a dealbreaker for you, just don't use the Facelets part and stick to JSP.  You can still localize just fine.

 

Localization in Java EE

 

Localization in Java EE is built on the simple ResourceBundle feature, which has been present in Java since 1996.  The average AngularJS developer (currently about 24 years old) would be six years old at that time.  This feature is documented in the Java tutorial.  To add localization to the UI of a Java EE application, you need to pull in the FacesServlet add a faces-config.xml file to your WEB-INF directory.  Pulling in the FacesServlet is easy, just make sure to access your .xhtml or JSP pages with the /faces prefix.  There are other ways to pull in the FacesServlet but they are beyond the scope of this blog entry. The faces-config.xml file must contain a <resource-bundle> and a <locale-config> element.  For Reza's example, this is:

            
          
  1. <?xml version='1.0' encoding='UTF-8'?>
  2. <faces-config version="2.2"
  3.    
  4.     <application>
  5.         <resource-bundle>
  6.             <base-name>i18n</base-name>
  7.             <var>i18n</var>
  8.         </resource-bundle>
  9.        
  10.         <locale-config>
  11.             <default-locale>en</default-locale>
  12.             <supported-locale>de</supported-locale>
  13.             <supported-locale>ar</supported-locale>
  14.         </locale-config>
  15.        
  16.     </application>
  17.    
  18. </faces-config>
  19.  
          
 

Line 7 declares the <application> element.  This element contains any application singleton declarations.  Lines 8 - 11 declare a ResourceBundle that can be accessed from any JSP or Facelets page in the app.  The <base-name> element, on line 9, declares the fully qualified class name of the ResourceBundle.  In Reza's app, this is the localized i18n file in the src/main/resources directory.  It is currently localized in en, ar, and de locales.  Line 10 declares the symbol under which the name=value pairs of the ResourceBundle are exposed via EL.  This means that anything in the i18n file is available like this:

            
          
  1. <label class="chat-label">#{i18n.welcomeMessage} {{user}}</label>
          
 

Lines 13 - 17 declare the locale configuration for this app.  Line 14 declares the default locale.  This is what will be used if the browser doesn't send any locale preference, or a match between the desired locale and supported locales cannot be found.  Lines 15 and 16 declare that this application additionally supports German and Arabic locales. The JSF specification requires the container must look at the preferences expressed by the browser and find the best fit, given the locale config of the application.

 

The only remaining consideration is to ensure the dir attribute on the HTML element is correctly set.  This is only necessary for languages that read right-to-left such as Hebrew or Arabic.  This can be accomplished with a simple EL expression.  This example is taken from the Facelets chat.xhtml file:

            
          
  1.      ng-app="chatApplication"
  2.      dir="#{facesContext.viewRoot.locale.language eq 'ar' ? 'rtl' : 'ltr' }">
          
 

The xmlns declaration on line 1 is required for Facelets.  It is not required for JSP.  Line 2 is the AngularJS application directive.  Line 3 is the EL expression that evaluates to rtl if the locale is Arabic, and ltr otherwise.

 

The Arabic localized chat looks something like the following.

  Arabic localized chat 

The follow-up entry will look at how to apply another pinch of Java EE to spice up your AngularJS application with localized page modularity.

I've been blessed with the opportunity to speak at DevNexus 2014.  This is my first time speaking at a DevNexus event and I'm excited at the opportunity to meet and learn from many top-name speakers currently practicing today.  As I planned out my time here are the sessions I've added to my calendar.

 

Day 1: Monday 24 February

       
            
  • 09:00 Welcome and Sven Peters Keynote, Hall A

                

    From the buzz        around his provocative "Don't use git" meme, I expect a great        wake-up presentation.

               
  •         
  • 10:30 Intro to Vert.x 2.0 Burr Sutter, Room 103

                It'll be nice see what Burr's up to, and he's presenting on           home turf.  Also, the results for           recent JavaEE           8 developer survey included some advice that we take a           look at Vert.x.  Well, here's a great chance.
  •                
  • 13:00 AngularJS Bootcamp, Raju Ghandi,  Ballroom F

               

    This is part 1 of a two-part workshop-type session.  This           technology was also recommended on the JavaEE 8 developer           survey.

               
  •         
  • 14:30 Node.js intro, Ted Neward, Ballroom B

  •         
  • 16:00 JavaEE 7 in Practice, Me, Ballroom C

               

    I'll be using           the CargoTracker           app to showcase some features in JavaEE 7.  Yes I will have           slides, likely using           the bullet-riddled           corpse anti-pattern.

               
  •         
  • 17:30 Mobile Frameworks Smackdown, Ballroom A

               

    I'm glad to see people are still using           the smackdown           meme.

               
  •         
  • 18:45 Recpetion, Jocks and Jills Sports Bar

  •        
 

Day 2: Tuesday 25 February

       
            
  • 09:15 Selling your Mobile App, Jamie Turner, Hall A

               

    I don't know Mr. Turner, but this one looks good.

               
  •         
  • 10:30 PhoneGap, Andrew Trice, Ballroom A

               

    PhoneGap is central to           Oracle's ADF           Mobile framework.  I want to see what pure PhoneGap is all           about.

               
  •         
  • 13:00 A New Approach to the UI for Distributed Apps,        Me, Room 103

               

    May as well           just see           the abstract.

               
  •         
  • 14:30 Retro Gaming with Lambdas, Stephen Chin, Ballroom C       

               

    After my talk, I'm sure I'll need a cool-down presentation.           This one looks interesting.  We'll see if Stephen gets me as           clued in to lambdas           as Mario           Fusco does.

               
  •         
  • 16:00 Automated Tools for Software Development, Laura        Moore, Ballroom F.

               

    Normally I focus           on Hudson,           but it'll be nice to see what Ms. Moore has to say.

               
  •         
  • 17:15 Closing Ceremony, Hall A

               

    Not sure what this will be, but perhaps the DevNexus folks           will take a cue from NFJS and give some stuff away.

               
  •           

This blog entry describes an unsupported process for overwriting the version of Mojarra that comes bundled in WLS 12.1.2 and beyond with an arbitrary version (from groupId org.glassfish artifactId javax.faces).

 

Sometimes it is necessary to upgrade the version of Mojarra that comes bundled in WebLogic Server with a different version, either newer or older.  One such usage: the Mojarra team at Oracle uses this process to ensure the in-container tests for WLS use the just-built Mojarra during continuous integration.  To support this, a profile is added to the top level pom.xml for the automated tests.  Though the primary purpose of this profile is to aid our own continuous integration builds, the profile can also be used for general purpose WLS instrumentation.

       
            
  1. You        may check out the        entire Mojarra source tree or just grab the top level        pom for the source line you require.

                    
  2.          
  3. Invoke the package goal, being careful to use the non-recursive mvn invocation.       

             

    mvn -N -Djsf.version=<version> -Dintegration.container.home=<MW_HOME> -Phudson-wls-prepare package

             

    This will cause the maven         artifact org.glassfish:javax.faces:<version> to be pulled from the local         maven repository (downloading if necessary), and applied on top         of whatever version of Mojarra is in the WLS installation         at MW_HOME.  Note that MW_HOME must be         the value as specified in the README.txt in the WLS installation         zip.

              
  4.        
 

This approach is entirely unsupported by Oracle and is only provided for testing purposes.  Instructions for reverting your WLS installation to the previous version are outside the scope of this blog entry.  The recommended practice is to re-install WLS.

Filter Blog

By date: