Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2002-701
$eventId
ID of event: wwdc2002
$eventContentId
ID of session without event part: 701
$eventShortId
Shortened ID of event: wwdc02
$year
Year of session: 2002
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC02 • Session 701

WebObjects Technical Overview

WebObjects • 1:04:22

This session provides a technical overview of WebObjects for new developers. Highlights include key aspects of the WebObjects architecture and its technical advantages and relevance to web application development. Topics include a discussion and demonstration of WebObjects tools, design and flow of a typical WebObjects application, and a review of deployment scenarios.

Speaker: Steve Hayman

Unlisted on Apple Developer site

Transcript

This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.

So we're about ready to start our second session, the WebObjects Technical Overview. And I'd like to introduce Steve Hayman, who's our speaker and presenter for this session. Steve, where are you? Tony, you know how we got that memo that we were supposed to wear the speaker shirts? Yeah. And when I got here this morning, they didn't have any. They were out. When did you fly in, Steve? I'm going to do the best I can, all right? All right.

[Steve Hayman]

All right, okay. I'd like to introduce Steve. I got here on Sunday and they didn't have any shirts. There we go. Oh, wait a minute. It's cold up here. Just a second. I'd like to introduce Steve Hayman. Thank you. Please be seated. Please be seated. Thank you. But no, please sit down. Please, please. Oh, you're too kind.

How many people were here last year? Yeah? Do you remember James Dempsey did a song at the end of his session? Is James here today? I hope we have time. James wrote this song about EOF and he brought out his guitar and he announced that this was the first time he'd ever actually played the guitar in public. He wrote this fantastic song about EOF that I think a lot of people remember. So I was thinking, and I sure hope we have time, that we can have a conversation about EOF.

[Transcript missing]

I'm Steve. I'm from Toronto. Any other Canadians here? Were you all disappointed to hear James Gosling say Java yesterday? Oh, it killed me. The correct pronunciation is Java. I really wanted to get clarification on that from him, but I was unable to do so. But I want to talk to you today about WebObjects.

Bob covered a lot of what's new and some of the advanced features in the previous session. I want to talk more about the basics. Are there people here that are WebObjects beginners? Are there people here that are tired of people asking to put up your hands at the beginning of a session? Are there people like that? Yeah.

So we won't try not to do any more of that. But I want to talk about this. And more importantly, I want to actually build something in a little bit of time. So WebObjects, as Bob mentioned, is an application server, which is not my favorite term. But the best part is really these frameworks that come with WebObjects and enable you to build applications quickly. We give you a lot of code.

We give you a lot of tools that know how to generate HTML and that know how to manage sessions and that know how to talk to databases at the back end. And by leveraging those frameworks, those collections of objects and those tools, you can hopefully build a pretty good application pretty fast.

You're deploying something in the middle here, and it's integrating data from all these different places and sending it out through the web servers in a variety of ways, as you probably know. This is really a tool, however, for developers. Some of us have worked pretty hard to make it look pretty easy, but just I want you to keep in mind that this really is a tool for Java programmers. You have to be a serious Java programmer to get a sophisticated WebObjects app done. There is a steep learning curve associated with WebObjects, but that's okay because you're going to learn a lot in a short period of time.

All right, I'm retiring that joke. I've been doing that joke for three years. I think that's probably enough for that one. Does that joke work in Japanese? I like to say "Kanichiwa" to the translators. Everyone say "Kanichiwa." Translators? Hi. Kanichiwa. Oh, they're waving. Good, good, good. I wasn't sure if my mic was on. We cannot understand the Canadian man. We do not know what he is saying.

It's not funny even in English, so we're not going to bother translating it. So we have a tool here that works with Java, with a variety of databases, now with JNDI servers in WebObjects 5.1. A bunch of different UIs you can pump out, usually HTML, but often other technologies.

We work with a variety of web servers. We work with things that used to be competitors. Now that we have this servlet deployment, you can theoretically take your WebObjects app and bundle it up for servlets, and deploy it on somebody else's servlet engine. Lots of third-party objects, and open, open, open, open, open, open, open. I'll wait for the translators to catch up. Okay? Okay, good.

You can develop on Mac OS X, you can develop on Windows, you can deploy on Mac OS X Server, Windows 2000 or Solaris, and theoretically other places that have a Java environment as well. And now with Servlets, you have a choice of runtime environments you can use in which to deploy. And you can start small and grow bigger.

People often build a little application that's just running on one machine, and after they get it working, and without any real need to redesign or anything like that, you can scale an application to a big, scary, complicated diagram here where we've got multiple firewalls inside and outside, multiple adapters, and multiple copies of the application. We call those instances. You write up the application, and you have several of them going in several different places. So you can really move from this to this without any big architectural redesign of your application.

A lot of that stuff is built in. I just noticed my boss is sitting in the second row, and I think this is the first time he's ever seen me do a demo. Right, Alan? Did we have my performance review? Are you ready for this year? I don't know. I'm very nervous now. You didn't see me come out, did you? You came in after I put my shirt on, I hope? Okay, good.

But the key ideas surrounding WebObjects, we have components at the front end and a tool that builds those, and they're the things that create HTML and send it to the world. At the back end, we have enterprise objects, which are the things that talk to databases and that collect data from data, data, data, data, Java, Jaguar.

So many pronunciation options available to you at WWDC, but all these different pieces are bound together at runtime. We have a sophisticated technology that's sophisticated and lazy at the same time. If that's possible, I like to think that I'm that way myself, which is why I enjoy WebObjects. I'm sophisticated and lazy. And these objects are tied together dynamically. As the application runs, decisions are being made about who's connecting to who and who's sending what message where and where is the data actually going to come from.

You build these components at the front end that have this little WebObject tag in them that indicate in the HTML, here's where something is going to happen. Some message is going to get sent to something here and the result is going to be inserted into the HTML at this place. We call another thing, we call them bindings. Bindings are the definition of what happens when we see this WebObject tag.

