Professional WebObjects 5.0 with Java Michael DeMan Josh Flowers Gustavo Frederico Ben Galbraith John Hopkins Pero Maric Max Muller Jim Roepcke Bernhard Scholz Daniel H Steinberg Thomas Termini Pierce Wetter with Douglas Bergere mmalcolm Crawford Wrox Press Ltd Professional WebObjects 5.0 with Java © 2001 Wrox Press All rights reserved No part of this book may be reproduced, stored in a retrieval system or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews The author and publisher have made every effort in the preparation of this book to ensure the accuracy of the information However, the information contained in this book is sold without warranty, either express or implied Neither the authors, Wrox Press nor its dealers or distributors will be held liable for any damages caused or alleged to be caused either directly or indirectly by this book Published by Wrox Press Ltd, Arden House, 1102 Warwick Road, Acocks Green, Birmingham, B27 6BH, UK Printed in the United States ISBN 1861004311 Trademark Acknowledgements Wrox has endeavored to provide trademark information about all the companies and products mentioned in this book by the appropriate use of capitals However, Wrox cannot guarantee the accuracy of this information Credits Authors Michael DeMan Josh Flowers Gustavo Frederico Ben Galbraith John Hopkins Pero Maric Max Muller Jim Roepcke Bernhard Scholz Daniel H Steinberg Thomas Termini Pierce Wetter Technical Reviewers John Paul Ashenfelter Michael Boerner Oliver Breidenbach Bill Bumgarner Robert Burns Patrice Collardez David A Coyle Dave Every Hang Lau Paul Lynch Phil Powers-deGeorge Patrick Robinson Contributing Authors Douglas Bergere mmalcolm Crawford Production Manager Liz Toy Technical Architect Chanoch Wiggers Technical Editors John R Chapman Tabasam Haseen Christian Peak Mohammed Rfaquat Category Manager Louay Fatoohi Author Agent Velimir Ilic Project Administrators Simon Brand Production Coordinator Pip Wonson Production Assistants Paul Grove Natalie O’Donnell Abbie Forletta Indexers Adrian Axinte Proofreader Agnes Wiggers Cover Design Dawn Chellingworth About the Authors Michael DeMan Michael DeMan is a senior consulting engineer specializing in enterprise software development and systems integration using WebObjects and J2EE technologies He has been developing scalable multi-tier Internet applications since 1996, and has worked with object-oriented technologies since 1990 Michael is the founder of Gemini Solutions, Inc., a software services and solutions company, and also co-founded the Pattern Research Foundation, a non-profit organization that provides technical assistance to other non-profit organizations Michael graduated with his Bachelor's degree in Philosophy from Western Washington University (WWU) in 1994 He also attended the computer science graduate program at WWU before beginning work in the commercial sector Michael can be reached at michael@geminisolutions.com Josh Flowers BIO NOT RECEIVED YET Gustavo Frederico After nine years trying to learn how to play the violin, Gustavo Frederico started studying Computer Science at Universidade Federal Rio Grande Sul (Brazil) in 1992, where he graduated Gustavo now lives in Ottawa, Canada, and has survived four winters, so far He develops webbased solutions in Java for e-commerce projects at MONTAGE.DMC eBusiness Services, a division of AT&T Canada To my wife, Louise Ben Galbraith Ben Galbraith first started programming when he was eight years old He spent a considerable amount of his youth as a hobby programmer In his late teens, he was hired by a Silicon Valley computer manufacturer to develop Windows-based client-server applications In 1995,Ben began developing for the web and fell in love with Unix, VI, and Perl After some years as an Internet consultant, Ben now leads the Java development team at an insurance company in Salt Lake City He regularly lectures, evangelizes, and gives classes on Java technology To my wife Jessica John Hopkins Native of Fort Worth, Texas, I earned my B.S in Mathematics at Texas Christian University, then started my programming career in the local aircraft industry at General Dynamics, where I met my wife From there, we worked together in the electronic music industry in Australia, for Fairlight Instruments, Pty Ltd on a music printing system After a year of tutoring college-level mathematics, I moved on to desktop applications for the Mac OS, first with Data Tailor, then The SU5 Group, helping with the creation of Trapeze, Persuasion, DeltaGraph, FaxSTF Network and Meeting Maestro, and products for VariLite's theatrical lighting systems For the millennium, I helped scour UNIX system code for Y2K bugs Then, I helped implement web sites, using WebObjects and J2EE technologies and Tensor Information Systems I also taught classes in Java and XML, wrote for the company newsletter on programming and mathematics, and wrote a case study for Java Report I am studying current and upcoming XML and peer-to-peer computing technologies for virtual supercomputing and cycle selling projects In my spare time, I help Dr Laurence Furr with Trinity Lutheran Church's music activities: singing, playing piano, organ, violin and hand bells, composing and arranging I also play violin in the Fort Worth Civic Orchestra Occasionally, I get a jazz piano gig, either live performance or recording session (check out the Paul Warren CD "Sweet Deliverance") I try to keep up with developments in physics with the help of my friend, Dr Bruce Miller at TCU Most of all, I enjoy spending time with my wife, Darlene – a fellow software engineer and musician, and my daughter, Elise – a fellow author and musician Pero Maric Pero has been working with WebObjects since version 4.0 and has been developing Java applications since 1997 Currently he is a Technical Support Lead at MONTAGE.DMC (a Division of AT&T Canada), where he mentors and assists team members in providing support for WebObjects applications at Nortel Networks Pero's interests include application servers, long Ultimate games, cycling and squash Thanks to all the editors, authors and reviewers at Wrox Press for making this book possible Also, a big thanks goes out to Samantha for her support Max Muller Max Muller was raised in the Midwest and first discovered the joys of programming while attending the Oklahoma High School for Science and Mathematics Being a chronic overachiever, in four years at Georgetown University Max completed both a Bachelor of Science, majoring in Computer Science and Economics, and a Masters in Economics, focusing on mathematical modeling At Georgetown, Max competed on various mathematical modeling and ACM competitions It was also at university that Max first started working with WebObjects in his spare time, before taking an internship on a large Department of Defense WebObjects project in his junior year After graduating, Max moved to the bay area and worked for several dotcoms before finding the perfect combination in NetStruxr, a corporate real estate procurement and transaction platform Since starting at NetStruxr and learning the secrets of DirectToWeb from the original author and CTO of NetStruxr, Patrice Gautier, Max has become an outspoken advocate of building template and rule based user interfaces with WebObjects Max has written articles for online publication Stepwise, as well as giving presentations at the Bay Area NeXT Group In his spare time Max enjoys writing, reading, sailing and traveling Max lives in San Jose, California with his wife, and fellow WebObjects developer, Angela and their two hybrid Serval cats Jim Roepcke Jim Roepcke is an experienced WebObjects developer from Canada currently experiencing WO nirvana at NetStruxr in San Francisco Having lost much hair fighting with Active Server Pages in his early years developing web applications, Jim appreciates the refreshingly sane approach WebObjects takes Jim is a life-long Edmonton Oilers hockey fan, and a lover of silly British comedy – Red Dwarf and Black Adder are his favorites Jim wants to thank his daughter Cyan and wife Cheryl for putting up with his neglect as he toiled on this book, and WROX for not asking for a full-body shot for the cover ;-) Bernhard Scholz I am currently working as a Consulting Engineer for Apple Germany, specializing in WebObjects and networking technologies After studying Computer Science at the Technische Universität München I signed a contract with the biggest WebObjects company in Germany, joining the team for two years before I finally joined Apple Before this time I was also supporting the NeXT community by administrating the Peanuts-FTP-Server, which I'm told is still of high value for many people who love their black NeXT-boxes I've used Amiga, Windows32, X11R6, NEXTSTEP, OpenStep, WebObjects, Linux, Solaris, HPUX, VMS and other technologies trying to learn the best from them Currently I'm focusing on OO Design, project management, WebObjects and Mac OS X (especially server versions) I have used WebObjects from its early development and I believe it is one of the most beautiful pieces of software currently available For this book I want to thank my parents for giving me all the support and freedom to form my life as I wanted it to be I hope they are happy with the current result Daniel H Steinberg Daniel Steinberg is the Director of Java Offerings for Dim Sum Thinking in Cleveland, Ohio He has covered Java on the Mac for the last five years for JavaWorld magazine, writes a monthly column for the O'Reilly Mac DevCenter, and is a regular contributor for IBM's developerWorks Daniel is a recovering Mathematician who runs seminars in the latest interest areas in Computer Science for area colleges trying to stay current He is a non-apologetic Mac fan who curses whenever he has to spend too much time on his Windows box His favorite moments are cooking for and with his wife and kids Thomas Termini Tom Termini is a founder and managing director of BlueDog Inc (www.bluedog.net), the premier WebObjects application service provider Tom has been a NeXT and Apple developer since 1990, with clients from the World Bank, the U.S Government, Volkswagen of America, Lockheed Martin, Allied Irish Banks, Philip Morris Companies, among others Tom processes with an eye towards innovative user interfaces His ongoing goal: find new ways for information technology to serve business needs In the 1980s he trail blazed multimedia application design with database integration, and founded the new-media firm Enigma Concepts Inc Tom was born in Washington, DC; graduated in 1986 with a degree in Pre-17th Century English Literature from the University of Maryland, and was awarded an M.B.A in 1993 from Loyola College of Baltimore When not pushing a mouse, Tom explores the backcountry on his mountain bike with Indy, the Australian Cattle Dog mascot of BlueDog Pierce Wetter Pierce Wetter lives in beautiful Flagstaff, Arizona surrounded by one billion pine trees When not shoveling snow; visiting the nearby Grand Canyon; making fun of "flatlanders"; or reassuring people that Arizona does get snow (at least at 7,300 feet it does); Pierce works at Marketocracy (www.marketocracy.com) doing WebObjects programming Prior to trying to take over Wall Street, Pierce worked as a WebObjects consultant for companies like Apple and Time/Warner He was very excited about contributing to this book, because he feels that WebObjects is the best web application platform, but the Apple documentation stopped just short of demonstrating how powerful WebObjects can be Introduction What is WebObjects? WebObjects is the powerful new release of Apple's award-winning application server, built from the ground up in Java WebObjects was the first object oriented application server, and year on year remains the top application environment for many developers, offering a suite of tools for developing scalable three-tier web and standalone applications This mature product offers easy to develop and deploy distributed Java applications, and has powerful and simple data access, templating capabilities, and session management that allow the developer to get on with the task of writing business logic In addition, as WebObjects is based on java, it can now run on virtually any server making it easily accessible to millions of Java programmers In addition WebObjects application development is in Java and WebObjects also integrates with other Java-based solutions such as EJB containers, servlets, and web services The combination of a Java runtime with advanced native tools for Mac OS X and Windows 2000 makes WebObjects an obvious environment for customers needing rapid development of flexible, scalable web applications It's An Application Server Static web sites store all their content, presentation, and navigation in HTML files Not only does this make it very difficult for web masters to rapid and complex updates, it also means that every visitor sees exactly the same information in exactly the same way Some rising new standards such as XML help address some shortcomings, but a different approach has been around since the early days of the Web – the application server Evolving beyond client-server architecture developed in the 1980s, application serving addresses how to create, maintain, and distribute dynamic information Introduction An application server typically stores content in a database and employs some form of scripting to create web pages dynamically While this approach allows web developers to create sites that have easily updated content, flexibility comes at the price of greater complexity This complexity increases development time and makes a web site harder to maintain WebObjects improves on the traditional application server architecture by cleanly separating the database access layer, the application-specific Java code, and the web page presentation layer Supported by rich object-oriented frameworks and an object-relational mapping engine, this architecture is the foundation of the powerful technologies in WebObjects Web components enable the efficient generation of HTML, XML, or SMIL from reusable templates WebObjects provides an abstracted layer for database access via Enterprise Objects When an HTML interface just won't do, Java applets or multi-tier Java client applications are supported It's A Development Environment WebObjects provides an integrated suite of graphical tools to speed application development Unlike other graphical tools that generate hard-to-read code, WebObjects dynamically binds application components with XML-like data structures, greatly simplifying application maintenance Application components can be reused, and incremental development is easy – reducing total cost of ownership over the life cycle of an application At the heart of the WebObjects development process is Project Builder, a multilanguage integrated development environment used extensively by Mac OS X developers In addition to helping edit, compile, and debug WebObjects applications, Project Builder organizes all your components (including localized resources for multiple languages); provides templates and assistants covering the common application types; and, on Mac OS X, integrates with source code repositories such as CVS Perhaps the most powerful tool, EOModeler manages the object-relational mappings used by the data access layer, and can even help you organize your business logic It can also be used to manage your database schema, either by reverse engineering a model from the schema or by using a new model to create the schema In EOModeler, graphical entity-relationship diagrams represent the object relationships created and maintained by data access frameworks Although WebObjects uses standard HTML that can be edited with any text editing tool, a comprehensive layout tool called WebObjects Builder is also included that can manage the associated mapping files WebObjects Builder can be used for general HTML layout and provides the usual preview mode and drag-and-drop palettes common in such tools A developer can also drag a dynamic element into the web page, specify the mappings, and set the properties WebObjects Builder automatically generates the appropriate HTML and mapping information One widely used technique that takes advantage of Apple's integrated development environment is to have a web designer focus on the aesthetics of the user interface design as represented in dynamic HTML, JavaScript, and Flash, while letting a programmer focus on writing the associated Java code to implement the mapped methods Who Uses WebObjects? Many organizations are using WebObjects for both global internet and corporate intranet applications, including reservation systems, virtual catalogs, customer services, groupware, and several migration projects from Windows applications to the web Chapter 16 40 A Foundation Framework The Foundation Framework (associated with the package com.webobjects.foundation) defines a set of primitive classes used pervasively in WebObjects It also introduces several design patterns that are largely unique to WebObjects The Foundation Framework goals are to provide: ❑ A small set of basic utility classes ❑ Consistent conventions for features such as notifications, object persistence, key-value coding, and validation ❑ Some degree of operating-system independence The framework may be divided broadly into classes and interfaces Let's take a closer look Overview of the Framework The Foundation Framework classes can be further subdivided as follows: ❑ Data storage Storage for collections of objects is provided by NSArray, NSDictionary, and NSSet NSData objects store arrays of bytes NSPropertyListSerialization objects convert between property lists and arrays of bytes ❑ Dates and times Dates and times are stored by the NSTimestamp and NSTimeZone classes, while the NSTimestampFormatter class converts dates to formattable strings (and vice versa) Appendix A ❑ Application coordination and timing NSNotificationCenter provides a means of broadcasting notification of events to interested observers using instances of NSNotification NSDelayedCallbackCenter coordinates the events ❑ Object distribution and persistence Subclasses of NSCoder provide a means of archiving and unarchiving graphs of objects, together with information about the classes contained in the archive NSCoding.Support is an abstract class that defines a mechanism for one class to provide archiving behavior on behalf of another class ❑ Object locking The coordination of the locking of objects or graphs of objects is performed by the NSLock, NSRecursiveLock, and NSMultiReaderLock classes together with the NSLocking interface ❑ Operating system services NSPathUtilities provides us with a consistent interface we can use when working with file system paths, while NSBundle provides application resource access ❑ Other utility classes We can specify a range of values using an NSRange object If we wish to sort objects, NSComparator defines inequality relationships NSUndoManager objects manage applications' undo functionality The NSForwardException wrapper class wraps exceptions into a subclass of Java's RuntimeException Foundation Framework interfaces can also be subdivided on the following basis: ❑ Key-value coding The NSKeyValueCoding and NSKeyValueCodingAdditions interfaces (and support classes) allow objects to receive and return values for keys ❑ Validation A consistent validation mechanism is supported by the NSValidation interface and its support classes ❑ Object distribution and persistence The methods an object must implement to work with the NSCoder subclasses for archiving and unarchiving are defined by the NSCoding interface ❑ Object disposal The NSDisposable interface and the NSDisposableRegistry together manage Java's garbage collector The remainder of this appendix highlights the commonly-used classes, interfaces and methods, rather than providing exhaustive documentation about the whole framework Note that all of the methods listed below are implicitly public For complete documentation, see Apple's on-line materials at: http://developer.apple.com/techpubs/webobjects/FoundationRef/Java/Introduction.html Foundation Framework Foundation Framework Classes The principal classes that we will discuss in this Appendix are: ❑ NSArray ❑ NSMutableArray ❑ NSDictionary ❑ NSMutableDictionary ❑ NSData ❑ NSTimestamp ❑ NSComparator Let's take a closer look at these NSArray public class NSArray implements Cloneable, java.io.Serializable, NSCoding, NSKeyValueCoding, NSKeyValueCodingAdditions NSArray, like the Vector class, manages arrays Elements in an array can be accessed by their position in the array – the index You should note that an NSArray is immutable Constructors NSArray(Object anObject) Often overlooked, this constructor creates an NSArray containing the single element anObject It throws an IllegalArgumentException if anObject is null Useful in situations such as the following: EOFetchSpecification fs = new EOFetchSpecification("EntityName", aQualifier, new NSArray(aSortOrdering)); NSArray() Instantiates an empty, immutable NSArray; however, if you need an empty, immutable array, it's better to use EmptyArray() because it is more flexible NSArray(NSArray anArray) Instantiates an NSArray containing the objects in anArray You should note that when an immutable array has been initialized in this way, it can't be modified NSArray(Object[] objects) Instantiates an NSArray containing objects, and ignores any null values it encounters in objects NSArray(Object[] objects, Instantiates an array containing the objects from objects in the range specified by aRange Ignores any null values it encounters in objects NSRange aRange) Table continued on following page Appendix A NSArray(java.util.Vector aVector, NSRange aRange, boolean checkForNull) Instantiates an array which contains the objects from aVector in the range specified by aRange If checkForNull is true, null values are ignored, but if checkForNull is false, an IllegalArgumentException is raised Methods static NSArray componentsSeparatedByString( String string, Returns an array containing substrings from the string string that have been divided by the string separator separator If the string begins/ends with the separator, the first/last substring is empty String separator) String componentsJoinedByString( separator) Returns a String that is the result of placing the string separator between the elements of the array Each array element must handle either description() or toString() If the array has no elements, an empty String is returned int count() Returns the number of objects in the array void Invokes the method specified by selector on each object in the array, using the values in anObject as the method's parameters String makeObjectsPerformSelector( NSSelector selector, Object[] anObject[]) Object objectAtIndex(int index) Returns the object located at index index of the array Throws an IllegalArgumentException if the array is empty or if index is beyond the end of the array java.util.Enumeration Returns an Enumeration that allows you to access each object in the array in order objectEnumerator() NSArray sortedArrayUsingComparator( NSComparator comparator) throws NSComparator.ComparisonException java.util.Vector vector() Returns an NSArray that lists the array's elements in order, where the order is determined by comparator (see the description of NSComparator later) You should note that the new array does not contain copies of the original array elements, but the elements themselves This method throws a ComparisonException if the comparator's compare() method throws Returns the array as a Vector NSMutableArray public class NSMutableArray extends NSArray NSMutableArray provides similar functionality to NSArray but allows adding, removing and replacing elements in the array (in other words the array created is "mutable") Foundation Framework Methods void addObject(Object anObject) Adds anObject to the end of the array If anObject is null, an IllegalArgumentException is thrown void addObjects(Object[] otherArray) Adds the objects contained in otherArray to the end of the NSMutableArray If any of these objects are null, an IllegalArgumentException is thrown void addObjectsFromArray( Places the objects contained in anArray onto the end of the NSMutableArray NSArray anArray) void insertObjectAtIndex( Object anObject, int index) Inserts anObject into the array at a position specified by index This means that index must be greater than the number of elements in the array, or an IllegalArgumentException is thrown (this exception is also thrown if any of the objects are null) void removeAllObjects() Removes all elements from the array void removeObject(Object anObject) Removes all occurrences of anObject in the NSMutableArray If a range aRange is provided, this method removes all occurrences of anObject in that specified range Matches are determined according to the results of the equals() method void removeObject(Object anObject, NSRange aRange) void removeObjectAtIndex(int index) Removes the object at index, and moves all elements beyond index up by one void removeObjects( Similar to removeObject but removing an array of objects at once Object[] otherArray) void removeObjectsInArray( NSArray otherArray) void setArray(NSArray otherArray) Sets the NSMutableArray elements to the ones in otherArray void sortUsingComparator( Sorts the array elements according to the order specified by aComparator Throws an NSComparator.Exception if aComparator is null NSComparator aComparator) throws NSComparator.ComparisonException NSDictionary public class NSDictionary implements Cloneable, java.io.Serializable, NSCoding, NSKeyValueCoding, NSKeyValueCodingAdditions Appendix A An NSDictionary object is similar to a java.util.Hashtable, and contains associations of keys and values A single key-value pair within a dictionary is called an entry Each entry consists of one object, typically a String, that represents the key, and a second object that is the key's value No two keys in a single dictionary can be the same (as determined by equals()) – all keys must be unique Dictionaries, like arrays, can be immutable or mutable NSDictionary is immutable; NSMutableDictionary is its mutable counterpart In both cases, methods add the value object to the dictionary directly Also, you should make sure the keys not change, because each key object is used by the dictionary directly Constructors NSDictionary() Instantiates an empty dictionary Use the EmptyDictionary shared instance instead of this, because it improves performance NSDictionary(NSArray values, NSArray keys) Here values and keys are NSArrays holding values and keys respectively This method steps through values and keys, creating entries in the new dictionary An InvalidArgumentException is thrown if values and keys not have the same number of elements Instantiates another NSDictionary containing the keys and values found in the dictionary argument NSDictionary( NSDictionary dictionary) NSDictionary(Object value, Object Instantiates a dictionary containing a single value object with a single key key) NSDictionary(Object[] values[], Object[] keys[]) NSDictionary( java.util.Dictionary dictionary, boolean ignoreNull) Similar to NSDictionary(NSArray values, NSArray keys) but with array arguments that aren't NSArrays Instantiates a dictionary containing the keys and values found in the dictionary object If ignoreNull is false, this method throws an InvalidArgumentException if any key or value in dictionary is null Methods NSArray allKeys() This method returns an unordered array of the dictionary's keys, (or an empty array if the dictionary has no entries) NSArray allValues() As for allKeys(), but returns an unordered array of values instead int count() This method returns the number of entries in the dictionary java.util.Hashtable Returns a Hashtable containing the dictionary's entries hashtable() Foundation Framework java.util.Enumeration keyEnumerator() java.util.Enumeration objectEnumerator() Object objectForKey( Object aKey) NSArray objectsForKeys( NSArray keys, Object nullMarker) This method returns an Enumeration object that allows you to access each key in the dictionary When this method is used with mutable subclasses of NSDictionary, make sure your code does not change the entries during enumeration As with keyEnumerator(), but allows you to access each value in the dictionary This method returns a dictionary entry's value given its key, or returns null if no value is associated with the key This method returns a set of objects from the dictionary that corresponds to the specified keys (listed in the keys array), as an NSArray There will be a one-to-one correspondence between objects in the returned array and those in the keys array The marker object specified by nullMarker is a marker object, placed in the array element if an object specified by a key is not found NSMutableDictionary public class NSMutableDictionary extends NSDictionary NSMutableDictionary performs the same role as NSDictionary, but adds modification operations You should note, however, that NSMutableDictionary assumes that key objects are immutable If your key objects are mutable, make copies of them and add the copies to the dictionary instead Methods void removeAllObjects() Removes all entries from the dictionary Object removeObjectForKey( This method returns the entry's value identified by key, and removes the entry The method returns null if no such entry exists Object key) void setObjectForKey( Object anObject, Object aKey) Adds or replaces an entry of key aKey and value anObject to the dictionary, and throws an InvalidArgumentException if the key or value object is null NSData, NSMutableData public class NSData implements Cloneable, java.io.Serializable, NSCoding public class NSMutableData extends NSData NSData (and its subclass, NSMutableData) return data objects Data objects are object-oriented wrappers for data (byte buffers) of any size You should note that NSData objects contain no information about the data itself (such as its type) – it's up to you to decide what to with the data inside an NSData object Appendix A Constructors NSData() Instantiates an (empty) NSData object NSData(NSData data) Instantiates an NSData object which contains the contents of another NSData object NSData(byte[] bytes) Instantiates an NSData object with the data in the byte array bytes Here's an example of its use: NSData dataFromString = new NSData(aString.getBytes()); NSData(byte[] bytes, int offset, int count) NSData(byte[] bytes, NSRange range) NSData(byte[] bytes, NSRange range, boolean noCopy) NSData( java.io.InputStream inputStream, int chunkSize) throws java.io.IOException As with the previous constructor, but only the bytes from the array in the range specified by offset and count are placed in the NSData object As with the previous constructor but the range is supplied in the form of an NSRange object A variation on the previous constructor where we specify the range, and a boolean argument that specifies whether or not a copy of the bytes array is made Instantiates an NSData object with the data from the InputStream The size (in bytes) of the block that the InputStream returns when it reads is given by the chunkSize parameter (its best to set this to the approximate size of the data) The stream is read until either the end of the file or an exception is thrown Methods byte[] bytes(int offset, int count) byte[] bytes(NSRange range) A variation on the previous method where the range is supplied by an NSRange object byte[] bytes() Creates a byte array containing all the contents of the NSData object int length() The method returns the number of bytes in the NSData object void writeToStream( Writes the bytes from NSData to the outputStream If this fails, the method throws a java.io.IOException java.io.OutputStream outputStream) throws java.io.IOException Creates a byte array containing the contents of the NSData object that falls within the range specified by offset and count Foundation Framework NSTimestamp public class NSTimestamp extends java.sql.Timestamp implements NSCoding NSTimestamp objects are used to represent time, and are the required objects for this role in EOF In previous versions of the Foundation Framework, the NSGregorianDate class could be used to store times, and this class supported calendar functions, but NSTimestamp does not Constructors NSTimestamp() Represents the current time to the millisecond NSTimestamp( Instantiates an NSTimestamp object representing the same time as date java.sql.Timestamp date) NSTimestamp( java.util.Date date) NSTimestamp(long milliseconds) Represents the specified number of milliseconds since January 1, 1970, 00:00:00 GMT NSTimestamp(long milliseconds, Represents the specified number of milliseconds since January 1, 1970, 00:00:00 in the specified time zone java.util.TimeZone timezone) NSTimestamp(long milliseconds, int nanoseconds) NSTimestamp(long milliseconds, int nanoseconds, java.util.TimeZone timezone) NSTimestamp(long milliseconds, NSTimestamp timestamp) Represents the specified number of milliseconds since January 1, 1970, 00:00:00 GMT and sets the number of nanoseconds to the nanoseconds argument Represents the specified number of milliseconds and nanoseconds since January 1, 1970, 00:00:00 in the specified time zone Represents the specified number of milliseconds after the time specified by the contents of timestamp Let's have a few examples of how to use NSTimestamp A common operation might be to change a java.util.Date object aJavaUtilDate to an NSTimestamp: NSTimestamp anNSTimestamp = new NSTimestamp(aJavaUtilDate); Obviously we could just substitute aJavaUtilDate for a java.sql.Timestamp object aJavaSqlTimestamp If we wanted to create an NSTimestamp representing the current time, we can use the no-argument constructor: NSTimestamp currentTime = new NSTimestamp(); To break up a NSTimestamp into its temporal components, such as the month, the year, and so on, we need to convert it into a java.util.GregorianCalendar and use the setTime() method to pass the time stored in the NSTimestamp to the GregorianCalendar: Appendix A GregorianCalendar aCalendar = new GregorianCalendar(); aCalendar.setTime(anNSTimestamp); Then we can invoke the get() method on the individual fields For instance, to get the year and the day of the month, we can use: int year = aCalendar.get(GregorianCalendar.YEAR); int dayOfMonth = aCalendar.get(GregorianCalendar.DAY_OF_MONTH); NSComparator public abstract class NSComparator The abstract NSComparator class defines how to compare two objects so that we can sort them The one method declared by this class, compare(), compares two parameters and returns one of the following constants: OrderedAscending Indicates the objects are in ascending order (the value of the first object is less than the value of the second) OrderedSame Indicates the values of the objects are equal OrderedDescending Indicates the object arguments are in descending order Comparators are typically used in conjunction with array sort methods NSComparator provides default comparators to use with these sorting methods The following comparator constants are passed to these array sort methods (the NSArray method sortedArrayUsingParameter() or the NSMutableArray method sortUsingParameter()) String comparators: ❑ AscendingStringComparator ❑ DescendingStringComparator ❑ AscendingCaseInsensitiveStringComparator ❑ DescendingCaseInsensitiveStringComparator Number comparators: ❑ AscendingNumberComparator ❑ DescendingNumberComparator NSTimestamp comparators: 10 ❑ AscendingTimestampComparator ❑ DescendingTimestampComparator Foundation Framework Foundation Framework Interfaces The principal interfaces of the Foundation Framework are: ❑ NSKeyValueCoding ❑ NSValidation Let's take a closer look at them NSKeyValueCoding public interface NSKeyValueCoding The NSKeyValueCoding interface allows us to implement key-value coding (covered in Chapters and 8) In key-value coding, the properties of an object are accessed indirectly by name (or key), rather than directly through accessor methods or as instance variables In this way, key-value coding allows us to access all object properties in a consistent manner NSKeyValueCoding also defines the NullValue constant, a shared instance of NSKeyValueCoding.Null Methods void takeValueForKey(Object value, String key) Object valueForKey(String key) This method sets the value of the property identified by key to value This method returns the value of the property with key key NSValidation public interface NSValidation Usually, object properties are validated directly, through specific validation methods In the NSValidation interface, a validation mechanism is defined which validates the properties of an object indirectly by key, allowing us to validate all of the properties in a consistent manner The methods of the inner class NSValidation.DefaultImplementation (the default class implementation of the interface) search for property specific validate methods and call them if they exist Therefore, if a property has validation logic associated with it, you should implement a validate() method for it in your NSValidation class 11 Appendix A Methods Object validateTakeValueForKeyPath( Object value, String keyPath) throws NSValidation.ValidationException Object validateValueForKey( Object value, String key) throws NSValidation.ValidationException 12 Assigns the value to the property named by keyPath (provided the value is legal and different from the current value, otherwise the method throws an NSValidation.ValidationException A key path takes the form relationship.property, for example customer.loginName or order.payment.datePaid (there can be many relationships) Similar to the previous method, but this method is passed a key instead of a key path The value returned from this method can be different than the one passed to it as an argument Foundation Framework 13 Appendix A 14 .. .Professional WebObjects 5. 0 with Java © 200 1 Wrox Press All rights reserved No part of this book may be reproduced, stored in a retrieval system or transmitted in any form or by any means, without... integrates with other Java- based solutions such as EJB containers, servlets, and web services The combination of a Java runtime with advanced native tools for Mac OS X and Windows 200 0 makes WebObjects. .. deploy WebObjects on Mac, Windows 200 0, and to deploy on Solaris too Installing on a Mac To use WebObjects on a Power Macintosh running Mac OS X, you will need at least 128 MB of RAM and 50 0MB of