David Sean Taylor wrote:
>
> Hi All,
>
> Below is a proposal for a Jetspeed Profiler Service.
> It is not final and your input is welcome.
>
Excellent.
I just have a few implementation suggestions. See below.
I'm eagerly waiting for the implementation.
>
> <snip>
>
> -----------------
> Resource Names
> -----------------
>
> The Profiler expects to have a default resource for every user.
> To use the default resource, you don't need to specify a resource name in
> the resource URL path. The default resource name is set in the Profiler
> configuration.
>
> In order to specify a resource other than the default markup for a user,
> resource names are specified in the Resource URL Path. To specify a
> non-default resource, the first part of a resource path must be the keyword
> 'portal'. This tells Jetspeed that the request is for a portal markup
> resource.
>
> Next, the resource name can be specified. This name simply identifies the
> resource that the user is requesting. The resource is specified in the URL.
> An example of a 'BenefitsPage' resource would be:
>
> http://host/servlet/jetspeed/portal/BenefitsPage
>
> When no name or path is specified, the default resource is used for the
> current user. The resource name can also have an extension. If it is
> omitted, the default is to append a configurable extension (PSML).
>
> Resources names may also be prefixed. This proposal suggests three prefixes:
>
> /user/ - Specifies that the request can only be satisfied by a user
> resource. An example would be /portal/user/BenefitsPage, meaning that we are
> requesting the BenefitsPage, but only for the current user. Specifying the
> name of the user is not allowed, only the authenticated username is applied.
>
> /role/<RoleName> - Specifies that the request can only be satisfied by a
> common role resource . An example would be
> /portal/role/Accountant/FinancePage, meaning that we are requesting the
> FinancePage, and it is the Finance page for the Accountant role. It will be
> up to the Profiler implementation to determine if the user is authorized to
> assume this role. The Security service, whether it is Turbine Security or
> other, should hold the controlling access information.
>
> /group/<groupName> - Specifies that the request can only be satisfied by a
> common group resource. An example would be
> /portal/group/Finance/BenefitsPage, meaning that we are requesting the
> BenefitsPage, and it is the Benefits page for the group 'Finance'. It will
> be up to the Profiler implementation to determine if the user is a member of
> this group. The Security service, whether it be Turbine Security or other,
> should hold this mapping.
>
> When a prefix is not specified, the resource is resolved by first looking
> for a user resource, then a group resource, and finally a role resource.
> Only groups and roles that the user has read acess priveleges will be
> considered.
>
Be aware that this breaks the default behavior of Turbine DynamicURI and
ParameterParser which expects the path_info to be in the form :
<varname1>/<varvalue1>/<varname2>/<varval2>/
Implementing your proposal would require a subclassed implementation of
these classes. You can simplify the task by sticking to the Turbine convention
and using URI in the form:
/portal/BenefitsPage/user/david
...
It's not better than your proposal but a lot easier to implement :)
> -------------------------------
> Localized Resources
> --------------------------------
>
> Resource names can optionally be localized. This is done by suffixing the
> resource name. The suffix is made up of a required ISO-639 standard
> two-character language abbreviation, and an optional IS0-3166 standard
> two-character country code abbreviation.
>
> The suffix is of the format:
>
> _lc_cc
>
> where:
>
> lc = language code
> cc = country code
>
> Some examples
>
> groups/accounting/html/default_fr_FR.psml // french language, France
> groups/accounting/html/default_fr.psml // french language, any country
>
> For a given locale of fr_FR, the search order for the default accounting
> resource would be:
>
> groups/accounting/html/default_fr_FR.psml
> groups/accounting/html/default_fr.psml
> groups/accounting/html/default.psml
>
> The profiler will look at the "Content Language" HTML header for locale
> specific settings. If there are multiple settings, all settings will be
> searched until the first resource is found.
>
> Localization can be configured in the JetspeedResources.properties file.
>
> You can configure a default language. This language will be considered the
> default language and no prefix will be necessary for their resources.
>
> # only french belgium
> profiler.language.default=fr_BE
>
> # default language any spanish
> profiler.language.default=es
>
> # all resources must be suffixed
> profiler.language.default=
>
> To turn on/off all localization checking:
> profiler.default=true/false
>
IMO, the default language configuration is unnecessary, the fallback mechanism
to "default.psml" implicitely handle this case.
> -----------------------------------
> Turbine Resources Configuration
> -----------------------------------
>
> The Profiler Service must be implemented as a Turbine service.
> The Profiler Service is configured in the JetspeedResources.properties file:
>
> # Profiler used for assigning the�PSML URL to use for each request
> profiler.default.classname=org.apache.jetspeed.services.profiler.JetspeedPro
> filer
>
Since you're implementing a service, it's better to stick to the
standard service properties convention:
services.Profiler.classname=org.apache.jetspeed.services.profiler.JetspeedProfilerService
> -----------------------------------
> Jetspeed Resources Configuration
> -----------------------------------
>
> # Base URL for fetching user configuration files
> # for use with the default profiler
> profiler.base.url=/content/profiles/
>
> # Directory used for anonymous access
> profiler.anon.dir=/user/default/
>
These 2 properties should use the same data type, most likely:
full URL/webapp relative URI.
> ====================
> Interfaces
> ====================
>
> All profiler services must implement the ProfilerService interface.
> The Profile interface defines a profile instance.
> A Profile is the object representation of a Jetspeed PSML resource.
>
> interface ProfilerService extends Service
> {
> /*
> initialize the profiler service
> the profiler service is implemented as a turbine service
> */
> init();
>
This is already defined in Service, no need to be redundant.
> /*
> get the Profile object using the Rundata state and capability map
> this is the mapping functionality of the profiler
> */
>
> Profile getProfile(Rundata, CapabilityMap );
>
I don't like using a CapabilityMap as an explicit parameter in the Profiler
interface, this creates an unnesssary coupling of interfaces.
Either the capabilityMap is a service and is used implicitely within a
getProfile implementation or (my preferred solution) a getCapability() method
is added in RunData and populated by the CapabilityMap before the call to the
profiler.
> /*
> get the base URL for the profile registry
> */
> String getBaseURL();
>
> /*
> get the default resource name
> */
> String getDefaultResourceName();
>
> /*
> is security enabled
> */
> boolean isSecurityEnabled();
>
> getAuthorizedProfiles();
> getAnonymousProfiles();
>
These methods expose the configuration options of your default implementation
so they don't belong to the generic Profiler service interface but to your
specific implementation (and would most likely only ever be used by an
administration component, monitor componenet or your service itself).
> /*
> store cookie in response to the current resource
> */
> storeCookie();
I'm not sure how you plan to use this. Can you provide a pseudo-code
example ?
> }
>
> interface Profile
> {
> /**
> * Gets a PortletSet for this profile object.
> *
> * @return The root portlet set for this profile.
> */
>
> PortletSet getPortletSet(); // get the portlet set for this profile
>
Let's call it getRootSet() or something like that to explicit that you can
only get a reference to the root set from this method.
Since in this model, the profile encapsulate the PSML config accessor, I'd
propose that you add a method:
getFactory() or equivalent to let client classes access the real
factory in order to manipulate more precisely the PSML elements.
The getRootSet() would actually be a convenience method for
getFactory().getPortletSet( <my resource> );
> /*
> stores the resource by merging and rewriting the psml file
> */
> void store()
>
do you store the PSML or persist the Profile with this call ?
> /*
> accessors to new functionality - this may be default imp. specific....
> */
> String getUser();
> String getGroup();
> String getRole();
> String getResourceName();
> String getResourcePath();
> String getMediaType();
> String getLanguageCode();
> String getCountryCode();
I think this is mostly imp. specific. Better to try to expose the minimum methods
at first and complete afterwards if necessary than expose too much in the
beginning.
> }
>
> ==============================
> Future Directions
> ==============================
>
> - Full support of W3 CC/PP RDF descriptions
>
CC/PP support should be orthogonal to the Profiler work which should rely
only on a Capablity abstraction.
--
Rapha�l Luta - [EMAIL PROTECTED]
--
--------------------------------------------------------------
Please read the FAQ! <http://java.apache.org/faq/>
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Archives and Other: <http://marc.theaimsgroup.com/?l=jetspeed>
Problems?: [EMAIL PROTECTED]