oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Using WebObjects: More Practical Tips and Tricks
Pages: 1, 2

Put It to Use


You should now be able to build and run your application. When you receive the Login form, try:

  • Leaving the Username or Password fields empty.
  • Logging in using incorrect credentials.

When you decide to log in correctly, make sure you select the Assistant checkbox. Once you have received the Home Page, click on the Customize button. The D2WAssistant should launch in a new window. You then want to customize a List page for a User; a simple way to do so is to simply query for Users.

Display the Full Name

The D2WAssistant will then update to allow you to edit the current Rule(s). You should be able to select nameFull from the list of Properties. If you decide to Show nameFull, either click the Update or Save buttons to see your change reflected on the current page.

You'll notice D2W is displaying the property nameFull without prettifying it. You can change the display by simply selecting nameFull under the Show list and entering Full Name in the Display field:

But there's a more "global" way to accomplish it. For now, enter Full Name and save the changes.

A Helpful Rule

Although you can run the D2WAssistant while editing your .d2wmodel file, I choose not to in order to avoid overwriting or corrupting the file. So, to be safe, log out of your application. Locate and open the user.d2wmodel file in your project. You should now be editing your file using the Rule Editor application.

Since you'll probably want to display something other than a label like nameFull throughout your application, you can create a more generic Rule. To do so, simply select your new Rule, which has the Left-Hand Side argument of:

((task = 'list') and ( = 'User') and (propertyKey = 'nameFull'))

Remove the first argument: (task = 'list').

By simply removing the task argument, you've just enabled D2W to always display the Full Name label any time it needs to display a User's nameFull. In other words, any time a web page is created and that web page is going to display information obtained using a User's nameFull method, it will be labeled as Full Name. That's it ... I tried ... I don't know how else to explain it ... because I feel like I'm going in circles ... (Paragraph courtesy of Red Bull.)

Your Rule should now look something like this:

If you wanted to have a really generic Rule, you could even remove the = 'User' argument. You would then enable D2W to always display the label Full Name for every nameFull property. So, in the future, if you had a City class that had a nameFull property, D2W would implement this Rule just as it does for a User.

Run Through the Gap

Obviously, your User is pretty light on details. What if you wanted to contact a User? How would you do so? I'm partial to email.


Return to EOModeler and select your User Entity. You're not going to do anything too fancy here, just add another attribute and name it email. I took the lazy person's route and did a copy/paste using the username attribute, and simply renamed both the name and column.

Since you've now changed the schema of your User, you'll need to synchronize your EOModel and your database. As I discussed in the last article, how you synchronize your EOModel and your database is up to you. Please be aware you've now implemented a Login panel, so if you drop your table, you'll need to add a User to your database somehow.

Once you've made the change, go ahead and generate the Java file for your User again.

  1. Select the User Entity.
  2. Click the Java button .
  3. Click the Save As button (Do Not Overwrite or Merge).
  4. Rename the file to
  5. Replace the previous file.
  6. "Remove the wrench."

I realize these steps are fairly tedious for an application of this size, but you shouldn't have to change the schema of you model(s) too often.

Your nameFull method should have survived this minor onslaught. As your application grows, and the logic for each of your EOEnterpriseObjects becomes more complex, the Generation Gap pattern should prove quite beneficial. At the very least, you'll have a clean separation between code "owned" by EOModeler and code "owned" by you (or your employer).


Build and Run your application again. When logging in, select the Assistant checkbox. Choose to Customize, wait for the D2WAssistant to launch and then query for a User. You should ultimately receive a List page for a User.

In the D2WAssistant window, notice the email property is now available. Go ahead and select it and add it to the Show list. Directly to the right of the Show list is a popup button. This popup button will allow you to create a Rule to assign a reusable component, given these criteria (i.e., a List page, a User, and the email property). When you click on the popup button, you should be able to select a component named D2WDisplayMailTo.

By selecting this component, whenever a List page for a User needs to display the email property, it will be presented as a mailto: link. Therefore, clients will be able to simply click on a User's email address in order to compose and send email.


While still viewing the List page, you will be able to edit a User by clicking the Edit button . The D2WAssistant should update to reflect the fact you are now viewing an Edit page. Again, select the email property and add it to the Show list.

When you click on the Save button, in the D2WAssistant, you should notice your web page update. You can now edit a User's email address. Enter an appropriate address and click the Save button on the web page. You should then receive a List page.


Now, when viewing a List of Users you'll be able to send them an email with a simple mouse click.

When the address is clicked, your Mail application should launch and create an email addressed to the selected User.

For Fun

If you'd like, you can refactor your Login code (using Move Method) from to When doing so, you might wind up with a static method in your User class. In fact, your User class might look something like:

public static EOEnterpriseObject userForCredentials
	(EOEditingContext ec, String uid, String pwd)
 throws EOObjectNotAvailableException {
     EOEnterpriseObject aUser;
   // use with EOUtilities to query the database
     NSDictionary bindings;
   // used to determine which columns to query
     Object[] keys = {"username", "password"};
   // used to query the database rows
     Object[] values = {uid, pwd};

     if ((uid == null) || (uid.length() == 0) ||
   (pwd == null) || (pwd.length() == 0)) {
         throw new EOObjectNotAvailableException
	("Username and Password required.");

     aUser = null;
     bindings = new NSDictionary(values, keys);

     try {
         aUser = EOUtilities.objectMatchingValues(ec, "User", bindings);
     catch (EOUtilities.MoreThanOneException e1) {
         System.err.println("ERROR:  More than one User with username '" + uid +
         "' and password '" + pwd + "'.");
         throw new EOObjectNotAvailableException
		("Please contact a System Administrator.");
     catch (EOObjectNotAvailableException e2) {
         throw new EOObjectNotAvailableException
	("Your Login information was incorrect.");
     return aUser;

I will leave the Login implementation in to you.

Josh Paul is the founder and CEO of Aweli, a startup focused on digital video solutions, and the author of Digital Video Hacks. He has provided software and service solutions to entertainment production companies throughout Los Angeles and New York.

Return to Mac DevCenter