JavaEJBConsuming and Binding EJBs and Data in Creator

Consuming and Binding EJBs and Data in Creator

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

This article is the third and final in a series detailing the integration of Java Studio Creator into an existing software development process. In the example that has formed the basis for these articles, the architecture uses an EJB API that can be deployed to the Sun Application Server embedded in Creator and then consumed within Java Creator Studio itself. The previous two articles, Integrating Sun Java Studio Creator Into Your Development Process
and Deploying and Consuming EJBs in Java Studio Creator, covered first the creation of suitable EJB archives for use in Creator, and then the deployment and consumption within Creator.

This final article details how you can use the EJBs and the data returned from them to bind into on-page controls within Creator, thus seeing the fruits of your labor. There are a number of basic approaches covered for binding in the data, and some specific details and notes on that usage within Creator.

This article refers to example code that is available from the NewEnergy Associates Web page at the following locations:

The EJB example project was constructed using Oracle’s JDeveloper 10.1.2, available free for educational use after registration from http://www.oracle.com/technology/products/jdev/index.html. Make sure you get the 10.1.2 version to compile this project, not the newer early access version of 10.1.3 because it is untested with that version.

Because the aim here is to illustrate the EJB binding into Creator, the example jar is kept purposely simple and has no persistence and no error checking (it will be easy to cause NPEs in this demo, but I prefer clarity of the code in this case—persistence and error trapping are left as an exercise for the reader). Instead of persistent data, the EJB jar file uses static data to return results.

Preparation

Download at least the EJB EAR file and Client Jar from the link given above and unzip the file. You should find one EAR and one JAR inside.

The deployment process to the app server and the consumption in Creator are detailed in the previous article, but a quick recap of the steps is:

  1. Start Creator, and from within Creator, start the Deployment Server.
  2. Run the deploy tool from the SunAppServer8/bin directory under your Creator install directory.
  3. Open the EAR file downloaded above in the deploy tool.
  4. Deploy (Tools->Deploy) the EAR into the Creator App Server (the localhost:14848) choice. Check the Return Client Jar if you want, but I have included the client jar file created by that in the zip file you downloaded.
  5. When the EAR has been deployed successfully, close the deploy tool and in Creator, import the client jar file. (Right-click Enterprise Java Beans and select Add Set of Session EJBs.)
  6. In the dialog, fill in the values and add the client jar file. Remember to set the port to 13700, and fill in something meaningful for the name. An example screenshot is provided below:
  7. After you click OK, you should see a new CreatorDemo entry in the list of Enterprise Java Beans section. Expand this new entry and further expand each of the three EJBs in there; you should see several methods on each EJB, like this:
  8. If you see the above, the EJBs are ready for use in Creator, so you can use them.
  9. The final step: Create a new project from the Creator welcome screen. This will be your demo application, so name it what makes sense to you.

Simple Data Usage

First, examine the simplest level of data binding and EJB usage within Creator. The example page you will set up will allow the user to type in a number (between 1 and 3 because those are the company IDs I have provided; anything else will result in a error). After the number is accepted, the name and annual income for that company will be displayed on the screen as text labels.

