portals-jetspeed-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a..@apache.org
Subject cvs commit: jakarta-jetspeed-2/portals-bridges/struts/xdocs features.xml index.xml navigation.xml
Date Mon, 31 Jan 2005 03:18:46 GMT
ate         2005/01/30 19:18:46

  Modified:    portals-bridges/struts/xdocs navigation.xml
  Added:       portals-bridges/struts/xdocs features.xml index.xml
  Log:
  First set of documents for the Struts Bridge: a summary and a (detailed) features overview.
  
  Revision  Changes    Path
  1.2       +12 -3     jakarta-jetspeed-2/portals-bridges/struts/xdocs/navigation.xml
  
  Index: navigation.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed-2/portals-bridges/struts/xdocs/navigation.xml,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- navigation.xml	29 Jul 2004 22:16:41 -0000	1.1
  +++ navigation.xml	31 Jan 2005 03:18:46 -0000	1.2
  @@ -15,9 +15,18 @@
   limitations under the License.
   -->
   <project>
  +
  +  <title>Portals Bridges - Struts Bridge</title>
  +
     <body>
  -      <links>
  -        <item name="Jetspeed 2" href="../../index.html"/>
  -      </links>
  +    <links>
  +      <item name="Portlet Specification" href="http://www.jcp.org/en/jsr/detail?id=168"/>
  +      <item name="Jetspeed 2" href="../../index.html"/>
  +    </links>
  +      
  +    <menu name="Documentation">
  +      <item name="Summary" href="index.html"/>
  +      <item name="Features" href="features.html"/>
  +    </menu>      
     </body>
   </project>
  
  
  
  1.1                  jakarta-jetspeed-2/portals-bridges/struts/xdocs/features.xml
  
  Index: features.xml
  ===================================================================
  <?xml version="1.0"?>
  <!--
  Copyright 2004 The Apache Software Foundation
  
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  -->
  <document>
    <properties>
      <title>Struts Bridge Features</title>
      <subtitle></subtitle>
      <authors>
        <person name="Ate Douma" email="ate@douma.nu"/>
      </authors>
    </properties>
    <body>
      <section name="Features">
        <p>
          The Struts Bridge provides the following features for developing and running Struts
Applications as Portlets:
          <ul>
            <li>
              <a href="#Struts Page URL">
                Provides a "virtual" page context and a "normal" page url to the Struts Application
              </a>
            </li>
            <li>
              <a href="#The ServletContextProvider interface">
                Allows Servlet invocation from an ActionRequest using an separate lightweight
interface to the Portal
              </a>
            </li>
            <li>
              <a href="#Portals requiring a more complex interface">
                Provides extension points if a more complex interface to the Portal is required
              </a>
            </li>
            <li>
              <a href="#Handling ActionRequests">
                Automatically separates Struts Action Processing and View Rendering when accessed
from an ActionRequest
              </a>
            </li>
            <li>
              <a href="#RenderContextAttributes to the rescue">
                Transparent communication of request attributes between ActionRequest and
RenderRequests
              </a>
            </li>
            <li>
              <a href="#Rendering valid Portlet urls with the Struts JSP Tags">
                Transparent translation of "normal" Web application resource and action link
urls to valid Portlet urls
              </a>
            </li>
            <li>
              <a href="#PortletRequestProcessor and PortletTilesRequestProcessor">
                Tiles support and automatic configuration of the correct (Portlet)RequestProcessor

              </a>
            </li>
            <li>
              <a href="#Running your application as Portlet and Web Application at the
same time">
                Deploy and run Struts Applications as Portlet and as Web Application at the
same time
              </a>
            </li>
            <li>
              Based on the latest official Struts release 1.2.4
            </li>
          </ul>
        </p>
        <subsection name="Struts Page URL">
          <p>
            Struts determines the Actions to perform on the request url. A Portlet on the
other hand doesn't
            have or receive an url, only request parameters.
          </p>
          <p>
            To be able to use Struts within a Portlet, a current Page context is maintained
