Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News


2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
SYS-CON.TV
Top Links You Must Click On


Prototyping an Advanced Calendar Class
Prototyping an Advanced Calendar Class

It is possible to create a very attractive look-and-feel prototype of a Calendar-based browser application in JavaScript, but to compete with tough-minded mainframe legacy systems such as MEMO requires a highly functional and scalable working prototype to justify the continued investment and potential encapsulation of a large mainframe system.

In Part 1, I discussed the Calendar functionality, prototyping success factors and the design constraints imposed by the corporate platform and JavaScript itself. I introduced an event-action model that supported asynchronous event handling between dependent objects and also the disposable requirement for an elementary client-based datastore. In this article, I continue with the technical detail of cookies, Calendar classes and the generation of the user interface using JavaScript. Essentially, we are coding the overriding of class methods manually in order to maintain a very simple interface to reasonably sophisticated objects based on how the data is used. this allows the dynamic rendering of an object's data based on simple object dependencies.

Elementary Datasets Using Cookies
Because the prototype Calendar is run solely on a user's PC without fetching data from a server, a disciplined approach to using cookies was developed.

The section Calendar Data' in Part One (JDJ, Vol. 2, Iss. 9) introduced the concept of cookies.

The following sections describe in detail how cookies are used by the Calendar. Cookie data has been treated as the most disposable part of the prototype, but the interface to the data has not. In the absence of a CGI/DBMS treatment, formatted data (cookies on the PC or text files on a server) will be required for some time.

Formatted strings represent the datasets used Calendar data is stored in cookies. Some are used as control flags, as in Table 1.

Each month had a separate cookie denoted by Mmmyyyy. This contained the complete, unordered set of meetings for that month, representing a heap structure.

The record format of each meeting is described in Table 2.

The field delimiter is the tilde (~) character.

Participants are chosen by name from the Select Participants popup, but only the e-mail address is stored. The participants sub-string was a list of e-mail addresses delimited by newline (\r\n), as in the following code sample:

pmanager@itlan.office.co.uk\r\nbill@itlan.office.co.uk\r\n.

Using the escape() and unescape() functions of JavaScript, the \r\n' characters are converted to %0D%0A' when cookie data is written and back to \r\n' when cookie data is read for both the participants list and the supplementary text field. An example meeting string is shown in the following sample:

20~Team Meeting~13~20~25~pmanager@it.office.co.uk\r\
nbill@it.office.co.uk\r\n~Meeting Room 2~
Don't forget last weeks\r\nMinutes!~

Class Interface to Cookie Data The interface to data should not be restructured when a server-based back end is attached, although the actual JavaScript code within the interface will. The class of objects defined should be simple enough to work with both persistent client data and remote data. This also means that the sequencing of client requests for data should be implemented in the prototype. In practice, the data handling methods described in this article have been used to implement an optimistic, demand-based model, although the detail is concerned with parsing formatted strings.

Some functions can be implemented on the server as database procedures in order to reduce the client/server dialogue and the associated, long code path; in particular, the sequence value function, which in a DBMS treatment could have the surrogate key generated on the server in the same transaction as the insert of the data, thus removing the processing from the client.

However, on a distributed client/server platform with many users and high concurrency, with many potential sequence value calls to lock the same table row and incur wait, a client-based surrogate key is the best option, but needs careful management. Sequencing Meetings using the sequence_value class

A meeting number is generated using the get_next_meeting_number() method from the sequence_value object to obtain the next meeting number. All meeting numbers generated on the client are unique.

The last used meeting number is stored in a cookie, sequenceValue , which is incremented and updated on demand, as shown in Listing 1.

The sequence value class is defined as follows:

function sequence_value()
{
this.meeting_number=0;
this.get_next_meeting_number=f_sequence_value;
}

An object is created when the HTML page loads, using the JavaScript onLoad() event handler

sv = new sequence_value()

and the methods invoked when a meeting object (this) is created:

this.meeting_number=sv.get_next_meeting_number();

Parsing Formatted Data
Since the String.split() method was not available, the formatted cookie had to be interpreted manually.