So I can talk more about this later, but this is really what, in raw form, WebObjects components look like. They're pieces of HTML. They're these things called a WAD file in the upper right. That's a definition of the meaning of the tag. So you see string one on the left is actually a WO string, and it's going to give its value by sending a certain message to a certain other object. WebObjects evaluates all this stuff at runtime, sends the message, and comes up with plain HTML going out to the end user. Components usually have a Java class associated with them as well, in which you can actually define behavior.

Now what comes out of these components? It's just text, just bytes, all sorts of stuff to be interpreted by the client, and WebObjects marks it up back in the server and transforms it and sends it out. At the back end is the Enterprise Objects Framework, or we call it EOF, Enterprise Objects Framework. EOF is not maybe the best name. I was not in the meeting when they picked the name EOF. That kind of meant something already. Did you know that? That was a term we used in computing already? EOF. But EOF is a good thing in this case.

Enterprise Objects is the back end database connection technology that underlies most WebObjects applications. It's driven by a model, which is a file that you can create that describes what database you want to use, what tables and rows and columns you're interested in, what kind of objects you want to make coming out the front end.

Together with that, you can create Java objects that contain the data from this database, customers, packages, vehicles, whatever. But you can also enhance them with business rules, and WebObjects will take care of creating sort of blank, empty Java objects of your choice and filling them in with data that it's found in the database.

So your object just springs to life, containing this data which has come ultimately through some sort of a JDBC data source in a process that's kind of unknown to the object itself. You write these sort of naive, middle-tier business objects that just spring to life with data that the EOF has brought in from the back end.

All driven through these models. These models are really files that tie object specifications to specific data sources. I'm going to show you all this later. I'm going to try to build something. And hopefully it'll be obvious how this all actually works. Ultimately, you're setting up definitions that say certain kinds of objects are associated bidirectionally with certain databases, certain tables. Every row in this cust table, I want to make a customer object. Every row in this other database table, I want to make a vehicle object.

And the relationships between objects are handled automatically as well. A customer might have a list of vehicles and so on. I think this is one of the great things about WebObjects is the way that it manages relationships for you. Anybody here in a relationship? Anybody in a relationship? Managing a relationship is hard, right?

I know I'm in a one-to-one relationship right now. For a while I was worried it was going to be a one-to-zero relationship, but I think we're okay. I guess there are people in one-to-many and many-to-many relationships, and that's all complicated. But WebObjects and EnterpriseObjects can support the automatic adding of things to and from these other relationships and handle all that for you.

It's the real gem. It's the best part of WebObjects. It's also, superficially it might seem simple, but there's a lot of depth to this thing and a lot of places where you can write code and leap in there and override the way it works if you want, but enhance it and take advantage of all this power that this persistence framework is bringing to the table. All this stuff, the backend enterprise objects and the frontend components are all tied together at runtime by WebObjects. It finds those WebObjects tags, maybe fetches some objects, sends some messages hither and yon, and produces a stream of HTML that goes out to the end user.

together with session management. Every WebObjects user has a session object created for them. By default, it doesn't really do anything, but it's a placeholder where you can go and say, "I want to add a shopping cart to this session. I want to keep track of which products somebody has purchased." And WebObjects will take care of handling that session object and making sure it sticks around for the entire lifetime of one user's interaction with your database.

You have complete control over how these sessions are stored. Are they in the database? Are they kept in a cookie? Are they kept, you know, hidden fields in a form or something? But it's a common place to extend and add behavior that's going to be unique to a particular user in the session object.

along with these runtime monitoring tools. We have Monitor and WoTaskD, which is our standard way of deploying applications, but now in 5.1 we have this ServLib deployment option as well, where you can let somebody else worry about how the application is actually going to run. I suppose there would be a different phone number you could call and complain about the way your application wasn't running because you're using somebody else's engine. So what is it you're actually creating? Pardon me. I'm so funny.

What is it you're actually creating? What is this water? Holy smokes, I thought this was just water. It's got... Vodka. Oh, vodka, yes, that is good. What is it you're creating? You're building something that, don't get hung up on this, but you're building this complicated structure here. You're taking a bunch of WebObjects components and your own Java code and maybe some images and some references to frameworks that other people have created, and it's all creating this big .woa folder. That's sort of what the result of building an application with WebObjects Builder is.

It's a folder like this, it's got a variety of resources in it, and hidden in there, for instance, is a shell script that's going to take all of your Java code that's been compiled into this jar file and run it and set it up in such a way, normally, that it finds images and so on in a folder that belongs to this application.

So you build this thing, and you don't need to worry about these details, but this is what's actually happening here. And then when it comes time to actually run the application, you'll see me do it this way. You might launch your application from Project Builder, and Project Builder is going to start your application, which is going to create some class path like you would not believe, that picks out the Java classes, spread over all these frameworks, and ultimately it's going to start the application object associated with your WebObjects application.

Part of that, normally, when you're launching from Project Builder, your application thinks for a moment, comes up with a random port number, and asks your web browser to connect to this particular port number, and the web browser just starts. When you're testing with WebObjects, this is usually how people start.

You do what we call direct connect. You just hit the run button in Project Builder, your application starts, your web browser is sent this particular URL, and it opens, and then you talk back and forth, and you try it out. That's maybe not the best way to deploy, however. We'd rather have you, well, sorry, yeah, in this direct connect mode, everything's happening to the application itself. Requests for images, requests for dynamic HTML, it's all coming into this one application and its resources.

Later on, when you're ready to deploy, you've probably got one or more app servers and one more web servers, and there's kind of a naive way to deploy, which is just to copy everything to the app server and let the web server just route all the requests for the images and everything else over to the application server. And that's not really taking advantage of what web servers can do for you. Web servers are pretty good at caching images and QuickTime movies and JavaScript and things like that that aren't going to change during the life of your applications. So we offer another approach.

called the split install, where you put most of the stuff on the application server and you put images and other static resources on the web server. And then at runtime, the requests are sorted out so that certain things go only as far as the web server where they're cached by Apache or IIS or whatever your web server is.

And other requests for dynamic stuff are getting routed through to your app server, which might be somewhere else. This is called a split install. These are terms that you might come across when it comes time to deploy your application. But we like the idea of splitting the static and the dynamic parts so that you can scale them each independently. You could have, if you didn't have a lot of images, you might have one web server and several application servers at the same time.

