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: wwdc2000-401
$eventId
ID of event: wwdc2000
$eventContentId
ID of session without event part: 401
$eventShortId
Shortened ID of event: wwdc00
$year
Year of session: 2000
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: ...

WWDC00 • Session 401

WebObjects: Technical Overview

Tools • 1:10:26

A technical overview of WebObjects for new developers and evaluators, this session highlights the key aspects of its architecture, its numerous technological advantages, and its relevance for web application development. Topics include what's new in version 4.5, a roadmap of features, building a high-level application, and an introduction to EOF.

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.

It's traditional to survey the audience at the beginning of one of these sessions, as you saw at the last one. So I want people to raise your hands. How many people here are Canadians? Yeah? How do you pronounce J-A-V-A? "Java! Java! Right? Java!" James Gosling, the inventor of Java, who I tried to get him here today. He's from Calgary, so I think if I pronounce Java, it's out of homage to the inventor of this wonderful language. By the way, it's also pronounced "Aqua." I seem to be losing on that one. And if I say process and project, I hope you'll forgive me.

This is a, oh yes, one other announcement. I'd like to, because this is a standing room only audience here, it's not quite as standing room as the last one. Seriously, I would like the Apple employees to please vacate their seats so that the paying developers can come and sit down. So if any of you guys are Apple developers, you've heard me talk about this a million times, you Apple employees, get out of here. I don't need you.

You're just going to ask me hard, embarrassing questions at the end anyway. I still see a few seats here. Put your hand up if there's a seat beside you. There's some people standing out there. Yeah, there's a few seats. There's a bunch over here. It's a good place to stand over there. Seriously, Apple people, out.

Out and about, Apple people. Pardon me. Well, I want to give you a technical overview of WebObjects, and I want to position this product for those of you who presumably don't know too much about WebObjects development. I have the great advantage in this seminar of not having to give an in-depth answer to virtually any question you might ask, because there's 16 more seminars coming after this one, and so the best answer I can give to just about any question you might ask is, "Go to session 417 on Direct or whatever," and they'll take care of it there.

But I would like you to understand how a WebObjects application works, what the different pieces are, what the different objects are that you write versus the ones that we write, how you choose ours, how you choose yours, what's at the front end, what's at the back end, and what do the tools do. If I can get most of that across, I'll be pretty happy.

So... That's our goal. We're going to look at the frameworks. If all goes well, and I have had some trouble with my database server here. My database server, by the way, is running Windows 2000, so that if it crashes, it's not my fault. But I do hope to build a little application at the end if all goes well.

And I'd like you to understand at least the titles of the other sessions. What the heck is direct-to-Java client, anyway? Let's find out about that. I'm going to have these little logos in my presentation when it's a good spot for you to go off and think about a different session that might answer more about this.

So what does WebObjects do? It's an application server. I hate that term, okay, because it sounds like all it's doing is coughing up applications. But this is the slot the industry has put us in, and I think it's much more than that. It's developer tools, it's frameworks, and a runtime environment and a monitoring environment, but most importantly, frameworks that do most of the hard part of development for you.

For instance, the WebObjects application, you might write some objects, you might choose some of ours, and deploy them on this box in the middle, this big square here, and those objects might talk to a variety of data services at the back end, and might deliver either a Java client or a web-based interface out the front end.

In fact, the same objects can do both kinds of interface, and there are other objects that can even do WAP interfaces. How many people here have WAP on their telephone, right here in the room? Darn, I was going to write a WAP application and have you log in and send me something during the demo. I knew that probably wouldn't work out. Now, who is this for? This is a developer product. Those of us who are Apple iServices employees can make this thing look much easier to use than it maybe actually is, but that's all right.

This is a powerful product with a huge amount of functionality and a corresponding learning curve associated with it. But a steep learning curve is good because it means you're going to learn a lot in a short period of time, right? WebObjects works with a whole variety of technologies. I'm going to talk for the most part about WebObjects 4.5, but I'll touch a little bit on what's coming in the future. We work with a variety of programs.

Well, okay, today with 4.5, you can use Objective-C and WebScript, although I would encourage you, if you're going to get started and you want to move ahead to the new all-Java version, probably best to start working in Java today. We work with a variety of databases, a variety of adapters that you can see there, and this is an open process. There are more adapters coming from third parties. We have a variety of mainframe connectivity solutions. You can build different user interfaces. You can work with a bunch of web servers.

The most important thing, open, open, open, open, open, open, open. This is a very open product that people have made integrate with a whole variety of oddball things that we've never heard of. We had a customer in New York that apparently wanted to use PIC as their database. When I heard this, I thought, "PIC, my God, didn't that database die in about 1975 or something like that?" But we have an open enough product where we can make it integrate with anything that has a reasonable API.

You can develop on those various platforms. You can deploy on those others. Note that Linux and Mac OS X are sort of future release platforms on this particular slide. You can mix and match those as needed and grow from a small deployment to a vast one without, hopefully, a huge amount of effort.

You might start with something like this where your application is all deployed on one little box there. Don't be frightened by this next slide, but you might grow from that to something like this where you've got multiple firewalls and multiple web servers and multiple web object servers. In fact, these purple things over here, these are actual identical copies of your web object's application running on a bunch of different machines. A little thing we call the adapter. It runs on the web server and sorts everything out, keeps everybody straight. You can move fairly seamlessly from that to this with our runtime environment. If you want to know more, go to the Building Large Scale Applications session.

A couple of key ideas. There's objects at the front end, objects at the back end. The ones at the front end we call Web Components, and you use WebObjects Builder to develop those. The ones at the back end are Enterprise Objects, and you use Enterprise Objects Modeler to do that.

I think they took me for this talk because I talk faster than anybody else at Apple, but... But these objects are kept completely separate. The objects that generate the HTML user interface have no idea what the heck is going on back at the database back end, because they're all talking to a common middle tier of business objects that provide functionality on request to the front end HTML components, and these middle objects are created on demand by the enterprise objects framework objects at the back end.

And all the decisions about how any of this works are actually made pretty much at runtime. So at the front end, a web component consists of some HTML that you might type up yourself or get from somewhere, along with this one special tag. This is all we put in the HTML is this tag that says WebObject.

It's a tag that says, "Here, something cool is going to happen." Really, that's all it is. A WebObject name equals picture. And then there's another file that says, you know what? When you see that WebObject tag, name equals picture, that means send this certain message to this object at the middle tier and take the result and put it where that WebObject tag was. And repeat this process over and over again to build a dynamic page on the fly.

These components at the front end that are producing these things can produce all sorts of stuff. They can produce plain text, they can produce more HTML, they can produce fancy, clever JavaScript effects, images, WAP, AppleScript, whatever you like. It's an open framework at the front end there. And you can have a variety of non-HTML components. We have a partner, ReportMill, that has a really interesting PDF-based reporting kit that takes your middle-tier objects and builds a dynamic PDF document that you can vend to the end user.

We have a partner in Europe called WAPObjects that's building WAP-enabled things. I just think that's so much fun to say, "WAPObjects!" It's like a cartoon sound effect. We also have APIs in the product that can generate XML in a fairly straightforward way that hopefully I can... I don't think I'm going to show you that one. There's a session on XML coming later. At the back end... Oh, I can see this down here now. This is great. Thank you. I would like to say "Konbanwa" to the Japanese translators.

