UNIVERSITY

OF

TARTU

FACULTY OF MATHEMATICS AND COMPUTER SCIENCE Institute of Computer Science Computer Science Specialty

Taimo Peelo

History Navigation Mechanisms and Web Application State Bachelor thesis (4 AP)

Supervisor: Jevgeni Kabanov, M.Sc.

Author: ....................................................................... “.....” May

2008

Supervisor: .................................................................. “.....” May

2008

Professor ..................................................................... “.....” May

2008

TARTU 2008

Contents Introduction

5

1 Browser History Mechanisms 1.1 Birth of History Navigation . . . . . . 1.2 Standardized History Navigation . . . 1.3 Navigation Event Detection . . . . . . 1.4 Mismatch of Applications and History 1.5 Conclusions . . . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

7 7 8 9 10 11

2 Web Application Models 2.1 Illustrative Use Case . . . . . . . . . . . . 2.2 URL-mapped scripts . . . . . . . . . . . . 2.2.1 Stateless Scripts . . . . . . . . . . . 2.2.2 Stateful Scripts . . . . . . . . . . . 2.3 Component-Based Server Side Frameworks 2.4 Component-Based Client Side Frameworks 2.5 Continuation Based Frameworks . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

12 12 13 13 14 14 15 15

3 Aranea Web Framework 3.1 Components . . . . . . . . . . . . . 3.2 Widgets . . . . . . . . . . . . . . . 3.3 State Management . . . . . . . . . 3.4 Relocatable Components . . . . . . 3.5 Widget Rendering . . . . . . . . . . 3.6 Resource Inclusion . . . . . . . . . 3.7 Aranea System Form . . . . . . . . 3.8 Preassembled Component Hierarchy

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

16 16 16 17 17 18 18 18 18

. . . . .

19 19 19 19 20 21

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

4 Aranea State Versioning 4.1 Configuring State Versioning . . . . . . . . . . . . . . . . . 4.1.1 Enabling Versioning Filter Component . . . . . . . 4.1.2 Enabling Versioning Support for XMLHttpRequests 4.2 State Versioning Implementation . . . . . . . . . . . . . . 4.3 State Versioning and XMLHttpRequests . . . . . . . . . .

3

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

5 Known Issues and Future Work 5.1 Known Issues . . . . . . . . . . . . . . 5.2 Future Work . . . . . . . . . . . . . . . 5.2.1 Session Storage Reduction . . . 5.2.2 Versioned Component Wrappers

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

23 23 24 24 24

Conclusions

25

Resu ¨ mee (in Estonian)

26

Bibliography

28

A Aranea Framework 1.2-M1

29

4

Introduction Prerequisites This work assumes that reader has knowledge of object-oriented programming in Java language, recognizes desktop application from a web application and is familiar with basics of HTTP protocol[FGM+ 99], HTML4 content description language[RHJ], W3C DOM[HHW+ 03] and Javascript[ECM99].

Motivation Like computers themselves, each computer program is essentially a state machine. This fact is most visible to casual computer user in the desktop applications where undo/redo facilities providing bidirectional state navigation have become essential and omnipresent. Well-known implementation pattern often referred by language tutorials describing how to implement such facilities is the Command pattern[GHJV95], which assumes that local state object is viable and application has exclusive access to it. Both of these assumptions are generally true for desktop applications working with unshared data. Curious perversion of bidirectional state navigation concept lies hidden in the back and forward buttons and other web browser history mechanisms[FGM+ 99, section 13.13]. Though they seem to produce bidirectional navigation events, these events remain external to the web application itself. Unfortunately, browser history mechanisms are used extensively: e.g. according to Tauscher and Greenberg survey from 1997, pressing of the Back button accounted for over 30 percent of all navigational acts[GC99], which is reported to have fallen to 14.3 percent in 2005[WOHM08]. Thus, web applications and web application platforms are forced to contemplate how to ignore, support or otherwise gracefully handle such obscure navigational acts.

Contributions and Outline The first chapter looks at the motives behind creation of browser history navigation facilities and highlights the problems that they can cause in modern web applications. Second chapter investigates different architectural approaches of building web applications, focusing on their natural ability to gracefully handle client-side navigation events. 5

Third chapter gives a brief overview of Aranea web framework[MK06], looking at its relations to already described web application models and describes inner workings of Aranea state management system. Fourth chapter describes the modifications which were done to Aranea to implement support for server-side state versioning and how such versioning can help to handle history navigations in an acceptable manner. Idea behind implemented solution is generally applicable and can be used by other component-based web frameworks similar to Aranea. Main contribution of this work is the implementation of Aranea state versioning, which is publicly available in Aranea web framework since release 1.2-M11 and is also bundled on the compact disc accompanying this work.

1

Both that and all later releases can be downloaded from http://sourceforge.net/project/ showfiles.php?group_id=158008

6

Chapter 1 Browser History Mechanisms This chapter investigates how the history navigation mechanisms came into being, looks at their current standardizations and implementations and underlines the developments that have caused these mechanisms to sometimes function less than satisfactorily.

1.1

Birth of History Navigation

The first web browser[Wik08b] implemented by Sir Tim Berners-Lee in 1991 was called WorldWideWeb1 and already contained few history navigation facilities, though some of these were quite different from what we have accustomed to nowadays. WorldWideWeb had a back button, which had pretty much same functionality as it does today, together with next and previous buttons which would automatically navigate to the next or previous link on the last page visited. Latter remained obscure and back button soon got a prominent partner in forward button. It is clear from the studies [TG97] that back and forward buttons provide great value to web users, as page revisitation occurs regularly. Indeed, early web adopters were bound to enjoy them even more as bandwidth of the typical modem connections was very low2 . As web was geared towards viewing and publishing, it was very practical to reduce traffic between client and server to a minimum. HTTP caching mechanisms were not common yet and client-side history navigations which avoided actual requests to web server helped to reduce bandwidth usage and fitted well with browsing patterns. Web pages were renewed at a slow pace, and possible information loss was minimal as resources were very unlikely to change during one browsing session. It should be noted that focus on serving non-interactive content was pretty much a necessity at the time. Navigation by clicking and following the hyperlinks was the only perceivable interaction between the web page and its end-user (and even this actually takes place on the client). First widespread interactive content description possibilities appeared with the introduction of HTML forms in HTML 2.0[BLC95]. 1 2

