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 may have transcription errors.
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... Let's bring him out! No, 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." Well, 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.
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? Thank you.
Engineering wanted me to take that off the slide. I'm glad I left it there. 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-- you know what, that's not right. That's better.
Well, OK, 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. But 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. And 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 here. and 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 and grow it. Now, 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.
And, in fact, these purple things over here, these are actual identical copies of your web objects application running on a bunch of different machines. And a little thing we call the adapter runs on the web server and sorts everything out, keeps everybody straight. So 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 WebObjectsBuilder to develop those. The ones at the back end are enterprise objects, and you use EnterpriseObjectsModeler to do that. I think they took me for this talk because I talk faster than anybody else at Apple.
Oh, is my mouth dry? 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 web object. It's a tag that says, here, something cool is going to happen.
Really, that's all it is. A web object name equals picture. And then there's another file that says, you know what? When you see that web object 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 web object 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 WAP Objects that's building WAP-enabled things. I just think that's so much fun to say, WAP Objects. 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 cameraman. So I like to go this way. Thank you. Back end, 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 back end 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. on. And, oh, a whisper, a whisper. Enterprise Objects manages this whole.
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 database world 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 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 EnterpriseObjects. 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 that 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. uh... you can have arranged for objects such nodding themselves 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. And I'm going to show you a few pieces of this here.
let's suppose on today's vast internet there are three users You know that's the net because it's a cloud that's some sort of ANSI standard. And you've got a web server with this WebObjectsAdapter on it. You've got a variety-- I'm showing three here-- a variety of application servers with EnterpriseObjectsAdapters to talk to databases.
The web server, as we've heard, can be pretty much any operating system, any web server. The web objects 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 web objects application here, where a user's going to log in. He's going to type shaman. It's going to do some processing. It's going to look up shaman 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-Haman, 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 webs, and the string shaman is coming along, they've 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 web object's 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, S-Haman, 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 W-O tag, and besides, it doesn't, it's not, the tag's not W-O, it's WebObjects." I don't care, I didn't have room in that thing. Previously, this login component was used before to generate that page that says, "What's your name?" Now that the response has come back in, the WebObjectSession 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. 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 Web Objects 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. The handle login 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 web object 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 shaman and return that and make it into a customer object.
So our back-end 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. Then 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, 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. 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. You can, 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 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?
And I used to go through a huge song and dance about this request response loop because this was how we licensed web objects 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. And we had a whole tier of architecture, right up to 50,000 bucks where you could have an unlimited quantity of these things. Now it's 699 bucks, 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. is this student uh... 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 other components build the u_i_ 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. I want to talk to you a little bit about each of these. The old version of Project Builder, frankly, not that exciting anymore.
The 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 Web Objects 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, all right. Thank you. Do you, this, you know, this, which is the top of this? Could you tell by looking at this, which one is, which way is the top? No, me neither, all right.
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 a 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 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 when we are looking at some component and in the middle of sections of html that's a rough view of what your html is going to look like there's a isn't 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 web objects building not bad html it does bold to make the text bigger you can drag in colors and pictures make a thing that really ugly really rapidly In the bottom half, so that represents main.wo slash 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. Um... 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 a little line like that in WebObjectsBuilder. 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 WebObjectsBuilder 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 got a hopefully run web objects builder live in a moment here to show you how this all actually works but this is the sort of methodology use you can work with a whizzy wig view like that or if you like you can also work in a raw you can type the html up yourself you take the wad yourself you probably forget to put in semicolons you probably forget to close some of the tags 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 WebObjectsBuilder. 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-- at least you are not exposing all of your business logic is no sql in there there's no custom code that says how we compute whether student graduate it's just interface just interface definitions Also, once you've written a bunch of these objects, Web Objects 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 Web Objects. We would love it if you would all put this one on your application. A little image there, ready to go, powered by Web Objects. Drag that, drop it on your application. I think that's actually a hyperlink that takes you to apple.com/webobjects or something.
But there's a bunch of other useful pre-written objects in here that are ready and raring to go. 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 off and share effectively. 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 pallets so I can use them in different scenarios. Thank you. So that's the front end, WebObjectsBuilder. 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. 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 EOModeler is one of the prime tools that somebody in your organization needs to understand this enterprise objects modeling stuff. It doesn't need to be every single programmer. Some people might be better at the UI parts with WebObjectsBuilder. 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 modeler, 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 model, 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 PR min column of that table, the minimum price of the car, is going to be available to these vehicle objects as a property called base price. So once I've fetched a vehicle object, I can send a message like base price, and the appropriate thing will come out of the database for me. I can send a message like loaded price or vehicle name. 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 out the bottom half the window there you have relationships between these objects vehicles need to know who their maker is an SQL as a joint similarly makers need to know what their list of corresponding vehicles is to one to many joint and all that stuff is defined graphically in one of these files and this is nothing more than a text file 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 makername, the string forward, and bring it back to me. And you hook up paths like that in WebObjectsBuilder, because WebObjectsBuilder is aware of all the definitions found in one of these object model files. Thank you.
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? to say it here, it comes out there. It comes out there. Five on this one, please.
I hate to say it in Japanese. There we go. 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. OK, 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. *laughter* 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 honking 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 server, we have a vast collection of adapters. 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 web objects? 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 in contact with that database and learned about all these tables that are available. I've got a few with spelling mistakes like inventory and I've got depth 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've got manufacturers and models of cars and I'd like category as well but I wouldn't like these ones I guess I want-- there, that's better. I want those three tables to participate in my model.
EOModeler 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 it will 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, it's a category of car, like a pickup truck or 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 gonna be used.
Maker vehicle. And you can look at this vehicle object, and this is the bare bones definition of how Enterprise Objects is going to make vehicle objects for you. It discovered that there were, 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 MDL name. 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. So 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 it 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. 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 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. OK, 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-buy 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 web objects application here. There's different kinds of web objects 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.
And 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 WebObjectsBuilder editing the main page of my I Love You application. OK? 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. so the base price is 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 WebObjectsBuilder, 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 Auto by Steve, which I bet you is a domain name that's already taken on the web. So we'll make it bigger. 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 added a web object 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. They're 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, Qualified 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, two 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, all right, sure, sure. Let's put in a table. I want it for each car. I want to display the name and the price, something really simple.
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 "whoa 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 gonna do when you work in a loop in computer science you've often got some kind of an i variable that you know the for loop or the while if it goes around the loop i'm gonna create a little variable here called vehicle i'm gonna 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.
usually safer open at ship it thank you very much thank you I put one more thing yeah we'll put in the how many vehicles you matched will put in a a string which is the count up the number 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? All right. 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 the vehicle display group. We've got another object called the vehicle. Those were added by the process of manipulating things in WebObjectsBuilder. 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. You, but not you, 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 happens. So it just 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 in 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'll 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 in WebObjectsBuilder, I set up another string that said, "Ask the vehicle for its maker and ask him for its maker name."
list of cars. See what else we can do. Let's go to my inspector here and 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. And 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. But I want to pick this table and in my inspector window up here, 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 you know I asked some of my Apple Canada colleagues how to pronounce it and they say so that's Anyway, 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. dollars. 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. Is there anyone from Microsoft here? I stole this from one of your websites. Oh, excuse me. I'm sorry. Thank you. 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, and 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, alright, alright, I'm, uh, 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. I want to, now, oh, let me think about that. Yeah, okay, that's gonna work. Oh, not there, oh, wait, undo, thank-- Oh, phew, another good feature in Web Objects 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 gonna fetch all the objects from the database and display their names on a pop-up list. One of them is gonna 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 Web Objects. 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. 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, not cheating, but I'm using an object that you're not supposed to be writing to, so don't you do that. Although, actually, it's worked so far, so I don't know what to put. 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 pickup trucks for $20,000. 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 EOModeler create a little vehicle.java object for me and add it to my project.
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 EO Modeler. So for instance, I might want to add a little bit of Java code here. Public, pardon me. Public, have a drink here just for a moment.
I'm better now, thank you. Don't translate that part. Don't translate that part. That was a mistake. I'm sorry. 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 forty three i'd you know i'd i bet it's more complicated than that but as far as i know it is So because I've actually extended this Java class here, now I do have to stop and recompile. Classmaker, not-- oh, yeah. Let me just-- you've got to do this too.
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 go back to OmniWeb how much money have you got? Well show me all the trucks make it snappy become a bunch of vehicles. Lease this one for $2.79 a month. Lease the next one for $3.36 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 Web Objects 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. 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, it's the same number as we just saw, count. 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. Oh, God. Didn't work. Hang on. We got this far. We got this far. We got to cheat. We got to cheat. We got to go here to Web Doodads. The code in the framework isn't working. We're going to find the Web Doodads framework here. Oh, my goodness. And we're going to find that class, which is here. It's a Pluralizer class. And, oh, my God, it's WebScript, and that's not supported in the next release. Well, fortunately, this demo is on the current release. So we put that in there and put the plural logic component. This is all supposed-- 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 web components suitcase. Thank you. 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? OK, see this? Zero vehicles, $9,000. one vehicle. Thank you, thank you. Twelve thousand dollars. Thank you.
14 vehicles. Oh, man. OK, I don't know why that little drag and drop thing didn't work. But generally, there are a collection of really useful objects like this that you can share. You can create your own, your own company kit, and share them around the organization like this. I've got to come back here and do two more slides, and then I'm done. So can I have this machine back up on both sides? That took longer than I thought.
It always takes longer than you think. There's other UIs you can do as well. That was an HTML UI that I was building there, but you saw a Java client this morning in Steve's keynote. I was gonna try to demo it, but because I'm over time and because you've already seen it probably twice today, we'll skip that, but that's a scheme by which the client and the server can exchange an XML write-up of what the UI should look like, and 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. And you really ought to go to that direct to Java client to hear more about that. We also have a partner called Report Mill that I'm not, another thing I'm not gonna 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 and 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. and this report mill uh... product is a is a a swell way for delivering somebody a rich and professional looking printable user interface go to report mill dot com they've got live web objects demos of their their product running right there xml with one xml becoming who cares about xml anybody have you read about it you heard the xml yeah so we've got uml we've got xml we've got wml is there vml vrml I'm going to work on ZML. I'm going to go back to Canada and do ZML. But XML is becoming popular as a way of exchanging data. And with a couple of lines of code, you can create what we call a WOXML coder object. And you can ask it, take this vehicle and turn it into an XML string for me. And 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's objects that can parse XML coming in as well. WAP, we've got a partner that does a wireless application framework. a little pallet 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.
And in addition, we've got these super-duper assistants. We've got direct-to-web, which I would like to say that I don't think direct-to-web 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 direct-to-web 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 Builder. So check that one out too at the session 405. Direct to Java client, 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. Deployment time, 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. This is 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 WebObject sessions? I'm just curious. 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. We love you and I hope not.
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?
Yeah, yeah. I was not in that meeting either. And finally, the best way to get up to speed with WebObjects is to take our week-long training class. Actually, this is the best way, coming to WWDC. But 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 the Solaris machine and the 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 refer you to all the remaining WebObjects sessions as they are all pretty good follow-ups to this one, but you've all got the schedule. can all see where they are. These ones that are on Tuesday I think are excellent and highly recommend it.