<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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.
-->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<chapter id="webapps">
  <title>Web applications</title>

  <section id="webapps.scenarios">
    <title>Usage scenarios</title>
    <para>TBW</para>
  </section>

  <section id="webapps.servlet-service-fw">
    <title>Servlet-Service framework integration</title>
    <para>TBW: Composition, servlet: protocol, inheritance</para>
  </section>

  <section id="webapps.http-environments">
    <title>Sitemaps in an HTTP environement</title>
    <para>TBW: Status codes, Conditional GET requests, Mime-type handling</para>
  </section>

  <section id="webapps.system-setup">
    <title>System setup</title>
    <para>TBW: Logging, JNet, Configuration, Spring integration Deployment: Blocks as deployment units AND Creating a web archive (WAR), Devleopment with Eclispe and Maven</para>
  </section>

  <section id="webapps.pipeline-fragments">
    <title>Connecting pipeline fragments</title>
    <para>TBW</para>
  </section>

  <section id="webapps.rest">
    <title>RESTful web services</title>
    <para>
    
    </para>
    <section id="webapps.rest.sitemap">
      <title>Sitemap based RESTful web services</title>
      <section>
        <title>Introduction</title>
        <para>
          TBW: REST controller, Rendering views using StringTemplate, Request-wide transactions (incl. Subrequests) 
        </para>
      </section>
    </section>
    <section id="webapps.rest.jaxrs">
      <title>JAX-RS based controllers (JSR311) </title>
      <section>
        <title>Introduction</title>
        <para>
          JAX-RS (JSR 311) is the Java standard for the development of RESTful web services. It provides a
          set of annotations that, when being applied, define resources that are exposed by using Uniform Resource 
          Identifiers (URIs).
        </para>
        <para>
          The <ulink url="http://wikis.sun.com/display/Jersey/Main">wiki of the Jersey project</ulink> that provides 
          the Reference Implementation of JAX-RS contains a lot of useful information about how to define REST resources.
        </para>
        <para>
          The main pieces of the JAX-RS/Cocoon-integration are
            <itemizedlist>
              <listitem><para>the <literal>CocoonJAXRSServlet</literal> Servlet-Service, which is responsible for
              the JAX-RS integration into the Cocoon Servlet-Service framework, and </para></listitem>
              <listitem><para>the <literal>URLResponseBuilder</literal> class, which allows calling  resources
              provided by other Servlet-Services (usually Cocoon pipelines exposed by sitemaps).
              </para></listitem>
            </itemizedlist>
        </para>
      </section>
      
      <section id="webapps.rest.jaxrs.sample">
        <title>Cocoon and JAX-RS by example</title>
        <para>
          Adding support for JAX-RS services to your Cocoon application requires following three steps: 
            <itemizedlist>
              <listitem><para>Add the <literal>cocoon-rest</literal> module as a dependency.</para></listitem>
              <listitem><para>Add the <literal>CocoonJAXRSServlet</literal> Servlet-Service</para></listitem>
              <listitem><para>Add at least one JAX-RS root resource</para></listitem>
            </itemizedlist>
        </para>
        
        <section id="webapps.rest.jaxrs.sample.dependency">
          <title>Cocoon-Rest dependency</title>
          <para>
            The first step is to add the <literal>cocoon-rest</literal> module to your Cocoon application:
          </para>
          <programlisting language="xml"><![CDATA[    <dependency>
      <groupId>org.apache.cocoon.rest</groupId>
      <artifactId>cocoon-rest</artifactId>
    </dependency>]]></programlisting>
        </section>
        
        <section id="webapps.rest.jaxrs.sample.resource">
          <title>JAX-RS resource</title>
          <para>
            Then at least one JAX-RS resource is required:
          </para>
          <programlistingco>
          <areaspec>
            <area id="webapps.rest.jaxrs.sample.resource.path1" coords="1" />
            <area id="webapps.rest.jaxrs.sample.resource.class" coords="2" />
            <area id="webapps.rest.jaxrs.sample.resource.method" coords="6" />
            <area id="webapps.rest.jaxrs.sample.resource.path2" coords="7" />
            <area id="webapps.rest.jaxrs.sample.resource.param.id" coords="9" />
            <area id="webapps.rest.jaxrs.sample.resource.param.req" coords="10" />
            <area id="webapps.rest.jaxrs.sample.resource.param.uriinfo" coords="11" />
            <area id="webapps.rest.jaxrs.sample.resource.param.request" coords="12" />
            <area id="webapps.rest.jaxrs.sample.resource.data" coords="14" />
            <area id="webapps.rest.jaxrs.sample.resource.responsebuilder" coords="20" />
            <area id="webapps.rest.jaxrs.sample.resource.beansetter" coords="25" />
          </areaspec>
          <programlisting language="java"><![CDATA[@Path("/sample")
public class SampleRestResource {

    private Settings settings;

    @GET
    @Path("/parameter-passing/{id}")
    public Response anotherService(
        @PathParam("id") String id, 
        @QueryParam("req-param") String reqParam,
        @Context UriInfo uriInfo, 
        @Context Request request) {
        
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("name", "Donald Duck");
        data.put("id", id);
        data.put("reqparam", reqParam);
        data.put("runningMode", this.settings.getProperty("testProperty"));

        return URLResponseBuilder.newInstance("servlet:sample:/controller/screen", data)
          .build();
    }

    public void setSettings(Settings settings) {
        this.settings = settings;
    }
}]]></programlisting>
          <calloutlist>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.path1">
              <para>The <literal>@javax.ws.rs.Path</literal> annotation identifies the URI path 
                that this resource class or class method will serve requests for. The path is
                relative to the mount point of the servlet-service that references this resource.
              </para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.class">
              <para>A JAX-RS root resource.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.method">
              <para>The <literal>@javax.ws.rs.GET</literal> annotations indicates that
              this method responds to HTTP GET requests.</para> 
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.path2">
              <para>Again a <literal>@Path</literal> annotation, but this time at
              method level. In this example requests for <literal>sample/parameter-passing/NNN</literal>
              will be handled by the <literal>anotherService()</literal> method.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.param.id">
              <para>The <literal>@PathParam</literal> annoation binds the URI template
              value of <literal>id</literal> to the method parameter <literal>id</literal>.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.param.req">
              <para>The <literal>@QueryParam</literal> annotation binds the request parameter
              <literal>req-param</literal> to the method parameter <literal>reqParam</literal>.
              </para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.param.uriinfo">
              <para>By annotating the <literal>URIInfo</literal> method parameter with the 
                <literal>@Context</literal> annotations, a current instance of <literal>URIInfo</literal>
                is passed to the method.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.param.request">
              <para>By annotating the <literal>Request</literal> method parameter with the 
                <literal>@Context</literal> annotations, a current instance of <literal>Request</literal>
                is passed to the method.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.data">
              <para>A map of <literal>String/Object</literal> is collected.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.responsebuilder">
              <para>The <literal>URLResponseBuilder</literal> sends the result of the
                passed URL as response. It allows passing a map of <literal>String/Object</literal> 
                which are available in the called resource (usually a pipeline).</para>
              <para>In this case the <literal>servlet:</literal> protocol is used.
                It allows accessing URLs (that usually expose pipelines) defined by other
                Servlet-Services.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.resource.beansetter">
              <para>A setter method to allow injecting the <literal>Setting</literal> bean.</para>
            </callout>       
          </calloutlist>
          </programlistingco>        
        </section>
        
        <section id="webapps.rest.jaxrs.sample.spring">
          <title>JAX-RS resource as Spring bean</title>  
          <para>This resource has to be configured as Spring bean:</para>
          <programlistingco>
          <areaspec>
            <area id="webapps.rest.jaxrs.sample.bean.definition" coords="6" />
          </areaspec>
          <programlisting language="xml"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

  <bean id="org.apache.cocoon.sample.rest.resource.one" 
    class="org.apache.cocoon.sample.jaxrs.SampleRestResource">
    <property name="settings" 
      ref="org.apache.cocoon.configuration.Settings" />
  </bean>