Konbanwa! Konbanwa! Oh, they're waving. Thank you. Thank you very much. Also, whenever I do a presentation, I like to try to fake out the camera man. So I like to go this way... For the backend, we've got these enterprise objects. We call them enterprise objects, and they are objects like anything else in the computer science sense of the term. They've got data.

They've got procedures that operate on this data. But what makes them special is that there is something gluing them to a data source. There is this whole backend architecture that says this kind of object, customers, comes out of this, let's say, Oracle table. For every row in some Oracle table, let's make a customer object. For every row in some other table, let's make another kind of object. Excuse me. on. Oh, a whisper, a whisper.

Enterprise Objects manages this whole... has a collection of middle-tier business objects and takes care of issuing the SQL necessary to fetch things out of databases and constructing the objects. It also notices when these objects change and it pushes the changes back into the database. Nothing I like less than SQL programming, and EOF is a great way to keep me from having to actually know anything about SQL, so don't ask me any questions about SQL.

EOF also has a very sophisticated architecture for managing relationships of objects. Customers purchased a bunch of products, so a customer object has a list of product objects. In the database world, it would be a one-to-many join. Students take classes. A student has a list of classes that they're in. A class has a list of students that are taking it. Many-to-many join with some sort of ugly middle-intermediate table in SQL.

In the WebObjects environment with Enterprise Objects, this is very, very seamless. You just think in terms of objects and their properties and their relationships to other objects. EOF, the Enterprise Objects framework, is the real gem of WebObjects. I want to say I was not in the meeting when they picked the name EOF. I mean, that kind of meant something in computing already, but this really is a dynamite product here. How's that joke working in Japanese? Probably not very well.

This really is the best part of WebObjects, is Enterprise Objects. I would encourage you to go to session 403, please, this object modeling session. I'm going to show you a rough look at object modeling here, but there really is a huge amount of meat behind this that provides you with all the rocket fuel necessary to turbocharge WebObjects.

Coming soon, EJB. Don't ask me, Rory, who was just here, he's the guy to ask. He loves talking about EJB. And all of these different objects are bound together at runtime by a WebObjects application that finds the front-end WO components, finds these tags, figures out what messages it has to send, fetches objects, maybe from databases, and mixes everything together and sends a stream of plain ordinary HTML, most of the time, to the end user.

along with some advanced session management. We have a very sophisticated session object in WebObjects. You might have only one copy of your application running and 100 users using it. There are going to be 100 different session objects created by the application maintaining data for each of those individual users. And this is a full comp sci kind of object.

You can subclass and implement your own behavior. You can use a variety of sophisticated strategies for dealing with people that seem to have connected to your application and then disappeared. You can arrange for objects, session objects themselves to be kept in the database. You can add shopping carts and security and so on. We give you a framework that provides this individualization as needed.

along with some runtime monitoring tools. Remember that big scary slide? You've got to get from the one copy of the application to the 45 distributed copies on seven different machines. We have a tool called Monitor, which itself is a WebObjects application. It lets you go clickety-clickety-click. I want four copies over there. I want three over here.

I want two over here. It starts them all. It keeps them running. It sends you mail if they crash. It measures the load and statistics and so on. Pretty good runtime environment. So here comes my big money slide. We have this thing called the request-response loop, which is sort of the core of everything that goes on in WebObjects.

A user makes a request. They fill in a form. They click on a hyperlink. Data comes whipping in through the web server. Something happens on the web application, and a response goes back. Understanding that is sort of the core of understanding the WebObjects architecture because it shows you where the various different components play. I'm going to show you a few pieces of this here.

Let's suppose on today's vast internet there are three users and You know that's the net because it's a cloud, some sort of ANSI standard. And you've got a web server with this WebObjects adapter on it. You've got a variety, I'm showing three here, a variety of application servers with Enterprise Objects adapters to talk to databases.

The web server, as we've heard, can be pretty much any operating system, any web server. The WebObjects adapter, we have special adapters for the more popular servers, and we have a CGI adapter that really you probably shouldn't use if you're using one of these other servers, but we have a variety of tuned adapters for certain web servers. The application server can be a variety of platforms. Again, Mac OS X and Linux are sort of future directions in the next product. And we have a collection of Enterprise Objects adapters that can talk to a whole bunch of back-end databases in a variety of ways.

So let's suppose we had a really incredibly complex WebObjects application here, where a user's going to log in, he's going to type "shayman", it's going to do some processing, it's going to look up "shayman" in the database, it's going to make a user object or something, and say "Welcome back, Steve." I thought long and hard about this particular example.

So there's two things that have to happen. We have to process that request. We have to figure out what to do with this string, S. Hayman, that's coming in from the web browser. And we have to generate a response. We have to make up some HTML and send it back to the web browser.

Well, it's actually three. It's actually three customizable phases of this loop. There's a second action-invoking phase. After WebObjects has collected all this data, then it thinks for a moment, what action should I send? What message should I send to what other object? And then that object is responsible for generating the response.

So to see how all this works in action, let's suppose a user has submitted a request to a web server. All the web--and the string S. Hayman is coming along. They filled in the form along with some HTTP gunk about what field that was and everything. That request comes to the web server, and the web server adapter hunts around for a copy of the WebObjects application just to hand this off to.

The very first time, it's going to pick one at random. There might be 30. It picks one at random. Subsequent times, it's usually going to redirect you to the same copy of the application that you started with, although that's optional. So all that the server really has to do is relay this string to the WebObjects application. So it finds one of those throbbing instances there.

passes this string, the user type is Hayman, that kind of information is coming along to this instance. And that particular instance is going to find the component that created this particular page. And a component is a combination, as I said, of some HTML and a second file that defines the meaning of these tags. And all you WebObjects wise guys in the audience are already saying, "He didn't close the WO tag, and besides, the tag is not WO, it's WebObjects." I don't care, I didn't have room in that thing.

But previously, this login component was used before to generate that page that says, "What's your name?" And now that the response has come back in, the WebObjects session is able to automatically find the component that caused that page to be generated, and to study these bindings down there, value equals username.

That means whatever they typed in the box called input, we want to assign to an object called username. So it takes a look at the various foreign values that came in, and it figures out what action to invoke. Now there's probably some Java code associated with this particular component.

You can see in this little example of a login.java, this object has a string called username, and it has a little procedure called handleLogin. And those bindings in that other file in red there, that's called the WAD file, the WebObjects declaration, that says where stuff goes. The data that you got as the username should be stuffed into this username variable, and then the method handleLogin should be invoked.

And the handleLogin method here is just messing around with a session saying, "Here's the customer name. You should go and fetch the customer object." And then it returns the welcome page. So that's phase one and phase two of this request-response loop. We've extracted some values. We've figured out what action to invoke.

The action is invoked, which, as you saw in that bit of code, says go find the component called Welcome. Another one of these things is loaded. And in this case, there's a tag in there that says WebObject name equals username. And there's a second file that says, you know what, username is a string and it gets its value by sending the message customer to the session object, and it sends the message first name to that one, so we're going to need to fetch some sort of customer object so we can send this message, and I'm getting to that.

