In developing Seawave's portal, I ran into a
philosophical issue with psml as it is currently used,
which I posted to the user mailing list a while back.

Seawave users will have their interface pretty much
dictated to them; they won't have the ability to
choose which portlets they see.  Also, their content
will vary widely depending on various influences:  the
billing status of the account, the type of user (crew
vs. operations, etc), whether the account has a
seawave email address, etc.    These influences can
change independently of each other at any time and the
user interface for affected users needs to instantly
change to reflect this.

However, for many portlets, users will be able to
change settings on the portlet level.  For example, a
user using our WeatherMapPortlet needs to be able to
change and persistently maintain the same setting for
which area to show a map for.
 
Using the current model, where a user's interface is
determined by a single psml file (whether it be the
user's personal file or from a role) it is difficult
or impossible to satisfy these requirements.   

The problem with using personal psml is that each psml
file, once spawned, is totally separated from its
roots.  Making a change to the psml of all
"crew" users, for example, would necessitate
writing a custom update script that would
intelligently loop through all the users and apply a
patch to the xml, then shutting down the server in
order to run the script.  Nightmare.

The problem with using role psml is that is basically
prohibits users from changing any settings at all. 
Anytime a user changed anything, every other user in
the same role would see the change.  Also, seawave
users can have more than one role so this model
wouldn't work at all.

I had to implement a style of profiling & psml
management that was a little different.  Now that it
works for Seawave, I think that with a little bit of
effort, this profiling style could prove quite useful
to others as well...  let me know if you're
interested, & if so I will definitely do whatever
extra work is necessary to aid in contributing it to
the jetspeed project as a whole.

This is how it works.  When a Profile is gathered from
the RunData, instead of just locating a single psml
file and returning it, the ProfilerService:

- obtains the User from the rundata.
- obtains all of that user's roles.
- reads through the psml documents for each of those
roles and assembles them into a PsmlList
- reads the user's personal psml file and tacks it
onto the PsmlList
- Loops through each document in the PsmlList and
intelligently merges them into a single PsmlDocument
- Stores the result of this merge as another psml
resource "fullContent", alongside the default
psml resource for the user (using CastorPsmlManager,
this will be "fullContent.psml" in the user's
personal psml directory).  This is mainly for
observation & debugging purposes.

I'm pretty happy with the way the merging works.  All
of the input files, as well as the generated
conglomeration, are valid psml and can be used as-is
by the existing profiler.   Each time it arrives at a
new document in the PSMLList, it recursively loops
through all of the portlets's and entries in the new
document...  

if the entry has an id in common with any id that
already exists in the conglomeration, the settings of
the original element are overridden by the settings in
the new element.  

if the entry's id is not found in the conglomerate
document, the profiler will assume that it is new and
add a copy of it somewhere in the conglomerate... if
the entry is a child of another entry that WAS in the
conglomerate already, the new entry will be added to
that entry, otherwise, the new entry will be added as
a child of the root portlet set of the conglomerate.

When a user changes parameters on a portlet through
PortletInstance.setParameter(), a new personal psml
document will be created for him/her if one doesn't
already exist.  To the personal document, a portlet
with the same id as the changed portlet will be added
if it doesn't already exist there.  Then the parameter
is changed on the personal entry.  

Since the user's personal psml is always last in the
PsmlList, if given the proper permissions, a user can
change parameters on a portlet without changing the
role psml that other users see.   

Benefits of this profiling strategy:
A given jetspeed user might have content based on 5
different influences.  Each influence can now be
separated into its own role ("crew",
"ops", "webmailUser", etc.) and each
role can be given its own set of associated content. 
Then whenever any content needs to change, editing one
psml file will immediately apply the change to all of
the appropriate users, without restarting the server
and without overwriting anyone's existing settings for
unrelated content.

However, the question of making this sort of profiler
available within jetspeed raises several issues.

- I am assuming that an entry's id is only supposed to
be unique within a single psml document.   This is how
the current jetspeed profiler operates, as all id's
are copied over from the turbine user when a new
account is created.

- I haven't implemented a way for the user to REMOVE
content from his conglomerate profile...  and to do so
I think the psml specification would have to be
extended.  Correct me if I'm wrong, but there is
currently no way to indicate that an entry exists but
has been closed; the entry is simply removed from psml
entirely.

- A role's profile often needs to be able to e.g.
insert new tabs into a pre-existing list of tabs
defined by another role.  If the order & position
of those tabs is important, this means that we need to
use position numbers for the tabs, but also that we
can't always count on the positions incrementing
straight up from 0;  in a different assemblage some of
the numbers could be skipped. 
I decided to change the "sortPortlets()" of
BasePortletSet to account for the possibility of
missing position #'s when sorting a bunch of entries. 
I just defined a Comparator as an inner class and used
Collections.sort() on the portlets.  This change
should be backwards compatible.

- Making a set of role profiles that will work
together takes some hand-coding.  You have to make
sure that the id's match up where they are supposed
to.
The customizer interface would need to be drastically
changed to fully work with a conglomerate style
Profiler.   While managing the content of the 10 or so
roles that a Seawave user can have in various
combinations, I still find the customizer extremely
useful and use it all the time.  However, to do this,
I switch to the old profiler in JetspeedResources,
restart jetspeed, log in, manage some user's personal
profile, log out,  open the generated psml and
retrieve the slices of it I want by hand and add them
to the appropriate role psml, then restart jetspeed
and log in again to observe the result.  
I would enjoy helping to extend the profiler to
account for a conglomeration of various psml files... 

- There is no order defined as far as which roles are
read first.  This is fine as long as you are carefully
maintaining the role psml by hand so that there are no
unwanted redundant attributes...  but I think the
system could benefit from some sort of an absolute
ordering of roles for the purpose of profile
conglomeration.

and there are more issues of course but this is
already turning into a novel...  please let me know
what you think so far.

-Matthew Forsyth. 

__________________________________________________
Do you Yahoo!?
New DSL Internet Access from SBC & Yahoo!
http://sbc.yahoo.com

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to