</beans>]]></programlisting>
          <calloutlist>
            <callout arearefs="webapps.rest.jaxrs.sample.bean.definition">
              <para>The <literal>SampleRestResource</literal> is a usual Spring bean and in this example it gets
              the <literal>org.apache.cocoon.configuration.Settings</literal> bean injected.</para>
            </callout>
          </calloutlist>
        </programlistingco>
        </section>
        
        <section id="webapps.rest.jaxrs.sample.servlet-service">
          <title>Servlet-Service integration</title>
          <para>Finally the Spring bean has to be exposed by the <literal>CocoonJAXRSServlet</literal>:</para>   
          <programlistingco>
          <areaspec>
            <area id="webapps.rest.jaxrs.sample.servlet-service.definition" coords="10" />
            <area id="webapps.rest.jaxrs.sample.servlet-service.mount-path" coords="12" />
            <area id="webapps.rest.jaxrs.sample.servlet-service.connections" coords="14" />
            <area id="webapps.rest.jaxrs.sample.servlet-service.resources" coords="19" />
          </areaspec>
          <programlisting language="xml"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:servlet="http://cocoon.apache.org/schema/servlet"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://cocoon.apache.org/schema/servlet 
    http://cocoon.apache.org/schema/servlet/cocoon-servlet-1.0.xsd>
  
  <!-- A servlet-service that exposes JAX-RS REST endpoints. -->
  <bean id="org.apache.cocoon.sample.rest.servlet" 
    class="org.apache.cocoon.rest.jaxrs.container.CocoonJAXRSServlet">
    <servlet:context mount-path="/jax-rs" 
      context-path="blockcontext:/cocoon-sample/">
      <servlet:connections>
        <entry key="sample" value-ref="org.apache.cocoon.sample.servlet" />
      </servlet:connections>      
    </servlet:context>
    
    <property name="restResourcesList">
      <list>
        <ref bean="org.apache.cocoon.sample.rest.resource.one" />
      </list>
    </property>
  </bean>