Later it was renamed to Nexus. V.32bis communication standard that appeared in 1991 allowed for maximum of 14.4 kbit/s.

7

1.2

Standardized History Navigation

There are few conventions today that browser implementors should follow when implementing history mechanisms. No browser creation guidelines exist, but topic was considered important enough to get its own subsection in HTTP/1.1[FGM+ 99] specification. Relevant section 13.13 (History Lists) is presented in full below: User agents often have history mechanisms, such as ”Back” buttons and history lists, which can be used to redisplay an entity retrieved earlier in a session. History mechanisms and caches are different. In particular history mechanisms SHOULD NOT try to show a semantically transparent view of the current state of a resource. Rather, a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved. By default, an expiration time does not apply to history mechanisms. If the entity is still in storage, a history mechanism SHOULD display it even if the entity has expired, unless the user has specifically configured the agent to refresh expired history documents. This is not to be construed to prohibit the history mechanism from telling the user that a view might be stale. Note: if history list mechanisms unnecessarily prevent users from viewing stale resources, this will tend to force service authors to avoid using HTTP expiration controls and cache controls when they would otherwise like to. Service authors may consider it important that users not be presented with error messages or warning messages when they use navigation controls (such as BACK) to view previously fetched resources. Even though sometimes such resources ought not to cached, or ought to expire quickly, user interface considerations may force service authors to resort to other means of preventing caching (e.g. ”once-only” URLs) in order not to suffer the effects of improperly functioning history mechanisms. Specification does not enforce any particular browser history mechanism behaviours3 , but widely used browsers4 follow specification recommendations closely. Recent browsers tend to implement the specifically allowed behaviour of warning user when history navigation event may not be appropriate. Such situations need careful handling to still keep history navigation facilities seamlessly working in majority of cases. Firefox 2.x browser gives the following warning: The page you are trying to view contains POSTDATA that has expired from cache. If you resend the data, any action the form carried out (such as search or online purchase) will be repeated. 3 4

Details of RFC lingo for requirement levels is specified in [Bra97]. At the time of writing these are Internet Explorer 6/7 and Mozilla Firefox 2.

8

when user tries going back to page that was constructed as a result of POST request and response headers contained “no-store” directive, in which case browser has to reissue historical POST request to reconstruct the page. Warning is technically inexact but gives a non-technical explanation of the problem which should be understandable to native English speakers. In any case, users can be expected to be more or less annoyed and confused by such warnings. There is just one other place [FGM+ 99, section 14.9.2] where specification touches on implementations of history navigation mechanisms, concerning navigation to the pages with the already mentioned “no-store” response header. First, all temporal storage of requests or responses with that particular header is disallowed, If sent in a request, a cache MUST NOT store any part of either this request or any response to it. If sent in a response, a cache MUST NOT store any part of either this response or the request that elicited it. This directive applies to both non- shared and shared caches. but afterwards explicit permission is granted to history mechanisms for storing those responses anyway. History buffers MAY store such responses as part of their normal operation. As the storage in this case remains optional, browser behaviours will differ in this aspect, e.g. we already saw that Firefox always honors no-store headers. Summing up the specification guidelines, history navigation mechanisms are expected to present the page exactly as it was first retrieved (which implicitly requires local caching) and may usually cache more content than other local and remote caches. Rest of this work is only concerned with history mechanisms that act similarly to those mentioned in HTTP/1.1 specification[FGM+ 99]. Bookmarking systems, long-term browsing histories and browse trees that are URL-based rather than cache-based will not be considered, as their behavior depends heavily on web application bookmarkability, which is outside the scope of this work.

1.3

Navigation Event Detection

To function well, history mechanism must be able to differentiate between navigational and other kinds of events. Recognized navigational events then cause the activation of history mechanism, resulting in creation of a new locally cached version of a page. For some time it used to be clear that navigation event constituted of a click on a hyperlink or submission of a form, and this is how all browsers known to author detect these events. However, this distinction has become insufficient with the widespread use of synchronous and asynchronous background HTTP requests. Most commonly these background requests are initiated by a page using scripting languages recognized by the browser. Ubiquitously supported client-side language is Javascript[ECM99]. Browsers 9

implement W3C DOM[HHW+ 03] bindings for Javascript which allow to manipulate HTML document dynamically and scripts running in browser environment have access to XMLHttpRequest[Wik08c] object which allows to initiate and construct HTTP requests from a scripting language and define callbacks for processing the HTTP responses. As callbacks can modify the page DOM, whole applications can be built with background requests, without ever activating a hyperlink or submitting a form, leaving history navigation mechanisms unusable. Background requests are handled by web application’s client-side scripts, so they are hard to classify as navigation events without some direct hints from the web application itself, e.g. requests might not even result in a DOM update if received response just gives a notice about requested information being unchanged. Current browsers do not provide APIs for supplying such hints, but some special clientside tricks can achieve similar results and allow client side history navigation mechanisms to distinguish navigational background requests. These hacks5 are described in more detail later in this work.

1.4

Mismatch of Applications and History

