WebObjects • 1:04:22
This session provides a technical overview of WebObjects for new developers. Highlights include key aspects of the WebObjects architecture and its technical advantages and relevance to web application development. Topics include a discussion and demonstration of WebObjects tools, design and flow of a typical WebObjects application, and a review of deployment scenarios.
Speaker: Steve Hayman
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it may have transcription errors.
the WebObjects Technical Overview. And I'd like to introduce Steve Hayman, who's our speaker and presenter for this session. Steve, where are you? Tony. Hey, Tony, you know how we got that memo that we were supposed to wear the speaker shirts? Yeah. And when I got here this morning, they didn't have any.
They were out. When did you fly in, Steve? I'm going to do the best I can, all right? All right. All right, okay. I'd like to introduce Steve. I got here on Sunday and they didn't have any shirts. There we go. Oh, wait a minute. It's cold up here. Just a second. I got something.
I'd like to introduce Steve Hayman. Thank you. Please be seated. Please be seated. Thank you. No, please, sit down. Please, please. Oh, you're too kind. Okay. How many people were here last year? Yeah? Do you remember James Dempsey did a song at the end of his session? Is James here today?
I hope we have time. James wrote this song about EOF, and he brought out his guitar, and he announced that this was the first time he'd ever actually played the guitar in public. And he wrote this fantastic song about EOF that I think a lot of people remember. So I was thinking, and I sure hope we have time. Um because uh... i'd still go another time because i i wrote a trombone solo book he value coding and uh... There's time at the end. Or if I get in trouble in the demo, I might have to just come over here and put this here. There. So we have time at the end, all right? Don't let me forget. So I'm... - Yeah.
I'm Steve. I'm from Toronto. Any other Canadians here? Were you all disappointed to hear James Gosling say Java yesterday? Oh, it killed me. The correct pronunciation is Java. I really wanted to get clarification on that from him, but I was unable to do so. But I want to talk to you today about WebObjects. Bob covered a lot of what's new and some of the advanced features in the previous session. I want to talk more about the basics. Are there people here that are WebObjects beginners? Are there people here that are tired of people asking to put up your hands at the beginning of a session? Are there people like that? Yeah. So we won't try not to do any more of that. But I want to talk about this, and more importantly, I want to actually build something in a little bit of time. So WebObjects, as Bob mentioned, is an application server, which is not my favorite term, but the best part is really these frameworks that come with WebObjects and enable you to build applications quickly.
We give you a lot of code. We give you a lot of tools that know how to generate HTML and that know how to manage sessions and that know how to talk to databases at the back end. By leveraging those frameworks, those collections of objects and those tools, you can hopefully build a pretty good application pretty fast.
You're deploying something in the middle here, and it's integrating data from all these different places and sending it out through the web servers in a variety of ways, as you probably know. This is really a tool, however, for developers. Some of us have worked pretty hard to make it look pretty easy, but just I want you to keep in mind that this really is a tool for Java programmers. You have to be a serious Java programmer to get a sophisticated WebObjects app done. There is a steep learning curve associated with WebObjects, but that's okay because you're going to learn a lot in a short period of time.
All right, I'm retiring that joke. I've been doing that joke for three years. I think that's probably enough for that one. Does that joke work in Japanese? I like to say konnichiwa to the translators. Everyone say konnichiwa. Translators. Hi, konnichiwa. Oh, they're waving. Good, good, good. I wasn't sure if my mic was on. We cannot understand a Canadian man. We do not know what he is saying.
It's not funny even in English, so we're not going to bother translating it. So we have a tool here that works with Java, with a variety of databases, now with JNDI servers in WebObjects 5.1. A bunch of different UIs you can pump out, usually HTML, but often other technologies. We work with a variety of web servers. We work with things that used to be competitors. Now that we have this servlet deployment, you can theoretically take your WebObjects app and bundle it up for servlets and deploy it on somebody else's servlet engine. Lots of third-party objects, and open, open, open, open, open, open, open. I'll wait for the translators to catch up. Okay? Okay, good.
You can develop on Mac OS X, you can develop on Windows, you can deploy on Mac OS X Server, Windows 2000 or Solaris, and theoretically other places that have a Java environment as well. And now with servlets, you have a choice of runtime environments you can use in which to deploy. And you can start small and grow bigger. People often build a little application that's just running on one machine, and after they get it working, and without any real need to redesign or anything like that, you can scale an application to a big, scary, complicated diagram here where we've got multiple firewalls inside and outside, multiple adapters, and multiple copies of the application.
We call those instances. You write up the application, and you have several of them going in several different places. So you can really move from this to this without any big architectural redesign of your application. A lot of that stuff is built in. I just noticed my boss is sitting in the second row, and I think this is the first time he's ever seen me do a demo. Right, Alan? Did we have my performance review already for this year? I don't know. I'm very nervous now. You didn't see me come out, did you? You came in after I put my shirt on, I hope? Okay, good. Okay.
But the key ideas surrounding WebObjects, we have components at the front end and a tool that builds those, and they're the things that create HTML and send it to the world. At the back end, we have enterprise objects, which are the things that talk to databases and that collect data from data--data, data, data, Java, Jagwire.
So many pronunciation options available to you at WWDC, but all these different pieces are bound together at runtime. We have a sophisticated technology that's sophisticated and lazy at the same time. If that's possible, I like to think that I'm that way myself, which is why I enjoy WebObjects. I'm sophisticated and lazy. And these objects are tied together dynamically. As the application runs, decisions are being made about who's connecting to who and who's sending what message where, and where is the data actually going to come from.
You build these components at the front end that have this little web object tag in them that indicate in the HTML, here's where something is going to happen. Some message is going to get sent to something here and the result is going to be inserted into the HTML at this place. We call another thing, we call them bindings. Bindings are the definition of what happens when we see this web object tag.
So I can talk more about this later, but this is really what, in raw form, WebObjects components look like. They're pieces of HTML. They're these things called a WAD file in the upper right that's a definition of the meaning of the tag. So you see string one on the left is actually a WO string, and it's going to get its value by sending a certain message to a certain other object. WebObjects evaluates all this stuff at runtime, sends the message, and comes up with plain HTML going out to the end user. Components usually have a Java a class associated with them as well, in which you can actually define behavior.
Now, what comes out of these components? It's just text, just bytes, all sorts of stuff to be interpreted by the client, and WebObjects marks it up back in the server and transforms it and sends it out. At the back end is the Enterprise Objects Framework, or we call it EOF, Enterprise Objects Framework. EOF is not maybe the best name. I was not in the meeting when they picked the name EOF. That kind of meant something already. Did you know that? That was a term we used in computing already, EOF. But EOF is a good thing in this case. Enterprise Objects is the back-end database connection technology that underlies most WebObjects applications. It's driven by a model, which is a file that you can create that describes what database you want to use, what tables and rows and columns you're interested in, what kind of objects you want to make coming out the front end. So, uh... Together with that, you can create Java objects that contain the data from this database, customers, packages, vehicles, whatever. But you can also enhance them with business rules, and WebObjects will take care of creating sort of blank, empty Java objects of your choice and filling them in with data that it's found in the database. So your object that springs to life, containing this data, which has come ultimately through some sort of a JDBC data source in a process that's kind of unknown to the object itself, you write these sort of naive middle tier business objects that just spring to life with data that the EOF has brought in from the back end.
all driven through these models. These models are really files that tie object specifications to specific data sources. I'm going to show you all this later. I'm going to try to build something, and hopefully it'll be obvious how this all actually works. Ultimately, you're setting up definitions that say certain kind of objects are associated bidirectionally with certain databases, certain tables. Every row in this cust table, I want to make a customer object. Every row in this other database table, I want to make a vehicle object. Thank you.
And the relationships between objects are handled automatically as well. A customer might have a list of vehicles and so on. I think this is one of the great things about WebObjects is the way that it manages relationships for you. Are anybody here in a relationship? Anybody in a relationship? Managing a relationship is hard, right? Right, I know I'm in a one-to-one relationship right now. For a while I was worried it was going to be a one-to-zero relationship, but I think we're okay. And I guess there are people in one-to-many and many-to-many relationships, and that's all complicated. But web objects and enterprise objects can support the automatic adding of things to and from these other relationships and handle all that for you.
It's the real gem. It's the best part of WebObjects. It's also-- superficially it might seem simple, but there's a lot of depth to this thing and a lot of places where you can write code and leap in there and override the way it works if you want, but enhance it and take advantage of all this power that this persistence framework is bringing to the table.
All this stuff, the back end enterprise objects and the front end components are all tied together at run time by WebObjects. It finds those WebObject tags, maybe fetches some objects, sends some messages hither and yon, and produces a stream of HTML that goes out to the end user.
together with session management. Every WebObjects user has a session object created for them. By default, it doesn't really do anything, but it's a placeholder where you can go and say, "I want to add a shopping cart to this session. I want to keep track of which products somebody has purchased."
And WebObjects will take care of handling that session object and making sure it sticks around for the entire lifetime of one user's interaction with your database. You have complete control over how these sessions are stored, are they in the database, are they kept in a cookie, are they kept, you know, hidden fields in a form or something. But it's a common place to extend and add behavior that's going to be unique to a particular user in the session object.
Along with these runtime monitoring tools, we have Monitor and WoTaskD, which is our standard way of deploying applications, but now in 5.1, we have this servlet deployment option as well, where you can let somebody else worry about how the application's actually going to run. I suppose there would be a different phone number you could call and complain about the way your application wasn't running because you're using somebody else's engine. So what is it you're actually creating? Pardon me. I'm so funny.
What is it you're actually creating? What is this water? Holy smokes, I thought this was just water. It's got... Vodka. Oh, I thought you were vodka. Yes, that is good. Um... What is it you're creating? You're building something that, don't get hung up on this, but you're building this complicated structure here. You're taking a bunch of WebObjects components and your own Java code and maybe some images and some references to frameworks that other people have created, and it's all creating this big.woa folder. That's sort of what the result of building an application with WebObjects Builder is. It's a folder like this. It's got a variety of resources in it, and hidden in there, for instance, is a shell script that's going to take all of your Java code that's been compiled into this jar file and run it and set it up in such a way normally that it finds images and so on in a folder that belongs to this application. So you build this thing, and you don't need to worry about these details, but this is what's actually happening here. And then when it comes time to actually run the application, you'll see me do it this way. You might launch your application from Project Builder, and Project Builder is going to start your application, which is going to create some class path like you would not believe that picks out the Java classes spread over all these frameworks. And ultimately, it's going to start the application object associated with your WebObjects application.
Part of that, normally when you're launching from Project Builder, your application thinks for a moment, comes up with a random port number, and asks your web browser to connect to this particular port number, and the web browser just starts. When you're testing with WebObjects, this is usually how people start. You do what we call direct connect. You just hit the run button in Project Builder. Your application starts. your web browser is sent this particular URL, and it opens, and then you talk back and forth, and you try it out. That's maybe not the best way to deploy, however.
We'd rather have you, well, sorry, in this direct connect mode, everything's happening to the application itself. Requests for images, requests for dynamic HTML, it's all coming into this one application and its resources. Thank you. Later on, when you're ready to deploy, you've probably got one or more app servers and one more web servers, and there's kind of the naive way to deploy, which is just to copy everything to the app server and let the web server just route all the requests for the images and everything else over to the application server. And that's not really taking advantage of what web servers can do for you. Web servers are pretty good at caching images and, you know, QuickTime movies and JavaScript and things like that that aren't going to change during the life of your applications. So we offer another approach.
called the split install, where you put most of the stuff on the application server, and you put images and other static resources on the web server, and then at runtime, the requests are sorted out so that certain things go only as far as the web server where they're cached by Apache or IIS or whatever your web server is. And other requests for dynamic stuff are getting routed through to your app server, which might be somewhere else. This is called a split install. These are terms that you might come across when it comes time to deploy your application. But we like the idea of splitting the static and the dynamic parts so that you can scale them each independently. You can have a lot of images. You might have one web server and several application servers at the same time. So there's a lot of flexibility in how you actually deploy. One good thing about that approach is that the actual code is on the app server, which is usually protected by a firewall in some way, and there's no way for people to get at it. And then the images, which you don't care about, can sit on the web server where people can download them and copy them all they want.
So typically in Mac OS X, the images would wind up over here. Thank you. New. New in 5.1. Servlet deployment. The same as before. You build your application the same way as before. You add this magic Java WOJSP servlet dot framework, and through some process that I don't completely understand, it winds up creating a.war file in addition to this big.woa file. You're welcome to try to understand the build process. It's, uh... Mark over here has tried to understand the build process, and that's why he's laughing. But it all happens magically for you. And in addition to your application, one single file called a WAR file is created. And then if you want to do servlet deployment, it's more or less as simple as copying that WAR file to wherever your servlet engine expects to find it. You know, we support Tomcat, and Tomcat wants to find servlets in library, Tomcat, web apps, myapp.war. So deployment in a servlet scenario is as simple as moving this one file over to this other place and then looking up the documentation on your servlet container and deciding how to tell it about the application. Sometimes it's automatic. Now, I should tell you that at the moment, you do need to have the rest of WebObjects installed on the servlet engine. This WAR file that you're copying is only your application and its code.
Are we thinking about doing anything about that? People often ask, couldn't we make it so that the WAR file was even more humongous and contained all of WebObjects so that it was just one thing to plop in the server? That would be a great question at Q&A. Someone should ask that at Q&A, but not to me.
To one of these people over here. - So what's going on when one of these applications actually runs? You've got the Internet. It's got three or four computers on it out there. You've got a web server and an application server and some kind of a database. We don't care at all what the web server is. We put a little adapter thing on it that allows it to find the application server. But it can be anybody's web server at all. We care a little bit more about what the application server is. There are certain platforms that are officially supported, and then there are other platforms like Linux that might work, but they're not officially supported.
And there are database adapters at the back end that speak to certain databases. We have, uh... Oh, I should have put... I'm sorry, I should have put MySQL on here. We have a variety of supported databases. And then there are others that work through, uh... through SQL as well. You know, if you wanted to get FrontBase or something, that's a fine database as well. You can use your choice of databases, not just the ones that we officially sanctioned here. So what's going on when you have a really simple application?
I, uh... This was sort of my first WebObjects application, trying to do something incredibly sophisticated here, where I would type my username, it would look up me in the database and welcome me back by my first name. So there's really three steps that are going on. When the form is submitted from the web browser, to the application server. There's a phase called take values from request. Let's have your application extract what did you type in all the form fields and what check boxes did you hit and what radio buttons have you selected. Let's take all that information and present it to whichever WebObjects components actually want to hear about it. That phase is called take values from request and the components can extract these values and decide, oh, you typed S. Heyman in the log in field. That sort of happens automatically.
Second What do you want to do when the user hits "login"? Well, I want to run this little bit of Java code. And then finally, you want to generate a response. You want to take one of these HTML templates and send all the messages and send HTML back to the end user.
So users are submitting requests like this, and they come flying in from their iMac or their eMac. You know, I have to say, as an old Unix guy, it's interesting to me that we now make eMacs. I think that's kind of fun. Although, I have to say, I'm really hoping we're also going to come up with a viMac, because that, personally, would be my choice.
Anyway, the request comes in from the Emacs and the Vimacs to the web server, and it gets sent to one copy of your application, which is running somewhere on this application server. The first time, it picks one at random. The second time, it usually sends you back to the same one as the first time.
And the session has to go and find the component that caused the original page to be created. We have to go and find that so we can decide what to do with the string shaman. And by studying that component, we can see that it should be associated with value username. We should find some variable called username and take the form value that was typed here and stuff it in to that variable. So it finds those form values, and then it invokes the action. You click on the submit button, and this particular component says, oh, when it hits submit, and you should send the handle login message back to the page. And that would fire up a little bit of Java code that would maybe look up another page, or you could insert some code here to tell the session to do something, or you might want to log something. But when that button is associated with a particular message being sent to one of these classes-- so in this case, it's going to look up another page, a page called Welcome.
And it's going to go and find the welcome.wo page, which has its own little bit of HTML and its own WAD file, its own WebObject declaration file. And then we're going to decide how to process this thing. And all this is happening in the response phase. We're going to find any WebObject tags that might be inside that HTML. We're going to find the associated value. Whenever there's a WO string, you have to send a message to decide what to put at that place in the HTML. Let's generate a string, put it in there. So we look up that message. And then some messages might be sent to objects that are coming from the database in this hypothetical scenario. And a WebObjects developer doesn't really worry about SQL too much. You've built one of those object model files, and it has all the database information inside it. And from that point on, you just start thinking about objects and relationships and their properties. So... In this case, maybe the object model says that, you know, customers are coming from this Oracle table and products are coming from this Oracle table.
I understand Oracle is very popular in California. Like, everybody has a copy. Is that what I read in that paper the other day? That the state bought a copy of Oracle for everybody? That's pretty... I'd have to suggest that when I get back home. That'd be great. I'd love to have my own copy of Oracle. And SQL, to fetch, in this case, a customer object, is going to be generated automatically.
By studying this model, the application knows that you want to create a customer object, but the model says, "Customers get their data "from this table and these columns over here." So automatically, EOF puts together an SQL statement, sends it to the database, fetches some rows. The rows come riding back like this, and an object is created, in this case, a customer object with my name in it. And then we send the message that we wanted to send. Well, give me the first name of that customer object, and that comes back with a string, "Steve." And we find that tag that said, here's where the web object was, and we replace that with this string, Steve. And then the plain, ordinary HTML goes back out to the VI Mac at the back end. Okay.
This, in a nutshell, is the request-response loop. A request comes in. various objects are given the opportunity to handle it the d_i_ do you care about the data in this form various objects are asked for you the action responsible for the submit button that was clicked and in a up another component will be loaded in this given the opportunity to attend html the response and uh... You can subvert all this if you want. There's plenty of opportunity to insert your own code if you want-- you usually don't have to-- but if you want, into this process and do all kinds of crazy things like extracting things from header fields or logging stuff somewhere and so on.
But notice that the SQL and the HTML are kept pretty far apart. They're in entirely different files. Your HTML is in one of these WebObject components, and the SQL doesn't even exist, really, until the application runs. At runtime, the application figures out the SQL and sends it off to the database. So you do not need to write any of this unless you want to.
Thank you. I guess they want to. So let me talk about the tools. Bob had, like, six tools on his slide. I'm only going to show you three because I'm going to do a fairly simple demo in a moment here. But WebObjects Builder is the prime tool for creating these components, for managing the HTML and the associated declaration file and maybe WebObjects Builder doesn't really manage the Java file, but it can manage associations between them. You could edit all this stuff by hand if you wanted to, But one interesting thing is that now in 5.1, we have spent-- you know, I started at Next a long time ago, and we spent a lot of time telling people what a good idea it was to keep the HTML and the business logic and the SQL and everything as far apart as possible. We spent a lot of time trying to hammer that point home, that separation was good. But now in 5.1, if you want, you can just put it all back in one file with JSP.
Be my guest. You can develop this way. And, in fact, if there are programmers in your organization who are more familiar with the JSP model, this might seem more accessible to them. But, you know, typically in the old style of WebObjects is to keep everything separate. And, of course, I would encourage you to do it that way. It's really a much cleaner result than this. But if you have a need to go JSP and you want to squeeze everything into one file, that's now an option for you.
So you're going to create a lot of these things. Usually at least one for every different kind of page, but often sub-components, the title bar, the menu down the side, some kind of a footer. And we provide you with some reusable components for most of the HTML UI things that you might want. And you can make your own. You can create your own components. And if I have time, I'm going to try to actually build-- well, you'll see. If we have time, you'll see. But you typically assemble a lot of these things into one application.
They're all files. You can use whatever text editor you like for these things. I have used stickies in the past as my development environment. That is possible. Cat, if you're a real, you know, studly Unix programmer. I suppose DD. I suppose the real Unix programmers would DD it directly onto a disk sector or something like that. But... I'd rather work at a slightly higher level. I'd rather use some kind of a WYSIWYG editor. You can use Dreamweaver or Go Live or anything that understands HTML. They usually don't understand this associated WAD file.
you can also work with WebObjects Builder, which is a graphical way of managing the HTML and the declaration file simultaneously. So here in an example is a screenshot of me assembling some sort of a page, and I just added a hyperlink that says click here to order, and I want to arrange that when a user sees that hyperlink and clicks on it, it sends this message, place order back to my application. And it's really in WebObjects Builder a matter of drawing a line. You draw a line from the bottom half of the screen, which is where sort of your object browser, your view of objects in the application. And you associate it, or you bind it, to something in the user interface at the top.
And as you do that, you can choose hyperlinks here. I'm seeing a menu of all the different properties I can associate with a hyperlink. Do I want them to trigger a specific Java action, or do I want them to just go to a specific page name, or I guess there's other fragment identifier. I guess I've never used that in my life. I suppose that's handy. But there's a variety of properties for any one of these objects that you can bind to. And you pick the one you want, and then up at the top in the inspector, you can see it now says, the hyperlink's action is place order. When anyone sees this page right now, there may be three thousand of you all hitting my application, you're all going to click in that hyperlink and it's going to send the message "Place order" back to the class associated with this application. I've apparently offended Tony in some way. Maybe she's looking for my shirt. That would be nice.
You can also use WebObjectsBuilder in what we call raw mode, which is just a view that lets you edit the HTML in the WAD file directly down here. That's sometimes necessary, but, you know, you're on your own if you leave out a semicolon in the WAD file. Don't come blaming me that I said it was all right. But it's nice to be able to do it both ways. We're giving you a choice with WebObjects, choice of a lot of different things here.
And you can use palettes to organize frequently accessed components in a nice reusable way. I'm a bit of a palette junkie. I don't know if any of you WoeBuilder guys have-- like, I have like 14 web object palettes loaded right now. And any time you get a good idea and you think you might want to use it again, well, take the extra 5% of the time and make it an object on a palette that you can drag and drop or give to someone else. It will pay off in the long run.
EO Modeler, you can hear all about in plenty of other sessions, but it's the tool that edits these.eomodeld files. They're really folders. They're folders of files. And EO Modeler is a tool that lets you state what kind of connection information, what database are you going to hit, and what tables in the database do you want to make objects for. In this case, we want to make vehicles out of the MDL table in this database. Information about entities and their specific properties, and information about relationships, too. A vehicle has a base price, which corresponds to a certain column in the database.
But a vehicle also has a relationship to an automaker, which corresponds to an object from another table. The Enterprise Objects Framework manages these relationships and does the joins for you automatically to fetch the related objects. So your model specifies a lot of information about how to do all the database work. Thank you. And it can manage some fairly complicated relationships here, too.
And you're going to see the usage of this A.B.C. business quite a bit in WebObjects Builder. That's a sequence of messages, a sequence of tokens that describe a series of messages to be sent. So you see the first one, vehicle.maker.name. Send the message maker to the current vehicle, and then send the message name to that thing, and that would give you Chevrolet, let's say, something like that. So if I mention a car, do I get, like, a free car? like endorsement opportunities in one of these sessions. If I mention that. So maybe you have a Corvette vehicle, and you send it to the message maker, and it returns the Chevrolet object. So this A.B. business is what we call key value coding, which is the fantastic... No, I don't have time right now.
Key value coding is this terrific piece of technology that's pervasive in web objects that lets you specify in a very simple manner complex series of messages. And you'll see these at signs that show up every once in a while. That's an extensible way that you can tell it to do something tricky with a list of objects.
You know, compute the average base price of all these vehicles. Find the one with the max. Find them, count them, and so on. So you'll see me do a little bit of that when I get the WebObjects builder in a moment. Project builder. You can hear all about project builder in hundreds of other sessions. Project builder, project builder, pro, project builder, project builder.
I'm going to say project builder. I don't care what you think. So you can hear all about project builder somewhere else, but let me actually try and build something here to show you how these tools fit together. If we could have demo one up on the screen, please. Enjoy a refreshing beverage. - Okay. How many people here are going to all the WebObject sessions? Yeah? Good. You'll see more elaborate versions of virtually everything I'm doing here. Bob, Bob Fraser is going to all the WebObject sessions, the product marketing manager.
We do have a marketing plan. We're sending Bob to all the WebObject sessions. I think we have to edit that out. Edit that out of the DVD. Okay, we're going to edit that part out of the DVD. the Last year, Tony told me that she had to edit some parts of my presentation.
well at remember last year you said that i said bite me by mistake in the middle of the presentation yet to cut yet to cut that part out So if I get in trouble, I know what to say. Like if something derails in the demo here. All right, the tools I'm going to use right now are Project Builder, WebObjects Builder, and EOModeler. I don't want that.
I don't want this. I used to use this all the time, but not now. But... The first step is usually to build one of these object models. I have a database running on here, and I'm wearing this shirt for a reason, because I have a database of... There was a recent major sporting event in the United States, in Salt Lake City, right? But I don't want to get in copyright trouble, so let's pretend it was in Pepper Lake City or something like that, and it was some kind of winter sporting festival. And... I've got a database here, an open base, of tables of athletes and teams and countries and medals. And I was kind of fascinated by this because every time I try to think about what demo to do for WWDC, it becomes apparent to me that there's always something going on in the United States that involves some kind of scoring controversy. Um... Last year I did this demo based on the 2000 election. You know, there was some kind of confusion about who the winner was. This year you might have read that there was some dispute about the pair's figure skating. So I put this database together, and I want to build a model that talks to that. That's sort of the first step. So here we are in EO Modeler. Here we are.
And you want to build a new model. Now, new in WebObjects 5.1, we have increased by 50% your choice of adapters. Um... I hope to live long enough to see this device actually scroll. This is a scrolling thing here. We're getting there. So I want to make a JDBC-based object model.
I happen to have-- I've got OpenBase on here, but, you know, it could be any decent relational database. And you get this terrific panel here where you have to type some string of cryptic gibberish that tells it how to connect. And it's different for every-- Yeah, I'm gonna hit the Wolympics database on this particular machine. You specify a URL in JDBC that says, "How do you want to connect? "What machine is it on and what database is it?" And the syntax of this is all over the map for different databases. I did memorize how to do it for OpenBase, so that's what we're gonna do.
Now, the model wizard is going to connect to the database and ask you a whole bunch of questions. Do you want primary keys? Well, yeah. Do you care about relationships? I don't know. Storage procedures? No. We'll do this later. And it asks you, here are all the tables in the database.
There's an athlete table and an event table and a flag table and metal and image and everything. Which ones do you want? Well, use all of them. And now here come all these -- you know, I never really understand what this is all about. This is question about relationships. I have to read one of those WebObjects books apparently. I suppose it would tell me. I should just blow right past that. Is that important?
I always hit next. I always hit next. And that's something to do with referential integrity. You know, you delete Team Canada. Do you want to delete all the athletes from Team Canada as well? Well, no. So here is a starting object model. This is a file that I'm editing here. And you can see it's got all this information in here that athlete objects come from the athlete table. And flag objects come from the flag table. And medals come from here. And we have all these different kinds of objects we can make.
And I can get in here and, you know, change the names around. Maybe we want to have song out of these instead of anthem out of these. I was really kind of, eh, maybe not. I was really hoping that today would be the national day of somewhere so we could all stand and sing the national anthem of something. But it's not. I looked on the Internet. Last year I did my demo on Victoria Day. We all sang God Save the Queen. Yesterday was Independence Day, or Liberation Day in Norway. That was the closest thing I could find to today. Are there any Norwegians here? Anyone want to bring a flag up on the stage and we could all sing the Norwegian anthem? No? Oh, shoot. But here is really a file that's describing what kind of objects you want to make out of where. And you can look into this and see it on what we call the diagram view. You can see that it's picked up... Whoa, complicated. You can see that it's picked up all these relationships that are specified in the database as well. So a team has a list of athletes, and there's one-to-one joins, there's one-to-many joins, and it's all constructed according to the various relationship information that's in the database. Or I could add additional relationships here, and I could delete things and I could manipulate properties and get rid of the ones I don't want. But rather than mess around with that for a while, I did a little bit of this last night. I got my iPod here. I understand that the marketing guy in England markets web objects and also the iPod. Well, he would like this.
Here, right off of my iPod, I've got the object model that I want to use. So... I understand you can actually put music on an iPod. Is that true? I haven't tried that. But... Actually, what am I doing? I'm going to put that there. All right, here's my object model that I want to use. Close, close, close. I'm getting rattled. I might have to say the word here in just a minute. No, I don't want to say it. All right, here we go. This one's just slightly tidied up. I added a few relationships, and I flattened a few things and so on. And I'm going to use this to build a simple WebObjects application. So let's just make this a little smaller and put it off to the side.
And start up your friend and mine, Project Builder. And Project Builder lets you build all sorts of different exciting things, much as i would love to build a Carbon bundle right at the moment or an i'll pick driver maybe fun to try that in a web objects uh... i think i'll build a web objects application and at this point you get to give your application name about this word stuck in my head i've been here this world we jag wire and call me up It rhymes with fire war, I think. I'm not sure. But that's going to be the name of my application. That'll be part of the URL. And here's this panel. Do you want to deploy this servlets? And do you want to do this and that?
And you know, I want to go to one of the sessions and learn what these checkboxes are. So I'm going to turn them off for now. And this is a good one. Something to do with web services. Bob mentioned web services. This panel is new to me. I don't know what this is at all. But it looks great, doesn't it? Add the Java Access Framework. Do I want to do that, Bob?
No? Okay. Please refer to the WebObjects web services documentation for more information. All right, I will. I'm sure that's great. And here I get to add some frameworks. Just in the interest of saving a bit of time, I have pre-written a few objects, and in fact, they're just objects that I like so much that I carry them around on my iPod, so I'm going to add a few frameworks off of my iPod here. Here's my iPod. Frameworks. Yeah, these are all good. I'll talk about what these are later, but they're, you know, compiled Java things that I'm going to use later in the demo.
And we're done, and so here is a blank WebObjects application. So far, it doesn't have any connection to a database. All it really has is one Web component called main that's got, you know, an HTML file in it, which is really not very exciting. And it's got an even less exciting WAD file in it because there are no objects to find in the first file.
I could edit this all here if I want, or I could double-click on this to actually edit this component in WebObjectsBuilder. Thank you. which i'm doing that so here's will build a good the area appear we can type each team of your fat that this page the games two thousand two and i really love these horizontal rules and and this is enough of an html editor you can make things bigger and and you can put them in color and really you should probably go and get dream weaver go live or something like that that's a better html editor and do that part if you want but you're completely free to use web objects builder if you like as well i think will build a response for getting started so here we go the games of 2002, I'm going to put in a form because I want to search for who are you looking for we're going to look up athletes And I want to be able to look them up by their first name and have a text field. Maybe their last name.
and have another text field and a submit button, and I'm just designing my UI here. We really want to find athlete objects. The idea is going to be when I hit submit, I want to cause something to fetch a list of athlete objects and then display them. And I want it to fetch the athlete objects based on what I typed in those two text fields.
Well, this model file knows how to create athlete objects. It's got all the information in it about databases and tables. And so I can drag this athlete thing out of EOModeler and drop it over here and add what we call a display group. Pardon me, what was that? Okay.
I think it's offended that I'm calling this Jagwire. The source file is unparsable. What are you talking about? Bite me, bite me, bite me, bite me, bite me. and Could not open source file. Okay, are you smart guys? How come I can't open my source file? Bite me, bite me, bite me. I'm working off the beta here of ERTE, so we'll just--give me one sec here.
There we go. For some reason it was not connected to the project builder, but now we're fine. Stop biting me. So here we go. We want to add this. Yes? There. Oh, man, thank you. I've added now to this page something called a display group, which is an object that knows how to go and fetch certain kinds of other objects from the database.
It's going to fetch them out of this object model here, which I don't really need now. And you can hook a few things up. You can say that the submit button, here's all the messages you're allowed to send to a display group, and up above it are the various properties you can set. So I want to send the message qualified data source whenever someone clicks on that submit button. So the submit button in my inspector is now going to send that message to cause this object modeling thing to go and fetch. And you can set up a few other bindings here to say, well, let's match, see it knows the properties of athlete objects. Let's mask their last name here when we're forming our search and their first name here.
Okay? Now, this is a complete application that would actually go and fetch all those things, and it's not actually displaying anything yet, and I think I would probably get bonus marks if I were to display the athletes that it found in the database. So I'm going to add a little table, and this is an HTML table with a special difference. There's a blue line around the second row, meaning that this second row is encased in a web object's repetition, a WO repetition object. This object is going to repeat over and over again once for every object on some other list. So if I fetched 37 athletes, I'll have 37 rows plus the title row in my table. So I'm going to display the athlete's name.
name and we'll just leave that blank. And here we're going to display the athlete's first name. Well, but before we set this up, you want to be able to tell it how to loop through this list of athletes. Well, the display group has a thing called displayed objects. That's all the things that it just fetched. And you can connect that like this to the repetition and say, that's the list that you should go through. Now, if you fetch some objects, you go through that list. And here's a common design paradigm in WebObjects. You have lists and you have items. I want to have my own little private athlete object. that's going to be used to go around this list. List item. And now I can say, "Well, let's display the athlete's full name on that string." Get rid of this word here. So there, I think that's probably enough to start. Let's try compiling this.
and running it. Project Builder's compiling, it's making the huge-- look at the class path, holy mackerel. And starting my application here, and it's going to ask Internet Explorer to come back and rendezvous on this particular URL. So here's IE. It's made up my first page here. I'm looking for people named, I don't know, Steve.
And oh, here's a bunch of Olympic athletes named Steve. Team Steve, yeah, that's great. Find people named Bob. Is there-- there's only one guy named Bob in the game. But this is actually my favorite. Yang Yang. Don't leave me alone. There are actually two athletes in the Winter Olympics named Yang Yang. This is why primary keys are important in your database.
This doesn't uniquely identify anybody, but you might want to go back and say, well, what team are they on? Well, I put another string in here, because each athlete has a relationship to a team object. What team were they on? Let's display the name of the team that Yang Yang was on. Oops, sorry, I dragged it to the wrong place. Right to that string right there. Thank you. And if you save that, the thing I like is that you can keep going here without even restarting, and it helpfully tells you that they're both from China. Well, I still can't quite tell them apart. Maybe if I knew what sport they played.
I'll put another thing in here. We'll go over to the discipline object. What discipline were they in? Are they skiers? Is one a skier and one is a skater? Maybe that will help me out. Oh, great. They're both short track speed skating. Um... There's got to be some way to tell them apart. How about an image? Those are just strings. I'm going to put in an image object here. And athletes in this case in my database are related to an image, and images have some binary data. And here I'm hooking it up to an image object. And a MIME type--is it GIF or JPEG or what is it? Let's see there. How are we doing now?
Oh, okay. Oh, it is two different people. Okay, one has a yellow sleeve on her suit, and the other one has a... But, you know, without me having to write any SQL so far, I can actually fetch objects from a couple of different tables. There's all this fetching going on for me, and I'm kind of blissfully unaware of it at this point. Web objects does have a way that you can turn on SQL debugging. You can send some crazy message to say, I want to turn on logging of SQL so I can see the SQL that's being generated for me. And I used to go to the documentation and look that up every single time. But I got tired of that. So I decided to use this palette feature. These palettes are places that you can put objects that you've written once that you might want to reuse again.
And I've got this palette over here that just contains a checkbox that turns SQL logging on and off. We'll add that to my page here. You're going to see... The SQL will go whipping by over here, okay? So, uh... Now I've got this checkbox. I can turn logging on and off and submit.
Oh, it generates some SQL to find those guys. Let me find all the people named Steve again. Okay. Here's all my Steves, and you can see this is all the SQL that I did not need to write. That checkbox is just sending a message to say, turn on the logging for me. So we're selecting this from there, and we're selecting this from there, and it's going across three or four different tables and pulling back all this information. So there's a lot happening for me in an application like this that I didn't have to write. Like I tell you, I was putting this demo together, and I was unable to borrow. Were there seven or eight guys named Steve in the database? That really is Steve Bradbury from Australia, who won that terrific NASCAR speed skating race where they all crashed in the last turn and he came whipping through. But I didn't have pictures of all the other Steves. I had Steve Iserman, the hockey player, but I didn't have anybody else. So I did have iPhoto. And last night in my hotel room, I thought I gotta put some more pictures in this database to make it complete.
Some of these are my children, and some of these are other things I just happen to have sitting around. So you can probably try to decide which of these are real Olympic athletes and which ones are not. But the whole Enterprise Objects framework layer makes it fairly easy to do this sophisticated fetching across four or five different tables. Well, I'd like to make this even a little more elaborate, if that's possible. And maybe we can tell our yangs apart if we have a list of the actual events that they were in. So here in the second cell, I'd like to add what we call a repetition. This is just something that explicitly goes through a list. And I'd like to loop through each of the events associated with each athlete. And let me create a variable like I did the other time, event.
This here, this means event object from the event database, not some other kind of event. You could really mess people up by having a database with tables that were named like adapter and property. And you'd never be able to describe what you were doing in WebObjects. So let's see here. Here we're going to loop through all of the events. And I want to display each event somebody was in on a string. Event name, like that.
Now here I do need to recompile because in that move of adding the event object, it actually created one more line of Java. It added this thing to my main object, saying, "Oh, we now have an object called event, "so I do need to pause and recompile here."
I like it better when you don't need to recompile. Here we go. So show me all the Steves again. Here they are, and they're, oh, that guy was in short track, pardon me, that guy was in short track speed skating, and oh, that handsome fellow was in speed skating, and the bunny was in the men's aerials, and so on. So we're looping through a bunch of different tables. And so far I've done this all with one component. This is one big component that just displays stuff. And I want to really have a detail component. I'd love to be able to click on short track speed skating men's 1500 meters and see the results, you know, load another one of these components to display the results. There's a lot of things I'd like to do.
And actually, oh, I really wanted to show this object to Mark Ritchie, who's sitting up here. Me being a bit of a palette junkie, I've got all these things on palettes that I've collected over the years. And I figured this one out the other day. Drag and drop that in here and save it. And that gives me alternating row colors in my table. Hey, cool!
Thank you. Thank you. Somebody said cool. Thank you. Thank you. Let's make a second component that's going to display details of a particular event. My goal is to have it so that this is a hyperlink that takes me to the details of men's ice hockey. well like that a second page here of the same right away on call event details and let yes i want to add the project and this is going to be something that just displays one particular event object i want and i want to return your head was like a motor would that get i'd miss one checkbox uh... i want to add an event object And here's what I meant. I want to have a way to set the event object associated with this page from somewhere else. When we load this page, I want to be able to tell it, here, 1,500 meter speed skating. Please display that particular event object.
And I just want to save a little bit of time here. And you can have just HTML fragments on palettes, too. So here's a little table that just goes through the event and displays all the medal winners. It asks the result for the medal and the medal for the name. And it asks the result for the winning team. And it asks that for the flag and puts it up here. And it loops over all the athletes. And I wanted to avoid the four or five minutes of fumbling around to actually construct this table. So there it is. But I do need to add another couple of objects. This is just exactly what we did before. We want to have a result object. and we want to have a athlete object, just like before.
So there's my component that's going to display all the results of a particular event. And if we go back to the first page, Remember that? That's the string that's displaying the name of the event. Well, I want to click on this that turns it into a hyperlink. It wraps it inside a hyperlink object, and in particular, it puts it in a hyperlink object that can send a message somewhere, and I get to decide what message I want to send.
I want to send a message that says, let's find the event details page, and let's give it this particular event and tell it to go. So in WebObjectsBuilder, you get to add what we call an action. I'm not declaring a variable here. I'm creating a little stub of a procedure that's going to load up another page. Show Whatever name you want. And what page do you want? Well, look, I can just start to type E-V-O, event details. It knows about the pages I've got in my application already. That's really nice. And you draw one more line to say, whenever anyone clicks on that hyperlink, This is the action method associated with that hyperlink. Even though there may be 20 of those hyperlinks on the page, they're all sending the same message back to my application. Show me this here event.
And I now get to demonstrate my incredible command of Java and write a line of code here. This is the main Java file. This is all the code associated with the main page. Not really very much of it. A couple of object declarations. And then this thing here. It wrote out this little stub for me. It said, all right, I'm going to look up the page called event details for you and give it to you as a certain kind of object. And you can add any little initializations or anything you want here. And then I'm going to return that page, which will cause it to be generated. Well, I've got to do one thing. I've got to say, next page, set the event that you are going to display to be the same one as I'm currently displaying on my list. Remember this page, the first page, had an event object as it went through the list of events?
And this is just kind of mind-boggling to people in web objects that it figures this out sometimes. And it just knows when the request comes back in which one of those 40 hyperlinks, which specific event object caused that hyperlink to be created. And hopefully this transition is fairly smooth here. Let's try it here. Now we're going to compile it. It's going to add the other.wo component to the application. ClassPath's probably even bigger now. I don't know where it goes. And we'll launch this now. Now we have a two-page application. Thank you.
It did it did he here go. Show me Steve's again. Now these are hyperlinks right and there are. If the hyperlinks in this page each one of these is sending that same message back to the application show me this here event. Web objects can sort out which event object was used to create this piece of the loop and then pass that automatically to the other page. Tell me about the men's five hundred meters hey that was a good one gold for Canada and silver for Canada. Holy smokes. So now we're fetching, we're going through the database and we're picking up the winning team and the members of the team because there can be, in this particular database, there can be more than one person on a winning team. You know, if you get down to hockey or something, there's like a whole bunch of winners on a hockey team. Oh, Canada wins again. Oh, isn't that nice? And so, chance of two randomly selected events I might just happen to click on here. So this is some, you know, if you wanted to code this in SQL and HTML, and, you know, by hand, It might get kind of ugly with all the joins you'd have to be doing at this point, but I'm just exploiting relationships that are found... Hi. Did you get that? You want to take another one? Take another one. Oh, come on. Take another one. Hi. Bye.
So we're just working through various relationships that are found in the database here. Now, I look at this and I think this is not nearly as stirring and emotionally evocative this page as it could be. And people come to my session really wanting to hear national anthems for some reason.
So we go to the event details page here, and I want to add something. I'm going to add right here. See, there's the medal named gold, the country name Canada, and the flag. I want to add another thing here called a WO embedded object. This is a little thing that comes with web objects that dumps binary data to the browser and lets it figure it out with an embed tag, so QuickTime movies or Flash or something like that. And I don't want it to be too big, so I'm going to go in here and just... Oh, just a second. I can go up to the inspector of this embedded object and add a couple of bindings. I want its width to be, I don't know, 150 pixels, and I want its height to be... These aren't dynamic at all. These are just going to get dumped straight through to the... How many pixels high does a QuickTime player have to be? 16 pixels? Does anyone remember that magic number? No? Okay, well... But more importantly, what data do I want this thing to dump out to the browser? Well, conveniently... Uh... Each result is associated with a team, and each team is associated with an Anthem object. Oh, what was that? Oh, jeez. What the heck have I done now? All right, well.
And some of these Anthems, I'll tell you, are MIDI files. Some of them are MP3s in the database, so they have different MIME types, but I can just bind it here and let the thing figure it out on the fly. Hope the sound's working on this computer. Thank you. Sound? Going to be okay? Yeah? All right. Great crew in the back. Look how alive they are. It's fantastic. So let's try this again here. Here we go. Here comes some national anthems. Oh!
Oh, they're all playing at once. Well, that's nice. Hmm. that's a lovely effect uh... i guess is a couple ways i could fix that i i could find on find that component and you can add whatever bindings you want. You know, I happen to know that you can add an autoplay false to these things. And that just embeds autoplay equals false in the HTML that goes out. So now hopefully they don't all play this time. Thank you.
Phew, that's better. But even better, you know, you wouldn't really play this anthem if your country had lost to Canada in the Olympics. You know, we wouldn't hear that. So... And I only mention that because it's an excuse to introduce another object from the collection here. We'll -- we'll -- I want to add, this is one of my favorites. How many of you like the good old W key value conditional? How many WebObjects programmers have ever... Oh, thank you, thank you, thank you. Key value conditional, thank you very much. Like I had anything to do with it. But the idea of a key value conditional is it exploits this key value business that people love so much. No, no, later.
It exploits key value coding, and you give it a key, a message you want it to send, and a value, which is maybe another object, and say, compare these things, And if they're equal, display everything inside me. It's conditionally displaying something. Well, the key I happen to want in this case is-- let me think here. I want result.metal.name. I'm just going to go through the graph and figure out the name of the current metal. And I want to compare that to gold.
That could be an object. It could be a string. It could be, you know, any other object and thing. It's just gonna compare the two things. And hopefully this time we have only the winning country's anthem. Oh, that's better. So in this case, we've used an object that dynamically sends some messages and makes a decision on the fly about what else it wants to include in the database. So we've now got only one anthem player here. I went to the same public school as this guy here, Eric Lindros. Anybody from Philadelphia or New York here? Yeah, all right. I'm happy for you. Okay.
Enjoying the show? Yeah? Okay, good. Well... This might have seemed like a lot of work. I think that's actually quite a bit to get done in just a few minutes, you know, starting really from nothing. I admit I did drag a couple of things off pallets, but they were genuinely reusable objects. But I want to take a moment or two to show you one of the many direct-to family of fine products we have here with WebObjects growing every year. I want to show you the first one, direct-to-web. Direct-to-web is a technology that uses one of these rules-based engines to decide on the fly by study-- you give it one of these object models, and you tell it, you know, "Go and study this object model "and learn what kind of objects "are embedded in the object model, "and please make me up an application "that lets me fetch things and change them "and search for them and add new ones." And Direct-to-Web, by looking at the model, can generate a UI on the fly. Direct-to-Java Client is the same general idea with a different sort of UI. So I want to just quickly make a second application here where we can modify Olympic results, because sometimes after an event is over, you change with the winner is this is a new thing the u_s_ election well you can change the thought of it really hard so i want to make a direct to web app application here jag wire direct will call this one here and uh... More exciting checkboxes that I need to learn more about and frameworks. But here I want to tell it specifically what object model do I want to use. Well, I kept that one on my desktop. There it is. That's the object model I want to use with the information about fetching athlete objects and teams.
You can choose a variety of different styles here. And that's it. We're done. We now have a complete application that can actually fetch anything from the database that will let me update any property of anything in the database. Let me make new objects and delete things and so on. Plus, as a bonus, I get to refine the UI from within my browser. Here inside my browser, I get to tell it, no, I want to have a pop-up list for that thing instead of a browser. And you know what? I don't want to display this, and this thing should be uneditable. I get to tell it all that right here in my browser, and that writes rules back at the back end, which interact with this rules engine and modify the UI the next time it's generated. So let's log in here. This is the completed application. My password, which is a six, seven, eight, nine of those dots. Yeah, that's good. You should make your password dots like that, because then you can cut and paste them. That's very neat. And I would like to be able to change the UI, so I'm going to click on that checkbox there.
So here is direct2web's first stab at a user interface for fetching and updating anything from this object model. It's found the list of objects and knows all the properties of all the different objects. And you can fetch anything. Fetch all the athletes whose last name begins with H. And it will make up a page for me here with every property of every athlete whose last name begins with H. This is not the world's best UI, but it's not bad for a start. And I can tweak it here. I can hit this Customize button.
And a little Java op-let is going to pop up here that lets me modify the display of these various properties. You see this thing here? This is a list of all the properties that are currently being shown in this window. So we're showing them in alphabetical order. Date of birth, first name, full name, gender, highlights, yadda-dadda-dadda. Well, I can change it all around here.
I'd really like full name to be first, and there's no need to display first name or last name at all. And let's have date of birth. Well, that's a couple of simple changes. Thank you. And you hit save, and that writes some new rules at the back end that rewrites this UI on the fly by studying the rules engine. You want this rule applied when this object is generated. We can get even fancier here. You can say, I want the page to be a different style of page. This is my favorite here.
And then that writes these things out as a different kind of page here. There's a bunch of rules at the back end that govern how every possible thing is going here. There are rules that state what the layout of one of these editing pages looks like, for instance. And you can dive in here with this wizard and refine the rules. It's usually a pretty good start, but you can refine them on the fly here. Well, I want to get to, let's see here, I want to fetch... figure skating events. What do we got? Figure skating events. We got four different figure skating disciplines in web... oh this was a good one.
Pairs. Anyone remember that? Was there something about that in the paper? We had uh... two golds and a bronze... two golds and a bronze? Oh yeah, two golds and a bronze. I'm almost done. What? Is my zipper undone or something? What? I am? Yeah. Let me just finish this. I'll be one minute and then I'll take some questions, okay? I thought I had until this was done. That's when the Q&A is done. Oh, the Q&A is done then. Oh, sorry, pardon.
customize this i want uh... properties i want that actually want to display air results on a a table Because I want to edit that bronze result. I feel bad for the Chinese team that got a bronze medal. Let's use direct-to-web to display a pop-up list of all the possible medals like that. And here's the Chinese team. And let's give them a gold medal, too. You know, I think they should... Everybody should have a gold medal. That's better. Now we've got three gold medals in that event. So... That's as far as I wanted to go. I'm done, I guess.