cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h...@apache.org
Subject cvs commit: cocoon-2.1/lib jars.xml
Date Tue, 14 Oct 2003 16:40:09 GMT
haul        2003/10/14 09:40:09

  Modified:    .        blocks.properties gump.xml
               lib      jars.xml
  Added:       src/blocks/jms/samples sitemap.xmap
               src/blocks/jms/samples/database access-error.xml
                        eventcache.xsp install.xsp invalidated.xml
                        remove.xsp sitemap.xmap
               src/blocks/jms/java/org/apache/cocoon/samples/jms
                        HTTPTrigger.java JMSTrigger.java
               src/blocks/jms/java/org/apache/cocoon/components/jms
                        JMSConnection.java JMSConnectionImpl.java
                        JMSEventListener.java JMSPublisherAction.java
               src/blocks/jms/conf jms.xsamples jmsconnection.xconf
                        jmslistener.xconf
  Log:
  Start of an JMS block.
  Goes together with the eventcache block.
  Default: excluded
  Anyone an idea about the licence for JMS & JNDI redistribution?
  
  Revision  Changes    Path
  1.36      +1 -0      cocoon-2.1/blocks.properties
  
  Index: blocks.properties
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/blocks.properties,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- blocks.properties	11 Oct 2003 01:25:41 -0000	1.35
  +++ blocks.properties	14 Oct 2003 16:40:08 -0000	1.36
  @@ -72,6 +72,7 @@
   #exclude.block.cron=true
   #exclude.block.deli=true
   #exclude.block.eventcache=true
  +exclude.block.jms=true
   #exclude.block.linotype=true
   #exclude.block.mail=true
   #exclude.block.midi=true
  
  
  
  1.91      +23 -1     cocoon-2.1/gump.xml
  
  Index: gump.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/gump.xml,v
  retrieving revision 1.90
  retrieving revision 1.91
  diff -u -r1.90 -r1.91
  --- gump.xml	11 Oct 2003 15:57:00 -0000	1.90
  +++ gump.xml	14 Oct 2003 16:40:08 -0000	1.91
  @@ -1044,6 +1044,28 @@
       <nag from="Gump" to="dev@cocoon.apache.org"/>
     </project>
   
  +  <project name="cocoon-block-jms" status="unstable">
  +    <package>org.apache.cocoon</package>
  +
  +    <ant target="gump-block">
  +      <property name="block-name" value="jms"/>
  +      <property name="version" value="@@DATE@@"/>
  +    </ant>
  +
  +    <depend project="cocoon" inherit="all"/>
  +    <depend project="cocoon-block-eventcache"/>
  +    <depend project="cocoon-block-databases"/>
  +    <depend project="cocoon-block-hsqldb"/>
  +
  +    <work nested="tools/anttasks"/>
  +    <home nested="build/cocoon-@@DATE@@"/>
  +    <work nested="build/cocoon-@@DATE@@/blocks/jms/mocks"/>
  +
  +    <jar name="blocks/jms-block.jar"/>
  +
  +    <nag from="Gump" to="dev@cocoon.apache.org"/>
  +  </project>
  +
   
     <!--
       ********************************************
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  <?xml version="1.0" encoding="UTF-8"?>
  <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
   <map:pipelines>
    <map:pipeline>
  
      <!--+
          | Mount everything else by calling the sitemap.xmap file located
          | in the requested folder.
          +-->
      <map:match pattern="*/**">
        <map:mount check-reload="yes" src="{1}/" uri-prefix="{1}"/>
      </map:match>
  
    </map:pipeline>
   </map:pipelines>
  </map:sitemap>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/database/access-error.xml
  
  Index: access-error.xml
  ===================================================================
  <?xml version="1.0"?>
  <html><body><p>access rules forbid you to access this URL.</p></html>
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/database/eventcache.xsp
  
  Index: eventcache.xsp
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <!--
      XSP event-based cache sample.
  
      Cvs $Id: eventcache.xsp,v 1.1 2003/10/14 16:40:08 haul Exp $
   -->
  
  
  <xsp:page language="java"
            xmlns:xsp="http://apache.org/xsp"
            xmlns:esql="http://apache.org/cocoon/SQL/v2"
            xmlns:xsp-request="http://apache.org/xsp/request/2.0">
  
  <xsp:structure>
      <xsp:include>org.apache.excalibur.source.SourceValidity</xsp:include>
      <xsp:include>org.apache.excalibur.source.impl.validity.AggregatedValidity</xsp:include>
      <xsp:include>org.apache.excalibur.source.impl.validity.TimeStampValidity</xsp:include>
      <xsp:include>org.apache.cocoon.caching.validity.EventValidity</xsp:include>
      <xsp:include>org.apache.cocoon.caching.validity.NamedEvent</xsp:include>
      <xsp:include>java.io.Serializable</xsp:include>
  </xsp:structure>
  
  <xsp:logic>
  
      // artificial slowdown to make the effects of the cache visible
      final int DELAY_SECS = 2;
      final String DATABASE_TABLE = "user";
  
      /**
      * Generate the unique key for the cache.
      *
      * This key must be unique inside the space of this XSP page, it is used
      * to find the page contents in the cache (if getValidity says that the
      * contents are still valid).
      *
      * This method will be invoked before the getValidity() method.
      *
      * @return The generated key or null if the component
      *         is currently not cacheable.
      */
      public Serializable getKey()
      {
         // this page will only render a single view
         // depending on the database table. Therefore
         // there is no need to distinguish different
         // outcomes in the cache. If we were paging
         // through the result set, those parameters
         // should be used for the key.
         return "";
      }
  
      /**
      * Generate the validity object, tells the cache how long to
      * keep contents having this key around.  In this case, it will
      * be until an Event is retrieved matching the NamedEvent created below.
      *
      * Before this method can be invoked the getKey() method
      * will be invoked.
      *
      * @return The generated validity object or null if the
      *         component is currently not cacheable.
      */
      public SourceValidity getValidity() {
         String key = DATABASE_TABLE;
  	   // a composite validity is required here since changes to
  	   // the source XSP file should invalid the cache as well as
         // changes to the database table.
  	   AggregatedValidity validity = new AggregatedValidity();
         // invalidate on external events
         // multiple events can be added, the cache will be invalidated
         // when any of those events occur.
         validity.add(new EventValidity(new NamedEvent(key)));
         // invalidate on changes to XSP source
  	   validity.add(new TimeStampValidity(this.dateCreated));
  	   return validity;
      }
   </xsp:logic>
  
  
    <page>
      <title>Demonstrating Event-Aware Caching or Database Generated Pages.</title>
      <content>
      	<para>
  	    	This xsp page is based on (copied from) the event aware cacheable
              xsp sample.
      	</para>
          <para>
              I pause for <xsp:expr>DELAY_SECS</xsp:expr> seconds during generation, so
              that you can tell if I'm being served from the cache or not.
              <br/>
              What you see here was generated on <b><xsp:expr>new java.util.Date()</xsp:expr></b>.
          </para>
  
          <para>
              I'm cached for a specific database table name: <b><xsp:expr>DATABASE_TABLE</xsp:expr></b>.
              Other parameters ie. request parameters do not matter.
          </para>
  
  		<para>
  			Unlike other cacheable pages in Cocoon, I can be un-cached by events external
  			to Cocoon - for instance, when a database table or row is updated. I will also
              be invalidated when the XSP source is modified.
  			<br/>
  			My cache entry will be invalidated (actually, removed) when an event named
  			<i><xsp:expr>DATABASE_TABLE</xsp:expr></i> occurs. Go to the
              <a href="../../databases/mod-db/user-list">database samples</a> and modify,
              insert, or delete a user and check if this page is updated.
  		</para>
  
          <para>Test links:
              <ul>
                  <li><a href="invalidate?table=user">uncache with action</a></li>
                  <li><a href="jms-invalidate?table=user">uncache with action emitting JMS messages</a><br/>
                      This is particularily useful if your DBMS of choice can easily do HTTP
                      requests but hooking on JMS would be difficult. Still you would like to
                      control several Cocoon caches through JMS.
                  </li>
                  <li><a href="install?what=http">install HTTP database triggers with HSQLDB</a><br/>
                      For the HTTP example triggers, this sample needs to be available at
                      <b>http://localhost:8888/samples/jms/database/eventcache</b> because
                      that location is hard-coded into the trigger. This is usually the case if you
                      have started the provided <i>cocoon.sh</i> resp. <i>cocoon.bat</i>.
                  </li>
                  <li><a href="install?what=jms">install JMS database triggers with HSQLDB</a><br/>
                      For the JMS example triggers, you need to have setup a JMS system, e.g.
                      <a href="openjms.sf.net">OpenJMS</a></li>
                  <li><a href="remove">uninstall database triggers</a></li>
              </ul>
          </para>
  
          <para>
            <esql:connection>
              <esql:pool>personnel</esql:pool>
                <esql:execute-query>
                  <esql:query>select * from user order by name, firstname, uname, uid</esql:query>
                  <esql:results>
                    <table>
                      <tbody>
                        <esql:row-results>
                          <tr>
                            <td><esql:get-string column="uname"/></td>
                            <td><esql:get-string column="firstname"/></td>
                            <td><esql:get-string column="name"/></td>
                            <td><esql:get-string column="uid"/></td>
                          </tr>
                        </esql:row-results>
                      </tbody>
                    </table>
                 </esql:results>
              </esql:execute-query>
            </esql:connection>
          </para>
  
          <para>
              Please refer to the <a href="../eventcache">event based cache example</a> for more details
              on the event based cache invalidation.
          </para>
  
          <xsp:logic>
            // slowdown page generation.
              try {
                Thread.sleep(DELAY_SECS * 1000L);
              } catch (InterruptedException ie) {
                // Not much that can be done...
              }
          </xsp:logic>
      </content>
    </page>
  </xsp:page>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/database/install.xsp
  
  Index: install.xsp
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <!--
      XSP event-based cache sample.
  
      Cvs $Id: install.xsp,v 1.1 2003/10/14 16:40:08 haul Exp $
   -->
  
  
  <xsp:page language="java"
            xmlns:xsp="http://apache.org/xsp"
            xmlns:esql="http://apache.org/cocoon/SQL/v2"
            xmlns:xsp-request="http://apache.org/xsp/request/2.0">
  
      <page>
          <title>Install Database Triggers with HSQLDB</title>
          <para>This page tries to install triggers with the demo database that
                comes with Apache Cocoon.</para>
  
          <para>Source for the triggers can be found in the eventcache block in your Cocoon
                source distribution: src/blocks/eventcache/java/org/apache/cocoon/samples/eventcache/</para>
  
          <esql:connection>
              <esql:pool>personnel</esql:pool>
          <xsp:logic>
              String trigClass = <xsp-request:get-parameter name="what" default="http"/>;
              if (trigClass.equals("http")){
                  trigClass = "org.apache.cocoon.samples.jms.HTTPTrigger";
              } else {
                  trigClass = "org.apache.cocoon.samples.jms.JMSTrigger";
              }
              String what = null;
              for (int i = 0; i &lt; 3; i++) {
                  switch(i) {
                  case 0: what="update"; break;
                  case 1: what="insert"; break;
                  case 2: what="delete"; break;
                  }
  
                  <para>Installing <xsp:expr>trigClass</xsp:expr> for <xsp:expr>what</xsp:expr> on table "user".</para>
  
                  <esql:execute-query>
                      <esql:query>create trigger myTrigger<xsp:expr>i</xsp:expr>
                                  after <xsp:expr>what</xsp:expr> on user
                                  call \"<xsp:expr>trigClass</xsp:expr>\"</esql:query>
                      <esql:error-results>
                          <para>Failed installing myTrigger<xsp:expr>i</xsp:expr>: <esql:get-message/></para>
                          <para>Trigger already installed?</para>
                      </esql:error-results>
                  </esql:execute-query>
              }
           </xsp:logic>
          </esql:connection>
  
          <para><a href="remove">Uninstall triggers</a> or go back to <a href="eventcache">sample page.</a></para>
      </page>
  
  </xsp:page>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/database/invalidated.xml
  
  Index: invalidated.xml
  ===================================================================
  <?xml version="1.0"?>
  <html><body><p>invalidated cache</p></html>
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/database/remove.xsp
  
  Index: remove.xsp
  ===================================================================
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <!--
      XSP event-based cache sample.
  
      Cvs $Id: remove.xsp,v 1.1 2003/10/14 16:40:08 haul Exp $
   -->
  
  
  <xsp:page language="java"
            xmlns:xsp="http://apache.org/xsp"
            xmlns:esql="http://apache.org/cocoon/SQL/v2"
            xmlns:xsp-request="http://apache.org/xsp/request/2.0">
  
      <page>
          <title>Uninstall Database Triggers with HSQLDB</title>
          <para>This page tries to remove triggers with the demo database that
                comes with Apache Cocoon.</para>
          <esql:connection>
              <esql:pool>personnel</esql:pool>
  
          <xsp:logic>
              for (int i = 0; i&lt;3; i++) {
  
                <para>Removing myTrigger<xsp:expr>i</xsp:expr>.</para>
                <esql:execute-query>
                  <esql:query>drop trigger myTrigger<xsp:expr>i</xsp:expr></esql:query>
                  <esql:error-results>
                    <para>Failed installing myTrigger<xsp:expr>i</xsp:expr>: <esql:get-message/></para>
                    <para>Trigger already removed?</para>
                  </esql:error-results>
                </esql:execute-query>
              }
          </xsp:logic>
          </esql:connection>
  
          <para>
              <a href="install?what=http">Install HTTP triggers</a>,
              <a href="install?what=jms">Install JMS triggers</a>,
              or go back to <a href="eventcache">sample page.</a></para>
      </page>
  
  </xsp:page>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/samples/database/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  <?xml version="1.0"?>
  
  <!--
    CVS $Id: sitemap.xmap,v 1.1 2003/10/14 16:40:08 haul Exp $
  
    Event Cache Sample
  -->
  
  <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
    <map:components>
      <map:generators default="file"/>
      <map:transformers default="xslt"/>
      <map:readers default="resource"/>
      <map:serializers default="html"/>
      <map:matchers default="wildcard">
          <map:matcher name="host-matcher"
                       logger="sitemap.matcher.wildcard"
                       src="org.apache.cocoon.matching.modular.CachingWildcardMatcher">
              <input-module name="request"/>
              <parameter-name>serverName</parameter-name>
          </map:matcher>
      </map:matchers>
      <map:selectors default="browser"/>
      <map:actions>
      	<map:action name="cacheevent" src="org.apache.cocoon.acting.CacheEventAction"/>
      	<map:action name="jmsevent" src="org.apache.cocoon.components.jms.JMSPublisherAction">
            <parameter name="connection" value="OpenJMS-demo"/>
          </map:action>
      </map:actions>
  
      <map:pipes default="caching">
  	  <!-- A pipe must be defined configured to use the EventAware cache. -->
        <map:pipe name="event-aware" src="org.apache.cocoon.components.pipeline.impl.CachingProcessingPipeline">
          <parameter name="cache-role" value="org.apache.cocoon.caching.Cache/EventAware"/>
        </map:pipe>
      </map:pipes>
    </map:components>
  
    <map:views>
      <map:view from-label="content" name="content">
        <map:serialize type="xml"/>
      </map:view>
    </map:views>
  
    <map:pipelines>
  
      <!-- Our content must occur in a pipeline configured to use our Event Aware cache -->
      <map:pipeline type="event-aware">
        <map:match pattern="eventcache">
          <map:generate type="serverpages" src="{0}.xsp"/>
  	    <map:transform src="context://samples/stylesheets/dynamic-page2html.xsl">
  	        <map:parameter name="servletPath" value="{request:servletPath}"/>
  	        <map:parameter name="sitemapURI" value="{request:sitemapURI}"/>
  	        <map:parameter name="contextPath" value="{request:contextPath}"/>
  	        <map:parameter name="file" value="{0}.xsp"/>
  	        <map:parameter name="remove" value="{0}"/>
  	    </map:transform>
          <map:serialize/>
        </map:match>
      </map:pipeline>
  
      <map:pipeline>
  
        <map:match pattern="">
          <map:redirect-to uri="eventcache"/>
        </map:match>
  
  	  <map:match pattern="invalidate">
          <map:match type="host-matcher" pattern="localhost">
              <map:act type="cacheevent">
                  <map:parameter name="event" value="{request-param:table}"/>
              </map:act>
              <map:read src="invalidated.xml"/>
          </map:match>
          <map:read src="access-error.xml"/>
  	  </map:match>
  
  	  <map:match pattern="jms-invalidate">
          <map:match type="host-matcher" pattern="localhost">
              <map:act type="jmsevent">
                  <map:parameter name="event" value="action|{request-param:table}"/>
              </map:act>
              <map:read src="invalidated.xml"/>
          </map:match>
          <map:read src="access-error.xml"/>
  	  </map:match>
  
        <map:match pattern="*">
          <map:generate type="serverpages" src="{1}.xsp"/>
  	    <map:transform src="context://samples/stylesheets/dynamic-page2html.xsl">
  	        <map:parameter name="servletPath" value="{request:servletPath}"/>
  	        <map:parameter name="sitemapURI" value="{request:sitemapURI}"/>
  	        <map:parameter name="contextPath" value="{request:contextPath}"/>
  	        <map:parameter name="file" value="{1}.xsp"/>
  	        <map:parameter name="remove" value="{0}"/>
  	    </map:transform>
          <map:serialize/>
        </map:match>
      </map:pipeline>
  
    </map:pipelines>
  </map:sitemap>
  
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/samples/jms/HTTPTrigger.java
  
  Index: HTTPTrigger.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.samples.jms;
  
  import java.net.HttpURLConnection;
  import java.net.URL;
  import java.net.URLEncoder;
  
  import org.hsqldb.Trigger;
  
  /**
   * @version CVS $Id: HTTPTrigger.java,v 1.1 2003/10/14 16:40:08 haul Exp $
   * @author <a href="mailto:chaul@informatik.tu-darmstadt.de">chaul</a>
   */
  public class HTTPTrigger implements Trigger {
  
      protected String protocol = "http";
      protected String hostname = "localhost";
      protected int port = 8888;
      protected String path = "/samples/jms/database/jms-invalidate";
  
      /* 
       * @see org.hsqldb.Trigger#fire(java.lang.String, java.lang.String, java.lang.Object[])
       */
      public void fire(String triggerName, String tableName, Object[] row) {
          try {
              HttpURLConnection con = (HttpURLConnection) new URL(this.protocol, this.hostname, this.port, this.path+"?trigger="
                              + URLEncoder.encode(triggerName.toLowerCase(), "UTF-8")
                              + "&table="
                              + URLEncoder.encode(tableName.toLowerCase(), "UTF-8")).openConnection();
              con.connect();
              con.getContent();
              con.disconnect();
          } catch (Exception e) {
              // not much we can do here.
              throw new RuntimeException("Cannot execute trigger: "+e.getMessage());
          }
      }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/samples/jms/JMSTrigger.java
  
  Index: JMSTrigger.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.samples.jms;
  
  import java.util.Hashtable;
  
  import javax.jms.DeliveryMode;
  import javax.jms.JMSException;
  import javax.jms.Session;
  import javax.jms.TextMessage;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSession;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import org.hsqldb.Trigger;
  
  /**
   * Example Trigger for HSQLDB doing cache invalidation through the eventcache
   * block and JMS messages. 
   * 
   * @version CVS $Id: JMSTrigger.java,v 1.1 2003/10/14 16:40:08 haul Exp $
   * @author <a href="mailto:haul@informatik.tu-darmstadt.de">haul</a>
   */
  public class JMSTrigger implements Trigger {
  
      // this exmaple class uses defaults to run with OpenJMS
      // TODO make this somehow configurable...
      protected String contextFactoryName = "org.exolab.jms.jndi.InitialContextFactory";
      protected String scheme = "rmi";
      protected String host = "localhost";
      protected String port = "";
      protected String jndiname = "";
      protected String topicFactoryName = "JmsTopicConnectionFactory";
      protected String topicName = "topic1";
      protected int deliveryMode = DeliveryMode.NON_PERSISTENT;
      protected int priority = 4;
      protected long timeToLive = 10000;
  
      protected Topic topic = null;
      protected TopicPublisher publisher = null;
      protected TopicSession session = null;
      protected TopicConnection connection = null;
      protected Context context = null;
      protected TopicConnectionFactory topicConnectionFactory = null;
  
      /**
       * 
       */
      public JMSTrigger() {
          super();
      }
  
      /**
       * Get initial context.
       * 
       * @return
       * @throws NamingException
       */
      public Context getContext() throws NamingException {
  
          Hashtable properties = new Hashtable();
  
          properties.put(Context.INITIAL_CONTEXT_FACTORY, this.contextFactoryName);
  
          if (this.port.equals("")) {
              if (scheme.equals("tcp") || scheme.equals("tcps")) {
                  port = "3035";
              } else if (scheme.equals("http")) {
                  port = "8080";
              } else if (scheme.equals("https")) {
                  port = "8443";
              } else if (scheme.equals("rmi")) {
                  port = "1099";
              }
          }
  
          String name = "";
          if (scheme.equals("rmi")) {
              name = this.jndiname;
          }
  
          String url = scheme + "://" + host + ":" + port + "/" + name;
  
          properties.put(Context.PROVIDER_URL, url);
          return new InitialContext(properties);
      }
  
      private void setupConnection() throws NamingException, JMSException {
          // setup JMS connection
          this.context = this.getContext();
          this.topicConnectionFactory = (TopicConnectionFactory) this.context.lookup(this.topicFactoryName);
          this.connection = this.topicConnectionFactory.createTopicConnection();
          this.connection.start();
      }
  
      private void setupSession() throws JMSException {
          this.session = connection.createTopicSession(false, Session.CLIENT_ACKNOWLEDGE);
          this.topic = session.createTopic(this.topicName);
          this.publisher = session.createPublisher(topic);
      }
  
      private void connect() throws NamingException, JMSException {
          if (this.connection == null)
              this.setupConnection();
          if (this.session == null)
              this.setupSession();
      }
  
      private void disconnect() throws JMSException, NamingException {
          // do we really need to do this every time??
          // OTOH we should expect to run this trigger rather infrequently.
          this.session.close();
          this.session = null;
          this.connection.close();
          this.connection = null;
          this.topicConnectionFactory = null;
          this.context.close();
          this.context = null;
      }
  
      /* 
       * @see org.hsqldb.Trigger#fire(java.lang.String, java.lang.String, java.lang.Object[])
       */
      public void fire(String trigName, String tabName, Object[] row) {
          try {
              connect();
              TextMessage message =
                  this.session.createTextMessage(
                      trigName.toLowerCase() + "|" + tabName.toLowerCase());
              this.publisher.publish(
                  this.topic,
                  message,
                  this.deliveryMode,
                  this.priority,
                  this.timeToLive);
              disconnect();
  
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnection.java
  
  Index: JMSConnection.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components.jms;
  
  import javax.jms.JMSException;
  import javax.jms.MessageListener;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSession;
  import javax.naming.NamingException;
  
  /**
   * JMSConnection properties container plus utilities.
   * 
   * @version CVS $Id: JMSConnection.java,v 1.1 2003/10/14 16:40:09 haul Exp $
   * @author <a href="mailto:haul@informatik.tu-darmstadt.de">haul</a>
   */
  public interface JMSConnection {
      
      static final String ROLE = JMSConnection.class.getName();
      
      /**
       * Register a new TopicListener for this connection.
       * 
       * @param listener
       * @param string
       */
      void registerListener(MessageListener listener, String selector)
          throws JMSException, NamingException;
          
      /**
       * Get a new TopicPublisher for this connection.
       * 
       * @return new TopicPublisher
       * @throws JMSException
       * @throws NamingException
       */
      TopicPublisher getPublisher() throws JMSException, NamingException;
  
      /**
       * Get the session associated with this connection. This is needed for example to
       * create messages.
       * 
       * @return TopicSession
       * @throws NamingException
       * @throws JMSException
       */
      TopicSession getSession() throws NamingException, JMSException;
  }
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnectionImpl.java
  
  Index: JMSConnectionImpl.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components.jms;
  
  import java.util.Hashtable;
  import java.util.Iterator;
  import java.util.LinkedList;
  import java.util.List;
  
  import javax.jms.JMSException;
  import javax.jms.MessageListener;
  import javax.jms.Session;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSession;
  import javax.jms.TopicSubscriber;
  import javax.naming.Context;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.parameters.ParameterException;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  
  /**
   * JMSConnection properties container plus utilities.
   * 
   * <p>Parameters:</p>
   * <table>
   *  <tbody>
   *   <tr><td>component      </td><td>(required, null)</td></tr>
   *   <tr><td>scheme         </td><td>(rmi)</td></tr>
   *   <tr><td>host           </td><td>(localhost)</td></tr>
   *   <tr><td>port           </td><td>(for rmi 1099)</td></tr>
   *   <tr><td>jndiname       </td><td>("")</td></tr>
   *   <tr><td>context-factory</td><td>(org.exolab.jms.jndi.InitialContextFactory)</td></tr>
   *   <tr><td>topic-factory  </td><td>(JmsTopicConnectionFactory)</td></tr>
   *   <tr><td>topic          </td><td>(topic1)</td></tr>
   *   <tr><td>ack-mode       </td><td>(dups)</td></tr>
   *  </tbody>
   * </table>
   * 
   * @version CVS $Id: JMSConnectionImpl.java,v 1.1 2003/10/14 16:40:09 haul Exp $
   * @author <a href="mailto:haul@informatik.tu-darmstadt.de">haul</a>
   */
  public class JMSConnectionImpl implements Parameterizable, Disposable, ThreadSafe, JMSConnection {
  
      // defaults to go with OpenJMS demo on localhost 
      protected String contextFactoryName = "org.exolab.jms.jndi.InitialContextFactory";
      protected String scheme = "rmi";
      protected String host = "localhost";
      protected String port = "";
      protected String jndiname = "";
      protected String topicFactoryName = "JmsTopicConnectionFactory";
      protected String topicName = "topic1";
      protected String ackModeName = "dups";
      protected String durableSubscriptionID = null;
  
      protected TopicConnection connection = null;
      protected TopicSession session = null;
      protected List subscribers = null;
      protected Topic topic = null;
      protected int ackMode = Session.DUPS_OK_ACKNOWLEDGE;
      protected Context context = null;
      protected TopicConnectionFactory topicConnectionFactory = null;
  
  
      /**
       * Register a new TopicListener for this connection.
       * 
       * @param listener
       * @param string
       */
      public synchronized void registerListener(
          MessageListener listener,
          String selector)
          throws JMSException, NamingException {
  
          TopicSubscriber subscriber = null;
          if (this.durableSubscriptionID != null) {
              subscriber =
                  this.getSession().createDurableSubscriber(
                      this.topic,
                      this.durableSubscriptionID,
                      selector,
                      false);
          } else {
              subscriber = this.getSession().createSubscriber(this.topic, selector, false);
          }
          if (this.subscribers == null) {
              this.subscribers = new LinkedList();
          }
          this.subscribers.add(subscriber);
  
          subscriber.setMessageListener(listener);
      }
  
      /**
       * Get a new TopicPublisher for this connection.
       * 
       * @return
       * @throws JMSException
       * @throws NamingException
       */
      public TopicPublisher getPublisher() throws JMSException, NamingException {
          return this.getSession().createPublisher(this.topic);
      }
  
      /**
       * Get the session associated with this connection. This is needed for example to
       * create messages.
       * 
       * @return
       * @throws NamingException
       * @throws JMSException
       */
      public synchronized TopicSession getSession() throws NamingException, JMSException {
          if (this.session == null) {
              this.connect();
          }
          return this.session;
      }
  
      /**
        * Get initial context.
        * 
        * @return
        * @throws NamingException
        */
      protected Context getContext() throws NamingException {
  
          Hashtable properties = new Hashtable();
          properties.put(Context.INITIAL_CONTEXT_FACTORY, this.contextFactoryName);
  
          String name = "";
          if (scheme.equals("rmi")) {
              name = this.jndiname;
          }
  
          String url = scheme + "://" + host + ":" + port + "/" + name;
  
          properties.put(Context.PROVIDER_URL, url);
          return new InitialContext(properties);
      }
  
  
      /**
       * Setup connection.
       * 
       * @throws NamingException
       * @throws JMSException
       */
      private void setupConnection() throws NamingException, JMSException {
          // setup JMS connection
          this.context = this.getContext();
          this.topicConnectionFactory =
              (TopicConnectionFactory) this.context.lookup(this.topicFactoryName);
          this.connection = this.topicConnectionFactory.createTopicConnection();
          this.connection.start();
      }
  
      /**
       * Setup session for this connection.
       * 
       * @throws JMSException
       */
      private void setupSession() throws JMSException {
          this.session = connection.createTopicSession(false, this.ackMode);
          this.topic = session.createTopic(this.topicName);
      }
  
      /**
       * Setup connection and session for this connection.
       * 
       * @throws NamingException
       * @throws JMSException
       */
      private void connect() throws NamingException, JMSException {
          if (this.connection == null)
              this.setupConnection();
          if (this.session == null)
              this.setupSession();
      }
  
      /**
       * Disconnect session and connection, close all subscribers.
       * 
       * @throws JMSException
       * @throws NamingException
       */
      private void disconnect() throws JMSException, NamingException {
          if (this.subscribers != null) {
              for (Iterator i = this.subscribers.iterator(); i.hasNext();) {
                  ((TopicSubscriber) i.next()).close();
              }
              this.subscribers.clear();
          }
          this.session.close();
          this.connection.close();
      }
  
      /* 
       * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
       */
      public void parameterize(Parameters parameters) throws ParameterException {
  
          this.scheme = parameters.getParameter("scheme", this.scheme).toLowerCase();
          if (scheme.equals("tcp") || scheme.equals("tcps")) {
              port = "3035";
          } else if (scheme.equals("http")) {
              port = "8080";
          } else if (scheme.equals("https")) {
              port = "8443";
          } else if (scheme.equals("rmi")) {
              port = "1099";
          }
          this.host = parameters.getParameter("host", this.host);
          this.port = parameters.getParameter("port", this.port);
          this.jndiname = parameters.getParameter("jndiname", this.jndiname);
          this.contextFactoryName =
              parameters.getParameter("context-factory", this.contextFactoryName);
          this.topicFactoryName =
              parameters.getParameter("topic-factory", this.topicFactoryName);
          this.topicName = parameters.getParameter("topic", this.topicName);
          this.durableSubscriptionID =
              parameters.getParameter(
                  "durable-subscription-id",
                  this.durableSubscriptionID);
  
          this.ackModeName =
              parameters.getParameter("ack-mode", this.ackModeName).toLowerCase();
          // see if an ack mode has been specified. If it hasn't
          // then assume CLIENT_ACKNOWLEDGE mode.
          this.ackMode = Session.CLIENT_ACKNOWLEDGE;
          if (this.ackModeName.equals("auto")) {
              this.ackMode = Session.AUTO_ACKNOWLEDGE;
          } else if (this.ackModeName.equals("dups")) {
              this.ackMode = Session.DUPS_OK_ACKNOWLEDGE;
          } else if (!this.ackModeName.equals("client")) {
              // ignore all ack modes, to test no acking
              this.ackMode = -1;
          }
      }
  
      /* 
       * @see org.apache.avalon.framework.activity.Disposable#dispose()
       */
      public void dispose() {
          try {
              this.disconnect();
          } catch (JMSException e) {
          } catch (NamingException e) {
          }
      }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSEventListener.java
  
  Index: JMSEventListener.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components.jms;
  
  import javax.jms.Message;
  import javax.jms.MessageListener;
  
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.ParameterException;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.caching.EventAware;
  import org.apache.cocoon.caching.validity.NamedEvent;
  
  /**
   * JMS listener will notify an {@link org.apache.cocoon.caching.EventAware} component
   * of external events. This could be used for example to do external cache invalidation.
   * Configuration parameters default to <a href="http://openjms.sf.net">OpenJMS</a> demo
   * installation on localhost using "topic1".
   * 
   * <p>Parameters:</p>
   * <table>
   *  <tbody>
   *   <tr><td>connection     </td><td>(required, no default)</td></tr>
   *   <tr><td>component      </td><td>(required, no default)</td></tr>
   *   <tr><td>scheme         </td><td>(rmi)</td></tr>
   *   <tr><td>host           </td><td>(localhost)</td></tr>
   *   <tr><td>port           </td><td>(for rmi 1099)</td></tr>
   *   <tr><td>jndiname       </td><td>("")</td></tr>
   *   <tr><td>context-factory</td><td>(org.exolab.jms.jndi.InitialContextFactory)</td></tr>
   *   <tr><td>topic-factory  </td><td>(JmsTopicConnectionFactory)</td></tr>
   *   <tr><td>topic          </td><td>(topic1)</td></tr>
   *   <tr><td>ack-mode       </td><td>(dups)</td></tr>
   *   <tr><td>selector       </td><td>("")</td></tr>
   *  </tbody>
   * </table>
   * 
   * @version CVS $Id: JMSEventListener.java,v 1.1 2003/10/14 16:40:09 haul Exp $
   * @author <a href="mailto:chaul@informatik.tu-darmstadt.de">chaul</a>
   */
  public class JMSEventListener
      extends AbstractLogEnabled
      implements Serviceable, Parameterizable, MessageListener, Startable, ThreadSafe {
  
      protected String selector = "";
  
      protected ServiceManager manager;
  
      protected String serviceName = null;
      protected EventAware service = null;
      protected String connectionName = null;
      protected JMSConnection connection = null;
  
  
      /* 
       * @see org.apache.avalon.framework.activity.Startable#start()
       */
      public void start() throws Exception {
  
          this.connection = (JMSConnection) this.manager.lookup(JMSConnection.ROLE+"/"+this.connectionName);
          this.connection.registerListener(this, this.selector);
      }
  
      /* 
       * @see org.apache.avalon.framework.activity.Startable#stop()
       */
      public void stop() throws Exception {
          if (this.manager != null){
              if (this.connection != null){
                  this.manager.release(connection);
              }
              
              if (this.service != null) {
                  this.manager.release(this.service);
              }
          }
      }
  
      /* 
       * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
       */
      public void parameterize(Parameters parameters) throws ParameterException {
  
          this.connectionName = parameters.getParameter("connection");
          this.serviceName = parameters.getParameter("component");
          this.selector = parameters.getParameter("message-selector", this.selector);
      }
  
      /* 
       * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
       */
      public synchronized void onMessage(Message message) {
          EventAware service = this.service;
          try {
              if (service == null) {
                  service = (EventAware) this.manager.lookup(this.serviceName);
              }
              if (this.getLogger().isInfoEnabled())
                  this.getLogger().info(
                      "Notifying "
                          + this.serviceName
                          + " of "
                          + this.convertMessage(message.toString()));
              service.processEvent(new NamedEvent(this.convertMessage(message.toString())));
          } catch (ServiceException e) {
              if (this.getLogger().isErrorEnabled()) {
                  this.getLogger().error(
                      "Could not obtain " + this.serviceName + " from component manager.",
                      e);
              }
          } finally {
              if (service instanceof ThreadSafe) {
                  this.service = service;
              } else {
                  this.manager.release(service);
              }
          }
      }
  
      /**
       * Convert the message contents to a cache key. Assume that the message contains of
       * the trigger name, a '|', and the table name. Extract the tablename only. You might
       * want to override this method.
       * 
       * @param message
       * @return
       */
      protected String convertMessage(String message) {
          int pos = message.indexOf('|');
          return message.substring(pos + 1);
      }
  
      /*
       * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
       */
      public void service(ServiceManager manager) throws ServiceException {
          this.manager = manager;
      }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSPublisherAction.java
  
  Index: JMSPublisherAction.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Apache Cocoon" and  "Apache Software Foundation" must  not  be
      used to  endorse or promote  products derived from  this software without
      prior written permission. For written permission, please contact
      apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation and was  originally created by
   Stefano Mazzocchi  <stefano@apache.org>. For more  information on the Apache
   Software Foundation, please see <http://www.apache.org/>.
  
  */
  package org.apache.cocoon.components.jms;
  
  import java.util.Collections;
  import java.util.Map;
  
  import javax.jms.DeliveryMode;
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.TopicPublisher;
  
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.ParameterException;
  import org.apache.avalon.framework.parameters.Parameterizable;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.acting.Action;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.SourceResolver;
  
  /**
   * Creates new TextMessages containing the event name and publishes them on the
   * {@link org.apache.cocoon.components.jms.JMSConnection}.
   * 
   * <p>Parameters:</p>
   * <table>
   *  <tbody>
   *   <tr><td>connection         </td><td>(required, no default)</td></tr>
   *   <tr><td>priority           </td><td>(4)</td></tr>
   *   <tr><td>time-to-live       </td><td>(10000)</td></tr>
   *   <tr><td>persistent-delivery</td><td>(false)</td></tr>
   *  </tbody>
   * </table>
   * 
   * <p>Sitemap-Parameters:</p>
   * <table>
   *  <tbody>
   *   <tr><td>event              </td><td>Content of TextMessage to publish (required, no default)</td></tr>
   *  </tbody>
   * </table>
   * 
   * @version CVS $Id: JMSPublisherAction.java,v 1.1 2003/10/14 16:40:09 haul Exp $
   * @author <a href="mailto:haul@informatik.tu-darmstadt.de">haul</a>
   */
  public class JMSPublisherAction
      extends AbstractLogEnabled
      implements Action, Serviceable, Parameterizable, ThreadSafe, Initializable, Disposable {
  
      protected ServiceManager manager = null;
      protected JMSConnection connection = null;
      protected TopicPublisher publisher = null;
  
      protected int mode = DeliveryMode.NON_PERSISTENT;
      protected boolean persistent = false;
      protected int priority = 4;
      protected int timeToLive = 10000;
  
      protected String connectionName = null;
  
      /* 
       * @see org.apache.cocoon.acting.Action#act(org.apache.cocoon.environment.Redirector, org.apache.cocoon.environment.SourceResolver, java.util.Map, java.lang.String, org.apache.avalon.framework.parameters.Parameters)
       */
      public Map act(
          Redirector redirector,
          SourceResolver resolver,
          Map objectModel,
          String source,
          Parameters parameters)
          throws Exception {
  
          Map result = null;
          Message message = null;
          try {
              // publish message
              message =
                  this.connection.getSession().createTextMessage(
                      parameters.getParameter("event"));
              this.publisher.publish(message, this.mode, this.priority, this.timeToLive);
              result = Collections.EMPTY_MAP;
              if (this.getLogger().isInfoEnabled())
                  this.getLogger().info("Sent message '"+parameters.getParameter("event")+"'");
          } catch (Exception e) {
              if (this.getLogger().isWarnEnabled())
                  this.getLogger().warn("Could not deliver message.", e);
          }
  
          return result;
      }
  
      /* 
       * @see org.apache.avalon.framework.service.Serviceable#service(org.apache.avalon.framework.service.ServiceManager)
       */
      public void service(ServiceManager manager) throws ServiceException {
          this.manager = manager;
      }
  
      /* 
       * @see org.apache.avalon.framework.parameters.Parameterizable#parameterize(org.apache.avalon.framework.parameters.Parameters)
       */
      public void parameterize(Parameters parameters) throws ParameterException {
          this.connectionName = parameters.getParameter("connection");
          this.priority = parameters.getParameterAsInteger("priority", this.priority);
          this.persistent =
              parameters.getParameterAsBoolean("persistent-delivery", this.persistent);
          this.mode =
              (this.persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
          this.timeToLive =
              parameters.getParameterAsInteger("time-to-live", this.timeToLive);
      }
  
      /* 
       * @see org.apache.avalon.framework.activity.Initializable#initialize()
       */
      public void initialize() throws Exception {
          this.connection = (JMSConnection) this.manager.lookup(JMSConnection.ROLE + "/"+ this.connectionName);
          this.publisher = this.connection.getPublisher();
      }
  
      /* 
       * @see org.apache.avalon.framework.activity.Disposable#dispose()
       */
      public void dispose() {
          if (this.publisher != null) {
              try {
                  this.publisher.close();
              } catch (JMSException e) {
                  if (this.getLogger().isWarnEnabled()) {
                      this.getLogger().warn("Could not close publisher.", e);
                  }
              }
          }
          if (this.connection != null) {
              if (this.manager != null) {
                  this.manager.release(this.connection);
                  this.connection = null;
              }
          }
      }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/conf/jms.xsamples
  
  Index: jms.xsamples
  ===================================================================
  <?xml version="1.0"?>
  
  <xsamples xpath="/samples" unless="group[@name='JMS']">
    <group name="JMS">
    	<sample name="JMS invalidated Event Based Cache" href="jms/database/">
        A sample showing external cache invalidation using database triggers
        emitting either JMS messages or HTTP requests. For this sample, the
        HSQLDB block and the databases block need to be present. For the JMS
        part, a JMS service and libraries e.g. OpenJMS needs to be present and running.
        JMS connection parameters are set in a way to work with the OpenJMS demo.
      </sample>
    </group>
  </xsamples>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/conf/jmsconnection.xconf
  
  Index: jmsconnection.xconf
  ===================================================================
  <?xml version="1.0"?>
  <xconf xpath="/cocoon" unless="component[@class='org.apache.cocoon.components.jms.JMSConnectionImpl']">
  	<component class="org.apache.cocoon.components.jms.JMSConnectionImpl"
                 role="org.apache.cocoon.components.jms.JMSConnection/OpenJMS-demo" logger="core">
         <!-- parameters to go with OpenJMS.sf.net demo on localhost -->
         <parameter name="scheme" value="rmi"/>
         <parameter name="host" value="localhost"/>
         <parameter name="port" value="1099"/>
         <parameter name="jndiname" value=""/>
         <parameter name="context-factory" value="org.exolab.jms.jndi.InitialContextFactory"/>
         <parameter name="topic-factory" value="JmsTopicConnectionFactory"/>
         <parameter name="topic" value="topic1"/>
         <parameter name="ack-mode" value="dups"/>
      </component>
  </xconf>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/conf/jmslistener.xconf
  
  Index: jmslistener.xconf
  ===================================================================
  <?xml version="1.0"?>
  <xconf xpath="/cocoon" unless="component[@class='org.apache.cocoon.components.jms.JMSEventListener']">
  	<component class="org.apache.cocoon.components.jms.JMSEventListener"
                 role="org.apache.cocoon.components.jms.JMSEventListener" logger="core">
         <parameter name="component" value="org.apache.cocoon.caching.Cache/EventAware"/>
         <parameter name="connection" value="OpenJMS-demo"/>
      </component>
  </xconf>
  
  
  
  1.113     +52 -4     cocoon-2.1/lib/jars.xml
  
  Index: jars.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/lib/jars.xml,v
  retrieving revision 1.112
  retrieving revision 1.113
  diff -u -r1.112 -r1.113
  --- jars.xml	10 Oct 2003 06:10:00 -0000	1.112
  +++ jars.xml	14 Oct 2003 16:40:09 -0000	1.113
  @@ -863,7 +863,7 @@
   	<lib>ojb/lib/antlr.jar</lib>
   	<homepage>http://www.antlr.org/</homepage>
     </file>
  -  
  +
     <file>
       <title>Jakarta Commons DBCP</title>
   	<description>
  @@ -873,7 +873,7 @@
   	<lib>ojb/lib/commons-dbcp.jar</lib>
   	<homepage>http://jakarta.apache.org/commons/dbcp/</homepage>
     </file>
  -  
  +
     <file>
       <title>Jakarta Commons Pool</title>
   	<description>
  @@ -884,7 +884,7 @@
   	<lib>ojb/lib/commons-pool.jar</lib>
   	<homepage>http://jakarta.apache.org/commons/pool/</homepage>
     </file>
  -  
  +
     <file>
       <title>Apache  ObJectRelationalBridge</title>
   	<description>
  @@ -896,4 +896,52 @@
   	<homepage>http://db.apache.org/ojb/</homepage>
     </file>
     <!-- OJB block end (6-Aug-2003) -->
  +  <!-- JMS block begin
  +  <file>
  +        <title>OpenJMS</title>
  +        <description>OpenJMS core libraries. OpenJMS is a OpenSource JMS, Java Messaging
  +        Service, implementation.</description>
  +        <used-by>JMS</used-by>
  +        <lib>jms/lib/exolabcore-0.3.6.jar</lib>
  +        <homepage>http://openjms.sf.net</homepage>
  +  </file>
  +  <file>
  +        <title>OpenJMS</title>
  +        <description>OpenJMS client libraries. OpenJMS is a OpenSource JMS, Java Messaging
  +        Service, implementation.</description>
  +        <used-by>JMS</used-by>
  +        <lib>jms/lib/openjms-client-0.7.6-rc2.jar</lib>
  +        <homepage>http://openjms.sf.net</homepage>
  +  </file>
  +  <file>
  +        <title>Sun JMS API</title>
  +        <description>Sun's Java Messaging Service APIs. From the website:
  +           Enterprise messaging provides a reliable,
  +           flexible service for the asynchronous
  +           exchange of critical business data and events
  +           throughout an enterprise. The JMS API adds to
  +           this a common API and provider framework that
  +           enables the development of portable, message
  +           based applications in the Java programming
  +           language.
  +        </description>
  +        <used-by>JMS</used-by>
  +        <lib>jms/lib/jms-1.0.2a.jar</lib>
  +        <homepage>http://java.sun.com/jms</homepage>
  +  </file>
  +  <file>
  +        <title>Sun JNDI</title>
  +        <description>Sun's Java Naming and Directory Interface. From the website:
  +           The Java Naming and Directory Interface (JNDI) is a standard extension to
  +           the Java platform, providing Java technology-enabled applications with a
  +           unified interface to multiple naming and directory services in the
  +           enterprise. As part of the Java Enterprise API set, JNDI enables seamless
  +           connectivity to heterogeneous enterprise naming and directory services.
  +           Developers can now build powerful and portable directory-enabled
  +           applications using this industry standard.</description>
  +        <used-by>JMS</used-by>
  +        <lib>jms/lib/jndi-1.2.1.jar</lib>
  +        <homepage>http://java.sun.com/jndi</homepage>
  +  </file>
  +  JMS block end -->
   </jars>
  
  
  

Mime
View raw message