Create a new page in Creator and call it something like SimpleBinding. Then, do the following:

  1. Drag an Output Text on to the page and change the text to read “Enter company ID.”
  2. Drag a Text Field next to it, and rename the text field to companyId. (It’s good practice to rename any controls you will manipulate from the java page bean because it makes it easier to figure out which control to use.)
  3. Right-click on the new text field and check the “Auto submit on change” option.
  4. Add two more Output Text controls, and rename them to companyNameText and companyIncomeText respectively. These will be the output fields.
  5. Your page should look something like this:
  6. You need to make a reference to the EJB you are going to use. Drag and drop the SimpleDemoEJB from the Enterprise Java Beans section in the server navigator onto the page somewhere. You should see a new reference, called SimpleDemoEJBClient1, appear at the bottom of the page.
  7. Now, double-click on the companyId Text Field. This should drop you through to the page bean in a new method called companyId_processValueChange. You are going to use this method to update the output fields on the page using the EJB reference you just created.
  8. In the body of the newly created method, add the following code:
  9. // first get the company ID typed in by the user
    String id = (String)this.getCompanyId().getValue();
    
    // use the EJB to look up the name and income for the company
    try {
       String name = this.simpleDemoEJBClient1.getCompanyNameForID(id);
       double income = this.simpleDemoEJBClient1.
                       getAnnualIncomeForCompanyId(id);
    
       this.getCompanyNameText().setValue(name);
       this.getCompanyIncomeText().setValue(new Double(income));
    }
    catch(RemoteException rex) {
       throw new FacesException(rex);
    }
    catch(NamingException nex) {
       throw new FacesException(nex);
    }
    catch(CreateException cex) {
       throw new FacesException(cex);
    }
    
  10. Some notes about the code above: In this case, I wanted to demonstrate the minimum exceptions that must be caught for an EJB remote method; these are RemoteException, NamingException and CreateException. This pattern can be put into a code clip (see the tips section), or you could choose to catch a more general exception and handle it instead of handling the three separately. Note also that you just use the simpleDemoEJBClient1 reference. All lookup and narrowing of the EJB has been handled for you by Creator. It makes life with EJBs very easy.
  11. When you paste in the code above, you may get several lines that do not compile because of classes that are not imported. Position the cursor in the underlined word and right-click; then choose the fast import option. This will give you the option of importing the class or the entire package. (I tend to import the package mostly because if I use one class from a package, I normally need several from the same package.) This will add the import statements automatically to the beginning of the file. Keep using this option until all of the underlined classes are gone.
  12. Next, compile the project, and then run it. You should get a screen that accepts a number; type in 1, 2 or 3 and you should see details come back about the company with the ID you typed in.

This is an example of the simplest way of using and binding data from an EJB API into Creator. In fact, depending on how you look at it, you are not really binding anything, merely using the results of the EJB methods to set values on the page. In essence, you are providing your own binding to the page, setting values, and potentially reading values back in and applied through other EJB calls (beyond the scope of this article, but I am sure you can work out the details).

You are also dealing with the easiest kind of data, scalars, and simple classes like String. What about if you want to return and bind more sophisticated data?

Tips
  • Fast Import: When coding, quite often you reference a class that you have not imported yet. When this happens, right-click on the underlined class and select the Fast Import option. You then can chose the class or package to import from a selection list.
  • Code Clips: Code that is often repeated is a prime candidate to make a snippet. To create a snippet, select the area of code in question and then drag it across to the code-clips pane in the palette. This will create a new code clip with a generic name. Right-click on it to change the name. Also, if there is non-general code in the code clip that you want to remove, right-click on the clip and edit it. For example, the try…catch block used for EJB calls is a prime candidate for a code clip. Make the clip, and then pull out the body of the try { } block because that will change for each usage. Doing this will save time on EJB calls by not having to write all of the catch clauses each time.
  • Start Page: When developing a page, it is convenient to jump straight to that page when running the app. To do this, right-click on the page jsp in the project navigator and select the “Set as Start Page” option.

Binding Lists and Tables using Collections and Arrays

So far, you have a working EJB API and a simple screen, but it’s not very exciting and also not very representative of any real-world usage. You can up the ante by adding a new page with a table of company details in it. The page will use the an EJB method that returns a two-dimensional array of Strings with the details in it, and you will bind the details into the table and display them.