</beans>]]></programlisting>
          <calloutlist>
            <callout arearefs="webapps.rest.jaxrs.sample.servlet-service.definition">
              <para>The <literal>CocoonJAXRSServlet</literal> exposes REST resources.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.servlet-service.mount-path">
              <para>The mount path of this Servlet-Service is <literal>/jax-rs</literal>.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.servlet-service.connections">
              <para>Connections to other Servlet-Services.</para>
            </callout>
            <callout arearefs="webapps.rest.jaxrs.sample.servlet-service.resources">
              <para>A list of JAX-RS resources, which also have to be Spring beans, is
                exposed.</para>
              <para>Alternativly a <literal>&lt;map&gt;</literal> of resources can be injected
                by the <literal>restResourceMap</literal> property.</para>
            </callout>
          </calloutlist>
          </programlistingco>
        </section>
      </section>
    </section>
  </section>

  <section id="webapps.caching">
    <title>Caching and conditional GET requests</title>
    <para>TBW</para>
  </section>

  <section id="webapps.auth">
    <title>Authentication</title>
    <para>TBW</para>
  </section>

  <section id="webapps.testing">
    <title>Testing</title>
    <para>TBW: Integeration tests</para>
  </section>

  <section id="webapps.profiling">
    <title>Profiling support</title>
    <para>
      A cocoon request goes through many components; while performing a Cocoon request, servlets, sitemaps and pipeline 
      components are being executed.  It is also quite common that Cocoon requests are cascaded which makes it sometimes 
      difficult to understand what exactly was happening. Cocoon Profiling enables you to profile any request to your website.</para>
    <section>
      <title>Module configuration</title>
      <para>
        In order to use cocoon-profiling, you simply have to include the <literal>cocoon-profiling jar</literal> in your classpath. 
        Cocoon-profiling uses Spring AOP, so no further configuration is needed.
      </para>
    </section>
    <section>
      <title>Using Cocoon Profiling</title>
      <para>
        Cocoon-profiling provides several generators for xml and graphical output, which is used by the Firebug plugin. 
        However, you can directly access the data using
        <itemizedlist>
          <listitem>
            <para>
              <literal>yourdomain.com/controller/profiling/{id}</literal>  for the xml file (xml schema see 
              <literal>profilingSchema.xsd</literal> in cocoon-profiling)
            </para>
          </listitem>
          <listitem>
            <para>
              <literal>yourdomain.com/controller/profiling/{id}.png</literal> for the graphical representation (example see below)
            </para>
          </listitem>
        </itemizedlist>
        where {id} is the id of the request. This id (<literal>X-Cocoon-Profiling-ID</literal>) can be found in the header of the 
        original request.
      </para>
      <para>
        This is an example for the graphical representation:
      </para>
      <para>
        <mediaobject>
          <imageobject role="html">
            <imagedata fileref="graphics/profilingGraph.jpg" contentwidth="75%" format="JPG"/>
          </imageobject>
          <imageobject role="fo">
            <imagedata fileref="../src/docbkx/reference/graphics/profilingGraph.jpg" format="JPG"/>
          </imageobject>        
        </mediaobject>
      </para>
      <section>
        <title>How can I enable/disable cocoon-profiling on the fly?</title>
        <para>
          Cocoon-profiling is enabled per default. If you just want to use it, you can skip this section. 
        </para>
        <para>
          If you want to start or stop profiling while the server is running, you can use the management bean provided by cocoon-profiling. 
          Cocoon-monitoring automatically exposes this MBean; just make sure that cocoon-monitoring is in your classpath. You can then 
          connect to the server process using jconsole and call the "start" and "stop" method of the org.apache.cocoon.profiling MBean.
        </para>
        <para>
          Keep in mind that cocoon-profiling uses Spring AOP to intercept method calls, which cannot be enabled or disabled at runtime. 
          Therefore, a disabled cocoon-profiling still affects the performance (at least a little bit). Only removing cocoon-profiling 
          from the classpath and restarting the server guarantees maximum performance.
        </para>
      </section>
      <section>
        <title>I need cocoon-profiling to profile my custom cocoon component, how can I do that?</title>
        <para>
          Generally, you don't have to change anything. Cocoon-profiling uses Spring AOP to profile all cocoon components and servlets 
          as well as any subclass or cocoon interface implementation.
        </para>
        <para>
          Advanced users might want to add their own Profiler class to cocoon-profiling if they have a specific component with 
          specific parameters or other bits of data they want cocoon-profiling to collect.
        </para>
      </section>
    </section>
    <section>
      <title>Using Firebug with Cocoon-profiling</title>
      <para>
        Getting the Firebug Plugin able to work is really easy. You'll need to install Firebug 1.4X from 
        <literal>http://getfirebug.com/releases/firebug/1.4X</literal> and then install the Firebug .xpi from 
        cocoon-profiling-firebug (opening it with Firefox should suffice). The generate the xpi from the sources, 
        simply switch to the cocoon-profiling-firebug folder and type <literal>mvn install</literal>. This will 
        automatically build a new xpi. After installing the plugins, you should have a little bug on the bottom 
        right corner of your Firefox. Clicking will open it, then you can navigate to the net-panel (you might want 
        to be sure its activated) and there open up a request (you might need to refresh). In the request, there 
        should be a tab called "Cocoon 3 Profiling", if you click it, and the Profiling Service works, you should 
        now see the generated profiling data.
      </para>
      <para>
        The data itself is presented in two textboxes. The left one is the tree which resembles the .xml that the 
        profiling-component generates, the right one displays the elements, properties, return-values and the profiler
        of a given (= selected) row in the left tree. You can navigate through the left tree, and based on which row 
        you currently have selected, the right textbox will display the names and values. To add some visual help, pictures 
        are being displayed, based on which kind of element is displayed.
      </para>
      <para>
        The underline is:
      </para>
      <para>
        <table id="webapps.profiling.firebug.table" pgwide="0">
          <title>Icons</title>
          <tgroup cols="3">
            <colspec colname="c1"/>
            <colspec colname="c2"/>
            <colspec colname="c3"/>
            <tbody>
              <row>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_argument.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_argument.jpg" format="JPG"/>
                     </imageobject>                         
                    <caption>Argument</caption>
                  </mediaobject>
                </entry>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_component.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_component.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Component</caption>
                  </mediaobject>
                </entry>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_exception.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_exception.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Exception</caption>
                  </mediaobject>
                </entry>
              </row>
              <row>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_invocation.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_invocation.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Invocation</caption>
                  </mediaobject>
                </entry>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_node.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_node.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Node</caption>
                  </mediaobject>
                </entry>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_profiler.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_profiler.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Profiler</caption>
                  </mediaobject>
                </entry>
              </row>
              <row>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_property.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_property.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Property</caption>
                  </mediaobject>
                </entry>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_return.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_return.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Return-value</caption>
                  </mediaobject>
                </entry>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_servlet.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_servlet.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Servlet</caption>
                  </mediaobject>
                </entry>
              </row>
              <row>
                <entry>
                  <mediaobject>
                    <imageobject role="html">
                      <imagedata fileref="graphics/profiling_firebug_sitemap.jpg" format="JPG"/>
                    </imageobject>
                    <imageobject role="fo">
                      <imagedata fileref="../src/docbkx/reference/graphics/profiling_firebug_sitemap.jpg" format="JPG"/>
                     </imageobject>                       
                    <caption>Sitemap</caption>
                  </mediaobject>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </table>
      </para>
      <para>
        You also have two options which can change what you'll be able to see in the Firebug Plugin. 
        These are located on the net Tab Option Panel, which is a little triangle. The options are marked {c3p} 
        and allow you to Show / Hide the Sitemap and to change if the invocations element of the tree is 
        closed or opened. These changes will require a reload, 
        either by reloading your browser, or by clicking the "Reload"-Button in the Profiling Panel.
      </para>
      <para>
        The other button on the panel will open a new tab in your Firefox in which a graphical outline will 
        be shown which lists your components and the execution time of each of these components. Be aware, 
        though, that the first profiling cycle will present you a kind of wrong picture (it takes a lot longer), 
        because of the java-intern class-loading and other administrative stuff. You'll need to reload the request, 
        not the picture, to change this.
      </para>
      <section>
        <title>Customizing your Firebug Plugin</title>
        <para>
          To customize your Firebug Plugin, go to the plugin folder in your Firefox, select the Profiling plugin, 
          then navigate to <literal>chrome\skin\classic\cocoon3profiling.css</literal>. In this css, you can change 
          the heigth and width of the trees and of their columns. Simply navigate to the element you want to change, 
          and change the value in there.
        </para>
      </section>
    </section>
  </section>

  <section id="webapps.monitoring">
    <title>Monitoring support</title>
    <para>
      This module gives you the possibility of monitoring Cocoon 3 applications. It expose a simple API
      via <literal>Spring JMX MBeans</literal> and it can be user via <literal>jconsole</literal>
      or other <literal>JMX</literal> console.
    </para>
    <section id="webapps.monitoring.configuration">
      <title>Module configuration</title>
      <para>
        All module configurations are defined in <literal>META-INF/cocoon/spring/cocoon-monitoring.xml.</literal>
        Each part of module can be enabled or disabled by commenting (or removing) appropriate
        entry in configuration file, by default all parts are enabled.    
      </para>
    </section>
    <section id="webapps.monitoring.parts">
      <title>Available parts</title>
      <section id="webapps.monitoring.logging">
        <title>Inspect logging settings and reconfigure them</title>
        <section>
          <title>Inspect all configured loggers</title>
          <para>
            The operation <code>getLoggers()</code> returns a list of all configured Log4j loggers in the 
            application, it consists of pairs: <literal>&lt;class or package name&gt;</literal> (category)
            => <literal>&lt;logging level&gt;</literal>
          </para>
        </section>
        <section>
          <title>Permanent change of a logging level</title>
          <para>
            For doing permanent changes of logging level for particular class or package use the operation
            <code>setLoggingLevel(String category, String newLogLevel)</code>. Where 
            <literal>Category</literal> is name of <literal>class</literal> or <literal>
            package</literal> with you want to change logging level and <literal>newLogLevel
            </literal> is one of logging level: <literal>OFF</literal>, <literal>INFO</literal>,
            <literal>WARN</literal>, <literal>ERROR</literal>, <literal>FATAL</literal>,
            <literal>TRACE</literal>, <literal>DEBUG</literal>, <literal>ALL</literal> (this parameter
             isn't case sensitive, so you can also use lower case names).
          </para>
        </section>
        <section>
          <title>Temporal change of a logging level</title>
          <para>
            For doing temporal changes of logging level for particular class or package use the operation
            <code>setLoggingTempoporalLevel(String category, String temporalLogLevel, String
            timeOut)</code>. First two parameters are same as in <code>setLoggingLevel()</code>,
            last one determinate how long this logging level should be used (after that amount of
            time logging level would be set back to old level). <literal>timeOut</literal> parameter
            should match regular expression: <literal>^[0-9.]+[dhm]?$</literal>, for example if value
            of <literal>timeOut</literal> is set for <code>1,5h</code> that means that new logging level
            would be active for one and half hour.
          </para>
        </section>
        <section>
          <title>Load a new configuration file</title>
          <para>
            For loading a completely new configuration file use the operation <code>loadNewConfigurationFile(String path)</code>.
            This method is capable for both <literal>XML</literal> and <literal>properties</literal> configuration
            files. There is only one parameter <literal>path</literal> that should contain absolute path to new
            configuration file located locally on the server. Before performning any action that file is validated. First of
            all the file extension (there are only two appropriate extensions: <literal>*.xml</literal>
            and <literal>*.properties</literal>) is checked. The next validation step is different for both files, for 
            <literal>XML</literal> files its content is validated against the Log4j <literal>DTD</literal> or
            <literal>schema</literal> then all output log files are checked that they exist and they are writable.
            <literal>Properties</literal> configuration files are validated that they contain at least one
            appender and each output file directory exists and is writable. These validations are done to
            prevent Log4j to get into an inconsistent state. 
          </para>
        </section>
      </section>
      <section id="webapps.monitoring.servletservices">
        <title>Inspect available Servlet-Services</title>
        <para>
          Every single Servlet-Service makes his own node in JXM MBean tree. Such node contains below above functions.
        </para>
        <section>
          <title>Get path of Servlet-Services</title>
          <para>
            Function <code>getServletServiceMountPaths()</code> returns Servlet-Service mount path.
          </para>
        </section>
        <section>
          <title>Get all connections for Servlet-Service</title>
          <para>
            Function <code>getServletServiceConnections()</code> returns an array of <code>String</code> contains
            all connections names for given Servlet-Service. Every connection is represented by: <literal>
            &lt;short name&gt;</literal> => <literal>&lt;full qualified bean name&gt;</literal>
          </para>
        </section>
        <section>
          <title>Get informations about Servlet-Service</title>
          <para>
            Function <code>getServletServiceInfo()</code> returns information about Servlet-Service, such as author,
            version, and copyright.
          </para>
        </section>
        <section>
          <title>List Servlet-Service parameters</title>
          <para>
            Function <code>getServletServiceInitParameters()</code> list all init parameters provided for that
            Servlet-Service.
          </para>
        </section>
      </section>
      <section id="webapps.monitoring.cacheoverview">
        <title>Overview of cache entries</title>
        <para>
          This module contains three smaller submodules:
          <simplelist>
            <member><link linkend="webapps.monitoring.cacheoverview.cachemonitor">CacheMonitor</link></member>
            <member><link linkend="webapps.monitoring.cacheoverview.cacheburstactions">CacheBurstActions</link></member>
            <member><link linkend="webapps.monitoring.cacheoverview.cacheentrysmonitor">CacheEntrysMonitor</link></member>
          </simplelist>
        </para>
        <section id="webapps.monitoring.cacheoverview.cachemonitor">
          <title>CacheMonitor</title>
          <para>
            This submodule exposes all configured caches on with basic operations on every cache.
          </para>
          <section>
            <title>Clear cache</title>
            <para>
              Operation <literal>clear()</literal> remove all cache entry's from this particular cache.
            </para>
          </section>
          <section>
            <title>List all cache key</title>
            <para>
              Operation <literal>listKey()</literal> returns list of all <literal>CacheKey</literal>s that are stored in this particular cache.
            </para>
          </section>
          <section>
            <title>Removing cache entry</title>
            <para>
              If you want remove single cache entry you should use operation <literal>removeKey(String)</literal>, where parameter is
              <literal>CacheKey</literal> name taken from <literal>listKey()</literal> result. This operation returns <literal>true</literal>
              if it was successes otherwise it return <literal>false</literal>.
            </para>
          </section>
          <section>
            <title>Checking size of cache</title>
            <para>
              It is also possible to check size of particular cache using function <literal>size</literal>. It will return human readable
              size of this cache.
            </para>
          </section>
        </section>
        <section id="webapps.monitoring.cacheoverview.cacheburstactions">
          <title>CacheBurstActions</title>
          <para>
            This module add set of operations that can be performed on all caches. You can find and remove all cache entry's which meet certain
            requirements, specified in operation parameters.
          </para>
          <section>
            <title>Find all cache entry's that size is greater then specified value</title>
            <para>
              Operation <literal>listAllGreatherThen(long)</literal> finds all cache entry's in all configured cache's that size (in bytes)
              is greather then value passed as a parameter.
            </para>
          </section>
          <section>
            <title>Find all cache entry's that size is smaller then specified value</title>
            <para>
              Operation <literal>listAllSmalledThen(long)</literal> finds all cache entry's in all configured cache's that size (in bytes) is
              smaller then value passed as a parameter.
            </para>
          </section>
          <section>
            <title>Find all cache entry's that are older then specified date</title>
            <para>
              Operation <literal>listAllOlderThen(String)</literal> finds all cache entry's in all configured cache's that are older then
              value specified in a parameter. Parameter value must match regular expression: <literal>^\d+[smhd]$</literal> where each
              letter stands for:
              <simplelist>
                <member>s - second</member>
                <member>m - minutes</member>
                <member>h - hours</member>
                <member>d - days</member>
              </simplelist>
            </para>
          </section>
          <section>
            <title>Find all cache entry's that are younger then specified date</title>
            <para>
              Operation <literal>listAllYoungerThen(String)</literal> finds all cache entry's in all configured cache's that are younger
              then value specified in a parameter. For parameter description see <literal>listAllOlderThen(String)</literal>.
            </para>
          </section>
          <section>
            <title>More flexible cache entry's search</title>
            <para>
              If you want to get more flexibility searching you can use <literal>list(long, long, String, String, Sting, Sting)</literal>.
              First two <literal>long</literal> parameters limits cache entry's size, their minimum and maximum size. Second two
              <literal>String</literal> parameters limits cache entry minimum and maximum age (syntax is same as in
              <literal>listAllOlderThen(Sting)</literal> and <literal>listAllYoungerThen(String)</literal> functions). Last two
              <literal>String</literal> parameters are applicable only to <literal>ExpiresCacheKey</literal> instances and they limit
              result entry's on minimum and maximum experience time of entry. Every result entry meets all limitations. For excluding one
              (or more) limitation you must pas value -1 for <literal>long</literal> parameters and <literal>null</literal> or empty
              <literal>String</literal> for rest parameters.
            </para>
          </section>
          <section>
            <title>Remove all cache entry's that size is greater then specified value</title>
            <para>
              Operation <literal>clearAllGreatherThen(long)</literal> perform same search action as <literal>listAllGratherThen(long)</literal>
              but it removes cache entry's that fulfilled requirements instead of listing them. It will return <literal>true</literal> if
              every cache entry was successfully removed, after first failure of removing cache entry this operation will stop and return
              <literal>false</literal>.
            </para>
          </section>
          <section>
            <title>Remove all cache entry's that size is smaller then specified value.</title>
            <para>
              Operation <literal>clearAllSmallerThen(long)</literal> perform same search action as <literal>listAllSmallerThen(long)</literal>
              but it removes cache entry's that fulfilled requirements instead of listing them. It will return <literal>true</literal> if
              every cache entry was successfully removed, after first failure of removing cache entry this operation will stop and return
              <literal>false</literal>.
            </para>
          </section>
          <section>
            <title>Remove all cache entry's that are older then specified value.</title>
            <para>
              Operation <literal>clearAllOlderThen(String)</literal> perform same search action as <literal>listAllOlderThen(String)</literal>
              but it remove cache etry's that fulfilled requirements instead of listing them, this operation also require same parameter schema
              as in <literal>listAllOlderThen(String)</literal>. It will return <literal>true</literal> if every cache entry was successfully
              removed, after first failure of removing cache entry this operation will stop and return
              <literal>false</literal>.
            </para>
          </section>
          <section>
            <title>Remove all cache entry's that are younger then specified value.</title>
            <para>
              Operation <literal>clearAllYoungerThen(String)</literal> perform same search action as <literal>listAllYoungerThen(String)</literal>
              but it remove cache etry's that fulfilled requirements instead of listing them, this operation also require same parameter schema
              as in <literal>listAllYoungerThen(String)</literal>. It will return <literal>true</literal> if every cache entry was successfully
              removed, after first failure of removing cache entry this operation will stop and return
              <literal>false</literal>.
            </para>
          </section>
          <section>
            <title>More flexible cache entry's removing</title>
            <para>
              Operation <literal>clear(long, long, String, String, String, String)</literal> perform same search action and takes same parameters
              as described above <literal>list(long, long, String, String, String)</literal> please see it if you are looking for detailed description.
            </para>
          </section>
          <section>
            <title>Extending BurstCacheAction module</title>
            <para>
              You can add your own burst actions. It is very simple, just obtain instance of <literal>org.apache.cocoon.monitoring.cache.CacheBurstActions</literal>
              from the container and you can perform any action on cache entry's using <literal>performActionOnCaches(long, long, String, String,
              String, String, CacheAction)</literal> method. Meaning of each parameter in this method is same as in <literal>list(long, long, String,
              String, String, String)</literal> and <literal>clear(long, long, String, String, String, String)</literal> methods, but there is one
              additional parameter, it is implementation of <literal>CacheAction</literal> interface. This interface has only one method
              <literal>performAction(Cache, CacheKey)</literal> and it will be executed on every cache entry that match passed parameters.
            </para>
          </section>
        </section>
        <section id="webapps.monitoring.cacheoverview.cacheentrysmonitor">
          <title>CacheEntrysMonitor</title>
          <para>
            This module enables overview of cache entry's that are connected with specified pipeline. This module will only publish cache entry's for
            those pipeline's that had <literal>jmx-group-id</literal> parameter set for unique value/name. This module also require additional refresh
            action, it can be performed by user or it can be executed in some period of time eg every one minute. Behavior of refresh action can be
            configured by <literal>CacheEntrysMonitorInitializer</literal> constructor parameter or on JMX.
          </para>
          <section>
            <title>Configuring refresh action</title>
            <para>
              <literal>AutoRefresh</literal> action can be enabled and disabled during runtime. This action will register new <literal>MBean</literal>s
              that are connected with new cache entry's and unregister old <literal>MBean</literal>s that was connected with expired or removed
              cache entry's.
            </para>
            <section>
              <title>Enable <literal>AutoRefresh</literal> action</title>
              <para>
                For enable <literal>AutoRefresh</literal> action call operation <literal>enableAutoRefresh(long)</literal> where <literal>long</literal>
                parameter is period time (in millisecond) between each refresh. This operation will stop previously configured <literal>AutoRefresh</literal>
                action and run new with new time period.
              </para>
            </section>
            <section>
              <title>Disable <literal>AutoRefresh</literal> action</title>
              <para>
                Operation <literal>disableAutoRefresh()</literal> will stops actual running <literal>AutoRefresh</literal> action.
              </para>
            </section>
            <section>
              <title>Manually perform refresh action</title>
              <para>
                Operation <literal>performRefreshAction()</literal> will immediately refre's published cache entry's.
              </para>
            </section>
          </section>
          <section>
            <title>Cache entry's operations</title>
            <para>
              On each published cache entry you can perform that set of actions:
            </para>
            <section>
              <title>Obtain <literal>CacheKey</literal> for that entry</title>
              <para>
                Operation <literal>getCacheKey()</literal> will return <literal>CacheKey</literal> connected with that entry.
              </para>
            </section>
            <section>
              <title>Obtain cache value</title>
              <para>
                Operation <literal>getCacheValue()</literal> will return value of this cache entry.
              </para>
            </section>
            <section>
              <title>Set cache value</title>
              <para>
                Operation <literal>setCacheValue(String)</literal> will set new value of this cache entry.
              </para>
            </section>
            <section>
              <title>Obtain size of entry</title>
              <para>
                Operation <literal>getSize()</literal> will return human readable size of current entry.
              </para>
            </section>
          </section>
        </section>
      </section>
    </section>
  </section>
  
  <section id="webapps.tutorial">
    <title>Tutorial</title>
    <para>TBW</para>
  </section>
</chapter>
