<?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.
-->
<!-- $Id$ -->
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
<document>
  <header>
    <title>Apache™ FOP: Events/Processing Feedback</title>
    <version>$Revision$</version>
  </header>
  <body>
    <section id="introduction">
      <title>Introduction</title>
      <p>
        In versions until 0.20.5, Apache™ FOP used
        <a href="http://excalibur.apache.org/framework/index.html">Avalon-style Logging</a> where
        it was possible to supply a logger per processing run. During the redesign
        the logging infrastructure was switched over to
        <a href="http://commons.apache.org/logging/">Commons Logging</a> which is (like Log4J or
        java.util.logging) a "static" logging framework (the logger is accessed through static
        variables). This made it very difficult in a multi-threaded system to retrieve information
        for a single processing run.
      </p>
      <p>
        With FOP's event subsystem, we'd like to close this gap again and even go further. The
        first point is to realize that we have two kinds of "logging". Firstly, we have the logging
        infrastructure for the (FOP) developer who needs to be able to enable finer log messages
        for certain parts of FOP to track down a certain problem. Secondly, we have the user who
        would like to be informed about missing images, overflowing lines or substituted fonts.
        These messages (or events) are targeted at less technical people and may ideally be
        localized (translated). Furthermore, tool and solution builders would like to integrate
        FOP into their own solutions. For example, an FO editor should be able to point the user
        to the right place where a particular problem occurred while developing a document template.
        Finally, some integrators would like to abort processing if a resource (an image or a font)
        has not been found, while others would simply continue. The event system allows to
        react on these events.
      </p>
      <p>
        On this page, we won't discuss logging as such. We will show how the event subsystem can
        be used for various tasks. We'll first look at the event subsystem from the consumer side.
        Finally, the production of events inside FOP will be discussed (this is mostly interesting
        for FOP developers only).
      </p>
    </section>
    <section id="consumer">
      <title>The consumer side</title>
      <p>
        The event subsystem is located in the <code>org.apache.fop.events</code> package and its
        base is the <code>Event</code> class. An instance is created for each event and is sent
        to a set of <code>EventListener</code> instances by the <code>EventBroadcaster</code>.
        An <code>Event</code> contains:
      </p>
      <ul>
        <li>an event ID,</li>
        <li>a source object (which generated the event),</li>
        <li>a severity level (Info, Warning, Error and Fatal Error) and</li>
        <li>a map of named parameters.</li>
      </ul>
      <p>
        The <code>EventFormatter</code> class can be used to translate the events into
        human-readable, localized messages.
      </p>
      <p>
        A full example of what is shown here can be found in the
        <code>examples/embedding/java/embedding/events</code> directory in the FOP distribution.
        The example can also be accessed
        <a href="http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/examples/embedding/java/embedding/events/">via the web</a>.
      </p>
      <section id="write-listener">
        <title>Writing an EventListener</title>
        <p>
          The following code sample shows a very simple EventListener. It basically just sends
          all events to System.out (stdout) or System.err (stderr) depending on the event severity.
        </p>
        <source><![CDATA[import org.apache.fop.events.Event;
import org.apache.fop.events.EventFormatter;
import org.apache.fop.events.EventListener;
import org.apache.fop.events.model.EventSeverity;

/** A simple event listener that writes the events to stdout and stderr. */
public class SysOutEventListener implements EventListener {

    /** {@inheritDoc} */
    public void processEvent(Event event) {
        String msg = EventFormatter.format(event);
        EventSeverity severity = event.getSeverity();
        if (severity == EventSeverity.INFO) {
            System.out.println("[INFO ] " + msg);
        } else if (severity == EventSeverity.WARN) {
            System.out.println("[WARN ] " + msg);
        } else if (severity == EventSeverity.ERROR) {
            System.err.println("[ERROR] " + msg);
        } else if (severity == EventSeverity.FATAL) {
            System.err.println("[FATAL] " + msg);
        } else {
            assert false;
        }
    }
}]]></source>
        <p>
          You can see that for every event the method <code>processEvent</code> of the
          <code>EventListener</code> will be called. Inside this method you can do whatever
          processing you would like including throwing a <code>RuntimeException</code>, if you want
          to abort the current processing run.
        </p>
        <p>
          The code above also shows how you can turn an event into a human-readable, localized
          message that can be presented to a user. The <code>EventFormatter</code> class does
          this for you. It provides additional methods if you'd like to explicitly specify
          the locale.
        </p>
        <p>
          It is possible to gather all events for a whole processing run so they can be
          evaluated afterwards. However, care should be taken about memory consumption since
          the events provide references to objects inside FOP which may themselves have
          references to other objects. So holding on to these objects may mean that whole
          object trees cannot be released!
        </p>
      </section>
      <section id="add-listener">
        <title>Adding an EventListener</title>
        <p>
          To register the event listener with FOP, get the <code>EventBroadcaster</code> which
          is associated with the user agent (<code>FOUserAgent</code>) and add it there:
        </p>
        <source><![CDATA[FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
foUserAgent.getEventBroadcaster().addEventListener(new SysOutEventListener());]]></source>
        <p>
          Please note that this is done separately for each processing run, i.e. for each
          new user agent.
        </p>
      </section>
      <section id="listener-example1">
        <title>An additional listener example</title>
        <p>
          Here's an additional example of an event listener:
        </p>
        <p>
          By default, FOP continues processing even if an image wasn't found. If you have
          more strict requirements and want FOP to stop if an image is not available, you can
          do something like the following in the simplest case:
        </p>
        <source><![CDATA[public class MyEventListener implements EventListener {

    public void processEvent(Event event) {
        if ("org.apache.fop.ResourceEventProducer".equals(
                event.getEventGroupID())) {
            event.setSeverity(EventSeverity.FATAL);
        } else {
            //ignore all other events (or do something of your choice)
        }
    }
    
}]]></source>
        <p>
          Increasing the event severity to FATAL will signal the event broadcaster to throw
          an exception and stop further processing. In the above case, all resource-related
          events will cause FOP to stop processing.
        </p>
        <p>
          You can also customize the exception to throw (you can may throw a RuntimeException
          or subclass yourself) and/or which event to respond to:
        </p>
        <source><![CDATA[public class MyEventListener implements EventListener {

    public void processEvent(Event event) {
        if ("org.apache.fop.ResourceEventProducer.imageNotFound"
                .equals(event.getEventID())) {
            
            //Get the FileNotFoundException that's part of the event's parameters
            FileNotFoundException fnfe = (FileNotFoundException)event.getParam("fnfe");

            throw new RuntimeException(EventFormatter.format(event), fnfe);
        } else {
            //ignore all other events (or do something of your choice)
        }
    }
    
}]]></source>
        <p>
          This throws a <code>RuntimeException</code> with the <code>FileNotFoundException</code>
          as the cause. Further processing effectively stops in FOP. You can catch the exception
          in your code and react as you see necessary.
        </p>
      </section>
    </section>
    <section id="producer">
      <title>The producer side (for FOP developers)</title>
      <p>
        This section is primarily for FOP and FOP plug-in developers. It describes how to use
        the event subsystem for producing events.
      </p>
      <note>
        The event package has been designed in order to be theoretically useful for use cases
        outside FOP. If you think this is interesting independently from FOP, please talk to
        <a href="mailto:fop-dev@xmlgraphics.apache.org">us</a>.
      </note>
      <section id="basic-event-production">
        <title>Producing and sending an event</title>
        <p>
          The basics are very simple. Just instantiate an <code>Event</code> object and fill
          it with the necessary parameters. Then pass it to the <code>EventBroadcaster</code>
          which distributes the events to the interested listeneners. Here's a code example:
        </p>
        <source><![CDATA[Event ev = new Event(this, "complain", EventSeverity.WARN,
        Event.paramsBuilder()
            .param("reason", "I'm tired")
            .param("blah", new Integer(23))
            .build());
EventBroadcaster broadcaster = [get it from somewhere];
broadcaster.broadcastEvent(ev);
]]></source>
        <p>
          The <code>Event.paramsBuilder()</code> is a
          <a href="http://en.wikipedia.org/wiki/Fluent_interface">fluent interface</a>
          to help with the build-up of the parameters. You could just as well instantiate a
          <code>Map</code> (<code>Map&lt;String, Object&gt;</code>) and fill it with values.
        </p>
      </section>
      <section id="event-producer">
        <title>The EventProducer interface</title>
        <p>
          To simplify event production, the event subsystem provides the <code>EventProducer</code>
          interface. You can create interfaces which extend <code>EventProducer</code>. These
          interfaces will contain one method per event to be generated. By contract, each event
          method must have as its first parameter a parameter named "source" (Type Object) which
          indicates the object that generated the event. After that come an arbitrary number of
          parameters of any type as needed by the event.
        </p>
        <p>
          The event producer interface does not need to have any implementation. The implementation
          is produced at runtime by a dynamic proxy created by <code>DefaultEventBroadcaster</code>.
          The dynamic proxy creates <code>Event</code> instances for each method call against
          the event producer interface. Each parameter (except "source") is added to the event's
          parameter map.
        </p>
        <p>
          To simplify the code needed to get an instance of the event producer interface it is
          suggested to create a public inner provider class inside the interface.
        </p>
        <p>
          Here's an example of such an event producer interface:
        </p>
        <source><![CDATA[public interface MyEventProducer extends EventProducer {

    public class Provider {
        
        public static MyEventProducer get(EventBroadcaster broadcaster) {
            return (MyEventProducer)broadcaster.getEventProducerFor(MyEventProducer.class);
        }
    }

    /**
     * Complain about something.
     * @param source the event source
     * @param reason the reason for the complaint
     * @param blah the complaint
     * @event.severity WARN
     */
    void complain(Object source, String reason, int blah);
    
}]]></source>
        <p>
          To produce the same event as in the first example above, you'd use the following code:
        </p>
        <source><![CDATA[EventBroadcaster broadcaster = [get it from somewhere];
TestEventProducer producer = TestEventProducer.Provider.get(broadcaster);
producer.complain(this, "I'm tired", 23);]]></source>
      </section>
      <section id="event-model">
        <title>The event model</title>
        <p>
          Inside an invocation handler for a dynamic proxy, there's no information about
          the names of each parameter. The JVM doesn't provide it. The only thing you know is
          the interface and method name. In order to properly fill the <code>Event</code>'s
          parameter map we need to know the parameter names. These are retrieved from an
          event object model. This is found in the <code>org.apache.fop.events.model</code>
          package. The data for the object model is retrieved from an XML representation of the
          event model that is loaded as a resource. The XML representation is generated using an
          Ant task at build time (<code>ant resourcegen</code>). The Ant task (found in
          <code>src/codegen/java/org/apache/fop/tools/EventProducerCollectorTask.java</code>)
          scans FOP's sources for descendants of the <code>EventProducer</code> interface and
          uses <a href="http://qdox.codehaus.org/">QDox</a> to parse these interfaces.
        </p>
        <p>
          The event model XML files are generated during build by the Ant task mentioned above when
          running the "resourcegen" task. So just run <code>"ant resourcegen"</code> if you receive
          a <code>MissingResourceException</code> at runtime indicating that
          <code>"event-model.xml"</code> is missing.
        </p>
        <p>
          Primarily, the QDox-based collector task records the parameters' names and types.
          Furthermore, it extracts additional attributes embedded as Javadoc comments from
          the methods. At the moment, the only such attribute is "@event.severity" which indicates
          the default event severity (which can be changed by event listeners). The example event
          producer above shows the Javadocs for an event method.
        </p>
        <p>
          There's one more information that is extracted from the event producer information for
          the event model: an optional primary exception. The first exception in the "throws"
          declaration of an event method is noted. It is used to throw an exception from
          the invocation handler if the event has an event severity of "FATAL" when all
          listeners have been called (listeners can update the event severity). Please note
          that an implementation of
          <code>org.apache.fop.events.EventExceptionManager$ExceptionFactory</code> has to be
          registered for the <code>EventExceptionManager</code> to be able to construct the
          exception from an event.
        </p>
        <p>
          For a given application, there can be multiple event models active at the same time.
          In FOP, each renderer is considered to be a plug-in and provides its own specific
          event model. The individual event models are provided through an
          <code>EventModelFactory</code>. This interface is implemented for each event model
          and registered through the service provider mechanism
          (see the <a href="#plug-ins">plug-ins section</a> for details).
        </p>
      </section>
      <section id="event-severity">
        <title>Event severity</title>
        <p>
          Four different levels of severity for events has been defined:
        </p>
        <ol>
          <li>INFO: informational only</li>
          <li>WARN: a Warning</li>
          <li>ERROR: an error condition from which FOP can recover. FOP will continue processing.</li>
          <li>FATAL: a fatal error which causes an exception in the end and FOP will stop processing.</li>
        </ol>
        <p>
          Event listeners can choose to ignore certain events based on their event severity.
          Please note that you may recieve an event "twice" in a specific case: if there is
          a fatal error an event is generated and sent to the listeners. After that an exception
          is thrown with the same information and processing stops. If the fatal event is
          shown to the user and the following exception is equally presented to the user it
          may appear that the event is duplicated. Of course, the same information is just
          published through two different channels.
        </p>
      </section>
      <section id="plug-ins">
        <title>Plug-ins to the event subsystem</title>
        <p>
          The event subsystem is extensible. There are a number of extension points:
        </p>
        <ul>
          <li>
            <strong><code>org.apache.fop.events.model.EventModelFactory</code>:</strong> Provides
            an event model to the event subsystem.
          </li>
          <li>
            <strong><code>org.apache.fop.events.EventExceptionManager$ExceptionFactory</code>:</strong>
            Creates exceptions for events, i.e. turns an event into a specific exception.
          </li>
        </ul>
        <p>
          The names in bold above are used as filenames for the service provider files that
          are placed in the <code>META-INF/services</code> directory. That way, they are
          automatically detected. This is a mechanism defined by the
          <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Service%20Provider">JAR file specification</a>.
        </p>
      </section>
      <section id="l10n">
        <title>Localization (L10n)</title>
        <p>
          One goal of the event subsystem was to have localized (translated) event messages.
          The <code>EventFormatter</code> class can be used to convert an event to a
          human-readable message. Each <code>EventProducer</code> can provide its own XML-based
          translation file. If there is none, a central translation file is used, called
          "EventFormatter.xml" (found in the same directory as the <code>EventFormatter</code>
          class).
        </p>
        <p>
          The XML format used by the <code>EventFormatter</code> is the same as
          <a href="ext:cocoon">Apache Cocoon's</a> catalog format. Here's an example:
        </p>
        <source><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<catalogue xml:lang="en">
  <message key="locator">
    [ (See position {loc})| (See {#gatherContextInfo})| (No context info available)]
  </message>
  <message key="org.apache.fop.render.rtf.RTFEventProducer.explicitTableColumnsRequired">
    RTF output requires that all table-columns for a table are defined. Output will be incorrect.{{locator}}
  </message>
  <message key="org.apache.fop.render.rtf.RTFEventProducer.ignoredDeferredEvent">
    Ignored deferred event for {node} ({start,if,start,end}).{{locator}}
  </message>
</catalogue>
]]></source>
        <p>
          The example (extracted from the RTF handler's event producer) has message templates for
          two event methods. The class used to do variable replacement in the templates is
          <code>org.apache.fop.util.text.AdvancedMessageFormat</code> which is more powerful
          than the <code>MessageFormat</code> classes provided by the Java class library
          (<code>java.util.text</code> package).
        </p>
        <p>
          "locator" is a template that is reused by the other message templates
          by referencing it through "{{locator}}". This is some kind of include command.
        </p>
        <p>
          Normal event parameters are accessed by name inside single curly braces, for example:
          "{node}". For objects, this format just uses the <code>toString()</code> method to turn
          the object into a string, unless there is an <code>ObjectFormatter</code> registered
          for that type (there's an example for <code>org.xml.sax.Locator</code>).
        </p>
        <p>
          The single curly braces pattern supports additional features. For example, it is possible
          to do this: "{start,if,start,end}". "if" here is a special field modifier that evaluates
          "start" as a boolean and if that is true returns the text right after the second comma
          ("start"). Otherwise it returns the text after the third comma ("end"). The "equals"
          modifier is similar to "if" but it takes as an additional (comma-separated) parameter
          right after the "equals" modifier, a string that is compared to the value of the variable.
          An example: {severity,equals,EventSeverity:FATAL,,some text} (this adds "some text" if
          the severity is not FATAL).
        </p>
        <p>
          Additional such modifiers can be added by implementing the
          <code>AdvancedMessageFormat$Part</code> and <code>AdvancedMessageFormat$PartFactory</code>
          interfaces.
        </p>
        <p>
          Square braces can be used to specify optional template sections. The whole section will
          be omitted if any of the variables used within are unavailable. Pipe (|) characters can
          be used to specify alternative sub-templates (see "locator" above for an example).
        </p>
        <p>
          Developers can also register a function (in the above example:
          <code>{#gatherContextInfo})</code>
          to do more complex information rendering. These functions are implementations of the
          <code>AdvancedMessageFormat$Function</code> interface. Please take care that this is
          done in a locale-independent way as there is no locale information available, yet.
        </p>
      </section>
    </section>
  </body>
</document>