Any needed objects might be fetched from the database here, and some SQL is going to be generated automatically. So one of these object model files, which I'll show you in a moment, is automatically loaded, and that's just a textual description that says, you know what, we're talking to Oracle in this case, customer objects are coming out of the cust table, so you should probably find the row where some property equals shayman and return that and make it into a customer object.

So our backend automatically figures out this SQL, sends it to the database, some text comes back from the database, and is automatically stuffed into a blank customer object that EOF automatically fetched. So the application is really kind of disconnected from the details of how these customer objects are actually created. All that SQL flow back and forth happens automatically.

And this response component says, oh, now that we've got that object, I need to send the message first name to it, some string, Steve Hayman. And then Steve comes back, and we take that web objects tag and we substitute it with whatever the object responded with, Steve, and then some fascinating HTML goes flowing back to the end user.

I assure you, you can write more sophisticated applications than this one with WebObjects, but there's a basic loop like this at the heart of every single one of them. And every one of those arrows that you saw is an opportunity for you as a developer to customize what's going on here.

You can leave the session object alone if you want, but if you want, you can also have it intercept these things, intercept the loading of components and do clever things. Steve Hayman In fact, you can do quite a bit without writing any code at all, although I don't want to give the impression that that's how this works, because most of the objects as they come out of the box are prepared to wire themselves into this request-response loop. So the request response loop, one of the reasons I came up with this slide, and one of the interesting things about this job, is that you never really know what Steve Jobs is going to announce in the keynote.

Is he here? I used to go through a huge song and dance about this request-response loop because this was how we licensed WebObjects, and this is how we decided what to charge you. The more of these requests and responses per second, the more money you had to give us. We had a whole tier of architecture, right up to $50,000 where you could have an unlimited quantity of these things. Now it's $699, but that doesn't excuse you from having to understand how this actually works.

Please note that there was no mixing of SQL and HTML in here. In fact, they're kept as far apart as possible. I think the worst scenario you could imagine is to have SQL and HTML in the same file. Something's wrong there. You've got your user interface and your persistence and your business logic all mixed up.

In our case, we keep them pretty separate. We have one kind of object that sends out HTML. We have another kind of object that connects to a database. We have a middle object that implements the business rules. Is this student allowed to graduate? That might be a business rule on a student object.

What's his first name? That might be a string. But something like, "Is he allowed to graduate?" might be a complicated piece of Java that determines whether he's paid his parking fines and returned his library books and sends a bunch of other messages and then says yes or no.

You write logic at a middle tier like that, and you let our framework map the data into and out of Oracle or whatever you like. You let our other frameworks and our other components build the UI on the fly. And you don't personally have to write SQL or HTML at all, unless you want to. Some people want to.

So we have three tools here that are used in WebObjects development. Project Builder, as I'm going to refer to it, has sort of been retro-renamed to now be Project Builder WO. For those of you who are experienced WebObjects developers, this is the new name of the project builder you're used to, Project Builder WO, just to keep it straight from the brand new project builder that engineering is working on for a future release.

But we have two other tools, WebObjects Builder that builds the front-end components, and EO Modeler that sets up this mapping to these middle-tier objects. And I want to talk to you a little bit about each of these. The old version of Project Builder, frankly, not that exciting anymore.

WebObjects developers in the room would agree with me that it's great that Project Builder is undergoing a major overhaul, and better debugging is coming. I had to do the WebObjects debugging seminar at WWDC last year, and I'm glad now, having done that seminar, that our story is improving a little bit.

By the way, do we have Mark Ritchie in here? Mark won the World WebObjects Debugging Championship last year at WWDC in my session. I'm sorry, Mark, you have no opportunity to defend your title today. Anyway, let's talk about these tools. Let's talk about these tools. Oh, this way, okay. No, come on, yeah, alright. Thank you. This, you know, this, which is the top of this? Can you tell by looking at this which one is, which way is the top? No, me neither, alright.

Please go to James Dempsey's session on designing reusable web components to hear a lot more about how that is designed. But the goal with building one of these front-end components is to come up with some HTML with these special tags in it that say, "Here's where something interesting is going to happen." And that might be a directory called main, main.wo, that's a WebObjects component, and it's got an HTML file in it.

It's also got a WAD file, a WebObjects declaration, that defines the meanings of each of these tags. The tag called string1 is actually a string object that gets its value by sending the message cost to the current product. And then there's some other properties on there, what number format should we use. The object called link1 is a hyperlink, and it's going to cause the message place order to be sent back to this object. And the third part of one of these components is typically some executable Java code here.

you need to create some of these things to build a WebObjects application. In fact, you'll probably create lots of them. You usually have one for each page and it's a whole fractal kind of relationship. You can have components that contain other components, you could have a header bar component and the menu thing down the side and you could have a footer and you could have components that cause a loop to happen inside of which other components are firing.

You build a lot of these things to come up with a complex application. And how do you make these? Well, you could use stickies if you want, you know. You can use Emacs, VI, whatever your favorite. How many people think VI is a much better editor than Emacs? Any other VI people? Good, good.

Emacs? Stickies? But the point is that all these things are just text files. We have some nice tools, but you don't have to use them if you don't like them. You can use whatever tool you want. Or you could use some kind of a WYSIWYG HTML editor, and there happen to be a couple out there that are smart about this extra WebObjects tag. Or you could use our own WebObjects Builder. And WebObjects Builder presents you with something like this. I should, I've been waving at that screen too long. Come over here.

In this bottom window, you're looking at some component, okay? And in the middle, that section that says HTML, that's a rough view of what your HTML is going to look like. There's an image object, that's the square. There's a string, that's the thing in between the curly things. There's a hyperlink down here, and you can dress this up with whatever HTML formatting you want. WebObjects Builder is a not-bad HTML editor. It does bold, it'll make the text bigger, it can drag in colors and pictures and make your thing look really ugly really rapidly.

So that represents main.wo/main.html, let's say. In the bottom half is kind of a visual representation of this WAD file. My current main object apparently has an object called "product" associated with it. There's a line, and below that are methods. It has a message called "place order" that you could send to it. And I might conceivably want to arrange that when you click here, where it says "click here" and by the way, that's the terrible UI to have it actually say "click here" in a hyperlink. That is so 20th century.

You need to make a relationship between that, you need to indicate that you want that message called when this link is clicked. How far can you go with this? So you draw, you draw a little line like that in WebObjects Builder. You draw a line from one to the other that says I want that place order message to be sent when this hyperlink is clicked. And new in WebObjects Builder 4.5, it pops up a little list of all the possible properties of a hyperlink object right there. You pick the one you want called Action in this case. This is the action I want the hyperlink to trigger.

and then you're done. In the top window that's an inspector. That shows you all the properties of the currently selected thing. And I'm going to hopefully run WebObjects Builder live in a moment here to show you how this all actually works. But this is the sort of methodology you use. You can work with a WYSIWYG view like that or if you like you can also work in a raw mode. You can type the HTML up yourself.

You can type the WOD yourself. You'll probably forget to put in semi-colons. You'll probably forget to close some of the tags. It's probably not such a hot idea to work in the raw mode. But you could also, if you want, farm out the HTML to a graphic artist in your department. They wouldn't need to know anything about WebObjects Builder.