So there's a lot of flexibility in how you actually deploy. One good thing about that approach is that the actual code is on the app server, which is usually protected by a firewall in some way and there's no way for people to get at it. And then the images, which you don't care about, can sit on the web server where people can download them and copy them all they want. So typically in Mac OS X, the images would wind up over here.

New in 5.1, servlet deployment. The same as before. You build your application the same way as before. You add this magic Java WOJSP servlet dot framework, and through some process that I don't completely understand, it winds up creating a dot war file in addition to this big dot WOA file. You're welcome to try to understand the build process. Mark over here has tried to understand the build process, and that's why he's laughing.

But it all happens magically for you. And in addition to your application, one single file called a war file is created. And then if you want to do servlet deployment, it's more or less as simple as copying that war file to wherever your servlet engine expects to find it. You know, we support Tomcat, and Tomcat wants to find servlets in library, Tomcat, web apps, my app dot war. So deployment in a servlet scenario is as simple as moving this one file over to this other place, and then looking up the documents.

You're going to have to do a lot of documentation on your servlet container and deciding how to tell it about the application. Sometimes it's automatic. Now I should tell you that at the moment you do need to have the rest of web objects installed on the servlet engine. This war file that you're copying is only your application and its code.

Are we thinking about doing anything about that? People often ask if, couldn't we make it so that the war file was even more humongous and contained all of web objects so that it was just one thing to plop in the server? That would be a great question at Q&A. Someone should ask that at Q&A, but not to me. It's one of these people over here.

So what's going on when one of these applications actually runs? You've got the Internet, it's got three or four computers on it out there. You've got a web server and an application server and some kind of a database. We don't care at all what the web server is.

We put a little adapter thing on it that allows it to find the application server. But it can be anybody's web server at all. We care a little bit more about what the application server is. There are certain platforms that are officially supported, and then there are other platforms like Linux that might work, but they're not officially supported. And there are database adapters at the back end that speak to certain databases.

We have, oh, I should have put, I'm sorry, I should have put MySQL on here. We have a variety of supported databases, and then there are others that work through SQL as well. You know, if you wanted to get FrontBase or something, that's a fine database as well. You can use your choice of databases, not just the ones that we officially sanction here.

So what's going on when you have a really simple application? This was sort of my first WebObjects application, trying to do something incredibly sophisticated here, where I would type my user name. And it would look up me in the database and welcome me back by my first name.

So there's really three steps that are going on. When the form is submitted from the web browser, is the head of the WebObjects application development team. He is the head of the WebObjects application development team. Steve Hayman is the head of the WebObjects application development team. He is the head of the WebObjects application development team. He is the head of the WebObjects application development team. So users are submitting requests like this and they come flying in from their iMac or their eMac. I have to say, as an old Unix guy, it's interesting to me that we now make eMacs.

I think that's kind of fun. Although, I have to say, I'm really hoping we're also going to come up with a VI Mac because that personally would be my choice. Anyway, the request comes in from the Emacs and the Vimacs to the web server, and it gets sent to one copy of your application, which is running somewhere on this application server. The first time, it picks one at random. The second time, it usually sends you back to the same one as the first time.

And the session has to go and find the component that caused the original page to be created. We have to go and find that so we can decide what to do with the string S Hayman. And by studying that component, we can see that it should be associated with value username.

We should find some variable called username and take the form value that was typed here and stuff it in to that variable. So it finds those form values and then it invokes the action. You click on the submit button and this particular component says, oh, when it hits submit, you should send the handle login message back to the page.

And that would fire up a little bit of Java code that would maybe look up another page or you could insert some code here to tell the session to do something or you might want to log something. But when that button is associated with a particular message being sent to one of these classes. So in this case, it's going to look up another page, a page called welcome.

and it's going to find the welcome.w o page which has its own little bit of HTML and its own wide file its own WebObject declaration file and then we're going to decide how to process this thing and all this is happening in the response phase. We're going to find the any WebObject tags that might be inside that HTML.

We're going to find the associated value. Whenever there's a W0 string you have to send a message to decide what to put at that place in the HTML. Let's generate a string, put it in there. So we look up that message and then some messages might be sent to objects that are coming from the database in this hypothetical scenario. And a WebObjects developer doesn't really worry about SQL too much. You've built one of those object model files and it has all the database information inside it. And from that point on you just start thinking about objects and relationships and their properties.

So In this case, maybe the object model says that, you know, customers are coming from this Oracle table and products are coming from this Oracle table. I understand Oracle is very popular in California. Like, everybody has a copy. Is that what I read in that paper the other day?

That the state bought a copy of Oracle for everybody? That's pretty... I'd have to suggest that when I get back home. That'd be great. I'd love to have my own copy of Oracle. And SQL, to fetch, in this case, a customer object, is going to be generated automatically.

By studying this model, the application knows that you want to create a customer object, but the model says, customers get their data from this table and these columns over here. So automatically, EOF puts together an SQL statement, sends it to the database, fetches some rows. The rows come riding back like this. And an object is created, in this case, a customer object with my name in it.

And then we send the message that we wanted to send. Well, give me the first name of that customer object, and that comes back with a string, Steve. And we find that tag that said, here's where the WebObject was, and we replace that with this string, Steve. And then the plain ordinary HTML goes back out to the, the VIMAC at the, at the back end.

This in a nutshell is the request-response loop. A request comes in. Various objects are given the opportunity to handle it. Do you care about the data in this form? Various objects are asked, are you the action responsible for the submit button that was clicked? And then another component will be loaded, and it's given the opportunity to append HTML to the response.

You can subvert all this if you want. There's plenty of opportunity to insert your own code if you want. You usually don't have to, but if you want, into this process and do all kinds of crazy things like extracting things from header fields or logging stuff somewhere and so on.

But notice that the SQL and the HTML are kept pretty far apart. They're in entirely different files. Your HTML is in one of these WebObject components, and the SQL doesn't even exist really until the application runs. At runtime, the application figures out the SQL and sends it off to the database. So you do not need to write any of this unless you want to.

