You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by su...@apache.org on 2010/12/13 12:12:59 UTC

svn commit: r1045064 - /synapse/trunk/java/src/site/xdoc/Synapse_Extending.xml

Author: supun
Date: Mon Dec 13 11:12:58 2010
New Revision: 1045064

URL: http://svn.apache.org/viewvc?rev=1045064&view=rev
Log:
applying SYNAPSE-711 many thanks udayanga for the contribution

Modified:
    synapse/trunk/java/src/site/xdoc/Synapse_Extending.xml

Modified: synapse/trunk/java/src/site/xdoc/Synapse_Extending.xml
URL: http://svn.apache.org/viewvc/synapse/trunk/java/src/site/xdoc/Synapse_Extending.xml?rev=1045064&r1=1045063&r2=1045064&view=diff
==============================================================================
--- synapse/trunk/java/src/site/xdoc/Synapse_Extending.xml (original)
+++ synapse/trunk/java/src/site/xdoc/Synapse_Extending.xml Mon Dec 13 11:12:58 2010
@@ -6,519 +6,837 @@
     </properties>
     <head>
         <style type="text/css" xml:space="preserve">
-    .command {
-        border: 1px dashed #3c78b5;
-        text-align: left;
-        background-color: #f0f0f0;
-        padding: 3px;
-        font-size: 11px;
-        font-family: Courier;
-        margin: 10px;
-        line-height: 13px;
-    }
-    .consoleOutput {
-        border: 1px dashed #3c78b5;
-        font-size: 11px;
-        font-family: Courier;
-        margin: 10px;
-        line-height: 13px;
-        background-color: #f0f0f0;
-        border-bottom: 1px dashed #3c78b5;
-        padding: 3px;
-        border-style: solid;
-    }
-    .info {
-        border-style: solid;
-        border-width: 1px;
-        border-color: #090;
-        background-color: #dfd;
-        text-align:left;
-        margin-top: 5px;
-        margin-bottom: 5px;
-    }
-    li {
-        font-family: Verdana, arial, sans-serif;
-        font-size: 11px;
-        line-height: 16px;
-        color: #000000;
-        font-weight: normal;
-    }
-    p {
-        font-family: Verdana, arial, sans-serif;
-        font-size: 11px;
-        line-height: 16px;
-        color: #000000;
-        font-weight: normal;
-    }
-    pre {
-        padding: 0px;
-        margin-top: 5px;
-        margin-left: 15px;
-        margin-bottom: 5px;
-        margin-right: 5px;
-        text-align: left;
-        background-color: #f0f0f0;
-        padding: 3px;
-        border: 1px dashed #3c78b5;
-        font-size: 11px;
-        font-family: Courier;
-        margin: 10px;
-        line-height: 13px;
-    }
-    h1 {
-        font-size: 24px;
-        line-height: normal;
-        font-weight: bold;
-        background-color: #f0f0f0;
-        color: #003366;
-        border-bottom: 1px solid #3c78b5;
-        padding: 2px;
-        margin: 36px 0px 4px 0px;
-    }
-    h2 {
-        font-size: 18px;
-        line-height: normal;
-        font-weight: bold;
-        background-color: #f0f0f0;
-        border-bottom: 1px solid #3c78b5;
-        padding: 2px;
-        margin: 27px 0px 4px 0px;
-    }
-    h3 {
-        font-size: 14px;
-        line-height: normal;
-        font-weight: bold;
-        background-color: #f0f0f0;
-        padding: 2px;
-        margin: 21px 0px 4px 0px;
-    }
-    h4 {
-        font-size: 12px;
-        line-height: normal;
-        font-weight: bold;
-        background-color: #f0f0f0;
-        padding: 2px;
-        margin: 18px 0px 4px 0px;
-    }</style>
+            .command {
+            border: 1px dashed #3c78b5;
+            text-align: left;
+            background-color: #f0f0f0;
+            padding: 3px;
+            font-size: 11px;
+            font-family: Courier;
+            margin: 10px;
+            line-height: 13px;
+            }
+            .consoleOutput {
+            border: 1px dashed #3c78b5;
+            font-size: 11px;
+            font-family: Courier;
+            margin: 10px;
+            line-height: 13px;
+            background-color: #f0f0f0;
+            border-bottom: 1px dashed #3c78b5;
+            padding: 3px;
+            border-style: solid;
+            }
+            .info {
+            border-style: solid;
+            border-width: 1px;
+            border-color: #090;
+            background-color: #dfd;
+            text-align:left;
+            margin-top: 5px;
+            margin-bottom: 5px;
+            }
+            li {
+            font-family: Verdana, arial, sans-serif;
+            font-size: 11px;
+            line-height: 16px;
+            color: #000000;
+            font-weight: normal;
+            }
+            p {
+            font-family: Verdana, arial, sans-serif;
+            font-size: 11px;
+            line-height: 16px;
+            color: #000000;
+            font-weight: normal;
+            }
+            pre {
+            padding: 0px;
+            margin-top: 5px;
+            margin-left: 15px;
+            margin-bottom: 5px;
+            margin-right: 5px;
+            text-align: left;
+            background-color: #f0f0f0;
+            padding: 3px;
+            border: 1px dashed #3c78b5;
+            font-size: 11px;
+            font-family: Courier;
+            margin: 10px;
+            line-height: 13px;
+            }
+            h1 {
+            font-size: 24px;
+            line-height: normal;
+            font-weight: bold;
+            background-color: #f0f0f0;
+            color: #003366;
+            border-bottom: 1px solid #3c78b5;
+            padding: 2px;
+            margin: 36px 0px 4px 0px;
+            }
+            h2 {
+            font-size: 18px;
+            line-height: normal;
+            font-weight: bold;
+            background-color: #f0f0f0;
+            border-bottom: 1px solid #3c78b5;
+            padding: 2px;
+            margin: 27px 0px 4px 0px;
+            }
+            h3 {
+            font-size: 14px;
+            line-height: normal;
+            font-weight: bold;
+            background-color: #f0f0f0;
+            padding: 2px;
+            margin: 21px 0px 4px 0px;
+            }
+            h4 {
+            font-size: 12px;
+            line-height: normal;
+            font-weight: bold;
+            background-color: #f0f0f0;
+            padding: 2px;
+            margin: 18px 0px 4px 0px;
+            }
+        </style>
     </head>