by the Struts Bridge
            which is used to provide Struts with a "virtual" request context just as if it
were accessed from a Web
            Application.
          </p>
          <p>
            The Struts Page URL is maintained as a Portlet <code>RenderParameter</code>
and included in all Portlet URLs
            generated for the Portlet. When the <code>StrutsPortlet</code> receives
a request it uses the Struts Page URL
            to create a new <code>HttpServletRequest</code> with a redefined request
url before invoking the Struts
            <code>PortletServlet</code> (extending the Struts <code>ActionServlet</code>).

          </p>
          <p>
            None of the Action Mappings for an existing Struts Application have to be changed
(in this respect at least)
            to allow it to run in a Portlet context. 
          </p>
        </subsection>      
        <subsection name="The ServletContextProvider interface">
          <p>
            Processing <code>ActionRequest</code> and <code>RenderRequest</code>
events from a Servlet application is a
            problem with the current Portlet Specification. Although Servlets (and JSPs) can
be invoked from a Portlet,
            the Portlet Specification only supports this from the <code>RenderRequest</code>.
          </p>
          <p>
            As request parameters are only available during the <code>ActionRequest</code>,
not being able to use a Struts
            for processing these is a serious limitation. Together with no clear inter-portlet
application communication
            support, this is probably one of the biggest omisions from the Portlet Specification.
          </p>
          <p>
            But, because the Portlet Specification is build upon the Servlet Specification
(2.3), the Portlet Container
            implementation (like <a href="http://portals.apache.org/pluto">Pluto</a>)
and/or the Portal itself, usually
            does have direct access to, and also uses the <code>ServletContext</code>,
even during the
            <code>ActionRequest</code> event.           
          </p>
          <p>
            It is therefore usually very easy to provide access to the <code>ServletContext</code>
although it will
            require knowledge about the concrete implementation of the Portal and/or the Portlet
Container.
          </p>
          <p>
            The Struts Bridge uses the <code>ServletContextProvider</code> interface
from the Portals Bridges Common
            portals-bridges-common library, to get access to the <code>ServletContext</code>
it requires.
         </p>
          <p>
            To be able to use the Struts Bridge, a <code>StrutsPortlet</code>
must be provided with a concrete
            implementation of the <code>ServletContextProvider</code> interface
(through its initialization parameters).
            This implementation class can be supplied together with the Portlet or be provided
natively by the Portal as
            the <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2</a>
Portal does. 
          </p>
        </subsection>      
        <subsection name="Portals requiring a more complex interface">
          <p>
            Although the <code>ServletContextProvider</code> interface has been
defined to be easily implemented for a
            specific Portal, it might not be generic enough for all.
          </p>
          <p>
            To support those kind of Portals, the <code>StrutsPortlet</code> doesn't
uses the interface directly, but only
            through protected methods of its own which can be extended if needed.
          </p>
        </subsection>      
        <subsection name="Handling ActionRequests">
          <p>
            During an <code>ActionRequest</code> a Portlet (or invoked Servlet)
is not allowed to write content to the
            response. This is only allowed during the <code>RenderRequest</code>
event, but then a Portlet doesn't have
            access anymore to the (input) request parameters which makes it generally useless
(and bad practice anyway)
            for (Struts) Action processing.
          </p>
          <p>
            Struts on the other hand only knows one request event and is largely build upon
server-side forwarding to a
            JSP (or other View rendering technology) after an Action has been processed.
          </p>
          <p>
            The Struts Bridge solves this problem by allowing Struts Action processing to
occur during the ActionRequest.
            But, as soon as Struts forwards (or includes) to another handler (JSP, Velocity
script, <em>or even another
            Action></em>) it will intercept and freeze the processing.<br/>
            The Struts Bridge will then save the current processing context (like the path
to include or forward to) in a
            separate object, the <code>StrutsRenderContext</code>, and end the
ActionRequest.<br/>
            Once the RenderRequest is invoked, the Struts Bridge will use the <code>StrutsRenderContext</code>
to restore
            the state Struts (and/or an included or forwarded JSP) will expect and continues