So long as you begged and pleaded with them, I'm begging you, don't touch those WebObjects tags. Please leave them alone. That's kind of important. But At least you are not exposing all of your business logic. There's no SQL in there. There's no custom code that says how we compute whether a student can graduate. It's just interface. Just interface definitions.

Also, once you've written a bunch of these objects, WebObjects Builder has palettes where you can put common things you might want to use in several different scenarios. You can drag them off of here and drop them off of there. Four or five of these come with WebObjects. We would love it if you would all put this one on your application. A little image there, ready to go, powered by WebObjects. Drag that, drop it on your application. I think that's actually a hyperlink that takes you to apple.com/webobjects or something.

There's a bunch of other useful pre-written objects in here that are ready and raring to go. And then this last one is a palette that I personally have been working on. I keep re-implementing the same darn things on a lot of different projects, but I can now put them on a palette like this and drag them off of there and drop them into different components as I create them.

Or I could even mail that palette to you if you wanted to have a localizer bar or a cheesy bar graphing thing or a thing of a guy running like this with a PDF document in his hand. Those are just graphic representations of some interesting bit of functionality that I can drag and drop. I want to show you that a little bit later.

We've got a good session coming on designing reusable components that will talk more about how all this actually works and how to architect a component so that it really can be used effectively by people other than yourself. Personally, I write a lot of non-reusable components too. I'm not that proud of that, but I put my good ones on these palettes so I can use them in different scenarios.

So that's the front end, WebObjects Builder. The back end, we have another tool, EOModeler, Enterprise Objects Modeler, that lets you indicate what database you want. I want Oracle, I want Sybase, I want DB2. It lets you indicate what tables you want out of there, and what you want to do with those tables.

I would like my Cust table in Oracle to correspond to customer objects. Steve Hayman So with this EOModeler tool, you design relationships between some kind of database schema and Some collection of objects that are going to form the middle tier of your application. And what did I do with my water? Here it is.

I'm looking for the picture on here of the kids and the Toy Story logo, but I guess it didn't make it to this one. That was a camera pointing at a bottle, wasn't it? Anyway. So EO Modeler is one of the prime tools that you really, somebody in your organization needs to understand this enterprise objects modeling stuff. Doesn't need to be every single programmer.

Some people might be better at the UI parts with WebObjects Builder. But this is pretty important because this establishes the connections between the kind of objects you want to make and how they're going to be stored in a database. So for instance, I've got an Oracle database running on my trusty old laptop here, if it hasn't crashed, which it did several times today. Windows 2000, not ready for . And in that Oracle database is some car information.

I've got a manufacturer table, I've got a model of car table, I've got packages and features and so on. But it has kind of a crummy schema. The table names aren't very good. They're very compact and cryptic. There's more data in there that I actually need. There's tables I don't even care about.

There's tables with spelling mistakes. But that doesn't matter because with the EOModeler, I can say I would like nice, beautiful customer objects with easy to use APIs to come out of that particular Oracle database. So you do that with EOModeler in a very graphical way. You can indicate, for instance, in this I'm sorry for this, this little oval should be down a little bit. This is indicating vehicle objects are going to come out of the MDL table.

and the PRMin column of that table, the minimum price of the car, is going to be available to these vehicle objects as a property called BasePrice. So once I've fetched a vehicle object, I can send a message like BasePrice, and the appropriate thing will come out of the database for me. I can send a message like LoadedPrice, or VehicleName.

And I can also use this to define relationships. I've got vehicle objects and I've got maker objects. So there's a Mustang object and a Ford object that are going to come out of the database. And down at the bottom half of the window there, you have relationships between these objects.

Vehicles need to know who their maker is, and in SQL that's a join. Similarly, makers need to know what their list of corresponding vehicles is. It's a one-to-many join. And all that stuff is defined graphically in one of these files, and this is nothing more than a text file, a big fancy text file, that your application loads later.

And at runtime, by loading this file, it learns how to do all this stuff, how to fetch cars, how to fetch manufacturers. If the Sybase guy comes along and gives me a terrific deal, throw out Oracle, bring in Sybase, I could just tweak a couple of things in this model that say, "You know what, now we're talking to Sybase, making the same kind of object as before. My other applications wouldn't need to care. They're not concerned with SQL, they're just concerned with the kind of objects that this model defines." So this gives you a level of database and schema independence that's very valuable here.

It also lets you define complex relationships between different objects. I've got a vehicle object in the upper left-hand corner, I've got a maker object kind of in the top middle, and there's an arrow going between them. And we have this scheme called key-value coding, which is another wonderful thing you ought to learn about, where you can just send a sequence of messages as strings with dots in them.

So if I've got a vehicle, I can send vehicle.maker.makername that will automatically traverse this relationship, find the maker name, the string "Ford", and bring it back to me. And you hook up paths like that in WebObjects Builder, because WebObjects Builder is aware of all the definitions found in one of these object model files.

Pretty interesting stuff. Project Builder, the old Project Builder Woe is probably not worth spending any time talking about here, although if you install WebObjects 4.5, you will get this tool. I think you'll be very interested in the new Project Builder, which is coming. I personally cannot wait for that.

But Project Builder, as it stands now, they both have the same role, the new one and the old one. Let's organize all of your .wo components and your EO Model D files and your .java class code and anything else, images and sounds that you want in the application. Let's organize all that stuff and run the compiler and let you decide what things should be localized and so on.

So you do spend quite a bit of time in this tool typing in, hopefully not too much time, debugging code. Something that's definitely worth learning a little bit about, although I'm not going to dwell on that. So I really got my fingers crossed here that this development demo is going to work.

Could I have five on that one and four on this one, please?

[Transcript missing]

This machine is that screen. This machine is this screen over here. Actually, you know what? Can I change my mind? Can I have four on both screens? How good are you guys? Hey, that's better. Okay, here's some stuff that I started before that I'm going to come back to later.

I want to show you. The basics of building first an EO model and then an application with Project Builder. Then when I'm ready, not now, but I'm going to want five on that screen later. I'm calling an audible here. This is not what we discussed earlier. I'm changing my mind. Very dynamic, dynamic, late binding. That's what WebObjects is all about.

So we've got a bunch of tools here. I've got EOModeler going here, and I want to build a new object model of a database running on my big honkin' Oracle server over here. So let's start EOModeler and arrange to build a new model. Can everyone see this all right? On Mac OS X's server, we have a vast collection of adapters. is the founder of WebObjects, a new web application that will be available for your use. It's a great third-party opportunity. This is a browser. This could scroll to indicate more adapters.

And frankly, on some of the other platforms like Windows NT, you do have a little wider choice of adapters, just because Mac OS X Server is a little bit newer. But here I'm going to indicate which of these many adapters do I want to use. Do I want to use the LDAP adapter? Well, it will ask me for some LDAP connection information. Do I want to use OpenBase Lite, which is a pretty good free database that comes with WebObjects? Well, no. I actually want to use Oracle.