Thank you. I guess they want to. So let me talk about the tools. Bob had like six tools on his slide. I'm only going to show you three because I'm going to do a fairly simple demo in a moment here. But WebObjects Builder is the prime tool for creating these components, for managing the HTML and the associated declaration file and maybe WebObjects Builder doesn't really manage the Java file, but it can manage associations between them.

You could edit all this stuff by hand if you wanted to, but one interesting thing is that now in 5.1, we have spent, you know, I started at Next a long time ago, and we spent a lot of time telling people what a good idea it was to keep the HTML and the business logic and the SQL and everything as far apart as possible. We spent a lot of time trying to hammer that point home that separation was good, but now in 5.1, if you want, you can just put it all back in one file with JSP.

Be my guest. You can develop this way. And in fact, if there are programmers in your organization who are more familiar with the JSP model, this might seem more accessible to them. But, you know, typically in the old style of WebObjects is to keep everything separate. And of course, I would encourage you to do it that way. It's really a much cleaner result than this. But if you have a need to go JSP and you want to squeeze everything into one file, that's now an option for you.

So you're going to create a lot of these things. Usually at least one for every different kind of page, but often sub-components, the title bar, the menu down the side, some kind of a footer. And we provide you with some reusable components for most of the HTML UI things that you might want. And you can make your own. You can create your own components. And if I have time, I'm going to try to actually build--well, you'll see. If we have time, you'll see. But you typically assemble a lot of these things into one application.

And They're all files. You can use whatever text editor you like for these things. I have used stickies in the past as my development environment. That is possible. Cat, if you're a real, you know, studly Unix programmer. I suppose DD. I suppose the real Unix programmers would DD it directly onto a disk sector or something like that. I'd rather work at a slightly higher level. I'd rather use some kind of a WYSIWYG editor. You can use Dreamweaver or Go Live or anything that understands HTML. They usually don't understand this associated WAD file.

You can also work with WebObjects Builder, which is a graphical way of managing the HTML and the declaration file simultaneously. So here in an example is a screenshot of me assembling some sort of a page, and I just added a hyperlink that says click here to order. And I want to arrange that when a user sees that hyperlink and clicks on it, it sends this message, place order, back to my application.

And it's really in WebObjects Builder a matter of drawing a line. You draw a line from the bottom half of the screen, which is where sort of your object browser, your view of objects in the application. And you associate it, or you bind it, to something in the user interface at the top.

and as you do that you you you can choose hyperlinks here. I'm seeing a menu of all the different properties I can associate with a hyperlink. Do I want them to to trigger a specific java action or do I want them to just go to a specific page name or I guess there's other fragment identifier. I guess I've never used that in my life.

I suppose that's that's handy but there's a variety of properties for any one of these objects that you can bind to. And you pick the one you want and up at the top in the inspector you can see it now says the hyperlinks action is place order. When anyone sees this page right now there may be three thousand of you all hitting my application. You're all going to click on that hyperlink and it's going to send the message place order back to the class associated with this application. I've apparently offended Tony in some way. Maybe she's looking for my shirt. That would be nice.

You can also use WebObjects Builder in what we call raw mode, which is just a view that lets you edit the HTML in the WAD file directly down here. That's sometimes necessary, but, you know, you're on your own if you leave out a semicolon in the WAD file. Don't come blaming me that I said it was all right. But it's nice to be able to do it both ways. We're giving you a choice with WebObjects, choice of a lot of different things here.

And you can use palettes to organize frequently accessed components in a nice reusable way. I'm a bit of a palette junkie. I don't know if any of you WoeBuilder guys have -- like, I have like 14 WebObject palettes loaded right now. And any time you get a good idea and you think you might want to use it again, well, take the extra 5 percent of the time and make it an object on a palette that you can drag and drop or give to someone else. It will pay off in the long run.

EO Modeler you can hear all about in plenty of other sessions, but it's the tool that edits these .eomodeld files. They're really folders. They're folders of files. And EO Modeler is a tool that lets you state what kind of connection information, what database are you going to hit, and what tables in the database do you want to make objects for. In this case, we want to make vehicles out of the MDL table in this database. Information about entities and their specific properties, and information about relationships too. A vehicle has a base price, which corresponds to a certain column in the database.

But a vehicle also has a relationship to an automaker, which corresponds to an object from another table. The Enterprise Objects Framework manages these relationships and does the joins for you automatically to fetch the related objects. So your model specifies a lot of information about how to do all the database work.

And it can manage some fairly complicated relationships here, too. And you're going to see the usage of this A.B.C. business quite a bit in WebObjects Builder. That's a sequence of messages, a sequence of tokens that describe a series of messages to be sent. So you see the first one, vehicle.maker.name. Send the message maker to the current vehicle and then send the message name to that thing, and that would give you Chevrolet, let's say, something like that.

So if I mention a car, do I get like a free car? Are there like endorsement opportunities in one of these sessions if I mention it? So maybe you have a Corvette vehicle and you send it to the message maker and it returns the Chevrolet object. So this A.B. business is what we call key value coding, which is the fantastic, no, I don't have time right now.

Key value coding is this terrific piece of technology that's pervasive in WebObjects that lets you specify in a very simple manner complex series of messages. And you'll see these at some point. that show up every once in a while. That's an extensible way that you can tell it to do something tricky with a list of objects. You know, compute the average base price of all these vehicles.

Find one with the max, count them, and so on. So you'll see me do a little bit of that when I get the WebObjects builder in a moment. Project builder--you can hear all about project builder in hundreds of other sessions. Project builder, project builder, pro-- project builder? Project builder?

I'm going to say Project Builder. I don't care what you think. So you can hear all about Project Builder somewhere else, but let me actually try and build something here to show you how these tools fit together. We could have demo one up on the screen, please. Enjoy a refreshing beverage. How many people here are going to like all the WebObjects sessions? Yeah? Good. You'll see more elaborate versions of virtually everything I'm doing here. Bob, Bob Fraser is going to all the WebObjects sessions, the product marketing manager.

