GETTING STARTED WITH WEBOBJECTS
Apple, NeXT, and the publishers have tried to make the information contained in this manual as accurate and reliable as possible, but assume no responsibility for errors or omissions. They disclaim any warranty of any kind, whether express or implied, as to any matter whatsoever relating to this manual, including without limitation the merchantability or fitness for any particular purpose.
Contents
Table of Contents Contents iii Keeping Track of Multiple Guests 47 Creating a Guest List 48 Preface 7 About WebObjects 9 About This Book 9 Where to Go From Here 10 Creating a Simple WebObjects Application 11 Creating a WebObjects Application Project 14 Choosing the Programming Language 16 Examining Your Project 17 Launching WebObjects Builder 18 Creating the Page’s Content 20 Adding Guests to the Guest List 50 Adding a Second Component 51 Using a Repetition 53 Adding the Finishing Touches 56 Clearing t
Adding the MovieDetails Page 92 Creating the MovieDetails Component 93 Storing the Selected Movie 93 Navigating from Main to MovieDetails 94 Designing MovieDetails’ User Interface 95 Adding Date and Number Formats 96 Navigating from MovieDetails to Main 96 Running Movies 97 Refining Your Model 97 Opening Your Model 97 Removing Primary and Foreign Keys as Class Properties 98 Adding Relationships to Your Model 99 Using the Advanced Relationship Inspector 102 Where Do Primary Keys Come From? 103 Setting Up a
Preface
About WebObjects WebObjects is an object-oriented environment for developing and deploying World Wide Web applications. A WebObjects application runs on a server machine and receives requests from a user’s web browser on a client machine. It dynamically generates HTML pages in response to the user’s requests. WebObjects provides a suite of tools for rapid application development, as well as prebuilt application components and a web application server.
Preface Where to Go From Here After you have worked through the tutorials in this book, you should have a good working knowledge of WebObjects. For more in-depth information about how WebObjects works, read the WebObjects Developer’s Guide. Other valuable information about WebObject is available online. You can access all online information through the WebObjects Home Page. It is located in your server’s document root, and you can access it at this URL: http://localhost/WebObjects/Documentation/WOHomePage.
Chapter 1 Creating a Simple WebObjects Application
This chapter introduces you to the basic concepts and procedures of developing WebObjects applications. You’ll develop, in stages, a simple application for the World Wide Web. The application you’ll write is called GuestBook. When you’ve finished the steps in this chapter, your application will have a single web page containing a form that allows users to enter their names, e-mail addresses, and comments. When the form is submitted, the application redraws the page with the user’s information at the bottom.
Chapter 1 Creating a Simple WebObjects Application Project Builder is an integrated software-development application. It contains a project browser, a code editor, build and debugging support, and many other features needed to develop an application. In this tutorial, you’ll learn to use Project Builder to: • • • Create a new WebObjects application project. Write scripts or compiled code to provide behavior in your application. Build and launch your application.
Creating a WebObjects Application Project 4. Click Browse. Choose WebObjects under the server’s document root. Type project name here. Click when finished. 5. In the Save panel, navigate to the DocumentRoot/WebObjects directory. DocumentRoot is your HTTP server’s document root, which you specified when you installed WebObjects. 6. Type the name of the project you want to create (GuestBook). 7. Click Save. The New Project panel shows the path you specified. 8. Click OK.
Chapter 1 Creating a Simple WebObjects Application 9. For Available Assistance, choose None. If you are developing an application that accesses a database, you may wish to use one of the levels of assistance that WebObjects provides. For more information on these options, see Chapter 3, “Creating a WebObjects Database Application” (page 59). Choosing the Programming Language WebObjects supports three languages: • • • Java Objective-C WebScript Java and Objective-C are compiled languages.
Examining Your Project Examining Your Project Project Builder displays a browser showing the contents of your project. The first column lists several categories of files that your project may contain. This section describes some of the most important files you’ll use. Your project’s components. Files in the selected component. Categories (“suitcases”) of project resources. 1. Select Web Components. The next column displays a list with one element, Main.
Chapter 1 Creating a Simple WebObjects Application 3. Select Classes in the first column of the browser. Your application’s Java classes. The Main component’s code goes here. You’ll see three files listed in the second column: • Main.java is a file that allows you to specify behavior associated with the component. You do this by writing code in Java (since you specified Java as the language when you created the project). You use Project Builder to edit this file. • Application.java and Session.
Launching WebObjects Builder 2. Double-click Main.wo in the second column. The application WebObjects Builder launches and displays a window entitled Main.wo. This represents your application’s Main component. Pop-up list switches editing modes Click to inspect selected element. These buttons change properties of selected elements. Click one of these buttons to create a specific element. Elements pop-up list switches buttons displayed to its right.
Chapter 1 Creating a Simple WebObjects Application This pop-up list allows you to switch between graphical editing mode and source editing mode. When you choose source editing mode, the text of your HTML template (Main.html) appears. It is a skeleton at this point, since the page is empty. As you add elements graphically, their corresponding HTML tags appear in this file. The HTML source for your component. Information about bindings is displayed here. The bottom pane shows your declarations (Main.
Creating the Page’s Content • Structures . Use these buttons to create paragraphs, lists, images, and other static HTML elements. This setting is the default. • Tables . Use these buttons to create and manipulate HTML table elements. • Dynamic form elements . Use these buttons to create form elements in which users enter information. WebObjects gives your application access to the data entered by users by allowing you to associate, or bind, these elements to variables in your application.
Chapter 1 Creating a Simple WebObjects Application Using the Inspector You use the Inspector window to set properties of the elements in your component. The Inspector’s title and contents reflect the element you’ve selected in the component window. 1. Click . A window titled Heading Inspector appears. It allows you to set the level of the heading. The element path. Click to inspect different elements in the hierarchy. Click here to set the heading level. 2. Click “1”.
Creating the Page’s Content Each element has its own Inspector that allows you to set properties appropriate for the element. The Page Attributes Inspector allows you to set properties such as the page’s title and its text color. Enter page’s title here. 4. Enter a title (such as My Guest Book, or something else of your choosing) in the Title text field. This is the title of the window that appears in your web browser when you run the application. 5. Close the Inspector window. 6.
Chapter 1 Creating a Simple WebObjects Application 1. To display the dynamic form elements buttons in the toolbar, choose from the Elements pop-up list. 2. Place the cursor on the line after the “My Guest Book” text and press Enter. 3. Click . WebObjects Builder adds a form element to your component. The triangle at the upper-left corner indicates that it is a dynamic form, as opposed to a static form.The gray border indicates the extent of the form.
Creating the Page’s Content The window should now look like this: Dynamic form elements buttons. Dynamic text field elements. Dynamic text area element. Rectangle indicates extent of form. Resizing the Form Elements The text fields and text area are a bit small, so you’ll resize them using the Inspector window. To inspect an element, you must first select it. Some elements (such as text fields and text areas) can be selected simply by clicking them; they appear with a gray line underneath.
Chapter 1 Creating a Simple WebObjects Application 1. Inspect the Name text field (that is, select the text field and open the Inspector window). Choose Static Inspector from this pop-up list. Enter rows and columns here. 2. Change the setting of the pop-up list at the upper right of the window from Dynamic Inspector to Static Inspector. All WebObjects elements have a dynamic inspector, that is, one that allows you to set bindings (you’ll work with bindings in the next section).
Binding Elements 5. Inspect the multi-line text area. In Text Area Inspector, you can set various attributes corresponding to those of a
Chapter 1 Creating a Simple WebObjects Application WebObjects Builder allows you to declare variables without having to edit your source file directly. At the bottom of the window there is a pull-down menu called Edit Main.java. It has three items: • Add Variable/Method allows you to add a key to your source file. A key can be either an instance variable or a method that returns a value.
Binding Elements Binding the Input Elements Each dynamic element contains several attributes. These attributes determine what happens when the element is displayed or when a form element is submitted. When you bind an element, you actually bind one or more of its attributes. For example, a WOText element (which represents a multi-line text area) is defined as having two attributes: • • value specifies the string the user enters in the text area. name specifies a unique identifier for the text area.
Chapter 1 Creating a Simple WebObjects Application The Inspector window comes to the front, displaying the bindings for the text area. The value attribute is automatically selected (since that is the one that is most commonly used in bindings). If you wanted to choose a different attribute to bind (you don’t at this time), you would simply select the binding of your choice. 2. Click Connect Variable.
Binding Elements 3. From the “Page returned” pop-up menu, select null. The value returned by an action method represents the next page (component) to be displayed. When you return null (or nil if using WebScript), the current page is redrawn. In a later task, you’ll see how to return a new component. 4. Click Add. The submit action appears below a horizontal line in the first column of the object browser. 5. Click submit in the object browser and drag the cursor to the submit button.
Chapter 1 Creating a Simple WebObjects Application Variable definitions. submit action method. Creating the Application’s Output So far, you have a way for the guest to enter information and a way for the application to store that information. Now, the application needs to do something with the information. For now, you’ll have the application simply display the same information the user entered, in a slightly different format. This allows you to verify that you have correctly received the data.
Creating the Application’s Output 2. Choose buttons. 3. Click from the Elements pop-up list to display the Structures to create a horizontal line (an
element). 4. Press Enter to add a blank line. 5. Select from the Elements pop-up list to display the Other WebObjects buttons. 6. Add a WOString element by clicking . A WOString is a dynamic element whose value is determined at run time. It is shown as a small rectangle surrounded by two icons. 7.Chapter 1 Creating a Simple WebObjects Application 10. Save your component. It should now look like this: Choose View Source File from this menu. In summary, when the user clicks the Submit button, a new request-response cycle begins. WebObjects stores the data entered in the dynamic form elements in the variables they are bound to (guestName contains the value in the Name field, email contains the value in the E-mail field, and comments contains the value in the Comments field).
Building and Running Your Application Building and Running Your Application 1. Make Project Builder active. A quick way to do this from WebObjects Builder is to choose View Source File from the pull-down menu at the bottom of the window. To build and launch your application, you use buttons in Project Builder’s toolbar. Click here to open the Launch panel. Click here to open the Project Build panel. 2. Click in the toolbar to open the Project Build panel. 3. Click in the Project Build panel.
Chapter 1 Creating a Simple WebObjects Application 6. Click in the Launch panel to launch your application. The Launch Panel displays a series of messages. If all goes well, you should see messages such as the following, which mean that your application is running successfully. Your web browser (such as Netscape Navigator or Internet Explorer) should launch automatically and load the correct URL for your application. If it doesn’t, do the next step; otherwise, proceed to step 8. 7.
Chapter 2 Enhancing Your Application
Duplicating Your Project In the previous tutorial, you learned how to create a web component that has input and output elements and how to bind these elements to variables and methods in your code. Now you’ll add some additional features to your project that move it a bit more in the direction of being a real-world web application. The application will: • Use a custom Java class to represent the data for a guest, rather than using three separate variables.
Chapter 2 Enhancing Your Application 4. Duplicate the GuestBook folder. On Windows NT, you can do this by selecting the folder, choosing Edit m Copy, then Edit m Paste. 5. Open the new folder (Copy of GuestBook) and double-click the project file PB.project. Project Builder opens a new browser window for this project. (Alternatively, you could have opened the project from within Project Builder by choosing Project m Open, then navigating to the project folder and selecting PB.project.) 6.
Creating a Custom Guest Class Creating a Custom Guest Class In the first chapter, you created individual variables to store a guest’s name, e-mail address, and comments. When keeping track of multiple guests, it’s more useful to encapsulate all the data for a guest as a single entity. You’ll do this by creating a Java class that contains the data for a single guest. 1. In Project Builder’s browser, select Classes in the first column. 2. Choose File m New in Project. Type name of class here. 3.
Chapter 2 Enhancing Your Application also a class, specifically a subclass of the class next.wo.Component (called WOComponent in WebScript or Objective-C). Java classes require a constructor to initialize an instance (or object) of a particular class whenever one is created. A constructor has the same name as the class and returns no value. Whenever your application creates a new Guest class, its instance variables are initialized with empty strings, which is the default value if the user enters no data.
Creating a Custom Guest Class 6. Double-click the row containing the value binding. This removes the binding for guestName you made previously and binds currentGuest.guestName to the value attribute. 7. Bind the other two input elements to currentGuest.email and currentGuest.comments. Creating a Table to Display the Output In the first chapter, you created three WOString elements to display the information the guest entered.
Chapter 2 Enhancing Your Application 6. Double-click the upper-left cell. You can now edit the contents of the cell. If you want to resume structure editing, click in the toolbar, which allows you to toggle between modes. (Alternatively, you can hold down the Control key and click in a different cell to enter structure-editing mode.) 7. Change the text in the cell to Name. 8. Open the Inspector. The Inspector presents a number of modifiable settings that apply to the table cell you’ve selected.
Creating a Custom Guest Class 11. Click in the component window, then press Tab. Pressing Tab when editing a table causes the contents of the next cell to the right to be selected (or the first cell of the next row if in the rightmost column). Pressing Shift-Tab moves in the opposite direction through the table. 12. Repeat steps 7 through 11 for the second and third cells of the top row. Label the middle column E-mail and set its width to 150 pixels.
Chapter 2 Enhancing Your Application The table should now look like this: 3. Save the Main component. Creating the Guest Object Earlier in this chapter, you created a Java class of type Guest and wrote a constructor for it. You also added a variable of that class, currentGuest, to the Main component. However, adding a variable in this way doesn’t actually create a new Guest object; you need to create one explicitly at some point in your code.
Keeping Track of Multiple Guests 4. Save Main.java. 5. Build and run your application. The application should work similarly to the first chapter, except that the guest’s data is displayed in a table at the bottom of the page instead of as plain text. At this point, your application still handles information from a single guest only; in the next section, you’ll keep track of multiple guests.
Chapter 2 Enhancing Your Application Before doing this, it is important to understand the scope and life span of variables in WebObjects: • Component variables, such as currentGuest, exist for the lifetime of the component. These variables are defined in the component (in this case, Main.java) and are accessible only by its methods. Each user that uses a component gets a separate instance of the variable.
Keeping Track of Multiple Guests You add this line. You add this line. You add these two methods. Note that there is one method already defined: Application, which is the constructor for the application object. The first line calls the constructor for Application’s superclass (which is the class WebApplication). The second line prints a message, which you see in the Launch panel when you launch your application. 2.
Chapter 2 Enhancing Your Application 3. At the top of the Application class definition, enter this declaration: protected MutableVector allGuests; This declares allGuests to be of type MutableVector. Declaring it protected means that it is accessible only from this class or one of its subclasses. It is standard object-oriented practice for a class to prevent other classes from directly manipulating its instance variables.
Adding a Second Component Adding a Second Component In this section, you’ll create a new component. Instead of Java, you’ll implement its code using WebScript. 1. In Project Builder’s browser, click Web Components in the first column. 2. Choose File m New in Project. Note that the Web Components suitcase is selected. 3. Type GuestList as the name of the new component. Then click OK. The WebObjects Component Wizard appears. 4. Choose None for Available Assistance and WebScript for Component Language. 5.
Chapter 2 Enhancing Your Application 10. In the object browser, click application. There is an entry in the second column for the allGuests application variable you created. This entry appears in the Main component as well, since application variables are accessible from anywhere in the code. If you click allGuests, you’ll see in the third column an entry for count. This is a standard method that returns the number of objects in the array. 11.
Using a Repetition pageWithName is a standard WebObjects method (defined in the WebApplication class) that allows you to specify a new page to display. At this point, the code for Main.java looks like this: 14. Save Main.java. 15. Build and run your application. Each time you submit the form, the number of guests displayed in the WOString should increase. To return to the Main page, you’ll have to use your browser’s backtrack button.
Chapter 2 Enhancing Your Application You’ll bind the allGuests array to the WORepetition’s list attribute. This tells WebObjects to generate the elements in the repetition once for each item in the array. Each time WebObjects iterates through the array, it sets the repetition’s item attribute to the current array object. You bind item to the variable currentGuest and use currentGuest’s fields to bind the elements inside the repetition (such as WOStrings).
Using a Repetition 11. In the object browser, select application in the first column. 12. In the second column, click allGuests and drag the cursor to anywhere inside the row (but not inside one of the WOStrings). The Inspector window opens showing the repetition’s bindings. The list attribute is selected by default. Select table row , then click here to create repetition around row. Blue border and background means row is in a repetition.
Chapter 2 Enhancing Your Application By using the name currentGuest for the item attribute, you are taking advantage of the fact that the strings in your table are already bound to the fields of currentGuest. You now have finished implementing the repetition. When the table is generated, it will have one row for each item in the allGuests array. 15. Save the GuestList component. 16. Delete the table from Main, since you no longer need it. 17. Build and launch your application. 18.
Adding the Finishing Touches 4. Enter the following code before the return statement in clearGuestList: [[self application] clearGuests]; This code calls the application’s clearGuests method, which removes all the Guest objects from the array. 5. Save GuestList.wos. 6. Go back to WebObjects Builder. 7. Place the cursor below the table and press Enter. 8. Choose from the Elements pop-up list and click . This creates a submit button that the user will click to clear the guest list. 9.
Chapter 2 Enhancing Your Application 5. Select the pageName attribute, then double-click in the Binding column and type (including the quotes) "Main". Note: You must specifically type the quotation marks in “Main”, because you are specifying a string representing the name of the page to be returned. If you left off the quotes, you would be specifying a variable or method called Main. 6. Save the GuestList component. 7. Test your application.
Chapter 3 Creating a WebObjects Database Application
One of the most powerful features of WebObjects is its ability to provide access to databases. To do so, it uses a framework called the Enterprise Objects Framework. This chapter introduces you to the Enterprise Objects Framework by showing you how to create a simple database application. The steps you take in creating this application demonstrate the principles you’ll use in every other application you develop with the WebObjects and Enterprise Objects Framework.
Chapter 3 Creating a WebObjects Database Application The Movies Application The Movies application has two pages, each of which allows you to access information from the database in different ways: 62 • MovieSearch (the main page) lets you search for movies that match userspecified criteria. For example, you can search for all comedies starting with the letter “T” that have an R rating. Once you find the movie you’re looking for, you can make changes to its data or delete it.
The Movies Application Enterprise Objects and the Movies Database Enterprise Objects Framework manages the interaction between the database and objects in the Movies application. Its primary responsibility is to fetch data from relational databases into enterprise objects. An enterprise object, like any other object, couples data with methods for operating on that data. In addition, an enterprise object has properties that map to stored data.
Chapter 3 Creating a WebObjects Database Application MOVIE_ROLE table having a MOVIE_ID column. In the MOVIE table, MOVIE_ID is a primary key, while in MOVIE_ROLE it’s a foreign key. A primary key is a column or combination of columns whose values are guaranteed to uniquely identify each row in that table. For example, each row in the MOVIE table has a different value in the MOVIE_ID column, which uniquely identifies that row.
Designing the Main Page Movie movieRoles MutableVector movie MovieRole movie MovieRole Designing the Main Page Every WebObjects application has at least one component—usually named Main—that represents the first page the application displays. In Movies, the Main component represents the MovieSearch page. To design the Main component, you’ll use the WebObjects Application Wizard. The wizard performs all the setup that’s necessary to fetch database records and display them in a web page.
Chapter 3 Creating a WebObjects Database Application 5. Type Movies in the “File name” field. 6. Click Save. 7. In the New Project panel, click OK. This starts the WebObjects Application Wizard. 8. Choose Wizard under Available Assistance. With this option, the wizard guides you through the creation of a Main component for your application. When you finish, you can immediately build and run your application without performing any additional steps and without adding any code. 9.
Designing the Main Page Choosing an Adaptor An adaptor is a mechanism that connects your application to a particular database server. For each type of server you use, you need a separate adaptor. WebObjects provides adaptors for Informix, Oracle, and Sybase servers. If you’re working on a Windows platform, WebObjects also provides an ODBC adaptor for use with ODBC-compliant database sources. 1. In the wizard panel, choose the adaptor for your database. 2. Click Next.
Chapter 3 Creating a WebObjects Database Application 3. Complete the login panel. Specify the connection information you provided when you created and populated the Movies database. Post-Installation Instructions provides more information. 4. Click OK. When you use the wizard to create a model file, the wizard uses the adaptor you specify to connect to your database.
Designing the Main Page A relationship is a link between two entities that’s based on attributes of the entities. For example, the Movie entity has a relationship to the MovieRole entity based on the entities’ movieId attributes (although the attributes in this example have the same name in both entities, they don’t have to). This relationship makes it possible to find all of a Movie’s MovieRoles.
Chapter 3 Creating a WebObjects Database Application 3. Uncheck the “Ask about stored procedures” box. Checking this box causes the wizard to read stored procedures from the database’s schema information, display them, and allow you to choose which to include in your model. Because the Movies application doesn’t require the use of any stored procedures, don’t check this box. 4. Uncheck the “Use custom enterprise objects” box.
Designing the Main Page Choosing the Tables to Include 1. In the wizard panel, select MOVIE, MOVIE_ROLE, and TALENT in the Tables browser. Shift-click to select more than one table. Click to select all the tables. Click to deselect all the tables. The wizard creates entities only for the tables you select. Since the Movies application doesn’t interact with any of the other tables (DIRECTOR, PLOT_SUMMARY, STUDIO, and TALENT_PHOTO), you don’t need to include them in the model. 2. Click Next.
Chapter 3 Creating a WebObjects Database Application Shift-click to select more than one attribute. 1. Select movieId as the primary key for the Movie entity. 2. Click Next. 3. Select both movieId and talentId as the primary key for the MovieRole entity. MovieRole’s primary key is compound; that is, it’s composed of more than one attribute. Use a compound primary key when any single attribute isn’t sufficient to uniquely identify a row.
Designing the Main Page In this example, the relationship name is movieRoleArray, but the name is dependent on the adaptor you’re using. If foreign key definitions aren’t specified in your database server’s schema information (as with Microsoft Access), the wizard hasn’t created any relationships at all, and it skips this step. You’ll add relationships to your model using EOModeler later in this tutorial.
Chapter 3 Creating a WebObjects Database Application 2. Choose Cascade. This option specifies what to do when the source object (the Movie) is deleted. The cascade delete rule specifies that when a source object is deleted, the source’s destination objects should also be deleted—again, deleted in memory and correspondingly in the database. 3. Click Next. Now the wizard asks you about Talent’s relationship to MovieRole. 4. Check the “Talent owns its MovieRole objects” box. 5. Choose Deny.
Designing the Main Page Choosing a Layout The wizard provides several page layout options for formatting objects fetched from the database. 1. Choose Selected Record. 2. Choose Matching Records. A preview of the page is an approximation of what the finished page will look like given your choices. (The number of fields and items isn’t necessarily the exact number that will be in the finished page.) The wizard generates a title based on your chosen entity.
Chapter 3 Creating a WebObjects Database Application This is the query part, where users type search criteria. Clicking Match fetches movies that meet the criteria and displays their titles in the repetition part in the middle of the page. This is the repetition part. Clicking a movie title selects the movie and displays it in the editing part at the bottom of the page. This is the editing part, which displays information about the selected movie.
Designing the Main Page Double-click an attribute to move it to the Include list. OR Select an attribute... ...and click here to move it. The order in which you add the attributes determines the order in which they appear on the page, so add them in the following order: title, category, rating, dateReleased, and revenue. Don’t add any of the remaining attributes (language, movieId, and studioId). They don’t have meaning to users, and should not be displayed in the page. 2. Click Next.
Chapter 3 Creating a WebObjects Database Application When the wizard finishes, your new project is displayed in Project Builder. The wizard has produced all the files and resources for a fully functional, one-page application. All you need to do before running your Movies application is build it. Running Movies Build and run the application. Type matching criteria. A database string matches if it begins with the string in the text field.
Examining Your Project Examining Your Project Whenever you create a new project, Project Builder populates the project with ready-made files and directories. What it includes depends on the choices you make in the wizard, so this project has a set of files different from those of the GuestBook project. Like GuestBook, the Movies project contains a Main component (Main.wo) and classes (Application.java, Session.java, and Main.java).
Chapter 3 Creating a WebObjects Database Application Examining the Variables 1. Double-click Main.wo in Project Builder’s WebObjects Components category to open the Main component in WebObjects Builder. There are four variables in the object browser: the application and session variables that are available in all components and two others, movie and movieDisplayGroup. The movie variable is an enterprise object that represents a row fetched from the MOVIE table.
Examining Your Project Also note the comment explaining how movieDisplayGroup is initialized. The Main.java class doesn’t have any code to create and initialize the display group. Instead, it’s instantiated from an archive file, Main.woo, that’s stored in the Main.wo component. You shouldn’t edit woo files by hand; they’re maintained by WebObjects Builder. The woo file archiving mechanism is described in more detail later in “Specifying a Sort Order” (page 86).
Chapter 3 Creating a WebObjects Database Application Bindings in the Query Part In the query part of the component, movieDisplayGroup.queryMatch.title is bound to the Title text field. There are similar bindings to the Category and Rating text fields. The queryMatch bindings allow users to specify search criteria to use when movieDisplayGroup next fetches movies. The Match button is bound to movieDisplayGroup.qualifyDataSource, which actually performs the fetch.
Examining Your Project 1. Inspect the hyperlink. Its action attribute is bound to the action method selectObject. 2. Look in the Main.java class to see how selectObject is implemented. The method (shown below) simply sets movieDisplayGroup’s selected object to the movie the user clicked. public void selectObject() { movieDisplayGroup.
Chapter 3 Creating a WebObjects Database Application 1. Inspect the middle image button. Its action attribute is bound to the action method saveChanges. 2. Look in the Main.java class to see how saveChanges is implemented. The method (shown below with comments omitted) simply saves any changes that have been made to movieDisplayGroup’s objects to the database. public void saveChanges() throws Exception { try { this.session().defaultEditingContext().saveChanges(); } catch (Exception exception) { System.
Refining Main.wo group’s selected object. These changes happen only in memory—not in the database. To actually insert a new row in the database (or delete a row), the user must click the “Save to database” button, invoking saveChanges on the session’s EditingContext. The editing context analyzes the enterprise objects in memory; determines if any objects have been added, updated, or deleted; and then executes database operations to sync the database with the application. Refining Main.
Chapter 3 Creating a WebObjects Database Application Specifying a Sort Order You can change your application to sort movies alphabetically without writing any code. Display groups manage sorting behavior, and WebObjects Builder provides a Display Group Options panel for configuring this and other characteristics of display groups. 1. Double-click the movieDisplayGroup variable in the object browser. The Display Group Options panel opens for configuring movieDisplayGroup. Choose an attribute to sort on.
Refining Main.wo An image in this column means that the variable can be initialized from the component’s archive. A means that initialization parameters are already set. The variable is created and initialized from the archive as a part of the component’s initialization. A means that no initialization parameters have been set, and so the variable isn’t automatically created. Double-click the variable to configure it and add it to the archive.
Chapter 3 Creating a WebObjects Database Application The Movies application specifies default values for newly created Movie objects using the display group, movieDisplayGroup. 1. Open Main.java in Project Builder. 2. Add the following constructor: public Main() { super(); MutableHashtable defaultValues = new MutableHashtable(); defaultValues.put("title", "New Movie Title"); movieDisplayGroup.
Refining Main.wo Setting a Number Format In addition to a dateformat attribute, text field elements also have a numberformat attribute. 1. Inspect the revenue text field. The revenue text field’s numberformat attribute is bound to the string “###.##”. This binding tells the text field that it’s displaying a number and describes how to format it. 2. Change the text field’s numberformat binding value to the string (including the quotes): "$ #,##0.00".
Chapter 3 Creating a WebObjects Database Application Optional Exercise You can tidy up the user interface even further by putting the query part of the page in a table to match the editing part of the page. Also, you should consider capitalizing Main.wo’s text field labels. To put the query part of the page in a table, follow these steps: 1. Put the cursor inside the form element before the “title” text field. 2. In the Tables toolbar, click the button to add a table.
Refining Main.wo 4. In the Table Inspector, choose Unspecified for the table width. The table resizes to just fit its contents. When you change the cell contents later, the table will resize again to accommodate the new values. 5. Also in the Table Inspector, set the border to 0 to remove the appearance of a border. 6. Click the the table. button in the lower left of the table to add a new row to 7. Type the labels Title:, Category:, and Rating: in the cells in the first column.
Chapter 3 Creating a WebObjects Database Application Adding the MovieDetails Page The MovieDetails page shows you the detailed information about a movie you select in the Main page. For this to work, the Main page has to tell the MovieDetails page which movie the user selected. The MovieDetails page keeps track of the selected movie in its own instance variable. In this section, you’ll: • • • Create a new component whose interface you’ll create yourself.
Adding the MovieDetails Page Creating the MovieDetails Component 1. In Project Builder, choose File m New in Project. 2. In the New File panel, click the Web Components suitcase. 3. Type MovieDetails in the Name field. 4. Click OK. 5. In the wizard panel, choose None from the available assistance. 6. Choose Java as the component language. 7. Click Finish. 8. Open the new component in WebObjects Builder.
Chapter 3 Creating a WebObjects Database Application Movie isn’t actually a class; it’s an entity. It’s listed in the combo box as a type along with entries for all the entities in your model. When you choose an entity as the type for your variable, WebObjects Builder recognizes that the variable is an enterprise object. Using information in the model, WebObjects Builder can determine the entity’s corresponding enterprise object class and the properties of that class. 4.
Adding the MovieDetails Page 8. In Project Builder, modify the showDetails action to look like the following: public Component showDetails() { MovieDetails nextPage = (MovieDetails)application().pageWithName("MovieDetails"); EnterpriseObject selection = (EnterpriseObject)movieDisplayGroup.selectedObject(); nextPage.setSelectedMovie(selection); return nextPage; } This method creates the MovieDetails page and then invokes its setSelectedMovie method with the movie that’s selected in the Main page.
Chapter 3 Creating a WebObjects Database Application This adds a new level 3 heading element around the string. The MovieDetails page will show the title of the selected movie in this heading. 4. Add labels and string elements to display the selected movie’s category, rating, date released, and revenue. 5. Bold the labels. 6. Bind selectedMovie.title to the value attribute of the first string element (the one in the heading). 7.
Refining Your Model telling the application to open the MovieSearch page when the hyperlink is clicked. Running Movies Be sure that all your project’s files are saved (including the components in WebObjects Builder), and build and run your application. In the Main page, select a movie and click the Movie Details link. The MovieDetails page should display all the movie’s information. Refining Your Model The model created for you by the wizard is just a starting point.
Chapter 3 Creating a WebObjects Database Application Project Builder opens your model file in EOModeler, launching EOModeler first if it isn’t already running. EOModeler displays your model in the Model Editor. It lists the entities for the tables you specified in the wizard—Movie, MovieRole, and Talent. Removing Primary and Foreign Keys as Class Properties By default, EOModeler makes all of an entity’s attributes class properties.
Refining Your Model Click an entity in this frame to select the entity. Click in an attribute’s Class Property column to remove it as a class property. 4. In the MovieRole entity, remove movieId and talentId as class properties. 5. In the Talent entity, remove talentId as a class property. Adding Relationships to Your Model The Movies application uses two pairs of inverse relationships.
Chapter 3 Creating a WebObjects Database Application your relationship, and the relationship’s name is dependent on the adaptor the wizard used. Adaptors don’t all have the same naming convention for to-many relationships. For example, the Oracle adaptor names Movie’s relationship movieRoleArray instead of movieRoles.
Refining Your Model 8. Click Connect. EOModeler automatically renames the relationship based on the name of the destination entity. For example, after connecting a to-many relationship from Movie to MovieRole, EOModeler names the relationship “movieRoles.” To-one relationships are named with the singular form of the destination entity’s name. For example, EOModeler names the inverse to-one relationship (from MovieRole to Movie) “movie.
Chapter 3 Creating a WebObjects Database Application At this point your model has all the relationships it needs. The Diagram View gives you an overview of the entities in the model and their relationships to other entities. You can also use the Diagram View to edit your model. Double-click an attribute or relationship to change its name. To create a relationship and its inverse, Control-drag from the relationship’s source attribute to its destination attribute.
Refining Your Model 3. Ensure that the delete rule is set to Cascade. If the wizard created relationships for you, the relationship’s delete rule should already be set to Cascade. You specified this in the wizard. If you created your relationships by hand, you’ll have to set the delete rule yourself. 4. Ensure that the Owns Destination box is checked. As with the delete rule, if the wizard created relationships for you, the relationship’s Owns Destination box should already be checked.
Chapter 3 Creating a WebObjects Database Application Enterprise Objects Framework provides several mechanisms for generating and assigning unique values to primary key attributes. By default, Enterprise Objects Framework uses a native database mechanism to assign primary key values. See the chapter “Answers to Common Design Questions” in the Enterprise Objects Framework Developer’s Guide for more information.
Setting Up a Master-Detail Configuration In the Movies application, the master-detail configuration is built around Movie’s movieRoles relationship. The configuration is split across two pages in the application. The master, movieDisplayGroup, is in the Main component, while the detail is in MovieDetails. In this section, you’ll: • • Create and configure the detail display group. Extend the MovieDetails user interface to hold MovieRole and Talent information.
Chapter 3 Creating a WebObjects Database Application An Add Display Group panel opens. WebObjects Builder assigns a default name based on the relationship name. 3. In the Add Display Group panel, change the name to movieRoleDisplayGroup (remove the “s” from “Roles”). 4. Click Add and Configure. The Display Group Options panel opens so you can immediately configure the newly created display group.
Setting Up a Master-Detail Configuration Identifies this display group as a detail display group. You can’t set the entity of a detail display group. The entity is computed from the Master/Detail settings. Sort MovieRole objects by roleName... ...from ‘A’ to ‘Z’. Check this box so the display group automatically fetches its objects. Notice that the “Has detail data source” box is checked. This means that movieRoleDisplayGroup gets its objects from a DetailDataSource object.
Chapter 3 Creating a WebObjects Database Application 6. Check the “Fetches on load” box. When “Fetches on load” is selected, the display group fetches its objects as soon as the component is loaded into the application. You want this feature in the MovieDetails page so that users are immediately presented with the selected movie’s roles. In contrast, the Main page does not fetch on load; it shouldn’t present a list of movies until the user has entered search criteria and clicked Match. 7. Click OK. 8.
Setting Up a Master-Detail Configuration 1. In the MovieDetails component window, add the bolded text Starring: beneath the Revenue line. 2. Below the Starring label, add a repetition. 3. Replace the “Repetition” text with three string elements. The strings should all be on the same line, so don’t type carriage returns between them. 4. Type a space between the first two strings and the word “ as ” (with a space before and after) between the last two. 5. Add a carriage return after the last string.
Chapter 3 Creating a WebObjects Database Application When you’re done, the repetition bindings should look like the following: Running Movies Be sure that all your project’s files are saved (including the components in WebObjects Builder and the model in EOModeler), and build and run your application. In the Main page, select a movie and click the Movie Details link. Now, in addition to displaying all the movie’s information, the Movie Details page should also display the movie’s roles and actors.
Updating Objects in the Detail Display Group Updating Objects in the Detail Display Group In this section, you’ll add the ability to insert, update, and delete movie roles. The MovieDetails page will then look something like this: Click a role to select it and display its information in the editing part below. Use the browser to choose an actor for the selected role. Edit the name of the selected role. Click here to create a new, empty role. Click here to delete the selected role.
Chapter 3 Creating a WebObjects Database Application Managing a DisplayGroup’s Selection Remember how clicking a movie title in the Main page selects the corresponding Movie object in movieDisplayGroup. MovieDetails has a similar behavior for selecting a MovieRole object in movieRoleDisplayGroup. First you need to add a hyperlink element around the repetition’s role name string so that users can select a particular MovieRole.
Updating Objects in the Detail Display Group Adding a Form Now lay out the user interface used to view and edit the selected MovieRole. When you’re done, it should look like the following: 1. Add another horizontal rule after the repetition. 2. Use the button (in the “Dynamic form elements” toolbar) to add a browser element between the two horizontal rules. A form element is automatically created around the browser. 3. Beneath the browser, type the bolded text Role Name:. 4. Add a text field. 5.
Chapter 3 Creating a WebObjects Database Application 2. Using the Display Group Options panel, assign talentDisplayGroup’s entity to Talent. Remember that to open the Display Group Options panel, simply double-click the talentDisplayGroup variable in the object browser. The initially displayed next to the variable indicates that initialization parameters have not yet been set. icon 3. Configure talentDisplayGroup to sort its objects alphabetically (ascending) by lastName. 4.
Updating Objects in the Detail Display Group Talent browser, the selection should refer to a single object. Consequently, you need to add two methods to manage the browser’s selection: one to return a vector containing the selected Talent and one to set the selected Talent from a vector object. 4. Add the method talentSelection to the MovieDetails.
Chapter 3 Creating a WebObjects Database Application Again because the browser uses a vector for its selections attribute, the setTalentSelection method must take a vector as its argument. If talentVector’s size is nonzero, then this method sets the selected MovieRole’s talent to the first object in the vector. Note that by default, a user can’t select more than one actor in a browser. With the addition of these methods, WebObjects Builder now displays talentSelection in MovieDetail’s object browser. 6.
Adding Behavior to Your Enterprise Objects 6. Copy the saveChanges method from the Main.java class and paste it into the MovieDetails.java class: public void saveChanges() throws Exception { try { this.session().defaultEditingContext().saveChanges(); } catch (Exception exception) { System.err.println("Cannot save changes "); throw exception; } } 7. Bind movieRoleDisplayGroup.insert to the Insert/New image’s action attribute. 8.
Chapter 3 Creating a WebObjects Database Application 1. In EOModeler, inspect the Talent entity. 2. In the Entity Inspector for Talent, type Talent in the Class field. Type the name of your custom class here. 3. Set the MovieRole entity’s class to MovieRole. Now you can generate the source files for your Talent and MovieRole classes.
Adding Behavior to Your Enterprise Objects Adding Custom Behavior to Talent Now add the fullName method to Talent and bind it to the browser. 1. Open Talent.java in Project Builder. The class file declares instance variables for all of Talent’s class properties (firstName and lastName) and implements set and get methods for those instance variables. 2. Add the method, fullName, as follows.
Chapter 3 Creating a WebObjects Database Application Running Movies Be sure that all your project’s files are saved (including your model file), and build and run your application. Now when a user clicks the Insert/New button on the MovieDetails page, a new MovieRole is inserted, with “New Role” already displayed as the role name.