What happens when web application user navigates back several steps in history and executes server-interactive event? Typical legend-like example that is given about the evils of history mechanisms seems to date back to the introduction of HTML forms. It is a story of a man doing internet shopping, submitting his credit card info and completing the checkout. For whatever reason (probably because of suddenly remembering some mistake made in the checkout process) he then decides to go back a step or a few in history, change something and submit checkout confirmation again, getting unfortunately billed twice in the process. It is undoubtedly very convoluted example because real people have natural defense mechanisms, i.e brain, which help to suppress wish of navigating back to payment form and resubmitting it6 . Nevertheless, similar problem can arise in subtler ways, as users will try to treat history navigation facilities as undo mechanisms in web applications. What is most unintuitive about this example is that web application actually is able to process the second request at all. One would not hope that a desktop application which has a file-selector opened would react to arbitrary events that have nothing to do with file selection. Yet this is exactly what happens in this urban myth about a dumb internet shopper. In fact, this case of history navigation working “too well” is a result of early web applications being very closely modeled after the stateless request/response model of the HTTP protocol, and such behaviour will be more closely examined in the next chapter. 5

Hack here means an unaesthetic solution to nasty problem. More real scenario is the one where server just takes a lot of time to respond for some reason (e.g. validating credit card), user tires of waiting, thinks he has misclicked and submits a form again. That kind of double-submits are more common and can be avoided with both client-side and server side methods. 6

10

In the other end of the spectrum there are applications which are unable to handle history navigation events without unnatural tweaks. These are usually built with stateful server-side component based frameworks and their programming model and behaviour is very alike to desktop GUI components, resulting in sheer inability to cope with arbitrary requests from historical pages, stemming from the fact that components are truly stateful and thus able to process only certain allowed events in any given state. Then there are web applications whose component model is deployed on client-side and components make heavy use of XMLHttpRequests to fetch required data from the server. To even activate history navigation mechanisms these applications need to use special techniques. When component model is deployed in browser using some external plugin format like Adobe Flash7 or Microsoft Silverlight8 , supporting history navigation becomes even more troublesome.

1.5

Conclusions

Main difficulty in dealing with history mechanisms arises from the fact that intentions of history navigation pretty much require it to be completely extrinsic to a web application (DOM event model cannot help here, because navigation happens outside the DOM). Any interactive events executed from a historical page are however intrinsic again and application must strive to make sense of them, as otherwise end-users might be unhappy with the application. Additional problems have risen with common use of XMLHttpRequests and external plugins which are completely unsupported by history navigation mechanisms. Most developers would happily ditch support for history mechanisms in their web applications, leaving just navigation mechanisms internal to the application. Solving these problems at their roots is outside the scope of this work. As noted in [WOHM08], undo functionality internal to the application can be helpful: In the context of Web applications, navigation tools like the back button acquire a new meaning: if a user presses it to correct errors or to provide alternative input, it bears more similarity to an undo button. While undo functionality is a must in office applications, and generally considered a key factor for controllability [ISO 9241/110 2006], it is still rarely found in Web applications. And as browsing patterns are changing [WOHM08], The correlation between the frequent opening of new windows and a low back button rate indicated that opening link targets in a new browser area was a strategy to circumvent the need for backtracking. there could be hope that more suitable semantics with regard to web applications can be defined for history mechanisms someday. 7 8

http://www.adobe.com/products/flash/ http://silverlight.net/

11

Chapter 2 Web Application Models This chapter describes a few architectural approaches to building web applications that are clearly distinguishable and whose abilities of handling extrinsic navigation events differ naturally.

2.1

Illustrative Use Case

As a basis to highlighting the differences of explored web application models, consider an application that helps elderly dictator in launching nuclear missiles. It consists of wizard-like interactive process where active step depends on previous ones.

choosing

Continent choosing

I

Country

choosing

II

City

III

launching

IV

Missile

Figure 2.1: Multi-step process to lauch a nuclear missile.

First three steps are for narrowing down the target city, each step showing only the selections valid in running context, e.g. the countries that are situated on the chosen continent. Fourth step is committal, allowing launching of the missiles at chosen target. Connectors between steps in figure 2.1 have arrows at both ends when connected steps are non-committal and true bidirectional navigation between steps is feasible.

12

2.2

URL-mapped scripts

Most common web application construction model closely follows the request/response model of HTTP protocol. Scripts are mapped to URLs at the server and upon receiving a request to the URL, mapped script is executed. Script here is anything that forgets the control information between interactions and is responsible for processing the request and constructing the response, e.g. a CGI script invoked by the web server, a PHP script, or a Java servlet. Note that URL-mapped scripts can delegate actual response generation to some other script on server-side.

Request

URL HTML Page

Script Response

User Interaction Figure 2.2: User interaction with an URL-mapped script

As control information is not stored, each script can always be invoked separately once its URL is known. In regard to missile launching example, each step of the process is directly accessible e.g. missile launch script can be invoked when no targets have been chosen yet. History navigation can often work or at least seem to work in this model, until the committal part of the use case is reached and executed. Even here, scripts outof-order execution is susceptible to performing in an unexpected way and stateless and stateful scrips will exhibit different worrying symptoms in handling it: with stateful scripts offering plenty of chances for subtle mistakes when state becomes internally inconsistent and stateless scripts struggling to make sense of all possible parameter combinations.

2.2.1

Stateless Scripts

Scripts that act solely on incoming data (request) are completely stateless. To realize multi-step use cases, as in missile launching wizard, parameters of one step need to be carried over to following step(s), e.g. the country selection script must receive the information about continent. Initially these parameters can be passed either on client-side or server-side. Former can be done by rendering HTML page with links to next use case step, which then reads 13