We do have a marketing plan. We're sending Bob to all the WebObjects sessions. I think we have to edit that out. Edit that out of the DVD. Okay, we're going to edit that part out of the DVD. Last year, Toni told me that she had to edit some parts of my presentation. Well, I remember last year you said that I said bite me by mistake in the middle of the presentation. And you had to cut that part out.

So if I get in trouble, I know what to say, like if something derails in the demo here. All right, the tools I'm going to use right now are Project Builder, WebObjects Builder, and EOModeler. I don't want that, I don't want this, I used to use this all the time, but not now.

The first step is usually to build one of these object models. I have a database running on here, and I'm wearing this shirt for a reason, because I have a database of... There was a recent major sporting event in the United States in Salt Lake City, right? But I don't want to get in copyright trouble, so let's pretend it was in Pepper Lake City or something like that, and it was some kind of winter sporting festival.

And... I've got a database here, an open base, of tables of athletes and teams and countries and medals. I was kind of fascinated by this because every time I try to think about what demo to do for WWDC, it becomes apparent to me that there's always something going on in the United States that involves some kind of scoring controversy.

Last year I did this demo based on the 2000 election. You know, there was some kind of confusion about who the winner was. This year you might have read that there was some dispute about the pairs figure skating. So I put this database together and I want to build a model that talks to that. That's sort of the first step. So here we are in EOModeler. and you want to build a new model. Now new in WebObjects 5.1 we have increased by 50% your choice of adapters.

I hope to live long enough to see this device actually scroll. This is a scrolling thing here. : We're getting there. So I want to make a JDBC-based object model. I happen to have -- I've got OpenBase on here, but, you know, it could be any decent relational database.

And you get this terrific panel here where you have to type some string of cryptic gibberish that tells it how to connect, and it's different for every -- I don't know, I'm going to hit the Wolympics database on this particular machine. You specify a URL in JDBC that says, how do you want to connect? What machine is it on and what database is it? And the syntax of this is all over the map for different databases. I did memorize how to do it for OpenBase, so that's what we're going to do.

Now, the model wizard is going to connect to the database and ask you a whole bunch of questions. Do you want primary keys? Well, yeah. Do you care about relationships? I don't know. Storage procedures? No. We'll do this later. And it asks you, here are all the tables in the database. There's an athlete table and an event table and a flag table and metal and image and everything. Which ones do you want? Well, use all of them.

And now here come all these -- you know, I never really understand what this is all about. This is just asking me some -- Thank you for your question about relationships. I have to read one of those WebObjects books, apparently. I suppose it would tell me. I should just blow right past that. Is that important?

I always hit next. I always hit next. And that's something to do with referential integrity. You know, you delete Team Canada. Do you want to delete all the athletes from Team Canada as well? Well, no. So here is a starting object model. This is a file that I'm editing here.

And you can see it's got all this information in here that athlete objects come from the athlete table. And flag objects come from the flag table. And medals come from here. And we have all these different kinds of objects we can make. And I could get in here and, you know, change the names around. Maybe we want to have song out of these instead of anthem out of these.

I was really kind of, eh, maybe not. You know, I was really hoping that today would be the national day of somewhere so we could all stand and sing the national anthem of something. But it's not. I looked on the Internet. Last year I did my demo on Victoria Day.

We all sang God Save the Queen. Yesterday was Independence Day or Liberation Day in Norway. That was the closest thing I could find to today. Are there any Norwegians here? Anyone want to bring a flag up on the stage and we could all sing the Norwegian anthem? No? Oh, shoot.

Sorry. But here is really a file that's describing what kind of objects you want to make out of where. And you can look into this and see it on what we call the diagram view. You can see that it's picked up. Whoa, complicated. You can see that it's picked up all these relationships that are specified in the database as well. So a team has a list of athletes. And, you know, there's one-to-one joins. There's one-to-many joins. And it's all constructed according to the various relationship information that's in the database. Or I could add additional relationships here. And I could delete things. And I could manipulate properties.

Get rid of the ones I don't want. But rather than mess around with that for a while, I did a little bit of this last night. I got my iPod here. I understand that the marketing guy in England markets web objects and also the iPod. Well, he would like this. Here, right off of my iPod, I've got the object model that I want to use. I understand you can actually put music on an iPod. Is that true? I haven't tried that.

Actually, what am I doing? I'm going to put that there. All right, here's my object model that I want to use. Close, close, close. I'm getting rattled. I might have to say the word here. Just a minute. No, I don't want to say it. All right, anyway. This one's just slightly tidied up. I added a few relationships, and I flattened a few things, and so on. And I'm going to use this to build out a simple WebObjects application.

So let's just make this a little smaller and put it off to the side. And start up your friend and mine, Project Builder. And Project Builder lets you build all sorts of different exciting things, much as I would love to build a Carbon bundle right at the moment, or an IOCit driver. It might be fun to try that in a WebObjects demo.

I think I'll build a WebObjects application. And at this point, you get to give your application a name. And I've got this word stuck in my head. I've been hearing this word all week, Jagwire. I'm going to call my application... Um... Uh... It rhymes with fire war, I think. I'm not sure.

But that's going to be the name of my application. That will be part of the URL. And here's this panel. Do you want to deploy this servlets and do you want to do this and that? And you know, I want to go to one of the sessions and learn what these check boxes are, so I'm going to turn them off for now. And this is a good one. Something to do with web services. Bob mentioned web services. This panel is new to me. I don't know what this is at all, but it looks great, doesn't it?

Add the Java Access Framework. Do I want to do that, Bob? No? Okay. Please refer to the WebObjects web services documentation for more information. All right, I will. I'm sure that's great. And here I get to add some frameworks. Just in the interest of saving a bit of time, I have pre-written a few objects.

And in fact, they're just objects that I like so much that I carry them around on my iPod. So I'm going to add a few frameworks off of my iPod here. Here's my iPod. Frameworks. Yeah, these are all good. I'll talk about what these are later, but they're compiled Java things that I'm going to use later in the demo.

And we're done, and so here is a blank WebObjects application. So far it doesn't have any connection to a database. All it really has is one web component called main that's got an HTML file in it, which is really not very exciting. And it's got an even less exciting WAD file in it because there are no objects defined in the first file. I could edit this all here if I want, or I could double click on this to actually edit this component in WebObjects Builder.