To create the page:

  1. In the navigation view, add a new page. Call it something like ArrayBinding.
  2. In the project navigator, right-click on the new page and select “Set as Start Page.”
  3. Open the page, and then drag a Data Table control into it.
  4. The data you are binding in has five fields in each row in the string array. The data in these rows (in order) is: companyId, companyName, formedDate, annualIncome, and numberOfEmployees.
  5. Right-click on the table and select table layout. (Note: You need to select the whole table to see the table layout option. Click on the table repeatedly until the whole table is outlined.)
  6. In the Table Layout dialog, remove the columns that are already defined, then define 5 new ones. For the new columns, fill in (for the Header and Value fields respectively):
  7. Heading Value
    Company ID #{currentRow[0]}
    Company Name #{currentRow[1]}
    Formed #{currentRow[2]}
    Annual Income #{currentRow[3]}
    No. Of Employees #{currentRow[4]}

  8. The above Value setting binds in the current row elements by index name using the JSP 2.0 Expression Language.
  9. Next, you need to bind the array returned from the EJB method into the table. First, drag the CollectionDemoEJB onto the page so that it makes a reference.
  10. Make a property on the page. To do this, there are actually two ways to do this. I am going to use the quicker way:
    • Using the project explorer, open the Java Sources section of the tree, expand out the default package, and find the ArrayBinding.java file. Expand this class, and keep expanding until you see a node that reads “Bean Patterns.”
    • Right-click on the Bean Patterns node and then choose Add->Property.
    • When the dialog comes up, set the property name to be companyDetails and the type to be String[][].
    • Hit OK.

    What this has actually done is to create a companyDetails attribute, and a getter and setter for it. You could have accomplished the same by adding the attribute and accessor/modifier yourself, but this way is a little faster.

  11. Now, you need to load the data into the new property in the class constructor. Right-click on the page and select Edit ArrayBinding Java Source; then, go to the Constructor and add the following code after the comment about adding additional code here:
  12. try {
        this.companyDetails = this.collectionDemoEJBClient1.
                              listCompanyDetails();
    }
    catch (RemoteException rex) {
        throw new FacesException(rex);
    }
    catch (NamingException nex) {
        throw new FacesException(nex);
    }
    catch (CreateException cex) {
        throw new FacesException(cex);
    }
    
  13. Save and compile the new code. Remember to use the fast import option to add necessary import statements.
  14. Switch back to the jsp page and click on the table until the whole table is selected. Then, look in the properties and find the Value field; click on the … button at the side.
  15. In the dialog that comes up, Select the Bind to an Object tab and find the companyDetails String[][] property you just created. Select that and the binding is made.
  16. Now, run the page. You should see a list of three companies details in the Data Table.

Any list or array type can be bound into a data table in this manner. The iterator value will be whatever the elements of that list or array are in order (the default name for the iterator in the table is currentRow). How you use the data from the iterator is of course up to you and you can hit problems with array bounds exceptions or (as you will see below) bean properties that are incorrectly named.

What you have done here is bound a very simple grid of strings into a datatable. The approach is simplem but has a number of limitations. Firstly, the 2d array of Strings can only represent String data, while the datatable control can actually deal with more than just string data. Also, the expressions used to access the data in the table are not very friendly—you need to know the field positions of data in the array columns, for example. One approach to improving this might be to use a HashTable or HashMap to both name the data fields and allow non-string objects to be used.

The EL (Expression Language) to access a HashMap entry would be:

#{currentRow['myfield']}

Instead of using a numerical array index, you use the string key to access the field in the Map. However, an even richer and easier way of accessing data in the DataTable, and for that matter other controls in Creator exists, is that of using serializable beans.

Binding Serializable Objects

By making EJB methods return either Serializable beans, or collections of such beans, you are able to get structured data back to the client from the EJB. The SerializedDemoEJB is an example of doing this.

This is the culmination of the binding process, and you are going to build a moderately complex page for this last one. As a result, the steps will be slightly less detailed. Refer to the previous examples if you get stuck on a particular step.