the processing where it left
            off.
          </p>
          <p>
            Also saved in the StrutsRenderContext are the current <code>ActionForm</code>
(if it isn't already session
            bounded), the <code>ActionMessages</code> and/or <code>ActionErrors</code>
(if not already session bounded
            which is possible since Struts 1.2.1).
          </p>
          <p>
            <b><em>Important:</em></b> the StrutsRenderContext is
restored only once!
          </p>
          <p>
            The Portlet Specification expects Portlets to use a true MVC architecture: changing
the state of a Portlet is
            expected to be done during ActionRequest only. The RenderRequest, which may occur
many times, is expected to
            to only render the current state of the Portlet.
          </p>
          <p>
            For a proper usage of the Struts Bridge and to conform to the Portlet Specification
requirements, the Struts
            application too really should be configured to use separate Action processing
and View rendering Actions.<br/>
          </p>
          <p>
            The dependency on the StrutsRenderContext restoring the state during the (next)
RenderRequest should be
            limited to one situation only: input error processing.
          </p>
          <p>
            When Struts encounters input validation errors, it forwards (back) to the page
specified as input for the
            Action. The Struts Bridge handles this situation likewise. When it detects ActionErrors
are defined after the
            ActionRequest event, it will reset the Struts Page URL to the one from which the
ActionRequest was initiated
            StrutsRenderContext so subsequent (multiple) RenderRequest events will always
render that input page.
          </p>
          <p>
            Note: this will only result the same behavior as when the Struts Application is
accessed as Web Application if
            the Action Mapping input attribute indeed points to the originating input page,
which normally will be the
            case.
          </p>
          <p>
            As said, for a proper usage of the Struts Bridge, the Struts application should
be configured to use separate
            Action processing and View processing Actions. The Struts Bridge intercepts the
first include or forward 
            initiated from a Struts Action during the ActionRequest. During only the first
following RenderRequest it will
            invoke Struts with <em>the same Struts Page URL</em> as for the ActionRequest
but intercept before the actual
            execution of the mapped Action and then include (never forward) the intercepted
target url of the ActionRequest
            (normally a JSP).          
          </p>
          <p>
            A properly MVC configured Struts application though can (and should) make use
of a (client-side) redirect
            after the Action processing Action by using an ActionForward with redirect="true".
The behavior of such an
            Struts Application then truly complies to the requirements for a Portlet. In fact,
the reference
            implementation of the Portlet Specification, <a href="http://portals.apache.org/pluto">Pluto</a>,
actually
            sends a redirect to the client (browser) after an ActionRequest.
          </p>
          <p>
            The Struts Bridge supports this behavior as it will intercept a client-side redirect
during an ActionRequest
            by changing the Portlet Page URL to be used by subsequent RenderRequests to the
targeted redirect url.
          </p>
          <p>
            A Struts Application not complying to the above "rules" might not behave as expected
in a Portlet context:<br/>
            without this configuration a second RenderRequest event will not get the previously
saved StrutsRenderContext
            restored and the invoked Struts Action will be executed again (this time without
any parameters).
          </p>
          <p>
            Migrating an existing Struts Application to a Struts Portlet with doesn't comply
to these "rules" might seem
            problematic without major changes to the code, but it doesn't have to be. 
          </p>
        </subsection>      
        <subsection name="RenderContextAttributes to the rescue">
          <p>
            Although a StrutsRenderContext can only be used once to communicate request parameters
from the ActionRequest
            to the next RenderRequest (stored in the ActionForm), the Struts Bridge provides
another, completely
            transparent, solution which can be used without any required changes to the Struts
Application.
          </p>
          <p>
            The Struts Bridge can be configured, using a simple xml definition, to always
save specific named request
            attributes during an ActionRequest and restore these only during the next RenderRequest
or optionally every
            RenderRequest until the next ActionRequest or a RenderRequest for a different
Struts Page URL is invoked.
          </p>
          <p>
            The request attribute values will be saved in the web session which requires them