-  <body>
-    <div style="margin-top:-40px; float:right; _margin-top:0px;">
-      <img alt="Synapse logo"
-           src="images/synapse-logo-web2.png" width="197"
-           height="82"/>
-    </div>
-    <div>
-      <h1>
-        Apache Synapse ESB - Extending...
-      </h1>
-    </div>
-    <h2>
-      Writing custom Mediator implementations
-    </h2>
-    <p>
-      The primary interface of the Synapse API is the MessageContext interface
-      defined below. This essentially defines the per-message context passed
-      through the chain of mediators, for each and every message received and
-      processed by Synapse. Each message instance is wrapped within a
-      MessageContext instance, and the message context is set with the
-      references to the SynapseConfiguration and SynapseEnvironment objects. The
-      <a href="apidocs/org/apache/synapse/config/SynapseConfiguration.html">SynapseConfiguration</a>
-      object holds the global configuration model that defines
-      mediation rules, local registry entries and other and configuration, while
-      the <a href="apidocs/org/apache/synapse/core/SynapseEnvironment.html">SynapseEnvironment</a>
-      object gives access to the underlying SOAP implementation used -
-      Axis2. A typical mediator would need to manipulate the MessageContext by
-      referring to the SynapseConfiguration. However it is strongly recommended
-      that the SynapseConfiguration is not updated by mediator instances as it
-      is shared by all messages, and may be updated by Synapse administration or
-      configuration modules. Mediator instances may store local message
-      properties into the MessageContext for later retrieval by successive
-      mediators.<br/>
-    </p>
-    <h4>
-      <a
-      href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/MessageContext.java?view=markup">MessageContext
-      Interface</a>
-    </h4>
-    <p/>
-<pre xml:space="preserve">package org.apache.synapse;
-
-import ...
-
-public interface MessageContext {
-
-    /**
-     * Get a reference to the current SynapseConfiguration
-     *
-     * @return the current synapse configuration
-     */
-    public SynapseConfiguration getConfiguration();
-
-    /**
-     * Set or replace the Synapse Configuration instance to be used. May be used to
-     * programatically change the configuration at runtime etc.
-     *
-     * @param cfg The new synapse configuration instance
-     */
-    public void setConfiguration(SynapseConfiguration cfg);
-
-    /**
-     * Returns a reference to the host Synapse Environment
-     * @return the Synapse Environment
-     */
-    public SynapseEnvironment getEnvironment();
-
-    /**
-     * Sets the SynapseEnvironment reference to this context
-     * @param se the reference to the Synapse Environment
-     */
-    public void setEnvironment(SynapseEnvironment se);
-
-    /**
-     * Get the value of a custom (local) property set on the message instance
-     * @param key key to look up property
-     * @return value for the given key
-     */
-    public Object getProperty(String key);
-
-    /**
-     * Set a custom (local) property with the given name on the message instance
-     * @param key key to be used
-     * @param value value to be saved
-     */
-    public void setProperty(String key, Object value);
-
-    /**
-     * Returns the Set of keys over the properties on this message context
-     * @return a Set of keys over message properties
-     */
-    public Set getPropertyKeySet();
-
-    /**
-     * Get the SOAP envelope of this message
-     * @return the SOAP envelope of the message
-     */
-    public SOAPEnvelope getEnvelope();
-
-    /**
-     * Sets the given envelope as the current SOAPEnvelope for this message
-     * @param envelope the envelope to be set
-     * @throws org.apache.axis2.AxisFault on exception
-     */
-    public void setEnvelope(SOAPEnvelope envelope) throws AxisFault;
-
-    /**
-     * SOAP message related getters and setters
-     */
-    public ....get/set()...
-
-}</pre>
-    <p>
-      The MessageContext interface is based on the Axis2 MessageContext
-      interface, and uses the Axis2 EndpointReference and
-      SOAPEnvelope classes/interfaces. The purpose of this interface is to
-      capture a message as it flows through the system. As you will see the
-      message payload is represented using the SOAP infoset. Binary messages can
-      be embedded in the Envelope using MTOM or SwA attachments using the AXIOM
-      object model.
-    </p>
-    <h4>
-      <a
-      href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/Mediator.java?view=markup">Mediator
-      interface</a>
-    </h4>
-    <p>
-      The second key interface for mediator writers is the Mediator interface:
-    </p>
-<pre xml:space="preserve">package org.apache.synapse;
-
-import org.apache.synapse.MessageContext;
-
-/**
- * All Synapse mediators must implement this Mediator interface. As a message passes
- * through the synapse system, each mediator's mediate() method is invoked in the
- * sequence/order defined in the SynapseConfiguration.
- */
-public interface <span style="font-weight: bold;">Mediator </span>{
-
-    /**
-     * Invokes the mediator passing the current message for mediation. Each
-     * mediator performs its mediation action, and returns true if mediation
-     * should continue, or false if further mediation should be aborted.
-     *
-     * @param synCtx the current message for mediation
-     * @return true if further mediation should continue
-     */
-    public boolean mediate(MessageContext synCtx);
-
-    /**
-     * This is used for debugging purposes and exposes the type of the current
-     * mediator for logging and debugging purposes
-     * @return a String representation of the mediator type
-     */
-    public String getType();
-}</pre>
-    <p>
-      A mediator can read and/or modify the message encapsulated in the MessageContext in
-      any suitable manner - adjusting the routing headers or changing the
-      message body. If the mediate() method returns false, it signals to the
-      Synapse processing model to stop further processing of the message. For
-      example, if the mediator is a security agent it may decide that this
-      message is dangerous and should not be processed further. This is
-      generally the exception as mediators are usually designed to co-operate to
-      process the message onwards.
-    </p>
-    <h3>
-      Leaf and Node Mediators, List mediators and Filter mediators
-    </h3>
-    <p>
-      Mediators may be Node mediators (i.e. these that can contain child
-      mediators) or Leaf mediators (mediators that does not hold any other child
-      mediators). A Node mediator  must implement the
-      org.apache.synapse.mediators.ListMediator interface listed below, or extend from
-      the org.apache.synapse.mediators.AbstractListMediator.
-    </p>
-    <h4>
-      <a
-      href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/ListMediator.java?view=markup">The
-      ListMediator interface</a>
-    </h4>
-<pre xml:space="preserve">package org.apache.synapse.mediators;
-
-import java.util.List;
-
-/**
-* The List mediator executes a given sequence/list of child mediators
-*/
-public interface ListMediator extends Mediator {
-    /**
-    * Appends the specified mediator to the end of this mediator's (children) list
-    * @param m the mediator to be added
-    * @return true (as per the general contract of the Collection.add method)
-    */
-    public boolean addChild(Mediator m);
-
-    /**
-    * Appends all of the mediators in the specified collection to the end of this mediator's (children)
-    * list, in the order that they are returned by the specified collection's iterator
-    * @param c the list of mediators to be added
-    * @return true if this list changed as a result of the call
-    */
-    public boolean addAll(List c);
-
-    /**
-    * Returns the mediator at the specified position
-    * @param pos index of mediator to return
-    * @return the mediator at the specified position in this list
-    */
-    public Mediator getChild(int pos);
-
-    /**
-    * Removes the first occurrence in this list of the specified mediator
-    * @param m mediator to be removed from this list, if present
-    * @return true if this list contained the specified mediator
-    */
-    public boolean removeChild(Mediator m);
-
-    /**
-    * Removes the mediator at the specified position in this list
-    * @param pos the index of the mediator to remove
-    * @return the mediator previously at the specified position
-    */
-    public Mediator removeChild(int pos);
-
-    /**
-    * Return the list of mediators of this List mediator instance
-    * @return the child/sub mediator list
-    */
-    public List getList();
-}</pre>
-    <p>
-      A ListMediator implementation should call super.mediate(synCtx) to process
-      its sub mediator sequence. A FilterMediator is a ListMediator which
-      executes its sequence of sub mediators on successful outcome of a test
-      condition. The Mediator instance which performs filtering should implement
-      the FilterMediator interface.
-    </p>
-    <h4>
-      <a
-      href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/FilterMediator.java?view=markup">FilterMediator
-      interface</a>
-    </h4>
-<pre xml:space="preserve">package org.apache.synapse.mediators;
-
-import org.apache.synapse.MessageContext;
-
-/**
- * The filter mediator is a list mediator, which executes the given (sub) list of mediators
- * if the specified condition is satisfied
- *
- * @see FilterMediator#test(org.apache.synapse.MessageContext)
- */
-public interface <span style="font-weight: bold;">FilterMediator </span>extends ListMediator {
-
-    /**
-     * Should return true if the sub/child mediators should execute. i.e. if the filter
-     * condition is satisfied
-     * @param synCtx
-     * @return true if the configured filter condition evaluates to true
-     */
-    public boolean test(MessageContext synCtx);
-}</pre>
-    <h2>
-      Writing custom Configuration implementations for mediators
-    </h2>
-    <p>
-      You may write your own custom configurator for the Mediator implementation
-      you write without relying on the Class mediator or Spring extension for
-      its initialization. You could thus write a MediatorFactory implementation
-      which defines how to digest a custom XML configuration element to be used
-      to create and configure the custom mediator instance. A MediatorSerializer
-      implementation defines how a configuration should be serialized back into
-      an XML configuration. The custom MediatorFactory &amp; MediatorSerializer
-      implementations and the mediator class/es must be bundled in a JAR file
-      conforming to the J2SE Service Provider model (See the description for
-      Extensions below for more details and examples) and placed into the
-      SYNAPSE_HOME/lib folder, so that the Synapse runtime could find and load
-      the definition. Essentially this means that a custom JAR file must bundle
-      your class implementing the Mediator interface, and the MediatorFactory
-      implementation class and contain two text files named
-      "org.apache.synapse.config.xml.MediatorFactory" and
-      "org.apache.synapse.config.xml.MediatorSerializer" which will contain the
-      fully qualified name(s) of your MediatorFactory and MediatorSerializer
-      implementation classes. You should also place any dependency JARs into the
-      same lib folder so that the correct classpath references could be made.
-      The MediatorFactory interface listing is given below, which you should
-      implement, and its getTagQName() method must define the fully qualified
-      element of interest for custom configuration. The Synapse initialization
-      will call back to this MediatorFactory instance through the
-      createMediator(OMElement elem) method passing in this XML element, so that
-      an instance of the mediator could be created utilizing the custom XML
-      specification and returned. See the ValidateMediator and the
-      ValidateMediatorFactory classes under modules/extensions in the Synapse
-      source distribution for examples.
-    </p>
-    <h4>
-      <a
-      href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactory.java?view=markup">The
-      MediatorFactory interface</a>
-    </h4>
-<pre xml:space="preserve">package org.apache.synapse.config.xml;
-
-import ...
-
-/**
- * A mediator factory capable of creating an instance of a mediator through a given
- * XML should implement this interface
- */
-public interface MediatorFactory {
-    /**
-     * Creates an instance of the mediator using the OMElement
-     * @param elem
-     * @return the created mediator
-     */
-    public Mediator createMediator(OMElement elem);
-
-    /**
-     * The QName of this mediator element in the XML config
-     * @return QName of the mediator element
-     */
-    public QName getTagQName();
-}</pre>
-    <p/>
-    <h4>
-      <a
-      href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializer.java?view=markup">The
-      MediatorSerializer interface</a>
-    </h4>
-<pre xml:space="preserve">package org.apache.synapse.config.xml;
-
-import ...
-
-/**
- * Interface which should be implemented by mediator serializers. Does the
- * reverse of the MediatorFactory
- */
-public interface MediatorSerializer {
-
-    /**
-     * Return the XML representation of this mediator
-     * @param m mediator to be serialized
-     * @param parent the OMElement to which the serialization should be attached
-     * @return the serialized mediator XML
-     */
-    public OMElement serializeMediator(OMElement parent, Mediator m);
-
-    /**
-     * Return the class name of the mediator which can be serialized
-     * @return the class name
-     */
-    public String getMediatorClassName();
-}</pre>
-    <h2>
-      Configuring mediators
-    </h2>
-    <p>
-      Mediators could access the Synapse registry to load resources and
-      configure the local behaviour. Refer to the Spring mediator and Script
-      mediator implementations for examples on how this could be achieved.
-    </p>
-    <h4>
-      Loading of Extensions by the Synapse runtime
-    </h4>
-    <p>
-      Synapse loads available extensions from the runtime classpath using the <a
-      href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider">J2SE
-      Service Provider model</a>. This essentially iterates over the
-      available JAR files, for  a META-INF/services directory within each file,
-      and looks for a text file with the name
-      org.apache.synapse.config.xml.MediatorFactory which contains a list of
-      fully qualified classname that implement the above interface, listing each
-      class in a separate line. e.g. The built-in synapse-extensions.jar
-      contains the following structure
-    </p>
-<pre xml:space="preserve">synapse-extensions.jar
-    /META-INF/services
-        org.apache.synapse.config.xml.MediatorFactory
-        org.apache.synapse.config.xml.MediatorSerializer
-    /... the implementation classes as usual...</pre>
-    <h2 id="synObservers">
-        Writing Synapse Observers
-    </h2>
-    <p>
-       A Synapse observer is developed by either implementing the
-       org.apache.synapse.config.SynapseObserver interface or by extending the
-       org.apache.synapse.config.AbstractSynapseObserver class. A Synapse observer is notified
-       by the Synapse configuration when new elements are added to the configuration and
-       when existing elements are removed from the configuration. The following event
-       handlers are available to the Synapse observer implementations.
-    </p>
-<pre xml:space="preserve">
- public void sequenceAdded(Mediator sequence);
- public void sequenceRemoved(Mediator sequence);
- public void entryAdded(Entry entry);
- public void entryRemoved(Entry entry);
- public void endpointAdded(Endpoint endpoint);
- public void endpointRemoved(Endpoint endpoint);
- public void proxyServiceAdded(ProxyService proxy);
- public void proxyServiceRemoved(ProxyService proxy);
- public void startupAdded(Startup startup);
- public void startupRemoved(Startup startup);
- public void eventSourceAdded(SynapseEventSource eventSource);
- public void eventSourceRemoved(SynapseEventSource eventSource);
-</pre>
-     <p>
-         The AbstractSynapseObserver provides default implementations to all these
-         event handlers. It simply logs any received events.
-     </p>
-     <p>
-         In situations where the custom code has access to the SynapseConfiguration class
-         observers can be directly registered with the SynapseConfiguration by using the
-         registerObserver(SynapseObserver o) method. Otherwise SynapseObserver implementations
-         can be defined in the synapse.properties file which resides in the SYNAPSE_HOME/lib
-         directory. The following example shows how two observers are registered with the
-         Synapse configuration using the synapse.properties file.
-     </p>
-     <pre xml:space="preserve">synapse.observers=test.LoggingObserverImpl, test.SimpleObserverImpl</pre>
-  </body>
+    <body>
+        <div style="margin-top:-40px; float:right; _margin-top:0px;">
+            <img alt="Synapse logo"
+                 src="images/synapse-logo-web2.png" width="197"
+                 height="82"/>
+        </div>
+        <div>
+            <h1>
+                Apache Synapse ESB - Extending...
+            </h1>
+        </div>
+        <h2>
+            Writing custom Mediator implementations
+        </h2>
+        <p>
+            The primary interface of the Synapse API is the MessageContext interface
+            defined below. This essentially defines the per-message context passed
+            through the chain of mediators, for each and every message received and
+            processed by Synapse. Each message instance is wrapped within a
+            MessageContext instance, and the message context is set with the
+            references to the SynapseConfiguration and SynapseEnvironment objects. The
+            <a href="apidocs/org/apache/synapse/config/SynapseConfiguration.html">
+                SynapseConfiguration
+            </a>
+            object holds the global configuration model that defines
+            mediation rules, local registry entries and other and configuration, while
+            the
+            <a href="apidocs/org/apache/synapse/core/SynapseEnvironment.html">SynapseEnvironment</a>
+            object gives access to the underlying SOAP implementation used -
+            Axis2. A typical mediator would need to manipulate the MessageContext by
+            referring to the SynapseConfiguration. However it is strongly recommended
+            that the SynapseConfiguration is not updated by mediator instances as it
+            is shared by all messages, and may be updated by Synapse administration or
+            configuration modules. Mediator instances may store local message
+            properties into the MessageContext for later retrieval by successive
+            mediators.
+            <br/>
+        </p>
+        <h4>
+            <a
+                    href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/MessageContext.java?view=markup">
+                MessageContext
+                Interface
+            </a>
+        </h4>
+        <p/>
+        <pre xml:space="preserve">package org.apache.synapse;
+
+            import ...
+
+            public interface MessageContext {
+
+            /**
+            * Get a reference to the current SynapseConfiguration
+            *
+            * @return the current synapse configuration
+            */
+            public SynapseConfiguration getConfiguration();
+
+            /**
+            * Set or replace the Synapse Configuration instance to be used. May be used to
+            * programatically change the configuration at runtime etc.
+            *
+            * @param cfg The new synapse configuration instance
+            */
+            public void setConfiguration(SynapseConfiguration cfg);
+
+            /**
+            * Returns a reference to the host Synapse Environment
+            * @return the Synapse Environment
+            */
+            public SynapseEnvironment getEnvironment();
+
+            /**
+            * Sets the SynapseEnvironment reference to this context
+            * @param se the reference to the Synapse Environment
+            */
+            public void setEnvironment(SynapseEnvironment se);
+
+            /**
+            * Get the value of a custom (local) property set on the message instance
+            * @param key key to look up property
+            * @return value for the given key
+            */
+            public Object getProperty(String key);
+
+            /**
+            * Set a custom (local) property with the given name on the message instance
+            * @param key key to be used
+            * @param value value to be saved
+            */
+            public void setProperty(String key, Object value);
+
+            /**
+            * Returns the Set of keys over the properties on this message context
+            * @return a Set of keys over message properties
+            */
+            public Set getPropertyKeySet();
+
+            /**
+            * Get the SOAP envelope of this message
+            * @return the SOAP envelope of the message
+            */
+            public SOAPEnvelope getEnvelope();
+
+            /**
+            * Sets the given envelope as the current SOAPEnvelope for this message
+            * @param envelope the envelope to be set
+            * @throws org.apache.axis2.AxisFault on exception
+            */
+            public void setEnvelope(SOAPEnvelope envelope) throws AxisFault;
+
+            /**
+            * SOAP message related getters and setters
+            */
+            public ....get/set()...
+
+            }
+        </pre>
+        <p>
+            The MessageContext interface is based on the Axis2 MessageContext
+            interface, and uses the Axis2 EndpointReference and
+            SOAPEnvelope classes/interfaces. The purpose of this interface is to
+            capture a message as it flows through the system. As you will see the
+            message payload is represented using the SOAP infoset. Binary messages can
+            be embedded in the Envelope using MTOM or SwA attachments using the AXIOM
+            object model.
+        </p>
+        <h4>
+            <a
+                    href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/Mediator.java?view=markup">
+                Mediator
+                interface
+            </a>
+        </h4>
+        <p>
+            The second key interface for mediator writers is the Mediator interface:
+        </p>
+        <pre xml:space="preserve">package org.apache.synapse;
+
+            import org.apache.synapse.MessageContext;
+
+            /**
+            * All Synapse mediators must implement this Mediator interface. As a message passes
+            * through the synapse system, each mediator's mediate() method is invoked in the
+            * sequence/order defined in the SynapseConfiguration.
+            */
+            public interface<span style="font-weight: bold;">Mediator</span>{
+
+            /**
+            * Invokes the mediator passing the current message for mediation. Each
+            * mediator performs its mediation action, and returns true if mediation
+            * should continue, or false if further mediation should be aborted.
+            *
+            * @param synCtx the current message for mediation
+            * @return true if further mediation should continue
+            */
+            public boolean mediate(MessageContext synCtx);
+
+            /**
+            * This is used for debugging purposes and exposes the type of the current
+            * mediator for logging and debugging purposes
+            * @return a String representation of the mediator type
+            */
+            public String getType();
+            }
+        </pre>
+        <p>
+            A mediator can read and/or modify the message encapsulated in the MessageContext in
+            any suitable manner - adjusting the routing headers or changing the
+            message body. If the mediate() method returns false, it signals to the
+            Synapse processing model to stop further processing of the message. For
+            example, if the mediator is a security agent it may decide that this
+            message is dangerous and should not be processed further. This is
+            generally the exception as mediators are usually designed to co-operate to
+            process the message onwards.
+        </p>
+        <h3>
+            Leaf and Node Mediators, List mediators and Filter mediators
+        </h3>
+        <p>
+            Mediators may be Node mediators (i.e. these that can contain child
+            mediators) or Leaf mediators (mediators that does not hold any other child
+            mediators). A Node mediator must implement the
+            org.apache.synapse.mediators.ListMediator interface listed below, or extend from
+            the org.apache.synapse.mediators.AbstractListMediator.
+        </p>
+        <h4>
+            <a
+                    href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/ListMediator.java?view=markup">
+                The
+                ListMediator interface
+            </a>
+        </h4>
+        <pre xml:space="preserve">package org.apache.synapse.mediators;
+
+            import java.util.List;
+
+            /**
+            * The List mediator executes a given sequence/list of child mediators
+            */
+            public interface ListMediator extends Mediator {
+            /**
+            * Appends the specified mediator to the end of this mediator's (children) list
+            * @param m the mediator to be added
+            * @return true (as per the general contract of the Collection.add method)
+            */
+            public boolean addChild(Mediator m);
+
+            /**
+            * Appends all of the mediators in the specified collection to the end of this mediator's
+            (children)
+            * list, in the order that they are returned by the specified collection's iterator
+            * @param c the list of mediators to be added
+            * @return true if this list changed as a result of the call
+            */
+            public boolean addAll(List c);
+
+            /**
+            * Returns the mediator at the specified position
+            * @param pos index of mediator to return
+            * @return the mediator at the specified position in this list
+            */
+            public Mediator getChild(int pos);
+
+            /**
+            * Removes the first occurrence in this list of the specified mediator
+            * @param m mediator to be removed from this list, if present
+            * @return true if this list contained the specified mediator
+            */
+            public boolean removeChild(Mediator m);
+
+            /**
+            * Removes the mediator at the specified position in this list
+            * @param pos the index of the mediator to remove
+            * @return the mediator previously at the specified position
+            */
+            public Mediator removeChild(int pos);
+
+            /**
+            * Return the list of mediators of this List mediator instance
+            * @return the child/sub mediator list
+            */
+            public List getList();
+            }
+        </pre>
+        <p>
+            A ListMediator implementation should call super.mediate(synCtx) to process
+            its sub mediator sequence. A FilterMediator is a ListMediator which
+            executes its sequence of sub mediators on successful outcome of a test
+            condition. The Mediator instance which performs filtering should implement
+            the FilterMediator interface.
+        </p>
+        <h4>
+            <a
+                    href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/mediators/FilterMediator.java?view=markup">
+                FilterMediator
+                interface
+            </a>
+        </h4>
+        <pre xml:space="preserve">package org.apache.synapse.mediators;
+
+            import org.apache.synapse.MessageContext;
+
+            /**
+            * The filter mediator is a list mediator, which executes the given (sub) list of
+            mediators
+            * if the specified condition is satisfied
+            *
+            * @see FilterMediator#test(org.apache.synapse.MessageContext)
+            */
+            public interface<span style="font-weight: bold;">FilterMediator</span>extends
+            ListMediator {
+
+            /**
+            * Should return true if the sub/child mediators should execute. i.e. if the filter
+            * condition is satisfied
+            * @param synCtx
+            * @return true if the configured filter condition evaluates to true
+            */
+            public boolean test(MessageContext synCtx);
+            }
+        </pre>
+        <h2>
+            Writing custom Configuration implementations for mediators
+        </h2>
+        <p>
+            You may write your own custom configurator for the Mediator implementation
+            you write without relying on the Class mediator or Spring extension for
+            its initialization. You could thus write a MediatorFactory implementation
+            which defines how to digest a custom XML configuration element to be used
+            to create and configure the custom mediator instance. A MediatorSerializer
+            implementation defines how a configuration should be serialized back into
+            an XML configuration. The custom MediatorFactory &amp; MediatorSerializer
+            implementations and the mediator class/es must be bundled in a JAR file
+            conforming to the J2SE Service Provider model (See the description for
+            Extensions below for more details and examples) and placed into the
+            SYNAPSE_HOME/lib folder, so that the Synapse runtime could find and load
+            the definition. Essentially this means that a custom JAR file must bundle
+            your class implementing the Mediator interface, and the MediatorFactory
+            implementation class and contain two text files named
+            "org.apache.synapse.config.xml.MediatorFactory" and
+            "org.apache.synapse.config.xml.MediatorSerializer" which will contain the
+            fully qualified name(s) of your MediatorFactory and MediatorSerializer
+            implementation classes. You should also place any dependency JARs into the
+            same lib folder so that the correct classpath references could be made.
+            The MediatorFactory interface listing is given below, which you should
+            implement, and its getTagQName() method must define the fully qualified
+            element of interest for custom configuration. The Synapse initialization
+            will call back to this MediatorFactory instance through the
+            createMediator(OMElement elem) method passing in this XML element, so that
+            an instance of the mediator could be created utilizing the custom XML
+            specification and returned. See the ValidateMediator and the
+            ValidateMediatorFactory classes under modules/extensions in the Synapse
+            source distribution for examples.
+        </p>
+        <h4>
+            <a
+                    href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorFactory.java?view=markup">
+                The
+                MediatorFactory interface
+            </a>
+        </h4>
+        <pre xml:space="preserve">package org.apache.synapse.config.xml;
+
+            import ...
+
+            /**
+            * A mediator factory capable of creating an instance of a mediator through a given
+            * XML should implement this interface
+            */
+            public interface MediatorFactory {
+            /**
+            * Creates an instance of the mediator using the OMElement
+            * @param elem
+            * @return the created mediator
+            */
+            public Mediator createMediator(OMElement elem);
+
+            /**
+            * The QName of this mediator element in the XML config
+            * @return QName of the mediator element
+            */
+            public QName getTagQName();
+            }
+        </pre>
+        <p/>
+        <h4>
+            <a
+                    href="http://svn.apache.org/viewvc/synapse/trunk/java/modules/core/src/main/java/org/apache/synapse/config/xml/MediatorSerializer.java?view=markup">
+                The
+                MediatorSerializer interface
+            </a>
+        </h4>
+        <pre xml:space="preserve">package org.apache.synapse.config.xml;
+
+            import ...
+
+            /**
+            * Interface which should be implemented by mediator serializers. Does the
+            * reverse of the MediatorFactory
+            */
+            public interface MediatorSerializer {
+
+            /**
+            * Return the XML representation of this mediator
+            * @param m mediator to be serialized
+            * @param parent the OMElement to which the serialization should be attached
+            * @return the serialized mediator XML
+            */
+            public OMElement serializeMediator(OMElement parent, Mediator m);
+
+            /**
+            * Return the class name of the mediator which can be serialized
+            * @return the class name
+            */
+            public String getMediatorClassName();
+            }
+        </pre>
+        <h2>
+            Configuring mediators
+        </h2>
+        <p>
+            Mediators could access the Synapse registry to load resources and
+            configure the local behaviour. Refer to the Spring mediator and Script
+            mediator implementations for examples on how this could be achieved.
+        </p>
+        <h4>
+            Loading of Extensions by the Synapse runtime
+        </h4>
+        <p>
+            Synapse loads available extensions from the runtime classpath using the<a
+                href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider">J2SE
+            Service Provider model</a>. This essentially iterates over the
+            available JAR files, for a META-INF/services directory within each file,
+            and looks for a text file with the name
+            org.apache.synapse.config.xml.MediatorFactory which contains a list of
+            fully qualified classname that implement the above interface, listing each
+            class in a separate line. e.g. The built-in synapse-extensions.jar
+            contains the following structure
+        </p>
+        <pre xml:space="preserve">synapse-extensions.jar
+            /META-INF/services
+            org.apache.synapse.config.xml.MediatorFactory
+            org.apache.synapse.config.xml.MediatorSerializer
+            /... the implementation classes as usual...
+        </pre>
+        <h2 id="synObservers">
+            Writing Synapse Observers
+        </h2>
+        <p>
+            A Synapse observer is developed by either implementing the
+            org.apache.synapse.config.SynapseObserver interface or by extending the
+            org.apache.synapse.config.AbstractSynapseObserver class. A Synapse observer is notified
+            by the Synapse configuration when new elements are added to the configuration and
+            when existing elements are removed from the configuration. The following event
+            handlers are available to the Synapse observer implementations.
+        </p>
+        <pre xml:space="preserve">
+            public void sequenceAdded(Mediator sequence);
+            public void sequenceRemoved(Mediator sequence);
+            public void entryAdded(Entry entry);
+            public void entryRemoved(Entry entry);
+            public void endpointAdded(Endpoint endpoint);
+            public void endpointRemoved(Endpoint endpoint);
+            public void proxyServiceAdded(ProxyService proxy);
+            public void proxyServiceRemoved(ProxyService proxy);
+            public void startupAdded(Startup startup);
+            public void startupRemoved(Startup startup);
+            public void eventSourceAdded(SynapseEventSource eventSource);
+            public void eventSourceRemoved(SynapseEventSource eventSource);
+        </pre>
+        <p>
+            The AbstractSynapseObserver provides default implementations to all these
+            event handlers. It simply logs any received events.
+        </p>
+        <p>
+            In situations where the custom code has access to the SynapseConfiguration class
+            observers can be directly registered with the SynapseConfiguration by using the
+            registerObserver(SynapseObserver o) method. Otherwise SynapseObserver implementations
+            can be defined in the synapse.properties file which resides in the SYNAPSE_HOME/lib
+            directory. The following example shows how two observers are registered with the
+            Synapse configuration using the synapse.properties file.
+        </p>
+        <pre xml:space="preserve">synapse.observers=test.LoggingObserverImpl,
+            test.SimpleObserverImpl
+        </pre>
+
+        <h2 id="synXpathExtensions">
+            Synapse Xpath Extension Framework
+        </h2>
+        <p>
+            Synapse configuration language is a powerful and flexible tool to perform
+            authentication, validation, transformation, logging, routing based on the content etc.
+            It could be easily extended, with configuration extensions , mediation extensions and
+            even expression level extension. An expression is a lowest level particle in the
+            synapase configuration. To be precise , unlike static values ,expressions can be used to
+            define dynamically extracted values (using xpath) in a synapse configuration.
+            Mediators extensively uses expressions to extract properties from message context.
+            Expression is defined under attribute "expression" of a particular configuration. (see
+            property/header/iterator mediator ) .Although expressions can be purely xpath , synapse
+            allows extended to define extended expressions as well. These special xpath expressions
+            can be two fold , that is ,
+        </p>
+        <pre xml:space="preserve">
+            1.xpath variable expressions
+            2.xpath function expressions
+        </pre>
+        <p>
+            Synapse allows us to access xpath variables with "$" . Currently there are several
+            predefined synapse xpath variables avaiable.
+        </p>
+        <pre xml:space="preserve">
+            Ie:- $body - message SOAP body
+            $header ? message SOAP header
+            $ctxt:SOME_PROPERTY ? a property belonging to synapse meessage context scope
+            $axis2:SOME_PROPERTY ? a property belonging to axis2 meessage context scope
+            $trp:SOME_TRANSPORT_HEADER ? a transport header
+        </pre>
+        <p>
+            Synapse get-property() is an example xpath function expressions. The get-property()
+            function allows any XPath expression used in a configuration to lookup information from
+            the current message context. Similar to above , It is possible to retrieve properties
+            previously set with the property mediator, and/or information from the Synapse or Axis2
+            message contexts or transport header using get-property().
+        </p>
+        <p>
+            see synapse documentation for more details on usage of these expressions.
+            Synapse Xpath extension framework allows users to further extend xpath expressions to
+            suite user requirement. More specifically it allows users to define custom xpath
+            expressions and custom xpath functions that is required in a specific usecase
+            configuration scenario. Let's see how we can do this. We start by writng our HELLO_WORLD
+            custom xpath variable and hello-world() custom xpath function.
+        </p>
+        <h4>
+            Implementing HELLO_WORLD custom xpath variable
+        </h4>
+        <p>
+            Before going into implementation details , let me first define our final objective here.
+            What we need to do is to expose an HELLO_WORLD message in xml format to outside , so
+            that users would be able to access it using a xpath expression="$HELLOWORLD/...".
+            Following is the HELLO_WORLD mesasge we have.
+        </p>
+        <pre xml:space="preserve">
+            &lt;HELLO_WORLD&gt;
+            &lt;name&gt;Synapse&lt;/name&gt;
+            &lt;version&gt;2.0.0&lt;/version&gt;
+            &lt;release_date&gt;20/12/2010&lt;/release_date&gt;
+            &lt;/HELLO_WORLD&gt;
+        </pre>
+        <p>Every custom synapse xpath extension should implement
+            org.apache.synapse.util.xpath.ext.SynapseXpathVariableResolver interface to expose a
+            custom xpath variable. This interface consists of two methods , #getResolvingQName ,
+            #resolve . First interface method is used to indicate Synapse the fully qualified
+            variable name that this extesion support (in our case it is HELLO_WORLD). Later method
+            should contain what ever resolving logic required to give the desired output.(in our
+            case it should return HELLO_WORLD element) . Following is the implementation of our
+            custom xpath variable HELLO_WORLD,
+        </p>
+        <pre xml:space="preserve">
+            package org.sample;
+
+            import org.apache.axiom.om.OMAbstractFactory;
+            import org.apache.axiom.om.OMElement;
+            import org.apache.axiom.om.OMFactory;
+            import org.apache.synapse.MessageContext;
+            import org.apache.synapse.util.xpath.ext.SynapseXpathVariableResolver;
+
+            import javax.xml.namespace.QName;
+
+            public class HelloWorldXpathVariableResolver implements SynapseXpathVariableResolver {
+
+            public static final QName HELLO_WORLD = new QName("HELLO_WORLD");
+
+            public Object resolve(MessageContext messageContext) {
+                //create Hello world message
+                OMFactory factory = OMAbstractFactory.getOMFactory();
+                OMElement helloWorldElement = factory.createOMElement(HELLO_WORLD);
+
+                OMElement nameElement = factory.createOMElement(new QName("name"));
+                nameElement.setText("synapse");
+                OMElement versionElem = factory.createOMElement(new QName("version"));
+                versionElem.setText("3.1.0");
+                OMElement releaseDateElem = factory.createOMElement(new QName("release_date"));
+                releaseDateElem.setText("12/12/2010");
+
+                helloWorldElement.addChild(nameElement);
+                helloWorldElement.addChild(versionElem);
+                helloWorldElement.addChild(releaseDateElem);
+
+                return helloWorldElement;
+            }
+
+            public QName getResolvingQName() {
+                //to support xpath expression="$HELLO_WORLD"
+                return HELLO_WORLD;
+            }
+
+            }
+        </pre>
+        <p>
+            with implementation in place mediators can refer version , name , release date on
+            HELLO_WORLD message using expression="$HELLO_WORLD/version" , etc
+        </p>
+        <h4>
+            Implementing hello-world() custom xpath function
+        </h4>
+        <p>
+            Having an xpath function extension is easy as implementing an xpath variable extension.
+            In this case Extension class should implement
+            org.apache.synapse.util.xpath.ext.SynapseXpathFunctionContextProvider . This interface
+            also do have methods , #getResolvingQName and #getInitializedExtFunction . First method
+            serves the same purpose as in the previous example. However later method should be
+            implementated in such a way that this extension should return a custom jaxen function to
+            synapse , initialized with synapse message context. It is extension developers
+            responsibility to provide a properly initialized xpath function so that it can be
+            resolved at runtime. Our sample implementation is shown below
+        </p>
+        <pre xml:space="preserve">
+            package org.sample;
+
+            import org.apache.synapse.MessageContext;
+            import org.apache.synapse.util.xpath.ext.SynapseXpathFunctionContextProvider;
+            import org.jaxen.Function;
+            import javax.xml.namespace.QName;
+
+            public class HelloWorldXpathFunctionProvider implements SynapseXpathFunctionContextProvider {
+
+            public Function getInitializedExtFunction(MessageContext messageContext) {
+                CustomHelloWorldFunction helloWorldFunction = new CustomHelloWorldFunction(messageContext);
+                return helloWorldFunction;
+            }
+
+            public QName getResolvingQName() {
+                //letting know synapse new hello-world extension function
+                return new QName("hello-world");
+            }
+            }
+
+        </pre>
+        <p>
+            Shown bellow is the custom xpath function returned by our xpath function extension. Note
+            that this should implement org.jaxen.Function to resolve xpath .
+        </p>
+        <pre xml:space="preserve">
+            package org.sample;
+
+            import org.apache.axiom.om.OMAbstractFactory;
+            import org.apache.axiom.om.OMElement;
+            import org.apache.axiom.om.OMFactory;
+            import org.apache.commons.logging.Log;
+            import org.apache.commons.logging.LogFactory;
+            import org.apache.synapse.MessageContext;
+            import org.apache.synapse.SynapseConstants;
+            import org.jaxen.Context;
+            import org.jaxen.Function;
+            import org.jaxen.FunctionCallException;
+            import org.jaxen.function.StringFunction;
+
+            import javax.xml.namespace.QName;
+            import java.util.List;
+
+
+            public class CustomHelloWorldFunction implements Function {
+            private MessageContext synCtx;
+
+            private Log log = LogFactory.getLog(CustomHelloWorldFunction.class);
+            private static final Log trace = LogFactory.getLog(SynapseConstants.TRACE_LOGGER);
+
+            private String NULL_STRING = "";
+            public static final QName HELLO_WORLD = new QName("HELLO_WORLD");
+            private OMElement helloWorld;
+
+            public CustomHelloWorldFunction(MessageContext ctxt) {
+                this.synCtx = ctxt;
+                //create hello world message
+                OMFactory factory = OMAbstractFactory.getOMFactory();
+                OMElement helloWorldElement = factory.createOMElement(HELLO_WORLD);
+
+                OMElement nameElement = factory.createOMElement(new QName("name"));
+                nameElement.setText("synapse");
+                OMElement versionElem = factory.createOMElement(new QName("version"));
+                versionElem.setText("3.1.0");
+                OMElement releaseDateElem = factory.createOMElement(new QName("release_date"));
+                releaseDateElem.setText("12/12/2010");
+
+                helloWorldElement.addChild(nameElement);
+                helloWorldElement.addChild(versionElem);
+                helloWorldElement.addChild(releaseDateElem);
+                this.helloWorld = helloWorldElement;
+            }
+
+            /**
+            * Returns the string value of the hello world message for the corresponding child
+            proeprty
+            * arguments are hello-world(name | version | release_date)
+            *
+            * @param context the context at the point in the expression when the function is called
+            * @param args arguments of the functions
+            * @return The string value of the property
+            * @throws org.jaxen.FunctionCallException
+            *
+            */
+            public Object call(Context context, List args) throws FunctionCallException {
+
+                if (synCtx == null) {
+                    if (log.isDebugEnabled()) {
+                    log.debug("Synapse message context has not been set for the " +
+                    "XPath extension function 'synapse:hello-world(arg_name)'");
+                    }
+                    return null;
+                }
+
+                boolean traceOn = synCtx.getTracingState() == SynapseConstants.TRACING_ON;
+                boolean traceOrDebugOn = traceOn || log.isDebugEnabled();
+
+                if (args == null || args.size() == 0) {
+                    if (traceOrDebugOn) {
+                        traceOrDebug(traceOn, "argument key value for lookup is not specified");
+                    }
+                    return NULL_STRING;
+                } else
+                {
+                    int size = args.size();
+                    if (size == 1) {
+                        String argument = StringFunction.evaluate(args.get(0), context.getNavigator());
+                    if ("name".equals(argument) || "version".equals(argument) ||
+                        "release_date".equals(argument)) {
+                         return helloWorld.getFirstChildWithName(new QName(argument));
+                    }else{
+                        return helloWorld;
+                    }
+                }
+                }
+                return NULL_STRING;
+            }
+
+            private void traceOrDebug(boolean traceOn, String msg) {
+                if (traceOn) {
+                    trace.info(msg);
+                }
+                if (log.isDebugEnabled()) {
+                    log.debug(msg);
+                }
+            }
+
+            }
+        </pre>
+        <p>
+            Here we basically select an child element or the whole Hello World message based on the
+            aguments. Please refer to org.jaxen.Function for further details on the implementation.
+            With this extension in place synapse configuration can refer to a particular element of
+            our Hello World message with expression = "hello-world('name')" ,expression =
+            "hello-world('version')" , etc
+        </p>
+        <h4>
+            Registering Extensions
+        </h4>
+        <p>
+            We need one additional step to make all these extensions integrate into Synapse.
+            Registering extensions is done by declaring them in synapse.properties file.
+            synapse.properties can be found $SYNAPSE_HOME/repository/conf . Functions should be
+            declared under property synapse.xpath.func.extensions while Variables should be under
+            synapse.xpath.var.extensions .
+        </p>
+        <pre xml:space="preserve">
+            synapse.xpath.var.extensions=org.sample.HelloWorldXpathVariableResolver
+            synapse.xpath.func.extensions=org.sample. HelloWorldXpathFunctionProvider
+        </pre>
+        <p>
+            If multiple function / variable extesnions are needed comma delimited list can be
+            declared. Synapse at startup will register all these declared extensions (defined under
+            its CLASSPATH) and our HELLO-WORLD xpath extensions will be ready to roll.
+        </p>
+
+
+    </body>
 </document>
\ No newline at end of file