For this page, you will create a pulldown menu of company names to IDs, a section of information about the company, and then a table of employee details for that company.

  1. Create a new page. Call it CompanyDetails, and set it as the start page.
  2. Open the page, add a dropdown list called companySelect, and text labels and fields for Company Name, Company Formed, Annual Income and Number of Employees. Name the output text fields something meaningful in each case.
  3. Add a data table.
  4. The resulting screen before binding should look something like this:
  5. One by one, drag a reference to the CollectionDemoEJB and SerializedDemoEJB onto the page.
  6. Locate the CompanyDetails.java node in the project navigator, expand until you see the Bean Patterns, and add the following properties to the Bean Patterns:
    • property companyNameList of type java.util.Map
    • property currentCompany of type com.wallsoft.creator.demo.ejb.Company
    • property employeeDetails of type java.util.List
  7. Right-click on the page and Edit CompanyDetails Java Source.
  8. In the CompanyDetails.java source file, add the following code to the constructor:
  9. try {
       this.companyNameList = this.collectionDemoEJBClient1.
                              getCompanyMap();
       if(this.currentCompany == null) {
          this.currentCompany = 
             this.serializedDemoEJBClient1.getCompanyForId(
                 (String)this.companyNameList.values().iterator().
                         next());
          this.employeeDetails = this.currentCompany.
                                 getEmployees();
    }
    }
    catch(RemoteException rex) {
       throw new FacesException(rex);
    }
    catch(NamingException nex) {
       throw new FacesException(nex);
    }
    catch(CreateException cex) {
       throw new FacesException(cex);
    }
    
  10. What you are doing with this code is setting the map you will use in the dropdown menu, and initializing the current company to the first in the list if it is not already initialized.
  11. Go back to the JSP Page view and highlight the dropdown list. Look in the Application Outline pane (bottom right) and expand the dropdown list node. Select the dropdown1SelectItems node and, in the properties, click the value … button. (Note: You have to bind the value of the dropdown1SelectItems for the list, not the value of the list itself. Binding the value for the list sets the selected value, not the possible selections.)
  12. In the dialog, go to the Bind to an Object tab and then find and select the companyNameList property for the CompanyDetails bean. This will bind it to the map you retrieved in the above code.
  13. Right-click on the dropdown list and check the “Auto submit on change” option.
  14. Double-click on the dropdown list to go through to the event handler for the selection being changed.
  15. Replace the TODO comment with the following code:
  16.    try {
          this.currentCompany = 
             this.serializedDemoEJBClient1.getCompanyForId(
                     (String)this.companySelect.getValue());
          this.employeeDetails = this.currentCompany.getEmployees();
       }
       catch(RemoteException rex) {
          throw new FacesException(rex);
       }
       catch(NamingException nex) {
          throw new FacesException(nex);
       }
       catch(CreateException cex) {
          throw new FacesException(cex);
       }
    }
    
  17. The above code gets the value from the dropdown list for the selected entry, and using that to do the lookup of the company details in the EJB.
  18. Go back to the JSP page, and select each of the four output text fields in turn, using the value … button in the properties. Bind them to the relevant fields in the currentCompany property for the page. Note that you can expand the currentCompany bean to see the properties in it; bind the correct properties to the text fields.
  19. Select the whole table, and go to the value … button. In the dialog, select the CompanyDetails employeeDetails property. The use of the separate employeeDetails property should not really be necessary, but there appears to be a bug in Creator at present where binding currentCompany.employees into the table will not work. Putting it into an intermediate property on the class works and is an easy workaround.
  20. Right-click on the table and select layout. Hint, navigating to the Library References and finding the Employee class in the CreatorDemoClient library will show you the properties available on that class and makes binding in the table easier because you can see the properties available.
  21. Set up the following columns for the table:
    • Header Text:ID, Value: #{currentRow.employeeId}
    • Header Text:Name, value: #{currentRow.name}
    • Header Text:Hired, value: #{currentRow.hireDate}
    • Header Text:Salary, value: #{currentRow.salary}
  22. Save and build; then run. The page should work to allow a company to be selected from the list, and update the details on the page based on the selection.

Conclusion

In this, the final article of three about integrating Creator into an existing development process using EJB APIs to provide a wrapper around the business logic, you have seen the fruits of your labors from the previous articles. Creating and obtaining data through the EJB APIs is only a part of the problem; the data must then be displayed and bound into a Creator GUI (this is, after all, the point of the exercise). This article has detailed increasingly sophisticated methods of displaying and binding data in Creator.

While not covered explicitly in this article, it should be but a step to send updates back through an EJB API to affect the underlying data. (Hint, binding properties in beans causes modifiers to be used automatically when a value changes, and then pass the altered bean back into an EJB API call to update the data it is based on.)

If you have trouble with any of the examples, download and look at the CreatorDemoApp.zip file (see links at the top of this article). A working project with all three examples ready to run in it is there. This should help you find the problems with your own project.

About the Author

Dick Wall is a Lead Systems Engineer at NewEnergy Associates, a Siemens Company based in Atlanta, GA that provides energy IT and consulting solutions for decision support and energy operations. He can be reached for comment on this and other matters at dick.wall@newenergyassoc.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories