THE PROBLEM:
Most of the Web applications use links just as a mean to send themselves
an event. This event will trigger actions. A classical example is when a
listing has links in the head, as a mean for the user to control which
field will be used for sorting. When the amount of information is big,
also when the information is editable by the user, forms are used
instead of liks.
It is increasingly difficult, for developers, to keep track of the
different parameter names and values associated with events, actions,
etc. So, a better way is needed to express this information.
In Turbine, this problem arises in the context of running several
different applications in the same Turbine instance. In Jetspeed, the
problem is even worse, since PSML (piecemeal) is a language that enables
the developer to put together several different windows belonging to
different applications in the same browser page.
Also, the problem is worsened if we want to have the same java code
generating (possibly via XML) different versions (different markup
languages) of the same screen/portlet. The expression of URIs and Forms
is different in HTML and WML, PDF, ... We want to have reusable screens
in the applications.
PROPOSAL:
I feel that we should have something like "event" as an object. The
programmer should express that a URI is just a kind of I/F Widget, that
will trigger an event on the same application when pressed. This is a
different abstraction than a URI that will show a different page (in a
different application possibly) outside of the system.
There are some features (Action Event) in Turbine that enforce this
behaviour. But, for Jetspeed, we need more:
We need a way to isolate namespaces for parameters. This kind of
functionality is really essential to Jetspeed, to enable for instance
Turbine Screens or legacy HTML forms as portlets, and also several
instances of the same portlet in a screen (different views of the same
model, in MVC jargon).
NOTE:
I don't know Turbine very well. So, it may well be that, looking at the
Jetspeed screens and actions, I don't really understand the programming
abstractions in Turbine. Please, tell me if I'm wrong, or else if I
missed something.
Also, I don't know very well the template engines used in Turbine. How
will this kind of changes affect them?
SECOND NOTE:
I don't have a clean specification of the desired behaviour in advance.
I don't think we can anticipate the whole problem without some trial and
error. So, what I'm doing is to suggest some changes that would lead us
this way, hoping that:
- Some of you can anticipate problems and solutions I'm not seeing
- We can find issues through experimentation
FRAMING IT:
DynamicURI is no longer sufficient abstraction. First, it should not be
allowed to instantiate it without passing a RunData to it, so that it
knows the context under which it is running. This is so to enable it to
decide on parameter visibility. Second, it could possibly have (in
Jetspeed) parent DynamicURIs, corresponding to the enclosing PortletSet,
to compose the global links.
The overall picture I see is:
A screen will receive a RunData specific to the application/portlet to
which it belongs. This rundata will give DynamicURIs and
ParameterParsers that know about the scope they represent.
I don't have a clear idea on how this will be used in Turbine to have
different scopes for different applications, but it seems obviously
possible. To have that, I think you would need a Application object,
registered, ... I'm much more concerned about Jetspeed in this proposal.
For Jetspeed, this hierarchy of RunDatas will be used to map the
hierarchy in PSML of the Screen. There are two methods that could be
used to "prefix" parameter values and actions so that they are unique to
a given Jetspeed PSML:
A) Having a unique ID for each portlet/portletset
B) Similar to what Netscape does to handle MIME parts in messages,
something like *n*m*k* to indicate the kth portlet of the mth portlet of
the nth portlet. IE, the top level portletset will be *0*, portlets
inside *0*0* to *0*n*, and so on. Stars (or the market chosen) would
have to be escaped from parameter names, obviously. Also, the number of
numeric parameters is variable, correspondingly with the depth of the
PSML tree.
The first approach brings us to the same problem: how do we make unique
IDs for PortletSets, that are a rather dynamic object in PSML. The
second approach could give problems if the PSML structure changes from
one invocation to the next, for instance if we "close" a portlet in a
window. I don't have solutions for this yet.
CONCRETE CHANGES NEEDED NOW:
(I have part of it implemented in my working copy)
RunData is converted to an interface.
Current RunData is renamed to TurbineRunData (or something similar)
A JetspeedRunData is written, that has a "parent" RunData.
the RunDataFactory is adjusted. In any case, it should be private to the
Turbine and Jetspeed engines, as nobody should be able to build a
RunData except in the kernel of both frameworks.
The same process id done with ParameterParser (or else we enable
extensibility
by changing several "private" by "protected" ...)
The "new DynamicURI()" constructor is no longer public. Instead,
something like
data.getDynamicURI() should be used to enforce context propagation from
RunData
to ParameterParser and DynURI.
WHAT REMAINS TO BE DONE:
Now this rundata and the associated ParameterParser and dynamicURI can
be used
to propagate context (generating Portlet/Screen, etc. specific instances
of
this trio) so that parameter names are unique and parameters are private
to a
given screen/portlet. We could even emulate a HttpServletRequest to
return
parameter according to visibility and stripping/adding prefixes to
ensure
uniqueness, much like tomcat does for included servlets.
It would be even better to be able to tell something like
event = data.getEvent(); // ---> returning a dynamicURI or similar.
event.setAction("A");
event.setParameters(somehash);
//...
event.generateURI(); // or a more sophisticated
event.generateForm(); //having submit and hidden or editable parameter
fields...
Also, the action associated with the event would receive a RunData
containing
only visible (direct or inherited/global) parameters for it...
Then we could choose if the non editable parameters of an event are
propagated
as query string parameters, or post parameters, or hidden in the
session...
We could even have a system in which you always generate URIs like
//server/home/1 (1..n for internal links), and the session would map
this 1..n
to the different actions stored in the session.
PROBLEMS IN THE IMMEDIATE CHANGES:
I have tested making RunData interface, and creating TurbineRunData. It
breaks quite a few files in Turbine, Jyve and Jetspeed due to the use of
data.parameters, instead of data.getParameters() and similar problems.
Apart from this, it requires complete rebuild of all the turbine
applications.
FURTHER SPECIFICATION:
Scoping of parameter in URIs:
Do we have global scope parameters?
Are parameters state-tracking versus editable? A common practice is to
use query string or hidden fields to track state in the application. If
the syntax enable it, we could choose to track them in the session
instead. Actions to be triggered by a given event are also candidates to
being hidden from the user.
Jetspeed Specific: How do we handle interportlet communication, if we
do? Using global parameters? Or are parameters completely private to the
portlet/application that created them?
Do we have a hierarchy of event handlers like in windowing systems?
... Put your questions here (and answers, please)
Well, I'm sleepy now. This is the best I could do today. If somebody has
a clearer mind, please reorder/restructure this, and we keep discussing.
Sorry for the mess.
Thanks in advance,
Santiago
--
--------------------------------------------------------------
Please read the FAQ! <http://java.apache.org/faq/>
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Archives and Other: <http://java.apache.org/main/mail.html>
Problems?: [EMAIL PROTECTED]