Bug 220476 - Provide an RWT-based mechanism for persisting settings
Summary: Provide an RWT-based mechanism for persisting settings
Status: RESOLVED FIXED
Alias: None
Product: RAP
Classification: RT
Component: RWT (show other bugs)
Version: 1.0   Edit
Hardware: PC All
: P3 normal (vote)
Target Milestone: 1.1 M3   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 220477 222160
  Show dependency tree
 
Reported: 2008-02-26 17:21 EST by Elias Volanakis CLA
Modified: 2008-09-24 06:17 EDT (History)
0 users

See Also:


Attachments
Setting Store Patch v1 (78.49 KB, text/plain)
2008-02-27 16:14 EST, Elias Volanakis CLA
no flags Details
Example application using the new functionality (17.49 KB, application/x-zip-compressed)
2008-02-27 16:14 EST, Elias Volanakis CLA
no flags Details
Setting Store Patch v2 (109.41 KB, patch)
2008-02-29 21:36 EST, Elias Volanakis CLA
no flags Details | Diff
Example Application (18.38 KB, application/x-zip-compressed)
2008-02-29 21:37 EST, Elias Volanakis CLA
no flags Details
Setting Store Patch v3 (112.08 KB, patch)
2008-03-10 23:23 EDT, Elias Volanakis CLA
ruediger.herrmann: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Elias Volanakis CLA 2008-02-26 17:21:27 EST
Provide an RWT-based mechanism for persisting settings (i.e. key-value pairs, where key and value are Strings). 

Requirements:

- Storing key-value pairs (Strings)
- Any data being put into the store is considered persisted from that point on
- Has to support loading previously stored data
- Provide an implementation that persists to file system
- Pluggable mechanism so that different implementations can be used
	- for RWT-only scenario: do not rely on extension point
	- for RAP scenario: ok to use an extension point

Flow:

Session store is requested during a request / response cycle:
- Determine the current store id (working assumption: store id == session id)
- Do we have a store for this id?
	- yes 	--> end
	- no	-- retrieve store with given id; if it doesn't
		   exist create a new empty store; return store

Additionally, the API will allow loading previously stored data, based on an id provided by the application developer. This is for allowing to populate the store with data *after* the user has authenticated.

For example when using the application, the user initially is assigned to a new store based on the session id. After logging in, the application developer uses the provided API to initialize the store with persisted data associated with the user id.

API sketch:

- RWT provides access to a Setting Store Manager
- The Setting Store Manager provides access to a Setting Store, based on the currently  "registered" setting store implementation. It is possible to change the "registered" setting store implementation after the application has been deployed (RWT: web.xml, RAP: extension point). Possibly this could done by registering a particular implementation of a setting store factory.
- The Setting Store supports 
	- adding, getting, removing a key-value pair
	- adding / removing / notifying a listeners when settings are changed	- loading previously stored content from disk
Comment 1 Elias Volanakis CLA 2008-02-26 17:21:55 EST
I'm currently working on this.
Comment 2 Elias Volanakis CLA 2008-02-27 16:14:03 EST
Created attachment 90932 [details]
Setting Store Patch v1

Attaching non-finalized version so we can discuss.
Comment 3 Elias Volanakis CLA 2008-02-27 16:14:55 EST
Created attachment 90933 [details]
Example application using the new functionality
Comment 4 Elias Volanakis CLA 2008-02-27 16:34:32 EST
Hi Frank,

below are a few things to discuss on our upcoming call.