And I want to connect to my Oracle database, run on this laptop over here, and learn what its schema is, and define a way that I can make manufacturer objects and vehicle objects. So the first part is to remember the Oracle connection information. Anyone care to guess what my password is here? Tiger, that's right. That's how you break into an Oracle database. You try Scott and Tiger, because nobody ever changes that. And EOModeler is going to learn a bunch of things about that Oracle database.

It's going to, for instance, show me all the tables that are available. It's reached over and contacted that database and learned about all these tables that are available. I got a few with spelling mistakes like Invitory, and I got Bonnet, Dept, and Amp for the standard Oracle demo of the world of departments and employees. But the particular tables I'm interested in are Manu and MDL. I got manufacturers and models of cars. And I like category as well, but I wouldn't like these ones. I want those three tables to participate in my model.

EO Modeler will now go out and contact that database and ask you a few referential integrity questions that I always just hit next here. I suppose I really ought to think about that sometime, get open the documentation, find out what that was about. It's probably important. I might go to a couple more sessions this week. It would be good for me.

And you guys know, you guys know, you hit next when you see that panel too, and then you come back later, oh yeah, referential integrity, because I really should nullify when this thing is deleted. But it will also ask me if I want any stored procedures, and the correct answer is almost always no, none. And here we'll build a simple object model for me.

And this model says that, all right, you seem to have these tables in the database, cat, gree, manu, and middle. Therefore, I'm prepared to make cat, gree, manu, and middle objects for you, assuming that's what you want. Well, it's close to what I want. I would like them to have better names, though.

Category. What's a category of car, like a pickup truck or a minivan? Maker of car. Instead of MDL, why don't we call it vehicle? And let's fix these over here. These are the actual classes that are going to be used. A technical overview of WebObjects for new developers, this session highlights the key aspects of its architecture, its numerous technological advantages, and its relevance for web application development. Topics include what's new in version 4.5, a roadmap of features, building a high-level application, and an introduction to EOF.

Ha! These columns in the database, there's a column called Add Tag in the database, it's a Varchar2. There's a column called PRMax in the database, it's a number. Therefore, this model says, I will make your vehicle objects have a decimal number property called PRMax, corresponding to the number property called PRMax. They'll have a string property called MDLName. Let's call that something better, let's call that vehicle name. Let's call this loaded price. This is the base price.

You might want to fix up some properties of these other objects. Take my maker object, let's call that a maker name. Maybe I don't even care about some of these other properties. I could delete them, I could pick some subset of the database schema, but I'm designing objects here. I'm designing a recipe for creating objects out of a particular data source.

In addition, there are, down at the bottom, relationships that, in the case of Oracle, the modeler is able to automatically discover. It can ask the database for some information about primary and foreign key constraints or something. And then it decides that, "Oh, I guess makers have a one-to-many relationship to vehicles." So, I'm going to arrange... Oh, you know what? We've got a diagram view here.

Ooh. I was very excited to see this diagram view in the Project Builder demo today, so I don't have to come over here to see it. I've got vehicle objects, I've got maker objects, and I've got a one-to-many relationship between them. Every maker has a list of vehicle objects, and if I send the message "mdl array," I can get a list of all the matching vehicles.

And if necessary, SQL will be created, things will be lazily fetched only on demand, which is another great feature. But that's kind of an ugly name. Let's call that "vehicles." Now I can send the message "vehicles" to my forward object and get a list of all the forward cars.

We'll fix up these relationships that go the other way, too. Maker, category, and so... Oops. Category, and so on. And you're just defining a resource here, a file that's going to be used later by perhaps many different applications in your organization, so that not all your developers need to know these icky details of how this actually works. And believe me, there are a number of icky details.

Maybe that wasn't the best choice of words. There are inspectors on all these things, so you can look at something like this and determine exactly what SQL is going to be used, whether it's read-only, what to do if it's null, what do you want to do with these relationships. There's a lot of power in here.

And there's even... There's also the ability... This will tell me whether my database is actually still running... To go and fetch all of them and show you the contents, just so you can verify that what you think is happening really is happening. So there's all the vehicle names in my database.

I asked it to fetch all those properties. I could ask it to fetch all of the vehicles for me, just to confirm that the data I think is in this database actually is in this database. Okay? That is a complete and working EO model. I'm tempted to use the one that I already wrote. Because I know it works. Rather than this one. Well, we'll save this one. We'll live dangerously.

This will be the big "Auto-by-Steve" EO model here. I want to use this in a future application. I want to be able to load this model and then, bam, create maker objects and manufacturer objects and so on. So we may come back to EO Modeler later. We may spend a lot of time in EO Modeler if some of these other things don't work. But let me make a new... I want to make a new WebObjects application here. There's different kinds of WebObjects applications you can make in Project Builder Woe here.

I want to make a new one. And I was thinking about this earlier today. I wanted my application, my car browsing application, to be one that everybody will want to use. So I'm going to call this application "I Love You." I was originally going to call it something about cars, and then I had this great idea.

So we're building an application called I Love You. And there are a variety of, it says wizards here, but that's wrong, these are assistants. They're not wizards, they're assistants. We had a meeting last week, they're not wizards anymore, they're assistants. There are a variety of different assistants that you could use here. I've got 18 minutes, do I need an assistant? No, I think I'll be fine. My favorite assistant is the none assistant. I think that's the assistant that most developers actually use. Thank you. Yeah, I wrote the none assistant, thank you very much.

So Project Builder has created a basic WebObjects application for me here. And there's a couple of simple, basically empty, do-nothing Java classes. There's one called main, you can see that it's really not doing anything there. There's one called application that's printing to, welcome to, I love you. There's really nothing else going on in here other than a blank, an essentially blank, a virtually blank main component called main.wo that if I double-click on it, I can work on it in WebObjects Builder.

So this is WebObjects Builder editing the main page of my I love you application. Okay? I'm going to come back to that in a second here. We have this idea of resources. These are additional things that you want available to your application. And a great resource to add here would probably be my, what did I call that object model? Anybody remember? Autobuy Steve, there it is. Thank you.

Thank you. You guys are great assistants, too. So by adding that object model to my application, I've now got the ability to work with these vehicle objects right in here. So one thing you might want to say is we're going to build a simple application where you can type in something about the car that you want to buy. And it will find all the cars. Let's say you type in the maximum you can spend. So remember we have a base price property on cars. I want to find all the cars with the base prices less than whatever I type here.

And have it fetch some cars for me. There's a lot of great drag and drop awareness between these different tools of who does what. So I can get WebObjectsBuilder going here. And I can say, you know what? I want to be able to manipulate vehicle objects from this EO model in WebObjectsBuilder. I drag it there. I drop it here. And it adds a special object that knows how to go and fetch cars for me. A thing back here at the bottom called a vehicle display group.

So here in WebObjects Builder, it's starting to get a little bit more interesting. I've got some various things now here that I can connect to. I've got this vehicle display group object that's got a whole bunch of funny properties that I can message and leverage here. I don't have any UI yet. A little UI might be nice. Can I have a little UI creating music please? Oh, we don't have any music. All right. That's fine. Welcome to AutoBySteve, which I bet you is a domain name that's already taken on the web. So we'll make it bigger.