So here's WoeBuilder. Here's the area up here where you can type the HTML for your fabulous page, the games of 2002. And I really love these horizontal rules and this is enough of an HTML editor. You can make things bigger and you can put them in color and really you should probably go and get Dreamweaver or GoLive or something like that that's a better HTML editor and do that part if you want. But you're completely free to use WebObjects Builder if you like as well. I think WoeBuilder is fine for getting started. So here we go.

The games of 2002. I'm going to put in a form because I want to search for who are you looking for. We're going to look up athletes. Okay. and I want to be able to look them up by their first name and have a text field. Maybe their last name. and have another text field and a submit button. And I'm just designing my UI here.

We really want to find athlete objects. The idea is going to be when I hit submit, I want to cause something to fetch a list of athlete objects and then display them. And I want it to fetch the athlete objects based on what I typed in those two text fields.

Well, this model file knows how to create athlete objects. It's got all the information in it about databases and tables. And so I can drag this athlete thing out of EOModeler and drop it over here and add what we call a display group. Pardon me, what was that? Okay.

I think it's offended that I'm calling this Jagwire. The source file is unparsable. What are you talking about? Just hang on. Bite me, bite me, bite me, bite me, bite me. could not open source file. Okay, are you smart guys? How come I can't open my source file? I'm working off the beta here of ERTE, so we'll just, give me one sec here.

There we go. Ah, phew. For some reason it was not connected to the project builder, but now we're fine. Stop biting me. So here we go. We want to add this. Yes? There. Oh, man, thank you. I've added now to this page something called a display group, which is an object that knows how to go and fetch certain kinds of other objects from the database.

You know, it's going to fetch them out of this object model here, which I don't really need now. And you can hook a few things up. You can say that the submit button, here's all the messages you're allowed to send to a display group, and up above it are the various properties you can set. So I want to send the message qualified data source whenever someone clicks on that submit button. So the submit button in my inspector is now going to send that message to cause this object modeling thing to go and fetch.

And you can set up a few other bindings here to say, well, let's match, see it knows the properties of athlete objects, let's match their last name. name here when we're forming our search and their first name here Now this is a complete application that would actually go and fetch all those things, and it's not actually displaying anything yet, and I think I would probably get bonus marks if I were to display the athletes that it found in the database. So I'm going to add a little table.

And this is an HTML table with a special difference. There's a blue line around the second row, meaning that this second row is encased in a WebObjects repetition, a WO repetition object. This object is going to repeat over and over again once for every object on some other list. So if I fetched 37 athletes, I'll have 37 rows plus the title row in my table. So I'm going to display the athletes' name.

[Transcript missing]

and running it. Project Builders Compiling is making the huge--look at the class path. Holy mackerel. And starting my application here, and it's going to ask Internet Explorer to come back and rendezvous on this particular URL. So here's IE. It's made up my first page here. I'm looking for people named, I don't know, Steve.

And oh, here's a bunch of Olympic athletes named Steve. Team Steve, yeah, that's great. Find people named Bob. Is there any? There's only one guy named Bob in the game. This is actually my favorite. Yang Yang. Oh, don't leave me alone. There are actually two athletes in the Winter Olympics named Yang Yang. This is why primary keys are important in your database.

You know, this doesn't uniquely identify anybody, but you might want to go back and say, "Well, what team are they on?" Well, I put another string in here, because each athlete has a relationship to a team object. What team were they on? Let's display the name of the team that Yang Yang was on. And, oops, sorry, I dragged it to the wrong place. Right to that string right there. Thank you.

And if you say that, the thing I like is that you can keep going here without even restarting, and it helpfully tells you that they're both from China. Well, I still can't quite tell them apart. Maybe if I knew what sport they played. I'm going to put another thing in here. We'll go over to the discipline object. What discipline would they end with? Are they skiers? Is one a skier and one is a skater? Maybe that will help me out. Oh, great. They're both short track speed skating.

There's got to be some way to tell them apart. How about an image? Those are just strings. I'm going to put in an image object here. And athletes in this case in my database are related to an image and images have some binary data. Here I'm hooking it up to an image object. And a mime type, is it GIF or JPEG or what is it? Let's see there. How are we doing now?

Oh, okay. Oh, it is two different people. Okay, one has a yellow sleeve on her suit and the other one has a... But, you know, without me having to write any SQL so far, I can actually fetch objects from a couple of different tables. There's all this fetching going on for me, and I'm kind of blissfully unaware of it at this point. WebObjects does have a way that you can turn on SQL debugging. You can send some crazy message to say, I want to turn on logging of SQL so I can see the SQL that's being generated for me.

And I used to go to the documentation and look that up every single time, but I got tired of that, so I decided to use this palette feature. These palettes are places that you can put objects that you've written once that you might want to reuse again. And I've got this palette over here that just contains a checkbox that turns SQL logging on and off. We'll add that to my page here. You're going to see the SQL will go whipping by over here, okay?

So, uh...

[Transcript missing]

Some of these are, you know, my children and some of these are other things I just happen to have sitting around. So, you know, you can probably try to decide which of these are real Olympic athletes and which ones are not. But the whole Enterprise Objects framework layer makes it fairly easy to do this sophisticated fetching across four or five different tables. Well, I'd like to make this even a little more elaborate, if that's possible. And maybe we can tell our Yangs apart if we have a list of the actual events that they were in.

So here in this second cell, I'd like to add what we call a repetition. This is just something that explicitly goes through a list. And I'd like to loop through each of the events associated with each athlete. And let me create a variable like I did the other time, event.

This here, this means event object from the event database, not some other kind of event. You could really mess people up by having a database with tables that were named like adapter and property. And, you know, you'd never be able to describe what you were doing in WebObjects. So let's see here. Here we're going to loop through all of the events, and I want to display each event somebody was in on a string. Event name, like that.

Now here I do need to recompile because in that move of adding the event object, it actually created one more line of Java. It added this thing to my main object saying, "Oh, we now have an object called events, so I do need to pause and recompile here."