to implement the
            <code>Serializable</code> interface.
          </p>
          <p>
            An example struts-portlet-config.xml (the name of this file is configurable) definition
might look like:
            <source><![CDATA[
              <?xml version="1.0" encoding="UTF-8"?>
              <config>
                <render-context>
                  <attribute name="errors"/>
                  <attribute name="message" keep="true"/>
                </render-context>
              </config>]]></source>
            <em>(This (adapted) example is taken from the JPetstore Portlet example
provided with the
            <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2</a> Portal.)</em>
          
          </p>
          <p>
            With the above example configuration, all request attributes named errors and
message are saved after the
            ActionRequest. The errors object is restored only once, the message object will
be restored until the next
            ActionRequest or when the Struts Page URL is changed. 
          </p>
          <p>
            Using the RenderContextAttributes configuration, a Struts Action can still forward
(without redirecting) to a
            JSP in a Portlet while passing its required data through the request attributes.
Request scoped ActionForms
            can also safely be used for this as the Struts Bridge will automatically removes
them from the session again
            when they go out of scope!      
          </p>
          <p>
            Using the single use only configuration (without the keep="true" attribute) allows
one to pass on rather large
            objects to the RenderRequest because, even if they are stored in the Session,
this will only be for a very
            short period (milliseconds). Of course, with a subsequent RenderRequest these
objects won't be available
            anymore and the specific View Renderer must be defined to handle that situation
properly.<br/>
            Error objects or error messages (other than ActionMessages and ActionErrors which
are already automatically
            saved in the StrutsRenderContext) are also reasonable candidates to use like this.
          </p>
        </subsection>      
        <subsection name="Rendering valid Portlet urls with the Struts JSP Tags">
          <p>
            Another problem with using Struts for Portlet Development is rendering valid urls.
          </p>
          <p>
            There are actually two different type of problems: urls for resources likes images,
Javascript or CSS
            stylesheets which needs to be loaded by the client (browser), and urls for interacting
with the Portlet
            itself.
          </p>
          <p>
            The problem with resource urls is the fact that the content of a Portlet is only
included by the Portal,
            together with possible content of other Portlets shown on the same page. Although
the Portlet runs within
            its own context (the same as the web application it is based on), the client (browser)
sees only the context
            of the Portal page it is currently pointed at.
          </p>
          <p>
            A Portlet therefore cannot make use of relative src locations for a resource url
while this is perfectly valid
            (mostly usually preferred) in a Web Application. For a client to be able to retrieve
a resource, its url
            really must include the full context path of the Web Application.
          </p>
          <p>
            For interacting with the Portlet special PortletURLs must be used which can only
be generated using the
            Portlet API or through the Portlet JSP Tags. The Struts JSP Tags only generate
urls valid for a Web
            Application and also doesn't provide some kind of URLProvider interface like JSF.
          </p>
          <p>
            Furthermore there are two different PortletURL types: an ActionURL and a RenderURL.
            It is very important to generate the correct type of url for a certain interaction.
Forms must *always* use
            a POST to an ActionURL, but for all generated links it will have to be determined
which type of url actually
            is required. 
          </p>
          <p>
            To solve these problems, the Struts Bridge provides enhanced versions of the Struts
HTML JSP Tags (including
            EL variants), which take the Portlet environment into account. Furthermore, using
a separate element in
            the struts-portlet-config.xml definition, specific url paths can be configured
to be of a certain type
            (Resource, ActionURL, RenderURL) only.
          </p>
          <p>
            For the enhanced Struts HTML JSP Tags (html:form, html:link, html:rewrite, html:image
and html:img), four
            different TLDs are provided: a EL and non-EL variant, and for both a full replacement
of the Struts
            supplied struts-html.tld as well as a separate struts-portlet.tld containing only
the enhanced Tags definitions.  
          </p>
          <p>
            The full replacement TLDs makes it very easy for migrating a Struts Application