We'll show you the vast array of complex formatting that's available in WebObjects Builder here. And the incredible powerful tags you can put in, like the horizontal rule tag. You can, if you like, you can make any one. This is just static HTML, but you can make these things dynamic if you want as well. If you want a horizontal rule tag whose width corresponds to the price of the car, you can do that. You can click on this thing and say, "Make this a dynamic object," and hook up its width property to the price of the currently selected car.

I'm not going to do that. What I would like to do though is to have a simple form here where you're going to type in some information. How much money have you got? and we'll have a text field where you can type in your net worth and then it will find all the cars with a submit button that are worth up to that amount of money.

Now this is just basic UI stuff here. These things are what we call dynamic elements. They're objects that correspond sort of to HTML input fields. And if you click on this button here, you can actually look at the raw HTML and see what's actually gone on here. It's just, it's added a WebObject called form that goes from there up to here. By the way, for those of you who haven't used WebObjects 4.5, you can now triple click on the beginning tag and it selects all the way down to the closing tag.

Oh man, is this great. You should upgrade to WebObjects 4.5 just for that feature, let me tell you. But that's basic HTML with some tags in it that are going to be studied during this request response loop. And down here are some bindings that I haven't filled in yet of what do I want to have happen when you click on that submit button.

So for instance, This thing called the Vehicle Display Group, you can send all these messages to it. I can send this message "Qualify Data Source" to it. And you draw a line like that. I want that button to send this message to this object on the server when it's clicked.

I want this text field here to be used to restrict the cars that I'm fetching. I want the base price of the car to be no more than whatever you typed in there. So I've hooked up two objects now to objects back at this middle tier, and WebObjects is going to do some screwy things with the URLs when it sends this HTML to you, so that when you click on that button and fill in that field, it can unwind all that stuff and decide what message should be sent to what object at the middle tier, even if there's a thousand people simultaneously using this application.

Now that would be a complete application. Who says we should run this now? Or is there something we should add? Look at the cars maybe that it fetches? Okay, alright, sure, sure. Let's put in a table. For each car, I want to display the name and the price. Something really simple.

A little table wizard here. I want the second row wrapped in what we call a repetition. And if you can see, the second row of that table there has actually got a blue line around it. That means this thing is inside a woe repetition object, which just means anything inside here is going to repeat over and over again, once for everything on a list.

Well, we'd like to have the name of the car, and this is just basic HTML and its price. And then down here, for every car, we want to use a string object to display its name, and another string object to display its price. And now we need to arrange to loop over this list of cars that my display group has just fetched, and come up with a many, many rowed table.

So what I'm going to do, when you work in a loop in computer science, you've often got some kind of an "I" variable, you know, the for loop or the while loop that goes around the loop. I'm going to create a little variable here called "vehicle." I'm going to add to my class A vehicle object on this particular page that's going to be used to iterate through some other collection of vehicle objects. And the collection I'd like to iterate through is the list of all the objects that the display group just fetched.

So I'm going to draw a line to that repetition and say, "Use this list." All the displayed objects. "Use this item." Use this variable to go through the list. And then this item is a vehicle, so display its vehicle name here. Display its base price here. Okay, now that would be a completed application. I'm tempted to actually try running this, but you know, it's much more fun to actually talk about these things without running them.

Let me put in one more thing. We'll put in how many vehicles you matched. We'll put in a string which is the count of the number of vehicles that you matched. that many vehicles. Save. Now I'm going to go back to Project Builder and I was originally going to try to futz around and display it off of IE on this other machine rather than OmniWeb on Project Builder but I think it would be simpler. Everybody will be able to see better if we have the same stuff on both screens.

I think it wouldn't be fair to people to have all the good stuff over here and all the lame web browsing over there. Would that be fair? What do you think over here? Yeah? Alright. So in this case I'm going to actually use OmniWeb, the browser that comes with whatever this is here. Yeah, it's my favorite browser too. So I'm going to compile my big I love you project here.

and that just compiled these various Java classes and this one you'll notice, the main.java, it added a couple of objects to it. We've now got an object called a vehicle display group, we've got another object called vehicle. Those were added by the process of manipulating things in WebObjects Builder. So let's try actually running this here.

Please, please, please. So you can launch an application here in Project Builder, and it will ask your web browser to rendezvous on the URL of this application. Let me see if I can get exactly the right combination of overlapping windows on the screen here. U, but not U, and yes.

So here is a debugging window where all the SQL that's being generated is automatically going to appear here, along with a vast array of helpful debugging messages at the start telling you the state of all various things in the application. But here's my browser. How much money have you got? I've got $20,000.

And there are no vehicles for $20,000. Well, I click on Submit there. Over here you can see it connecting to Oracle. You can see the SQL here that it automatically generated. Can you see that on the right-hand side? I didn't type any of that. That was implied by these objects and their relationships to each other and the information in the model about how they're represented in Oracle. And I can tell over here that there were 95 rows.

95 rows of SQL came back. 95 blank vehicle objects were automatically created. They were each stuffed with these various properties from the columns of the database. Set your name to this and your minimum price to this and your maximum price to this. And then that repetition on the front-end side, the main component, was not aware of how any of this happened, so it just looped over somewhere.

It looped over some list of cars that you gave it, some list of objects. And it displayed them all for me here. So we've got all these various different 95 rows in the table. I have no idea who actually makes any of these cars. So it might be useful to add that to the displayed information here.

In every row of my table, I'll put that palette away for a moment. In every row of my table I'm displaying the vehicle name in one table cell here. But why not put in another string? and a blank space and ask the vehicle for its maker object. You're going through this object browser down at the bottom. You're traversing the relationships defined in your EO model. And I want the maker name to appear on that string.

Drag, drop. This will now, when I refetch here, it will now do a whole bunch more fetching because it's going to go and get all the manufacturer objects that it did not need until now. There's a whole lazy scheme in here called faulting where even though an object has a relationship to a manufacturer, we're not actually going to fetch that manufacturer object until you indicate you actually need it, until you ask for one of its properties. So I set up a, in WebObjects builder, I set up another string that said ask the vehicle for its maker and ask him for its maker name.

Let's go out to my inspector here. There's an inspector paradigm in WebObjects Builder. You can see that I'm deep inside a table here. I'm inside a string, inside a table data, which is inside a repetition, inside a table. There's this new path thing in 4.5 at the bottom that makes it much easier to select and to tell exactly where you are and manipulate things.

Selecting a string, like suppose you selected a bold string. Did you mean to select the bold tags at the beginning and the end, or just the string? There's some great new stuff in this new 4.5 WebObjects Builder to help you deal with that complex stuff. I want to pick this table, and in my inspector window up here, I'm going to pick a table that's I want to add on the right-hand side another column.

Let's call it picture. Where could he be going with this? And on this cell right here, let's put in instead of a string, let's put in an image object. This is another basic object in web objects. Just like the string knows how to send a message and take the result and interpolate it right into the page, this one knows how to send a message to someone to get some JPEG or GIF data.

GIF? GIF? GIF? GIF? How do you say it down here? Actually, I asked some of my Apple Canada colleagues how to pronounce it, and they say Java. So that's the... Anyway, I'm going to say, these cars happen to have a property called Image JPEG Data, which if I'd been planning a little better, I would have renamed that in EOModeler to be Picture.