I like it better when you don't need to recompile. Here we go. So show me all the Steves again. Here they are and they're both, that guy was in short track, pardon me, that guy was in short track speed skating and oh, that handsome fellow was in speed skating and the bunny was in the men's aerials and so on.

So we're looping through a bunch of different tables. And so far I've done this all with one component. This is one big component that just displays stuff. And I want to really have a detail component. I'd love to be able to click on short track speed skating men's 1500 meters and see the results. You know, load another one of these components to display the results. There's a lot of things I'd like to do.

And actually, oh, I really wanted to show this object to Mark Ritchie who's sitting up here. Me being a bit of a palette junkie, I've got all these things on palettes that I've collected over the years. And I figured this one out the other day. Drag and drop that in here and save it. And that gives me alternating row colors in my table.

Thank you. Thank you. Somebody said cool. Thank you. Thank you. Let's make a second component that's going to display details of a particular event. My goal is to have it so that this is a hyperlink that takes me to the details of men's ice hockey. Well, I'd like to have a second page here. I'll just save it right away and I'll call it Event Details.

And yes, I want to add to the project. And this is going to be something that just displays one particular event object. And I want to-- hang on. Can we turn your head aside for a moment here? We'll do that again. I missed one checkbox. I want to add an event object Here's what I meant. I want to have a way to set the event object associated with this page from somewhere else. When we load this page, I want to be able to tell it, "Here, 1500 meter speed skating. Please display that particular event object."

And I just want to save a little bit of time here. And you can have just HTML fragments on palettes, too. So here's a little table that just goes through the event and displays all the medal winners. It asks the result for the medal and the medal for the name, and it asks the result for the winning team, and it asks that for the flag and puts it up here. And it loops over all the athletes.

And I wanted to avoid the four or five minutes of fumbling around to actually construct this table, so there it is. But I do need to add another couple of objects. This is just exactly what we did before. We want to have a result object, and we want to have a athlete object, just like before.

So there's my component that's going to display all the results of a particular event. And if we go back to the first page, Remember that? That's the string that's displaying the name of the event. Well, I want to click on this that turns it into a hyperlink. It wraps it inside a hyperlink object. And in particular, it puts it in a hyperlink object that can send a message somewhere.

And I get to decide what message I want to send. I want to send a message that says, let's find the event details page and let's give it this particular event and tell it to go. So in WebObjects Builder, you get to add what we call an action. I'm not declaring a variable here.

I'm creating a little stub of a procedure that's going to load up another page. Show me this here event.

[Transcript missing]

This is the action method associated with that hyperlink. Even though there may be 20 of those hyperlinks on the page, they're all sending the same message back to my application. Show me this here event.

And I now get to demonstrate my incredible command of Java and write a line of code here. Here is, this is the main Java file. This is all the code associated with the, with the main page. Not really very much of it. A couple of object declarations. And then this thing here.

It wrote out this little stub for me. It said, all right, I'm going to look up the page called Event Details for you and give it to you as a certain kind of object. And you can add any little initializations or anything you want here. And then I'm going to return that page, which will cause it to be generated.

Well, I've got to do one thing. I've got to say, next page, set the event that you are going to display to be the same one as I'm currently displaying on my list. Remember this page, the first page, had an event object as it went through the list of events? And this is just kind of mind-boggling to people in WebObjects that it figures this out sometimes. And it just knows when the request comes back in, which one of those 40 hyperlinks, which specific event object caused that hyperlink to be created.

And hopefully this transition is fairly smooth here. Let's try it here. Now we're going to compile it. It's going to add the other .wo component to the application. ClassPath is probably even bigger now. I don't know where it goes. And we'll launch this now. Now we have a two-page application.

Here we go. Show me all the Steves again. Now these are hyperlinks, right? And there are, you know, 15 hyperlinks in this page. Each one of these is sending that same message back to the application. Show me this here event. But WebObjects can sort out which event object was used to create this piece of the loop and then pass that automatically to the other page. Tell me about the man's 500 meters. Hey, that was a good one. Gold for Canada and silver for Canada. Holy smokes.

So now we're fetching, we're going through the database and we're picking up the winning team and the members of the team because there can be, in this particular database, there can be more than one person on a winning team. You know, if you get down to hockey or something, there's like a whole bunch of winners on a hockey team. Oh, Canada wins again. Oh, isn't that nice?

And so, chance of two randomly selected events I might just happen to click on here. So this is some, you know, if you wanted to code this in SQL and HTML, you know, by hand, it might get kind of ugly with all the stuff that's in there. So, you know, if you wanted to code this in SQL and HTML, you know, by hand, it might get kind of ugly with all the stuff that's in there.

So this is some, you know, if you wanted to code this in SQL and HTML, you know, by hand, it might get kind of ugly with all the joins you'd have to be doing at this point, but I'm just exploiting relationships that are found. Hi. Did you get that? You want to take another one? Take another one. Oh, come on. Take another one.

Hi. So we're just working through various relationships that are found in the database here. Now, I look at this and I think this is not nearly as stirring and emotionally evocative, this page, as it could be. And people come to my session really wanting to hear national anthems for some reason.

So we go to the event details page here, and I want to add something. I'm going to add right here. See, there's the medal named gold, the country name Canada, and the flag. I want to add another thing here called a WO Embedded Object. This is a little thing that comes with WebObjects that dumps binary data to the browser and lets it figure it out with an embed tag, so QuickTime movies or Flash or something like that.

And I don't want it to be too big, so I'm going to go in here and just, oh, just a second. I'm going to go up to the inspector of this embedded object and add a couple of bindings. I want its width to be, I don't know, 150 pixels, and I want its height to be, these aren't dynamic at all.

These are just going to get dumped straight through to the, how many pixels high does a QuickTime player have to be? 16 pixels? Does anyone remember that magic number? No? Okay, well. But more importantly, what data do I want this thing to dump out to the browser? Well, conveniently, Uh... Each result is associated with a team, and each team is associated with an Anthem object.

And some of these Anthems, I'll tell you, are MIDI files. Some of them are MP3s in the database, so they have different MIME types, but I can just bind it here and let the thing figure it out on the fly. Hope the sound's working on this computer. Sound?