to a Portlet context: simply
            map the new TLD in web.xml or redefine the taglib uri in the JSP using:
            <source><![CDATA[
              <%@ taglib uri="http://portals.apache.org/bridges/struts/tags-portlet-html"
prefix="html" %>]]></source>
            or
            <source><![CDATA[
              <%@ taglib uri="http://portals.apache.org/bridges/struts/tags-portlet-html-el"
prefix="html-el" %>]]></source>
              <em>(Note: the Struts Bridge library contains all the TLDs so you don't
need to add them yourself 
              somewhere under WEB-INF/.)</em>
          </p>
          <p>
            For the enhanced html:link and html:rewrite Tags, three additional boolean attributes
are defined: actionURL,
            renderURL and resourceURL. Using these attributes one can specify which type of
url must be generated (only
            value "true" is supported).
          </p>
          <p>
            If non of these attributes is specified (with value "true") these Tags will by
default generate a RenderURL.          
          </p>
          <p>
            But, the default can be changed (only between renderURL and actionURL) using the
struts-portlet-config.xml
            definition. Furthermore, for specific url path (prefixes) you can specify which
type of url must be generated
            (specifying one of the three url type attributes will always override though).
          </p>
          <p>
            An example struts-portlet-config.xml with portlet url type definitions might look
like:
            <source><![CDATA[
              <?xml version="1.0" encoding="UTF-8"?>
              <config>
                <render-context>
                  <attribute name="errors"/>
                  <attribute name="message" keep="true"/>
                </render-context>
                <portlet-url-type>
                  <action path="/shop/add"/>
                  <action path="/shop/switch"/>
                  <action path="/shop/remove"/>
                  <action path="/shop/signoff"/>
                  <action path="/shop/viewCategory"/>
                  <action path="/shop/viewItem"/>
                  <action path="/shop/viewProduct"/>
                  <action path="/shop/viewCart"/>
                  <action path="/shop/newOrder"/>
                  <render path="/shop/newOrderForm"/>
                  <action path="/shop/listOrders"/>
                  <resource path="/images/"/>
                </portlet-url-type>
              </config>]]></source>
            <em>(This is the full configuration used for the JPetstore Portlet example
provided with the
            <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2</a> Portal.)</em>
          
          </p>
          <p>
            In the above example the portlet-url-type element contains three different sub
elements: action, render and
            resource. Their path attribute specifies the prefix to which specific urls are
matched. This matching will be
            done using best match. Internally, the paths will be ordered on longest definition
first.
          </p>
          <p>
            Not shown in the above example is the optional default="render"|"action" attribute
for the portlet-url-type
            element. With it, the default type of portlet-url can be changed from "render"
to "action" as is used in the
            Struts Mailreader Demo Portlet (also provided by the <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2</a>
            Portal):
            <source><![CDATA[
              <?xml version="1.0" encoding="UTF-8"?>
              <config>
                <portlet-url-type/>
              </config>]]></source>
              This feature is especially useful for Struts Applications who were configured
using an earlier version of
              the Struts Bridge (0.1) which used an ActionURL as default, like the above Struts
Mailreader Demo Portlet.
          </p>
          <p>
            The enhanced html:img and html:image Tags, as well as the html:link and html:rewrite
Tags, can be used to
            generate resource urls using relative (not prefixed with a '/') src references.
The Tags will then determine
            automatically determine the correct url to generate using the current Struts Page
URL as defined for this
            RenderRequest.
          </p>
          <p>
            This allows one to replace hard coded resource urls like 
            <source><![CDATA[<img src="../images/struts-bridge.gif"/>]]></source>
            with  
            <source><![CDATA[<html:image src="../images/struts-bridge.gif"/>]]></source>
            A simple change with no technical impact, but it will allow the same JSP to be
used for both a Web Application
            and a Portlet. The JPetstore Portlet example as provided by <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2</a>
            makes full use of this feature.
          </p>
        </subsection>      
        <subsection name="PortletRequestProcessor and PortletTilesRequestProcessor">
          <p>
            The Struts Bridge requires a different RequestProcessor to be used for the Struts
Application: a <code>
            PortletRequestProcessor</code>. If a Struts config doesn't define one, or