But let's drag that to this thing and say that's where your picture data is going to come from. I happen to know that they're, whoops, they're not pings, they're JPEG images. And now let's fetch not quite so many cars just to keep it useful. Let's fetch all the cars for $11,000.

Now we got pictures. Oh, thank you, thank you, yeah. Okay, I did not, thank. Thank you, but I did not actually take the pictures of the cars. Thank you. All right. Is there anyone from Microsoft here? I stole this from one of your websites. Excuse me. I'm sorry.

So there's a bunch of cars and some trucks too, and this isn't maybe as useful as it could be because we're getting everything mixed up here. We're getting cars and pickup trucks and minivans all mixed together. We might want to do a more complex qualification in some way.

Perhaps instead of just letting you choose the base price that you want to spend it, we could hook up a range in there if you wanted. You could say price more than this and less than this. You could do all that very elaborate stuff. In fact, you can graphically define some sophisticated fetches right inside EO Modeler itself. Alas, no time. I'm looking at this great counter here. I've got 6 minutes and 19 seconds. Okay, go, go, go.

All right, all right. I want to have a pop-up list, which is this one, that shows all the different categories of cars. You might remember there was a category object in the database that was just a list of things like pickup truck and minivan and so on. I might like to display all of those on a pop-up list here so I can restrict my fetch a little bit better.

Well, to do that, I might go back to my object model and say, let me bring in a category object. Drag, drop. Add that. This one, I want it to fetch all the objects when this page is loaded. Fetch all the category objects. Don't wait for me. Fetch them all.

And I'd like to go through all the category objects and display them on that pop-up list here. So we have another paradigm of lists and items that go through a list being applied to a pop-up. Same kind of design pattern happens on pop-ups and browsers and repetitions all throughout WebObjects.

I want to loop through it with this, we've got this convenient thing called Selected Object. Yeah, okay, that's going to work. Oh, not there! Oh, wait! Undo! Thank--oh, phew! Another good feature in WebObjects Builder. I want to work through that thing and display all the category names. So now I've got a pop-up, just with that little wiring there, that's going to fetch all the objects from the database and display their names on a pop-up list. One of them is going to be selected. And you can arrange that the vehicle display group matches exactly the category that you selected there.

I want the selected category to be used to qualify and restrict the kinds of cars that I'm going to get. These might seem kind of odd now, but this sort of paradigm comes up quite a bit in WebObjects. Now, at this point, I do need to stop and recompile, because it did add one whole line of code to my application at this point, which if -- oh, there it is.

Yeah, I know, it's all right, don't worry about it. It did add one line here, category display group, and there was a helpful, thank you, actually, that was very helpful. There is, someone did point out to me that I have a validation error on this page, and you can have WebObjects Builder offer bits of information to you. Item may not be a constant when display stringer value is bound. I don't think that's true, so I'm going to ignore that.

It doesn't expect me that I'm cheating a little bit. Well, I'm not cheating, but I'm using an object that you're not supposed to be writing to, so don't you do that. Although, it's actually worked so far, so I don't know what to... It's one less thing I have to type, and that always helps me in a demo. The less I type, the better. All right, we're almost done here.

And now, when we run this thing, you can see that it actually fetched a bunch of categories for me already. It's gone through the category list. We go back over to OmniWeb here. Now we've got this handy pop-up of all the different kinds of cars. Show me only the, I don't know, the pickup trucks for 20 grand. Here they come, all the pickup trucks. Oh, no, I changed my mind. I wanted the minivan.

So it's actually forming some more complex queries here on the fly, and yet I still haven't actually written any SQL or any HTML. Now, it wouldn't be a developer conference if I didn't try to write a line or two of Java code in here. So I want to show you one last powerful thing here in the Enterprise Objects Modeler, and that's the idea of extending these objects, these vehicle objects, so that it can implement additional business rules on your own. Right now the vehicle object is happy to fetch things for you and display them, and you can send it messages asking for its properties.

You could write an editing application, none of this is read-only. You could write another application where you change prices of cars, and you're sending a message to an object saying, "Set your price to this," and it tells the database, and we could go through that whole complex slide again. But I might like to trigger some business logic in these objects as well. I might want to have EO Modeler create a little vehicle.java object for me and add it to my project. Steve Hayman So that's the idea. Thank you.

So here's a vehicle.java. This is a basic data container. It's got messages that set the price and get the price, and set the name and get the name, and set this and get that. And they're all in terms of this take stored value for key method, which means they're really consulting a dictionary in the superclass, which is a generic record, and that's maybe more information than anyone really wants to hear at this point.

But the interesting thing is that I can add my own additional methods here. I recently bought a car. How many people recently purchased a car? Did you enjoy that experience? Is the internet not the greatest gift to the car buying process you could possibly imagine? I mean, thank you, that's the best.

But I could not get a straight answer from the guy as to whether leasing or buying was a good idea. How many people lease their car? How many people have purchased their car? Good, I'm with you. I didn't get leasing at all. I don't understand. Way too hard. It was partly because I couldn't ask the guy, "Well, what does it cost to lease?" Well, It depends.

How long are you going to keep the car? What's your trade in? What's the future value of this car? How much money do we think you make? Does the manager like you? All of these complex rules go into coming up with the number, which is the lease price of the car.

And in this sort of enterprise objects world, we can implement algorithms like that as extensions to these objects that you might have here in EOModeler. So for instance, I might want to add a little bit of Java code here.

[Transcript missing]

I'm better now, thank you. Don't translate that part. Don't translate that part. That was a mistake.

I swear, we can fix this in the editing, right? We can fix this in the editing. I want to write a method here called Monthly Lease Cost that returns an integer, and I'm going to extend this vehicle object with something that computes the leasing price of the car. Well, we're going to return the base price of the car as if it was an integer. Divided by 43.

I bet it's more complicated than that, but as far as I know, it isn't. So because I've actually extended this Java class here, now I do have to stop and recompile. It's got relationship to these other objects, I forgot to create them. We'll compile everybody now. Went pretty well up until that point.

So we're compiling all these things. We've added custom business logic to my car application right now. In fact, if I go back to WebObjects Builder here, in this cell, we might add a nice helpful string, "Lease me for only some amount of money per month." Well, let's ask the vehicle for its monthly lease cost.

You see how that new method I wrote has just shown up in the object browser down here? All these tools are aware of what the other ones are doing. So we're going to connect that lease cost to this string here. And because my mother might be watching, we'll be neat and we'll put dollar signs and commas on it. We've got nice formatter objects that can be applied to these strings. And let's try running this.

Again, come back to OmniWeb. How much money have you got? Well, show me all the trucks. Make it snappy. Here come a bunch of vehicles. Lease this one for $279 a month. Lease the next one for $336 a month. So my custom rule is being triggered every time it comes to one of these tags in the repetition, and WebObjects is sorting out the context and figuring what object you were talking about and locating the method and loading it and sending it to this string, and this string is sending everything back.

Okay, things have gone pretty well here. I've got time to do something that probably won't work. I'm getting the big hook here, but this is my last -- okay, I saw the sign. Okay, you can put this skull and crossbones sign down now. Let me do one last thing. You know what I hate? Yeah, yeah, everything about buying a car.