Going to be okay? Yeah? All right. Great crew in the back. Look how alive they are. Fantastic. So, let's try this again here. Here we go. Here comes some national anthems. Oh! Oh, they're all playing at once. Well, that's nice. Um... Um... Hmm. That's a lovely effect. I guess there's a couple of ways I could fix that.

I could find... Find that component and you can add whatever bindings you want. You know, I happen to know that you can add an autoplay false to these things. And that just embeds autoplay equals false in the HTML that goes out. So now hopefully they don't all play this time.

Phew, that's better. But even better, you know, you wouldn't really play this anthem if your country had lost to Canada in the Olympics. We wouldn't hear that. And I only mention that because it's an excuse to introduce another object from the collection here. We'll, we'll... I want to add, this is one of my favorites, how many of you like the good old W.O. Key Value Conditional? How many WebObjects programmers have ever... oh, thank you, thank you, thank you. Key Value Conditional, thank you very much. I had nothing to do with it.

But the idea of a Key Value Conditional is it exploits this key value business that people love so much. No, no, later. It exploits key value coding and you give it a key, a message you want it to send, and a value, which is maybe another object, and say compare these things, and if they're equal, display everything inside me. It's conditionally displaying something. Well, the key I happen to want in this case is, let me think here, I want result.metal.name. It's going to go through the graph and figure out the name of the current metal, and I want to compare that to gold.

That could be an object, it could be a string, it could be, you know, any other object and thing. It's just going to compare the two things. And hopefully this time we have only the winning countries anthem. Oh, that's better. So in this case we've used an object that dynamically sends some messages and makes a decision on the fly about what else it wants to include in the database. So we've now got only one anthem player here. I went to the same public school as this guy here, Eric Lindros. Anybody from Philadelphia or New York here? Yeah, all right. I'm happy for you.

Thank you for joining us. I'm Steve Hayman. I'm going to go ahead and start off by saying This might have seemed like a lot of work. I think that's actually quite a bit to get done in just a few minutes, you know, starting really from nothing. I admit I did drag a couple of things off pallets, but they were genuinely reusable objects.

But I want to take a moment or two to show you one of the many direct-to family of fine products we have here with WebObjects growing every year. I want to show you the first one, Direct-to-Web. Direct-to-Web is a technology that uses one of these rules-based engines to decide on the fly by studying.

You give it one of these object models, and you tell it, you know, go and study this object model and learn what kind of objects are embedded in the object model. And please make me up an application that lets me fetch things and change them and search for them and add new ones. And Direct-to-Web, by looking at the model, can generate a UI on the fly. Direct-to-Java Client is the same general idea with a different system. It's a sort of UI. So I want to just quickly make a second application here where we can modify Olympic results.

Because sometimes after an event is over, you change who the winner is. Which is, this is a new thing. Just like the U.S. election. Well, you didn't change it, but you thought about it really hard. So I want to make a Direct-to-Web application here. Or Jagwire Direct, we'll call this one here.

More exciting checkboxes that I need to learn more about and frameworks. But here I want to tell it specifically what object model do I want to use. Well, I kept that one on my desktop. There it is. That's the object model I want to use with the information about fetching athlete objects and teams. You can choose a variety of different styles here.

And that's it. We're done. We now have a complete application that can actually fetch anything from the database that will let me update any property of anything in the database. Let me make new objects and delete things and so on. Plus, as a bonus, I get to refine the UI from within my browser. Here inside my browser, I get to tell it, no, I want to have a pop-up list for that thing instead of a browser. And you know what?

I don't want to display this, and this thing should be uneditable. I get to tell it all that right here in my browser, and that writes rules back at the back end, which interact with this rules engine and modify the UI the next time it's generated. So let's log in here. This is the completed application.

My password, which is a 6789 of those dots. Yeah, that's good. You should make your password dots like that, because then you can cut and paste them. It's very handy. And I would like to be able to change the UI, so I'm going to click on that checkbox there.

So here is Direct2Web's first stab at a user interface for fetching and updating anything from this object model. It's found the list of objects and knows all the properties of all the different objects. And you can fetch anything. Fetch all the athletes whose last name begins with H. And it will make up a page for me here with every property of every athlete whose last name begins with H. Now this is not the world's best UI, but it's not bad for a start. And I can tweak it here. I can hit this customize button.

and a little Java Oplet is going to pop up here that lets me modify the display of these various properties. See this thing here? This is a list of all the properties that are currently being shown in this window. So we're showing them in alphabetical order. Date of birth, first name, full name, gender, highlights, yadda, yadda, yadda. Well, I can change it all around here. I'd really like full name to be first, and there's no need to display first name or last name at all. And let's have date of birth. Well, that's a couple of simple changes.

And you hit save and that writes some new rules at the back end that rewrites this UI on the fly by studying the rules engine. You want this rule applied when this object is generated. We can get even fancier here. You can say I want the page to be a different style of page.

This is my favorite here. And then that writes these things out as a different kind of page here. And there's a bunch of rules at the back end that govern how every possible thing is going here. There are rules that state what the layout of one of these editing pages looks like, for instance. And you can dive in here with this wizard and refine the rules. It's usually a pretty good start, but you can refine them on the fly here. Well, I want to get to, let's see here, I want to fetch... Figure skating events. What do we got?

Figure skating events. We've got four different figure skating disciplines in WebObjects. Oh, this was a good one. Pairs. Anyone remember that? Was there something about that in the paper? We had two golds and a bronze. Two golds and a bronze? Oh, yeah. Two golds and a bronze. I'm almost done. What? Is my zipper undone or something? What? Thank you for your time.

[Steve Hayman]

I am? Yeah.

[Steve Hayman]

Let me just finish this. I'll be one minute and then I'll take some questions, okay? I thought I had until this was done. That's when the Q&A is done.

[Steve Hayman]

Oh, the Q&A is done then. Oh, pardon. To customize this, I want properties, I want, actually I want to display results on a table like this.

[Transcript missing]

That's as far as I wanted to go. I'm done, I guess.