the required parameters itself (but becomes reliant on the internal implementation of the previous step). Latter can be done by linking to active use case script which processes the request and hands the actual response generation and expected parameters over to the script that is responsible for next step of the use case. To preserve the information for multiple steps, most web pages served by stateless scripts will contain hidden input fields1 with data obtained from previous steps. Each use case script must guarantee extensive validation of request parameters to ensure consistency and security. As long as the application does not perform committal or unrepeatable actions on shared data or external world (e.g. passive browsing of dynamic news site fits these criterias), this approach can work fairly well with history navigation. Obvious downside is that ensuring correct stateless operation results in large and unwieldy scripts which look a lot like spaghetti2 and are very hard to maintain. For that reason, stateless script approach is only practical for applications with simple UI and very simple business logic.

2.2.2

Stateful Scripts

Stateful scripts can make usage of server-side session object to reduce the complexity of stateless development. Though session is not exactly an object oriented way of doing state management, it can make application programming a lot easier. Unfortunately scripts necessarily have to use session storage in an ad hoc basis. With regard to missile launching example, one can imagine that each target selection step uses its own session variables to denote selected continent, country and city. After city has been selected, one could go to continent selection screen and select an arbitrary continent from there. This problem with an inconsistent state will rise often with ad-hoc session access from scripts, as session management is not governed by any enforced or intuitive rules. Though ad-hoc state management adds some convenience to script programming it does not really help to reduce the amount of errors. With regards to backtracking, stateful scripts can even perform worse than stateless scripts because state inconsistencies are bound to arise more often.

2.3

Component-Based Server Side Frameworks

Component based web frameworks process the requests and responses with component hierarchies. Each component will read in only the information dedicated for it and process events that concern it. Components might be stateless or stateful. If components are stateless, component hierarchy is usually created anew on each request, with created hierarchy depending on the request URL. Advantages and disadvantages concerning support for history navigation mechanisms are very similar to stateless scripts, but programming with components makes code generally less error-prone. 1 2

Hidden input fields are passed as request parameters on HTML form submits. http://en.wikipedia.org/wiki/Spaghetti_code

14

Frameworks with fully stateful component hierarchies are one of the most problematic with regard to browser history navigation mechanism support. Usually only one instance of the hierarchy exists at a time and events from historical pages will be considered illegal and will not be processed by the framework at all. Later in this work we tangle this problem in more detail, as we describe state versioning support for Aranea web framework.

2.4

Component-Based Client Side Frameworks

Popularity of web frameworks which deploy their component models on the client side is on the rise. These client-side components communicate with the server by RPC calls and all communication is done with XMLHttpRequests. Those frameworks typically offer very rich UI, but many (e.g. Echo3 , ExtJS4 ) have completely discarded the support for client-side history navigation mechanisms. Google Web Toolkit5 (GWT) implements partial support for history navigation mechanisms, they will work only across different components. History navigation for events taking place within one component is not supported. GWT approach of dealing with navigation mechanisms depends on scripts that change the location URL by changing its fragment identifier[BLFM05], whenever cross-component navigation event is detected. Additionally, client-side scripts will be monitoring URL location changes not caused by applications’ internal events and switch displayed components when such condition occurs.

2.5

Continuation Based Frameworks

Continuations represent the rest of the computation at a point in the computation[Wik08a]. Continuations can be suspended and resumed and thus model web conversations very well. Continuations are not widely supported in languages that are used for web development. However, some bytecode postprocessing based libraries exist for supporting continuations on a Java Virtual Machine (JVM). RIFE[Fra08] web framework supports continuations in Java. Each request and response will contain the continuation identifiers and request cycle between client and server will create a new continuation on the server that is completely independent of the previous one and can be invoked separately. At the same time it captures exact same execution flow as a previous continuation, just with some additions. By encoding continuation identifiers in URLs, each navigation step is always accessible from server as a continuation willing to serve. Of course, even continuations cannot call back missiles already launched. 3

http://echo.nextapp.com/site/demo http://extjs.com/ 5 http://code.google.com/webtoolkit/ 4

15

Chapter 3 Aranea Web Framework This chapter gives a general overview of Aranea framework that is sufficient to understand the state versioning implementation presented in the next chapter.

3.1

Components

Aranea is a server-side web MVC framework, based on the abstraction of components arranged into a dynamic hierarchy[Kab07]. Aranea components live in an environment provided by their ancestors in a hierarchy. Conventionally components will never store instance references to any components from ancestral hierarchy, using ancestors favours through the environment instead. Environment itself is a simple map-like lookup interface. Lookup keys are conventionally interface classes that expose services provided by an ancestor: interface Environment extends Serializable { Object getEntry(Object key); Object requireEntry(Object key) throws NoSuchEnvironmentEntryException; } For our purposes here, Component can be considered a Serializable entity whose life cycle is enforced by the framework, has a Scope (unique hierarchical identifier), lives in an Environment and talks with its successors by sending them Message instances. It does not deal with request or response handling, and is base interface for Service and Widget.

3.2

Widgets

Widget is a stateful non-reentrant component whose interface closely resembles the following code snippet. Note that action method is actually inherited from Service but was added here for clarity. Widget normally goes through update/event/render (in that order) methods in one request/response cycle. 16

interface Widget extends Service { void action(Path path, InputData input, OutputData output); void update(InputData data); void event(Path path, InputData input); void render(OutputData output); } Here, InputData and OutputData are just Aranea abstractions of request and response objects. Path is alike to Scope, by traversal of the Path one arrives at the component which is the target of an action or event. In update method, which is received by all widgets in a hierarchy, Widget reads data intended for it from request and updates its state accordingly, event method is called on all widgets that belong to its target Path, but event listeners are only invoked by the Widget which is target of the event. Finally, render method will be called on displayable widgets and causes them to render their newly updated state to a response. Widget may also receive actions, that are a lightweight XMLHttpRequest based communication mechanism between client and server. All lifecycle events are skipped when widget receives an action and ActionListener registered by receiving Widget is solely responsible for generating the response based on action input parameters.