I hate this kind of application. Show me all the cars for $9,000. One, vehicles. Oh, man, you know, people build these complex applications, then they can't be bothered. They get the pluralizing logic right. Or they try to be helpful and they put parentheses around the S, which shows I was kind of thinking about this.

Man, I hate that! Well, I wanted to solve this once and for all, so I've got my own little framework of objects here, which I'm going to add to local library frameworks. I've got a little Web Doodads toolkit here that I want to add to this application. And I'm going to go into WebObjects Builder, and these, remember these palettes? There's the string that's saying "three" and here's the word "vehicles" or "one vehicles." I got this object here called a pluralizer.

I spent a lot of time writing this two-line component. I'm going to take that word and delete it. I'm going to bring in my pluralizer here and I'm going to hook it up to a number. It needs to know a number. How many vehicles are we displaying? Well, this is the same number as we just saw. Count, right? You bind it to count. It needs to know a word. What word do you want to use here? Vehicle.

and it's even got some logic in there to put S on certain words, to put IES on other certain words, and so on. And let's see, is there any hope that that's going to work? I had a lot of trouble with this framework earlier today. We'll know in a second. It didn't work.

We got this far. We got to cheat. We got to go here to WebDoodads. The code in the framework isn't working. We're going to find the WebDoodads framework here. Oh my goodness. We're going to find that class which is here. It's a Pluralizer class. Oh my God, it's WebScript and that's not supported in the next release. Fortunately, this demo is on the current release.

Put that in there and put the Pluralizer component. This is all supposed to work. See how easy this is? This is supposed to work on the dragging and dropping from the ... Oh yeah, it doesn't go in the classes suitcase. It goes in the You try doing a demo for all these people. You try moving all your stuff from one machine to another at the last minute. You'll see a number of little things that just don't quite... Enough talking, smart guy. Let's just see it.

Please, baby, baby, please. Ah, zero vehicles. Oh, it needs a space. It needs a space between them. What a great object. Aren't you glad you came all the way here to WWDC to see something great like this? Okay, see this? Zero vehicles, $9,000. One vehicle. Thank you, thank you. $12,000.

Topics include what's new in version 4.5, a roadmap of features, building a high-level application, and an introduction to EOF. There are other UI's you can do as well. That was an HTML UI that I was building there. You saw a Java client this morning in Steve's keynote. I was going to try to demo it, but because I'm over time and because you've already seen it probably twice today, we'll skip that.

That's a scheme by which the client and the server can exchange an XML write-up of what the UI should look like. It means you don't have to think about the interface at all in a lot of cases. Or you can design your own fancier UI using Interface Builder and laying out swing widgets to build a much more complex thing.

You really ought to go to that direct-to-Java client to hear more about that. We also have a partner called Report Mill, another thing I'm not going to show you, which can generate high-quality PDF documents on the fly. You build a PDF template and you do this kind of dragging and dropping stuff.

It makes a very rich thing that might look exactly like the invoice you might be sending them in the mail, only it's PDF and they can print it. Printing HTML is hard. HTML is not really a language designed for printing, but PDF is. This Report Mill product is a great example of that.

This is a swell way for delivering somebody a rich and professional-looking printable user interface. Go to reportmill.com. They've got live WebObjects demos of their product running right there. XML. Who cares about XML? Anybody? Have you read about it? Have you heard of the XML? Yeah? So we've got UML, we've got XML, we've got WML.

Is there VML? There's VRML. XML is becoming popular as a way of exchanging data. With a couple of lines of code, you can create what we call a WOXML coder object. You can ask it, "Take this vehicle and turn it into an XML string for me." It will come back with an XML string, or it will encode a whole graph of objects as XML that you can then deliver to somebody in some special way. There are objects that can parse XML coming in as well. WAP.

We've got a partner that does a wireless application framework, a little palette of objects that know how to emit WAP bits and pieces, or WML, I guess it is, Wireless Markup Language, so you can design a little UI to run on your, if this was a phone, on your phone. And of course, you can mix and match all these different pieces as well. You can have an application that's aware of what different people are doing, and it sends WAP to this guy, and HTML to somebody else, and PDF to somebody else.

In addition, we've got these super-duper assistants. We've got Direct2Web, which I would like to say that I don't think Direct2Web is a toy at all. I think it's worthy of some serious study in that it's a terrific way to knock out a WebObjects application based on an EO model very rapidly. It builds a very elaborate rules-driven engine that you don't have to think about if you don't want to, but I bet you I could build a much better-looking application with Direct2Web within some certain user interface constraints.

I could build a great-looking application in about 10 minutes that would take me a week of equivalent messing around with WebObjects builders. So check that one out too at the session 4.05. Direct2JavaClient, which we've seen a couple of times today, for the same kind of idea: a rules-engine-based way of having the UI constructed on the fly and offering you an assistant where you can modify the UI that it's going to use.

Let's not look at them. Let's all go to that other session and check those out. In the meantime, we've got this tool, Monitor, and its little sidekick buddy, WOTaskD, that actually launches all of your applications in the complex environment. Keeps them running. Launches them again if they crash. Sends you mail.

Gathers statistics and so on. And it has a UI like this where you can indicate -- this is an actual WebObjects application, but here I'm showing I've got five copies of some application and two of them don't seem to be running, but I could click on those knife switches to start them up and down. And it gathers statistics and monitors deaths and so on.

So it's a nice tool for managing a complex deployment. We've got a bunch of sessions coming up on big application development and all these various issues. How many people here are going to most of the other WebObjects sessions? I'm just curious. Oh, that's fantastic. It's so great to see so many people here for all this stuff. We love it and we hope you love it too. And we love you. And I hope -- no.

Lots of ways to learn more. There's the WO Info Center application. After you install your free copy of WebObjects, the first thing you ought to run is this WO Info Center, which gives you an application where you can search all the documentation for keywords. You can run the live examples.

You can study things online. You can go through a whole hierarchy of books that are included and read them online and look at all the examples. The best place to get started. And also, the quickest way to verify that your WebObjects installation is working properly is to run WO Info Center and see if this comes up.

Shouldn't that be C-E-N-T-R-E? The best way to get up to speed with WebObjects is to take our week-long training class. This is the best way, coming to WWDC. To take the intensive class and go through the process of building an elaborate application with a qualified instructor is fantastic.

The second class is really an in-depth discussion of the Enterprise Objects Framework, that whole database layer. And we've recently added the third class on WebObjects deployment, where you get to manage your own little empire. Everybody gets an NTE machine and a Solaris machine and a Mac OS X machine, and you get to build these complex things with the database here and the web server there, and you get to make them break and try to put them back together.

It's really valuable for people who are going to be doing deployment. If you're planning a WebObjects app, you ought to send someone to that deployment class. And I think that's about all. I could talk, I could refer you to all the references. I'm going to go through the remaining WebObjects sessions, as they are all pretty good follow-ups to this one. But you've all got the schedule. You can all see where they are. These ones that are on Tuesday, I think, are excellent and highly recommend it.

So if there are any questions -- oh, we're almost out of time. Oh, I have to take questions. There's five more minutes. I'd be happy to take a few questions and perhaps not answer them properly. Oh, Ernie. Hello, Ernie. I'm here to help you not answer things. It's Ernie.