defines one which isn't based on the
            PortletRequestProcessor, it will be replaced automatically by the Struts Bridge.
          </p>
          <p>
            The Struts Bridge also supports Tiles to be used through its <code>PortletTilesRequestProcessor</code>.
If the
            TilesPlugin is defined (as required to be able to use Tiles in Struts) it will
be recognized by the Struts
            Bridge and then the PortletTilesRequestProcessor will be used instead (if not
configured already).          
          </p>
          <p>
            Tiles can be used without problem within a Portlet context, even for Action Mapping
or ActionForward paths,
            although the same considerations and restrictions must be taken into account as
described above.
          </p>
        </subsection>      
        <subsection name="Running your application as Portlet and Web Application at the
same time">
          <p>
            Although the Struts Bridge is created to allow Struts Applications to run in a
Portlet context, it also allows
            the same application to be run in a Servlet context too.
          </p>
          <p>
            If the Struts Bridge PortletServlet (which extends ActionServlet) detects it is
not accessed from a Portlet
            context is simply delegates back to the underlying Struts Framework.
          </p>
          <p>
            Provided the Struts Application doesn't use any Portlet specific features and
the Action Mapping configuration
            is also (still) valid for a Web Application, the same application war can be deployed
as Web application and
            as Portlet Application. When deployed in a Portal, the application can even be
accessed as Portlet or as 
            Web Application at the same time!
          </p>
          <p>
            The JPetstore Portlet example provided by <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2</a>
is one
            example of such a "dual" mode Struts Application.
          </p>
          <p>
            Another benefit of such a "dual" mode Struts Application is that it can be fully
tested as Web Application, 
            which <em>is</em> somewhat easier than testing it as a Portlet.
          </p>
        </subsection>      
      </section>
    </body>
  </document>
  
  
  1.1                  jakarta-jetspeed-2/portals-bridges/struts/xdocs/index.xml
  
  Index: index.xml
  ===================================================================
  <?xml version="1.0"?>
  <!--
  Copyright 2004 The Apache Software Foundation
  
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  -->
  <document>
    <properties>
      <title>Struts Bridge Summary</title>
      <authors>
        <person name="Ate Douma" email="ate@douma.nu"/>
      </authors>
    </properties>
    <body>
      <section name="Summary">
        <p>
          The Struts Bridge allows <a href="http://struts.apache.org">Struts</a>
and Struts Tiles applications to be run
          as <a href="http://www.jcp.org/en/jsr/detail?id=168">JSR-168</a> compliant
Portlets.
        </p>
        <p>
          Existing or new Struts Applications can be transparently deployed as Portlet Application
or
          Web Application.<br/>
          The Bridge wraps and enhances the native Struts Framework to overcome its limitations
and
          incompatibilities with the Java Portlet Standard requirements.
        </p>
        <p>
          An existing Struts Application can be used as a Portlet <em>without</em>
changes to the code or JSP files if:
          <ul>
            <li>a few common sense rules, based on a proper MVC architecture, are followed
for the Struts Action configurations</li>
            <li>Struts Tags are used for rendering all resource paths (like images)
and action links</li>
          </ul>
        </p>
        <p>
          If a Struts Portlet doesn't use Portlet specific features, it can also be accessed
and used as Web Application at
          the same time. Even testing the Struts Application can then be done completely independent
of a Portal.
        </p>
        <p>
          The Struts Bridge is developed to be independent from specific Portals and uses
only a very small interface to
          the Portal to be able to get access to the Servlet environment at runtime. As all
JSR-168 Portlet Containers are
          required to build upon the Servlet specification, providing this interface for a
specific Portal is usually very
          easy to do, if not done already.
        </p>
        <p>
          The Apache Portals <a href="http://portals.apache.org/jetspeed-2">Jetspeed-2
Portal</a> provides this interface
          natively, as well as example Struts Portlet Applications using the Struts Bridge
like a JPetstore Portlet. 
        </p>
      </section>
    </body>
  </document>
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jetspeed-dev-help@jakarta.apache.org


Mime
View raw message