3.3

State Management

All Aranea component classes are Serializable and stateful parts of the widget hierarchy are stored in the session between the requests. As hierarchy is stateful, it can not react correctly to events received from historical pages1 , indeed Aranea default component assembly will completely ignore inputs and events from historical pages and skip to the render phase to return response that contains representation of an up-to-date component hierarchy.

3.4

Relocatable Components

Aranea has Relocatable wrappers for all component types: interface Relocatable extends Serializable { public void overrideEnvironment(Environment newEnv); public Environment getCurrentEnvironment(); } which can be used to replace Environment of a component (normally this is set just once). This can be used to e.g. dynamically relocate components in a hierarchy. 1

It must be noted that there is no notion of “page” in Aranea, everything is built out of reusable components that are assembled into hierarchies as required. One page can be thought of as result of rendering the current component hierarchy.

17

3.5

Widget Rendering

Widgets typically render themselves with JSP templates, making extensive use of Aranea tag library which contains many of tags for rendering different widgets. There is also support for partial rendering of the component hierarchy. Partial update regions [Kve07] are defined by surrounding sections of JSP template with ui:updateRegion tags. After that, any events that wish to update only particular sections of a page must refer to these regions to take advantage of partial rendering features. Events that have associated update regions will communicate with the server by using XMLHttpRequests.

3.6

Resource Inclusion

To include various client-side resources in response, JSP tag library has a few resource inclusion tags—ui:importScripts and ui:importScripts. Resource inclusion should usually happen in an HTML HEAD section of a produced HTML document.

3.7

Aranea System Form

Aranea applications typically generate HTML pages which contain only one HTML form that surrounds almost all other page elements. This form is rendered with ui:systemForm tag and is always submitted when client side events occur.

3.8

Preassembled Component Hierarchy

Aranea has several standard components that perform general tasks on the request and response and participate in each request cycle. These are assembled in a relatively flat hierarchy (chain) and will process the request before it is handled on to applicationspecific components. StandardFileUploadFilterService is one example of such a component—it takes an incoming request (InputData), determines whether it is multi-part and wraps the request with a singular view where parameters from all parts of the request can be accessed in an easy way. It then passes wrapped request object on to its children and also makes itself accessible from the Environment under the FileUploadContext key.

18

Chapter 4 Aranea State Versioning This chapter describes the state versioning support implemented for Aranea framework to support history navigation. It starts with an explanation of how to enable state versioning in an Aranea application and then goes on to give a detailed overview of state versioning implementation.

4.1 4.1.1

Configuring State Versioning Enabling Versioning Filter Component

State versioning component must be enabled in Aranea component preassembly to use state versioning facilities that provide support for handling history navigation events. This is done by adding similar lines to “WEB-INF/aranea-conf.xml” file in a web application. maxVersionedStates property sets the limit on how many versioned states are kept at the server and can be changed as desired. Bean attributes should not be changed. If the application does not use any XMLHttpRequests, this is all that needs to be done.

4.1.2

Enabling Versioning Support for XMLHttpRequests

If Aranea actions or update regions are used, additional scripts have to be specified in widget rendering templates to support client-side history navigation correctly. Following inclusion directive must be placed after the import statements of other Aranea scripts (especially aranea.js) to do that. 19

Additionally, root JSP templates1 need to be modified, so that each of them would contain an update region called “araneaGlobalClientHistoryNavigationUpdateRegion”. That region should contain practically everything that will be rendered on a page, i.e. commonly it is defined around the system form. Example might look similar to this:

4.2

State Versioning Implementation