Because only Meeting level data is stored, a method was implemented in the Meeting class to parse the single meeting extracted from the cookie. Another method was implemented in the Meeting class to format a cookie string in order to write data to the cookies file.

The Day object controls the extraction of all meetings in the day by filtering out those meetings with that day number.

Parse Data - Meeting Class
The Meeting.parse_meeting() method (see Listing 2) can be superseded by the String.split() method if Navigator 3.0+ was the target platform. The keyword this' denotes the current Meeting object.

Parse Meeting - Day Class
The Day.parse_meeting() method filters out those meetings which exist on the day which the instance represents. This method would be superseded by the String.split() method in Navigator 3.0+.

Before:

m1f1~m1f2~m1f3~m1f4~..~m1f9~m2f1~m2f2~ etc.

After:

m1f1~m1f2~m1f3~m1f4~..~m1f9~|m2f1~m2f2~ etc.

Note the ~| character pair: the | denotes end of meeting, so the String.split() statement would operate as shown in Listing 3.

In Listing 4, the keyword this' refers to the Day object.

Format Meeting Data
Instead of reading the data, we want to write new data to the cookie for the month. The code in Listing 5 shows the Meeting object formatting the Meeting data for writing to the Cookies file (the keyword this' refers to the current meeting object).

Note: We can't use the expression for (i in this)' to yield each member of the Meeting class because the expression is not guaranteed to return members in the same order between JavaScript versions.

Cookie Constraints
Each month/year combination has its own cookie. Each month cookie can store approximately 20 meetings. On an uncontrolled platform (i.e., with unlimited WWW access), it is not feasible to rely on cookies to store vital data. On a controlled platform, it was reasonable to expect that up to 20 meetings per month could be stored for around 12 separate months. Each cookie has around 4K to play with, including cookie name, data, domain and expiry date information, so approximately 20 meetings per month is an acceptable figure for a working prototype.

A more important constraint is the implicit HEAP nature of the stored data. In a relational database (e.g., Ingres), a HEAP table is a table which has no order. Records are appended to the table in arrival sequence. The same goes for the meeting data, which is appended to the cookie string. Each inserted meeting is appended to the last regardless of day or time. When meetings are rendered, the meetings are listed in arrival sequence.

This means that to update and delete data the string has to be scanned from the start until the meeting has been identified using the meeting number. An update is a deletion followed by an insert. Deleted space is reclaimed in the cookie by the code that implements the delete.

Although JavaScript is interpreted, there is no real visible performance degradation using these heap-based scanning methods, but there is more code to maintain. Again, priority is given to delivering the critical functionality.

Calendar Object Model
Because JavaScript is an untyped language with a loose definition of classes, it can't really be called object-oriented. But JavaScript simulates it because the object-oriented method-invocation syntax is a useful one for building programs with component reusability. The design of the prototype benefited from adhering to simple object-oriented techniques, as the next two sections discuss.

Figure 1 shows a simple object model for the Calendar.
Simply put:

  • A Calendar is a collection of events with common properties.
  • A Day is a type of calendar event if it has a responsibility.
  • A Meeting is a type of calendar event that is dependent on the day for its anchor and context

    For simplicity, we can pretend that there are two dependencies in this very simple object model.

  • A Meeting is an extension of a Day event (e.g., a special time, place, etc.) (A).
  • A Day Event is responsible for it's Meetings (B).

    Because the objects are used in two different ways, we can have two dependencies; reading and formatting data (B) and object construction (A)

    What seems like over-engineering a very simple set of objects actually assists in allowing us to do three things:

  • Make the display image of the object's data and its dependent object's data a property of the objects themselves, which changes with the display context
  • Allow dependent objects to render themselves without regard to their parent
  • Ensure that when an object is created, its dependency on a higher level class is controlled as if using a super()' call, emulating Java's constructor chaining technique

    By attempting to maintain some form of abstract inheritance hierarchy for the objects, we hopefully can rely on the specialization to request the construction of its super' object (A). So, when we create a meeting object, we want the Meeting object to be initialized within a Day and the Day within the Calendar month.

    Conversely, when we want to display summary meeting details within the context of a day, we want the rendering to be controlled by the Day, which will generate the HTML around the meetings, which are then called upon to render their information in HTML.

    Remember that when viewing meetings in a day, they can be viewed:

  • in a separate frame
  • as a configurable list in a day cell
  • in a selection list

    Essentially, we are coding the overriding of class methods manually in order to maintain a very simple interface to reasonably sophisticated objects based on how the data is used. Using this reversible approach to dependencies, we can work with the loose typing of JavaScript to take handles at both ends of the object model.

    We can create a meeting object which will invoke methods in the containing class to position it. We can also display a meeting by invoking the appropriate higher level context. For example: To create a new meeting object which will invoke a method in a containing object:

    new meeting()

    The meeting constructor will store the position it occupies in the array of meeting objects (day):

    this.position_in_day_list = Day.new_meeting( this );

    The Day.new_meeting() method assigns the meeting object to the next free slot (see Listing 6)

    Generating Screens Using JavaScript
    The Month View Calendar screen (Figure 2) will be used to illustrate the techniques used. Select the Month from which to render the calendar and meetings (Month View)

    When the user clicks <SELECT>, the select_calendar() method is called and the form is passed to the method (see Listing 7).

    The calendar object retrieves the selected values from the pull down lists (Month View).

    The calendar object creates a Date object, which is used to render the calendar by selecting values from the pull down lists, as shown in Listing 8. The calendar object loads the data and writes to the calendar window (Month View) (Listing 9).

    Create the HTML text in JavaScript for the Month View

    In JavaScript (1.0), you have to be careful when concatenating strings because each +' operator creates a result that isn't garbage-collected until the page is unloaded. For example, to create a HTML table, see Listing 10.

    The Day cell has summary meeting info written to it
    We are relying on the ability to call a method of the Day class to render the day and to render the subject for each meeting in the day without worrying where the meetings are or how they are displayed in this particular window.

    The same method will be called regardless of the target window. In Java, a display method would be overloaded for each specific target window. In JavaScript, we encapsulate the window format in one method instead of defining many function references in the Day or Meeting class. Meetings are rendered differently in each window, but by keeping the interface the same we let the objects render themselves depending on the target window. So we have encapsulated the way data is formatted for display.

    In this way, the Calendar (either the whole Calendar, a Day or a Meeting) is passed to different windows and the data displayed as appropriate.

    In the following, the calendar has created a meeting object for every meeting in the month and allocated each meeting to the Day object for the day in which the meeting resides.

    The Calendar object contains a Day object for each day that contains a Meeting.

    Remember the need to manage JavaScript resources discussed in Part One? Note the use of var' inside the for' parentheses. Before the for', the variable does not exist. Outside the for', the variable will be discarded. You can use this optimization to control how much local storage you require at a given moment. This technique shouldn't be used in a loop where the allocation/deallocation of the local variable will take place repeatedly.

    The user may express a preference for how the Month View is displayed. Summary meeting details are displayed as text, as a scrollable list or as a pulldown list.

    The user's display preferences are stored in cookies called userPreference1/2, and the <HELP> button on the month view allows the user to customize the preference.

    The code in Listing 11 renders the calendar grid. The this' operator refers to the calendar object that contains the render_calendar() method.

    The Day object requests all Meetings to render the Subject

    A JavaScript string is used to store the HTML text for the Day cell that will contain the HTML which renders the summary meeting data.

    The user preference is used to select the different HTML tags. Two cookies are used, userPreference1 and userPreference2.

    The values of the user preferences are shown in Table 3.

    These values are set from the User Preference screen (Figure 3), which is selected using the button on the main Month View window.

    Each Meeting object that has a slot in the Day object has the render_subject method invoked.

    Figure 4 shows the typical rendering of calendar events. Figure 5 is a snippet from the same screen, but the user preference is a pulldown list of Calendar events. Figure 6 is another snippet from the same screen as Figure 4, but the user preference is a scrollable list of Calendar events.

    If embedded text is displayed, we can't scroll or pull down, so we have to display a continuation message.

    If we view Day as a specialization of Meeting because of the variable rendering requirements controlled by the Day class, then we are effectively calling the super()' method of Day.

    Using this reversal, we can code an artificial overriding which is kept in line by the requirement that each class implements its own display methods; the rule being that all pseudo overriding of methods have identical names.

    Remember that this HTML is generated for the main calendar window (or frame), which only contains embedded calls to methods in the controlling window (or frame), cal_control. This controlling window also contains the data objects. Because both frames share the same parent, there is no risk that closing a window will destroy the embedded references, which would be the case if they were separate window instances. JavaScript 1.0 does not give the user control over the dependencies between windows that may share window references.

    Note how the Day object is used in Listing 12. For each meeting in the array of Meeting objects (Day), we invoke the render_subject() method of the meeting. In Listing 12, the this' operator refers to the Day object, which is the dense array of meeting objects.

    The render_subject() method of the meeting object (see Listing 13) generates either a simple text string or an element of a HTML <SELECT> tag, the <OPTION> tag. For the <OPTION> tag, the value is the position which that particular Meeting object has in the Day object. When that option list element is clicked, the value is used by the calendar to display the meeting details in the right frame of the Browse Meetings window.

    Conclusion
    Although the technology described in this article is new, the principles of RAD and object-based design are not. The old issues remain, and are complicated by new ones specific to the maturing browser/JavaScript application platform. In order to implement a working prototype of a Calendar that is functionally rich enough to justify the cost of scaling upwards with server based data, several technical and non-technical issues have been raised and dealt with.

    The main technical focus has been on using JavaScript in a variety of ways: to generate HTML, parse formatted data streams and handle events asynchronously. Although JavaScript is a moderately simple scripting language, an object model was implemented which allowed the manual overriding of class methods to be demonstrated in a language that does not support inheritance.

    There are lots of practical tips and example screens to show how JavaScript interacts with HTML and browser objects to give vitality to the look and feel of the application. The article has also demonstrated how windows-like' a JavaScript application can be. The Select Participants' pop-up screen looks familiar to windows users, but is generated by JavaScript from the browser and is a browser window. Builders can employ the method described here of using cookies in their own JavaScript applications.

    From the project lifecycle perspective, the article has addressed functional prototyping, design and build, within the context of managing (corporate) user expectation against competing legacy applications.

    Those employed in making decisions on which technology to use to migrate a legacy application to a GUI interface will find a practical case for using the browser and JavaScript, with the added incentive of an application delivery vehicle that is platform independent.

    Designers and builders who may simply wish to know more about the advanced uses of JavaScript can use the implementation details covered. Those involved with making decisions on what and how to prototype should be able to use the criteria in this article to clarify and enhance their own decisions.

    About Graham P. Harrison
    Previously a Senior Consultant with BEA, Graham is the author of Dynamic Web Programming using Java (Prentice Hall, 2000) in addition to a number of articles for the Java Developers Journal and IBM DeveloperWorks. He has a focus on Enterprise Architecture, Performance Tuning and Capacity Planning

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Enterprise Open Source Magazine Latest Stories . . .
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP). The...
    With Cloud Expo 2012 New York (10th Cloud Expo) just four months away, what better time to start introducing you in greater detail to the distinguished individuals in our incredible Speaker Faculty for the technical and strategy sessions at the conference... We have technical and st...
    AMD said late Tuesday that its chief sales officer Emilio Ghilardi had left the company and that CEO and president Rory Read is going to do his job while a replacement is sought. AMD didn’t say why Ghilardi left but it’s assumed Read wants his own people. Read is relatively new to th...
    During the lifespan of M3 (Monitis Monitor Manager) there has always been something lacking – timers. M3 execution procedure was outlined in this previous article. The execution mentioned in the latter was a one-time-execution, whereas server monitoring requires periodic invocati...
    Red Hat is putting its bought-in Gluster scale-out NAS storage technology, acquired in October, on the Amazon cloud. It’s styled Red Hat Virtual Storage Appliance for Amazon Web Services and other clouds are supposed to follow in short order.
    A new episode of the screencast series is now available at the OpenNebula YouTube Channel. This screencast demonstrates the new easily-customizable self-service portal for cloud consumers. Its aim is to offer a simplified access to shared infrastructure for non-IT end users. The scree...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


    SYS-CON Featured Whitepapers
    ADS BY GOOGLE