1. Newbie question: How to do logging / exception handling in RWT?
   (e.printStacktrace() vs. request.getSession().getServletContext().log(msg, e)

2. Exception handling in the ISettingStore: Do we want the API to throw
   an exception to cliends when we fail to persist (setAttribute()) or fail
   to load (loadById())? But then, how could clients react to such an exception?

4. FileSettingStore: Do we need a "clean up" mechanism on startup, which
   deletes persisted setting stores that were only tied to a session but not
   tied to a user-specific id?

5. FileSettingStore: how to determine the working directory for persisting? 
   java.io.tempdir vs IInitialization.getWorkingDirectory (WEB-INF/classes/)
   vs state location. Do we need API to set it?

6. SettingStoreFactory registration: I've tried the EngineConfigWrapper as
   discussed, but this seems to register the Factory for each session, which
   is uneccessary (since there is only one static factory instance used by the
   SettingStoreManager). Any thoughs on that?

7. Currently I use SettingStore.getStore() [static] instead of
   RWT.getSettingStore().getStore(). Any preference?

8. Notification in ISettingStoreListener. Currently we have one 
   attributeChangedMethod() instead of several (added / modified / removed). 
   Ok with that?

Regards,
Elias.
Comment 5 Elias Volanakis CLA 2008-02-27 21:48:42 EST
BTW, regarding #5: the temp.dir is a bad choice, since we need a location that is instance dependend (i.e. VM-specific). Otherwise we'll run into trouble with several RAP instances on one host.
Comment 6 Elias Volanakis CLA 2008-02-29 14:12:39 EST
Regarding Comment #4 here are the minutes from our call.

1. request.getSession().getServletContext().log(msg, e) is the preferred way

2. Throw some kind of specialized exception that is not dependend on a particular implementation (i.e. not IOException). 

4. Regarding the preferences cookie: do not use the "session cookie", since it has a too short lifespan. Use own "preferences" cookie with a long expiration date. This should survive the session lifespan / application restart. Therefore we should keep these files around between restarts.

5. Requirements reg. FileSettingStore working dir: should survive an re-deployment; separate directory for each web application; use reasonable default directory without configuration; should be configurable for admin deploying the app.

Support configuration through the web.xml (RWT) / config.ini (RAP Workbench). If nothing specified use these defaults: Default values: For RWT: use javax.servlet.context.tempdir. For RAP Workbench: state location; org.eclipse.ui plugin.

6. ISettingStoreFactory registration

For RWT: In RWTServletContextListener and assume factory is registered in in web.xml. 

For RAP Workbench: EngineConfigWrapper() and assume setting is registered through the config.ini or environment variable. There should also be an extension point for contributing ISettingStoreFactories, so they can be found by the RAP workbench. 

In both cases, if nothing is specified use reasonable default (FileSettingStoreFactory)

Do not need API for registering the ISettingStoreFactory programmaticaly. 

7. [BTW: SettingStore.getStore() should be SettingStoreManager.getStore() in the original comment] Change to RWT.getSettingStore() and make SettingStoreManager internal.

8. Ok.
Comment 7 Elias Volanakis CLA 2008-02-29 21:36:48 EST
Created attachment 91267 [details]
Setting Store Patch v2
Comment 8 Elias Volanakis CLA 2008-02-29 21:37:11 EST
Created attachment 91268 [details]
Example Application
Comment 9 Elias Volanakis CLA 2008-02-29 21:51:53 EST
The attached patch addresses the issues discussed in comment #6.

Some points to discuss in the next sync up:

1. Do we want and are there ways to test the "register" mechanism and the cookie strategy?

2. RWTServletContextListener - multiple initialization in tests. I've added a workaround (Setting.hasFactory()) to avoid that

3. The storeId assigned to a user is stored in a cookie. From security standpoint I could manipulate the id to have the webapp start with the stored 
settings of another session. Thoughs on that?

4. Is there a way to do tracing in RWT? I.e. it could be useful to print out the directory used by the FileSettingStore.

5. There are now two different factories for the FileSettingStore. An RWT-only factory (obtaining the storage directory through the web.xml / javax.servlet.context.tempdir / java.io.tempdir ) and a Workbench-only factory (obtaining the storage directory through the config.ini/property / org.eclipse.ui.rap.workbech state location).
Comment 10 Elias Volanakis CLA 2008-03-05 13:11:11 EST
Minutes from the call

(In reply to comment #9)
> The attached patch addresses the issues discussed in comment #6.
> Some points to discuss in the next sync up:
> 1. Do we want and are there ways to test the "register" mechanism and the
> cookie strategy?

Discuss in next call.

> 2. RWTServletContextListener - multiple initialization in tests. I've added a
> workaround (Setting.hasFactory()) to avoid that

Ok.

> 3. The storeId assigned to a user is stored in a cookie. From security
> standpoint I could manipulate the id to have the webapp start with the stored 
> settings of another session. Thoughs on that?

We can't avoid that. Potential later improvement: using an algorithm that's harder to guess.

> 4. Is there a way to do tracing in RWT? I.e. it could be useful to print out
> the directory used by the FileSettingStore.

No.

> 5. There are now two different factories for the FileSettingStore. An RWT-only
> factory (obtaining the storage directory through the web.xml /
> javax.servlet.context.tempdir / java.io.tempdir ) and a Workbench-only factory
> (obtaining the storage directory through the config.ini/property /
> org.eclipse.ui.rap.workbech state location).

Ok.
Comment 11 Elias Volanakis CLA 2008-03-10 23:05:01 EDT
Attaching final version of the patch.

I've changed the following things as discussed:

* SettingStoreManager_Tests now tests the cookie is set / read
* MemorySettingStore + Factory is now internal and in the Test plugin
* RWTFixture.setUp() installs the MemorySettingStoreFactory
* Fixture.clearSingletons() clears the setting store factory

In contrary to what we discussed i've left the XXXFileSettingStoreFactory classes in the API package. Unfortunatelly they must be API since the RWT registration mechanism needs the fully qualified classname, i.e:

<init-param>
  <param-name>org.eclipse.rwt.settingStoreFactory</param-name>
  <param-value>org.eclipse.rwt.service.RWTFileSettingStoreFactory</param-value>   
</init-param>

Frank, feel free to move the factories to internal packages, if you want. 
Comment 12 Elias Volanakis CLA 2008-03-10 23:23:06 EDT
Created attachment 92114 [details]
Setting Store Patch v3
Comment 13 Rüdiger Herrmann CLA 2008-03-11 05:19:19 EDT
Adjusted target milestone.
Back then I couldn't think of a release after 1.0;) this is why M3 actually should be 1.0 M3
Comment 14 Elias Volanakis CLA 2008-03-11 19:35:27 EDT
Comment on attachment 91268 [details]
Example Application

Obsolete. A newer example is available on Bug #220476.
Comment 15 Frank Appel CLA 2008-03-14 08:12:55 EDT
The implementation is now available in CVS-HEAD
Comment 16 Frank Appel CLA 2008-04-01 09:25:39 EDT
As the implementation is available in CVS-Head and seems to work reasonable a change the state to resolved.