Aranea state versioning component was named StandardStateVersioningFilterWidget and was implemented as a widget level filter. It acts as router and depending on the received input it will select one versioned state which will continue the request processing. State versioning filter has just one child that is wrapped in a RelocatableDecorator, allowing to temporarily cut the child hierarchy off its Environment at the request time. As Environment contains references to non-serializable objects during the request processing, this trick allows us to serialize the child at times when it would otherwise be impossible. Thus the versioned state can be represented by a byte array which contains the serialized form of the component hierarchy, as saving and restoring states becomes a simple matter of serializing or deserializing child component into/from a byte array. To ensure that only a limited amount of versioned states is kept in memory at a time, states in their serialized form are stored in a fixed size LRUMap2 which begins to discard the oldest states when map becomes full. For matching the requests with their targeted component hierarchy, state version identifier is encoded in a web response which will arrive back in corresponding request, allowing to choose a matching state version on the server side. Moment when state version is stored and state version identifier encoded into response must be chosen carefully, to avoid situation where component hierarchy state changes after state version was stored and its identifier sent away with the response. The most suitable place to tap into the widget lifecycle would be immediately after the render method of a child completes3 : void render(OutputData output) throws Exception { // pseudocode child.render(); // render the child // save child state, write state identifier to response } 1

These are the templates which describe the rendering of the rootmost part of the displayable component hierarchy. Often there is just one these. 2 LRU—Least Recently Used 3 But not before, as rendering changes the state of the RenderStateAware components

20

By the time the child’s render call ends, response will already contain complete HTML document and due to sequential write restriction state identifier cannot be added to the response anymore. It is possible to set a custom response header with a state identifier, but that will not come back to the server on subsequent response. So this custom header would need to be processed and added to the DOM of the rendered document on the client side—which proves to be possible only for XMLHttpRequests, as client side scripts have no way of examining response headers of page retrieved by plain HTTP request. This implementation still chooses to set the custom state identification header after the child’s render call ends, but this is only helpful for XMLHttpRequests. Thus, state versioning filter cannot be completely encapsulated and needs to expose some of its parts to other classes to trigger state saving on-demand. So, in addition to being a Widget, state versioning filter implements the following interface: interface StateVersioningContext extends Serializable { State saveState(); State saveOrUpdateState(String stateId); /** Marks all stored versioned states expired.*/ public void expire(); } which allows external access to state saving methods. To trigger the state saving at the safest moment possible, saveState call was added to the JSP tag ui:systemForm which writes the state identifier to the response immediately before the system form ends. Unfortunately this is not completely safe as the following natural idiom becomes outlaw in the render method of widgets: void render(OutputData output) throws Exception { // pseudocode child.render(); // render the child instanceField = something; // reset the instance field after render } This part of the implementation is sufficient to support backtracking in applications that rely on plain HTTP request.

4.3

State Versioning and XMLHttpRequests

To implement support for actions and update region submits, we made use of Really Simple History4 (RSH) Javascript library. It encapsulates many browser specific hacks to detect use of history mechanisms (with a timer that monitors changes in page location) and helps to make browser recognize XMLHttpRequests as navigation events. 4

http://code.google.com/p/reallysimplehistory/

21

XMLHttpRequest communications that wish to register as navigation events should call an add: function(newLocation, historyData) method of RSH. That invocation was added to Aranea form submission functions responsible for performing XMLHttpRequests. // newLocation: This will be the #hash value in the URL. // historyData: This is for complex data that is relevant only to the current browsing session. add: function(newLocation, historyData) For actual handling of history navigation events, a navigation listener must be added with addListener(listener) call. When RSH timer detects an URL change it will notify the listener, supplying info about the new #hash value in the location URL and historyData. While experimenting with possible options of implementing that listener for Aranea, we came to conclusion that currently it is not possible to implement navigation support for pages created as result of XMLHttpRequests while adhering to the concept that history navigation mechanisms should not communicate with the server. Though RSH takes care of monitoring and changing URLs, browser’s local cache still contains just one (most current) copy of a page currently shown to the user. Any backtracking events must recreate the exact representation of previous page, which is very hard to do locally because Aranea component model is located on the server and does not have corresponding client side components. Cloning the whole DOM tree of the page and then restoring it at the needed time should work in theory—but in practice Element.cloneNode works very inconsistently across browsers and its different implementations are prone to losing or corrupting form field contents and losing event listeners added directly to the DOM. As Internet Explorer 6/7 performed unsatisfactorily in author’s tests with node cloning and node insertion, it was decided that history navigation listeners will restore client-side representation of needed state by performing XMLHttpRequest to the server and acquiring content of special update region named “araneaGlobalClientHistoryNavigationUpdateRegion”, which would then be processed in a usual manner by Aranea client-side partial rendering API. Corresponding listener implementation finally took the following form: AraneaPage.RSHListener = function(newLocation, historyData) { if (newLocation && !newLocation.startsWith("HTTP")) { window.dhtmlHistoryListenerRequestedState = newLocation; araneaPage().event_6( araneaPage().getSystemForm(), null, null, null, null, ’araneaGlobalClientHistoryNavigationUpdateRegion’); } window.dhtmlHistory.firstLoad = false; window.dhtmlHistory.ignoreLocationChange = false; }; 22

Chapter 5 Known Issues and Future Work This chapter lists known issues with Aranea state versioning implementation and ponders the possible directions of future work.

5.1

Known Issues

1. One of the existing states becomes inaccessible with browser history navigation mechanisms when switching from HTTP requests to XMLHttpRequests. If first request to a page is HTTP request and following communication with server is done by combining XMLHttpRequests and local DOM modifications, firstly served page gets modified by response callback and cannot be reached in its original state because it has been permanently modified in history cache. Simply adding a hash to the URL after the first page load activates the navigation mechanism, but apparently will not create a second history cache instance of a page, resulting in same problem. This seems to be rooted in a fact that everything following “#” in an URI is considered a fragment identifier[BLFM05], and browser chooses to keep just one cached copy of a page which fragments were referred to. 2. In some situations Aranea will instruct XMLHttpRequest callbacks to issue a plain HTTP submit to trigger re-rendering of the full component hierarchy. Submit is realized in AraneaPage.ReloadRegionHandler (update region handlers are described in [Kve07, section 3.4]), which modifies the state version and some other fields of a page before submitting it. After backtracking to the same page, events will be routed to the component hierarchy that does not correspond to it and further events from that page have no effect. To keep page functional after reload callback, AraneaPage.ReloadRegionHandler can be rewritten to construct a special URL and then perform page reload by setting the window.location.href property correspondingly.

23

5.2 5.2.1

Future Work Session Storage Reduction

As storage requirements depend linearly on the number of versioned states, the session size increases significantly with serialization based state versioning. Average size of a versioned state can get large when user navigates deep into complex use cases. Considering that individually most end-user actions affect rather small part of active component hierarchy, storing some kind of delta encodings of serialized states instead of states themselves might prove to be a good way of reducing session size. Rsync Algorithm Rsync[TM98] is a delta compression algorithm which is primarily used for synchronizing file contents across network or devices. At least one open-source Java implementation of rsync algorithm exists1 . Algorithm requires one pass to identify the deltas between compared items. It might be worthwhile to experiment with rsync algorithm at different block sizes to use it as solution for computing, storing and applying state deltas. Custom Serialization Java serialization mechanism creates deep clones of all objects in all state versions, data is not shared between versions. Java offers way to customize serialization by overriding readObject and writeObject methods in a Serializable class or by implementing Externalizable interface and its readExternal and writeExternal methods. It is possible that Aranea components could be made to implement custom serialization scheme which would duplicate less data between versioned states, e.g. by creating a serialized component pool where component lookup would be performed by their unique component identificators (not to be confused with component Scope) and component references to their children are versioned but stored shallowly.

5.2.2

Versioned Component Wrappers

Adhering to presented versioning principles it would be simple to build a small versioned wrapper for Aranea widgets. This could be useful for providing simple local undo/redo operations inside a widget, e.g periodically saving user entered data and still keeping open the option of reverting back to earlier version.

1

http://jarsync.sourceforge.net/

24

Conclusions This work investigated the common history navigation mechanisms present in web browsers and gave on overview of headaches that they cause in development of web applications. As it stands, many of contemporary web framework models are quite unable to deal with the history navigation events in the manner that users have become accustomed to over time. In the form of plugins even more application platforms are appearing inside a browser that itself became an application platform long ago. Struggle with keeping browser history navigation mechanisms working in this rapidly changing environment will no doubt continue. General feeling that author took away from this work is that browser history navigation mechanisms are really quite flawed in their current form and supporting them may already require more trouble than they are worth. It will be interesting to see whether some alternative history mechanisms will be proposed and experimented with in coming years. Implementation of the state versioning for Aranea web framework proved to be quite straightforward for HTTP requests, but more messy for XMLHttpRequests, where much of the time was spent digging the client-side javascript code with debugger. Due to bad support of some advanced DOM manipulation methods the state versioning implementation was also forced to resort to performing background requests when client side navigations are detected. As Aranea state versioning implementation is currently anything but space efficient, this work could be followed up by researching versioned storage scheme that would allow more efficient storage usage.

25

History Navigation Mechanisms and Web Application State Bakalauruset¨ o¨ o Taimo Peelo Resu ¨ mee J¨arjehoidjatena toimivad veebisirvijate ajaloomehhanismid (esmajoones edasi-tagasi nupud) on osutunud enam v˜oi v¨ahem konfliktseks veebirakenduste kontseptsioonidega. P˜ohjuseks on nende toimemehhanismide rakendusest s˜oltumatus, mis sobib k¨ ull h¨asti staatilise sisu serveerimiseks, osutub aga probleemseks interaktiivsete rakenduste korral mis opereerivad muudetavatel jagatud andmetel. Eriti problemaatiliseks osutub ajaloomehhanismide toetus veebirakendustes taustp¨aringute (XMLHttpRequest) kasutamise korral. Rikkalikule kasutajaliidesele orienteeritud kliendipoolsed veebiraamistikud mis teostavad ainult taustp¨aringuid on hakanud loobuma toetuse pakkumisest veebisirvija ajaloomehhanismidele. K¨aesolev t¨o¨o annab u ¨levaate veebisirvijate ajaloomehhanismide toimimisest ja kontseptuaalsetest probleemidest mida need veebirakenduste kirjutajatele valmistavad. Vaadeldakse erinevaid mudeleid veebirakenduste loomiseks — skripte, serveripoolseid ja kliendipoolseid komponendip˜ohised raamistikke ning j¨atkudel (continuations) t¨o¨otavaid raamistikke. Kirjeldatakse erinevaid probleeme millega arendajatel nende raamistike kasutamisel rinda tuleb pista, et tagada ajaloomehhanismide vastuv˜otav t¨o¨otamine l˜oppkasutaja jaoks. T¨oo¨ p˜ohisaavutuseks on olekuversioneerimise realiseerimine serveripoolse komponendip˜ohise veebiraamistiku Aranea jaoks. Olekuversioneerimine Aranea jaoks p˜ohineb serialiseeritud komponentide hierarhiate versioneerimisel ja v˜oimaldab kirjutada Aranea rakendusi mis veebisirvija ajaloomehhanismide kasutamisel reageerivad rakenduse l˜oppkasutaja ootustele vastavalt. T¨o¨o kirjeldab olekuversioneerimise implementatsiooni ja kuidas seda Aranea raamistiku kasutamisel t¨o¨ole konfigureerida. Rakendatud l¨ahenemine peaks olema kasutatav ka teiste Araneaga sarnaste komponendip˜ohiste veebiraamistike jaoks ajaloonavigatsioonimehhanismide toetuse loomisel.

26

Bibliography [BLC95]

T. Berners-Lee and D. Connolly. Hypertext Markup Language - 2.0. RFC 1866 (Historic), November 1995. Obsoleted by RFC 2854.

[BLFM05]

T. Berners-Lee, R. Fielding, and L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. RFC 3986 (Standard), January 2005.

[Bra97]

S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. RFC 2119 (Best Current Practice), March 1997.

[ECM99]

ECMA. ECMAScript Language Specification, December 1999. ECMA Standard 262, 3rd Edition.

[FGM+ 99] R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, and T. Berners-Lee. Hypertext Transfer Protocol – HTTP/1.1. RFC 2616 (Draft Standard), June 1999. Updated by RFC 2817. [Fra08]

RIFE Web Framework. http://rifers.org/, 2008. [Online; accessed 29May-2008].

[GC99]

S. Greenberg and A. Cockburn. Getting back to back: alternate behaviors for a web browser’s back button, 1999.

[GHJV95]

Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. Design patterns: elements of reusable object-oriented software. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, USA, 1995.

[HHW+ 03] Arnaud Le Hors, Philippe Le H´egaret, Lauren Wood, Gavin Nicol, Jonathan Robie, Mike Champion, and Steve Byrne. Document Object Model (DOM) Level 3 Core Specification. Technical report, World Wide Web Consortium – W3C, June 2003. [Kab07]

Jevgeni Kabanov. Aranea–A Web Development and Integration Framework, 2007. [Masters Thesis].

[Kve07]

Alar Kvell. Aranea AJAX, 2007. [Bachelor Thesis].

27

[MK06]

Oleg M¨ urk and Jevgeni Kabanov. Aranea-Web Framework Construction and Integration Kit. In PPPJ ’06: Proceedings of the 4th international symposium on Principles and practice of programming in Java, pages 163–172, New York, NY, USA, 2006. ACM Press.

[RHJ]

Dave Raggett, Arnaud Le Hors, and Ian Jacobs. HTML 4.0 Specification.

[TG97]

Linda Tauscher and Saul Greenberg. How people revisit web pages: empirical findings and implications for the design of history systems. Int. J. Hum.Comput. Stud., 47(1):97–137, 1997.

[TM98]

Andrew Tridgell and Paul Mackerras. The rsync algorithm, 1998. [Online; accessed 28-May-2008].

[Wik08a]

Wikipedia. Continuation — Wikipedia, The Free Encyclopedia, 2008. [Online; accessed 29-May-2008].

[Wik08b]

Wikipedia. WorldWideWeb — Wikipedia, The Free Encyclopedia, 2008. [Online; accessed 19-May-2008].

[Wik08c]

Wikipedia. XMLHttpRequest — Wikipedia, The Free Encyclopedia, 2008. [Online; accessed 22-May-2008].

[WOHM08] Harald Weinreich, Hartmut Obendorf, Eelco Herder, and Matthias Mayer. Not quite the average: An empirical study of Web use. ACM Trans. Web, 2(1):1–31, 2008.

28

Appendix A Aranea Framework 1.2-M1 Compact disc with Aranea Framework 1.2-M1 release, which contains the implementation of state versioning support.

29

History Navigation Mechanisms and Web Application ...

By default, an expiration time does not apply to history mechanisms. If the entity is still .... shopping, submitting his credit card info and completing the checkout.

240KB Sizes 0 Downloads 153 Views

Recommend Documents

A Tool for Registering and Replaying Web Navigation
current web document for the associated target element TE; if found, replays the event using TE as target using WebDriver. If not found, the trace replayer ...

Enhancing Web Navigation Usability Using Web Usage ...
decorated websites, but very little about marketing a website or creating a website .... R. Padmaja Valli, T. Santhanam published an article [8] on “An overview.

A Tool for Registering and Replaying Web Navigation
the buttons that compose the graphic interface of the iGoogle web application use the DOM 2 features to handle user events, so the approach taken by [2], [3] cannot register any event associated to those buttons, while the method described in this ar

Web application security frame
Feb 14, 2006 - tion environment to determine the application type, for example ... intelligence (AI) component that infers an action that a user ...... Files, paths,.

Web application security frame
Feb 14, 2006 - web application security frame component can be applied to. Chen et a1' ...... attacker successfully gains access as a legitimate user or host,.

web application
The mechanism allows us to define stereotypes, tagged values and constraints that can be applied to model elements. A stereotype is an adornment that allows us to define. COMMUNICATIONS OF THE ACM October 1999/Vol. 42, No. 10. 65. 3In the Rational Un

pdf web application
Loading… Page 1. Whoops! There was a problem loading more pages. pdf web application. pdf web application. Open. Extract. Open with. Sign In. Main menu.

Facilitating Effective User Navigation through Web Site Usability
weighty and increasing money put into business in internet-site design it is still let be seen however that having experience desired information in an internet-site is ... programming MP design to be copied that helps User keeping direction at sea o

Collaborative Filtering Supporting Web Site Navigation
rithms that try to cluster users with respect some (given ... tion Systems, with the emerging filtering technologies .... file, the user is interested in the document.

Facilitating Effective User Navigation through Web Site Usability - IJRIT
reports that the overall internet-site operations making payments increased in ... is not an unimportant or everyday work Galletta et giving an idea of that connected ... those of brick and army fighting device stores and at least part of the nothing

Senior Application Developer, Collections - Museums and the Web
The Art Institute of Chicago is seeking an experienced application developer to support the ongoing development and maintenance of the Museum Collections' Digital Asset Management System. The Art Institute of Chicago is a world-renowned art museum ho

Agile Web Application Development with Yii 1.1 and PHP5.pdf
Page 2 of 368. Agile Web Application. Development with Yii 1.1. and PHP5. Fast-track your web application development by. harnessing the power of the Yii PHP Framework. Jeffery Winesett. BIRMINGHAM - MUMBAI. Page 2 of 368 ...

Senior Application Developer, Collections - Museums and the Web
The AIC Collection DAMS, named LAKE, is meant to become the central place for preserving, managing, ... tracking system (Redmine, Github), updating these tickets as work progresses, and requesting feedback ... This position reports to the Director of

Multi-Model Similarity Propagation and its Application for Web Image ...
Figure 1. The two modalities, image content and textual information, can together help group similar Web images .... length of the real line represents the degree of similarities. The ..... Society for Information Science and Technology, 52(10),.

PDF Improving Web Application Security: Threats and ...
Online PDF Improving Web Application Security: Threats and Countermeasures (Patterns Practices), Read PDF Improving Web Application Security: Threats ...

PIET MCA - MCA 4 : 2640002 - Web Technology and Application ...
PIET MCA - MCA 4 : 2640002 - Web Technology and Application Development Lecture Notes. Unit 1 : Introduction to HTML & JavaScript. Prepared By: Adarsh ...

HS HONORS US HISTORY AND ECONOMICS APPLICATION 2017.pdf
Whoops! There was a problem loading more pages. Retrying... HS HONORS US HISTORY AND ECONOMICS APPLICATION 2017.pdf. HS HONORS US ...

Web Technology & Application Development (WTAD) - WordPress.com
Subject: Web Technology and Application Development (WTAD) ... To develop proficiency in creating web based applications using the Servlets and JSP,.

application-letter-web-developer.pdf
Download. Connect more apps... Try one of the apps below to open or edit this item. application-letter-web-developer.pdf. application-letter-web-developer.pdf.