cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From un...@apache.org
Subject cvs commit: cocoon-2.1 gump.xml
Date Thu, 01 Jul 2004 13:43:01 GMT
unico       2004/07/01 06:43:01

  Modified:    src/blocks/jms/samples/database sitemap.xmap
               .        gump.xml
  Added:       src/blocks/jms/java/org/apache/cocoon/components/jms
                        JMSConnectionManagerImpl.java
                        AbstractMessageListener.java
                        JMSConnectionManager.java
                        AbstractMessagePublisher.java
               src/blocks/jms/conf jms-connection-manager.xconf
                        jms-connection-manager.xroles
               src/blocks/eventcache/java/org/apache/cocoon/caching/impl
                        JMSEventMessageListener.java
               src/blocks/jms/java/org/apache/cocoon/acting
                        JMSPublisherAction.java
               src/blocks/eventcache/conf jmslistener.xconf
  Removed:     src/blocks/jms/java/org/apache/cocoon/components/jms
                        JMSPublisherAction.java JMSEventListener.java
               src/blocks/jms/conf jmslistener.xconf
  Log:
  jms block refactoring to provide more generic JMS support:
  - introduce JMSConnectionManager component to configure, start and stop JMS connections
  - provide abstract base component classes for message publishers and message listeners
  - make JMSPubliserAction and JMSEventListener use these respective base classes
  - move JMSEventMessageListener to eventcache block, introducing a dependency from eventcache
-> jms
  and removing the dependency from jms -> eventcache (except for samples)
  - move JMSPublisherAction to o.a.c.action package
  
  Revision  Changes    Path
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnectionManagerImpl.java
  
  Index: JMSConnectionManagerImpl.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.components.jms;
  
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Properties;
  
  import javax.jms.Connection;
  import javax.jms.ConnectionFactory;
  import javax.jms.JMSException;
  import javax.jms.QueueConnection;
  import javax.jms.QueueConnectionFactory;
  import javax.jms.TopicConnection;
  import javax.jms.TopicConnectionFactory;
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  
  import org.apache.cocoon.components.jms.JMSConnectionManager;
  
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.ParameterException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  
  /**
   * {@link org.apache.cocoon.components.jms.JMSConnectionManager} implementation.
   */
  public class JMSConnectionManagerImpl extends AbstractLogEnabled 
  implements JMSConnectionManager, Configurable, Initializable, Startable, Disposable, ThreadSafe
{
  
      // ---------------------------------------------------- Constants
      
      private static final int TOPIC_CONNECTION_TYPE = 1;
      private static final int QUEUE_CONNECTION_TYPE = 2;
      private static final int CONNECTION_TYPE = 3;
  
      private static final String CONNECTION_CONFIG = "connection";
      private static final String TOPIC_CONNECTION_CONFIG = "topic-connection";
      private static final String QUEUE_CONNECTION_CONFIG = "queue-connection";
      private static final String NAME_ATTR = "name";
      
      private static final String CONNECTION_FACTORY_PARAM = "connection-factory";
      private static final String USERNAME_PARAM = "username";
      private static final String PASSWORD_PARAM = "password";
      
      private static final String JNDI_PROPERTY_PREFIX = "java.naming.";
  
      // ---------------------------------------------------- Instance variables
  
      private Map m_configurations;
      private Map m_connections;
  
      // ---------------------------------------------------- Lifecycle
  
      public JMSConnectionManagerImpl() {
      }
  
      public void configure(Configuration configuration) throws ConfigurationException {
          m_configurations = new HashMap(configuration.getChildren().length);
          // <connection>s
          Configuration[] configurations = configuration.getChildren(CONNECTION_CONFIG);
          configureConnections(configurations, CONNECTION_TYPE);
          // <topic-connection>s
          configurations = configuration.getChildren(TOPIC_CONNECTION_CONFIG);
          configureConnections(configurations, TOPIC_CONNECTION_TYPE);
          // <queue-connection>s
          configurations = configuration.getChildren(QUEUE_CONNECTION_CONFIG);
          configureConnections(configurations, QUEUE_CONNECTION_TYPE);
      }
      
      private void configureConnections(Configuration[] connections, int type) throws ConfigurationException
{
          for (int i = 0; i < connections.length; i++) {
              final String name = connections[i].getAttribute(NAME_ATTR);
              if (m_configurations.containsKey(name)) {
                  throw new ConfigurationException("Duplicate connection name '" + name +
"'." +
                          " Connection names must be unique.");
              }
              final Parameters parameters = Parameters.fromConfiguration(connections[i]);
              ConnectionConfiguration cc = new ConnectionConfiguration(name, parameters, type);
              m_configurations.put(name, cc);
          }
      }
  
      public void initialize() throws Exception {
          m_connections = new HashMap(m_configurations.size());
          final Iterator iter = m_configurations.values().iterator();
          try {
              while (iter.hasNext()) {
                  final ConnectionConfiguration cc = (ConnectionConfiguration) iter.next();
                  final InitialContext context = createInitialContext(cc.getJNDIProperties());
                  final ConnectionFactory factory = (ConnectionFactory) context.lookup(cc.getConnectionFactory());
                  final Connection connection = createConnection(factory, cc);
                  m_connections.put(cc.getName(), connection);
              }
          }
          catch (NamingException e) {
              if (getLogger().isWarnEnabled()) {
                  Throwable rootCause = e.getRootCause();
                  if (rootCause != null) {
                      String message = e.getRootCause().getMessage();
                      if (rootCause instanceof ClassNotFoundException) {
                          String info = "WARN! *** JMS block is installed but jms client library
not found. ***\n" + 
                              "- For the jms block to work you must install and start a JMS
server and " +
                              "place the client jar in WEB-INF/lib.";
                              if (message.indexOf("exolab") > 0 ) {
                                  info += "\n- The default server, OpenJMS is configured in
cocoon.xconf but is not bundled with Cocoon.";
                              }
                          System.err.println(info);
                          getLogger().warn(info,e);
                      } else {
                          System.out.println(message);
                          getLogger().warn("Cannot get Initial Context. Is the JNDI server
reachable?",e);
                      }
                  }
                  else {
                      getLogger().warn("Failed to initialize JMS.",e);
                  }
              }
          }
          m_configurations = null;
      }
  
      public void start() throws Exception {
          final Iterator iter = m_connections.entrySet().iterator();
          while (iter.hasNext()) {
              final Map.Entry entry = (Map.Entry) iter.next();
              if (getLogger().isDebugEnabled()) {
                  getLogger().debug("Starting JMS connection " + entry.getKey());
              }
              final Connection connection = (Connection) entry.getValue();
              connection.start();
          }
      }
  
      public void stop() throws Exception {
          final Iterator iter = m_connections.entrySet().iterator();
          while (iter.hasNext()) {
              final Map.Entry entry = (Map.Entry) iter.next();
              if (getLogger().isDebugEnabled()) {
                  getLogger().debug("Stopping JMS connection " + entry.getKey());
              }
              try {
                  final Connection connection = (Connection) entry.getValue();
                  connection.stop();
              }
              catch (JMSException e) {
                  getLogger().error("Error stopping JMS connection " + entry.getKey(), e);
              }
          }
      }
  
      public void dispose() {
          final Iterator iter = m_connections.entrySet().iterator();
          while (iter.hasNext()) {
              final Map.Entry entry = (Map.Entry) iter.next();
              if (getLogger().isDebugEnabled()) {
                  getLogger().debug("Closing JMS connection " + entry.getKey());
              }
              try {
                  final Connection connection = (Connection) entry.getValue();
                  connection.close();
              }
              catch (JMSException e) {
                  getLogger().error("Error closing JMS connection " + entry.getKey(), e);
              }
          }
      }
  
      // ---------------------------------------------------- ConnectionManager
  
      public Connection getConnection(String name) {
          return (Connection) m_connections.get(name);
      }
  
      public TopicConnection getTopicConnection(String name) {
          return (TopicConnection) m_connections.get(name);
      }
  
      public QueueConnection getQueueConnection(String name) {
          return (QueueConnection) m_connections.get(name);
      }
  
      // ---------------------------------------------------- Implementation
  
      private InitialContext createInitialContext(Properties properties) throws NamingException
{
          if (properties != null) {
              return new InitialContext(properties);
          }
          return new InitialContext();
      }
  
      private Connection createConnection(ConnectionFactory factory, ConnectionConfiguration
cc) throws JMSException {
          if (cc.getUserName() != null) {
              switch (cc.getType()) {
                  case CONNECTION_TYPE: {
                      return factory.createConnection(cc.getUserName(), cc.getPassword());
                  }
                  case TOPIC_CONNECTION_TYPE: {
                      TopicConnectionFactory topicFactory = (TopicConnectionFactory) factory;
                      return topicFactory.createTopicConnection(cc.getUserName(), cc.getPassword());
                  }
                  case QUEUE_CONNECTION_TYPE: {
                      QueueConnectionFactory queueFactory = (QueueConnectionFactory) factory;
                      return queueFactory.createQueueConnection(cc.getUserName(), cc.getPassword());
                  }
              }
          }
          switch (cc.getType()) {
              case CONNECTION_TYPE: {
                  return factory.createConnection();
              }
              case TOPIC_CONNECTION_TYPE: {
                  TopicConnectionFactory topicFactory = (TopicConnectionFactory) factory;
                  return topicFactory.createTopicConnection();
              }
              case QUEUE_CONNECTION_TYPE: {
                  QueueConnectionFactory queueFactory = (QueueConnectionFactory) factory;
                  return queueFactory.createQueueConnection();
              }
          }
          return null;
      }
  
      private static final class ConnectionConfiguration {
          
          // ------------------------------------------------ Instance variables
  
          private final String m_name;
          private final int m_type;
          private final String m_connectionFactory;
          private final String m_username;
          private final String m_password;
          private Properties m_jndiProperties;
  
          private ConnectionConfiguration(String name, Parameters parameters, int type) 
          throws ConfigurationException {
              m_name = name;
              try {
                  m_connectionFactory = parameters.getParameter(CONNECTION_FACTORY_PARAM);
                  m_username = parameters.getParameter(USERNAME_PARAM, null);
                  m_password = parameters.getParameter(PASSWORD_PARAM, null);
                  
                  // parse the jndi property parameters
                  String[] names = parameters.getNames();
                  for (int i = 0; i < names.length; i++) {
                      if (names[i].startsWith(JNDI_PROPERTY_PREFIX)) {
                          if (m_jndiProperties == null) {
                              m_jndiProperties = new Properties();
                          }
                          m_jndiProperties.put(names[i], parameters.getParameter(names[i]));
                      }
                  }
                  
              }
              catch (ParameterException e) {
                  throw new ConfigurationException(e.getLocalizedMessage());
              }
              m_type = type;
          }
  
          private String getName() {
              return m_name;
          }
  
          private int getType() {
              return m_type;
          }
  
          private Properties getJNDIProperties() {
              return m_jndiProperties;
          }
  
          private String getConnectionFactory() {
              return m_connectionFactory;
          }
  
          private String getUserName() {
              return m_username;
          }
  
          private String getPassword() {
              return m_password;
          }
  
          public int hashCode() {
              return m_name.hashCode();
          }
  
      }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/AbstractMessageListener.java
  
  Index: AbstractMessageListener.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.components.jms;
  
  import javax.jms.ExceptionListener;
  import javax.jms.JMSException;
  import javax.jms.MessageListener;
  import javax.jms.Session;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicSession;
  import javax.jms.TopicSubscriber;
  
  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;
  
  /**
   * Abstract JMS MessageListener. Use this as a basis for concrete
   * MessageListener implementations.
   * 
   * <p>Parameters:</p>
   * <table border="1">
   *  <tbody>
   *   <tr>
   *     <th align="left">parameter</th>
   *     <th align="left">required/default</th>
   *     <th align="left">description</th>
   *   </tr>
   *   <tr>
   *     <td valign="top">connection</td>
   *     <td valign="top">required</td>
   *     <td valign="top">
   *       Name of the connection registered with 
   *       {@link org.apache.cocoon.components.jms.JMSConnectionManager}. 
   *       This must be a topic connection.
   *     </td>
   *   </tr>
   *   <tr>
   *     <td>topic</td>
   *     <td>required</td>
   *     <td>The name of the topic to subscribe to.</td>
   *   </tr>
   *   <tr>
   *     <td>subscription-id</td>
   *     <td>(<code>null</code>)</td>
   *     <td>An optional durable subscription id.</td>
   *   </tr>
   *   <tr>
   *     <td>message-selector</td>
   *     <td>(<code>null</code>)</td>
   *     <td>An optional message selector.</td>
   *   </tr>
   *  </tbody>
   * </table>
   * 
   * @version CVS $Id: AbstractMessageListener.java,v 1.1 2004/07/01 13:43:00 unico Exp $
   */
  public abstract class AbstractMessageListener extends AbstractLogEnabled
  implements MessageListener, ExceptionListener, Serviceable, Parameterizable, Initializable,
Disposable {
  
      // ---------------------------------------------------- Constants
  
      private static final String CONNECTION_PARAM = "connection";
      private static final String TOPIC_PARAM = "topic";
      private static final String SUBSCRIPTION_ID_PARAM = "subscription-id";
      private static final String MESSAGE_SELECTOR_PARAM = "message-selector";
  
      // ---------------------------------------------------- Instance variables
  
      protected ServiceManager m_manager;
  
      /* configuration */
      private String m_connectionName;
      private String m_topicName;
      private String m_subscriptionId;
      private String m_selector;
  
      protected int m_acknowledgeMode;
  
      /* connection manager component */
      private JMSConnectionManager m_jmsConnectionManager;
  
      /* our session */
      private TopicSession m_session;
  
      /* our subscriber */
      private TopicSubscriber m_subscriber;
  
      // ---------------------------------------------------- Lifecycle
  
      public AbstractMessageListener () {
      }
  
      public void service(ServiceManager manager) throws ServiceException {
          m_manager = manager;
          m_jmsConnectionManager = (JMSConnectionManager) m_manager.lookup(JMSConnectionManager.ROLE);
      }
  
      public void parameterize(Parameters parameters) throws ParameterException {
  
          m_connectionName = parameters.getParameter(CONNECTION_PARAM);
          m_topicName = parameters.getParameter(TOPIC_PARAM);
  
          m_subscriptionId = parameters.getParameter(SUBSCRIPTION_ID_PARAM, null);
          m_selector = parameters.getParameter(MESSAGE_SELECTOR_PARAM, null);
  
      }
  
      /**
       * Registers this MessageListener as a TopicSubscriber to the configured Topic.
       */
      public void initialize() throws Exception {
  
          // set the default acknowledge mode to dups
          // concrete implementations may want to override this
          m_acknowledgeMode = Session.DUPS_OK_ACKNOWLEDGE;
  
          // register this MessageListener with a TopicSubscriber
          final TopicConnection connection = (TopicConnection) m_jmsConnectionManager.getConnection(m_connectionName);
          if (connection != null) {
              m_session = connection.createTopicSession(false, m_acknowledgeMode);
              final Topic topic = m_session.createTopic(m_topicName);
              if (m_subscriptionId != null) {
                  m_subscriber = m_session.createDurableSubscriber(topic, m_subscriptionId,
m_selector, false);
              }
              else {
                  m_subscriber = m_session.createSubscriber(topic, m_selector, false);
              }
              m_subscriber.setMessageListener(this);
          }
          else {
              if (getLogger().isWarnEnabled()) {
                  getLogger().warn("Could not obtain JMS connection '" + m_connectionName
+ "'");
              }
          }
  
      }
  
      public void dispose() {
          if (m_subscriber != null) {
              try {
                  m_subscriber.close();
              } catch (JMSException e) {
                  getLogger().error("Error closing subscriber", e);
              }
          }
          if (m_session != null) {
              try {
                  m_session.close();
              }
              catch (JMSException e) {
                  getLogger().error("Error closing session", e);
              }
          }
          this.m_manager.release(m_jmsConnectionManager);
      }
  
      public void onException(JMSException exception) {
          if (getLogger().isWarnEnabled()) {
              getLogger().warn("JMS problem detected", exception);
          }
      }
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/JMSConnectionManager.java
  
  Index: JMSConnectionManager.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.components.jms;
  
  import javax.jms.Connection;
  
  /**
   * Manages a set of JMS Connections.
   */
  public interface JMSConnectionManager {
  
      public static final String ROLE = JMSConnectionManager.class.getName();
  
      public Connection getConnection(String name);
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/components/jms/AbstractMessagePublisher.java
  
  Index: AbstractMessagePublisher.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.components.jms;
  
  import javax.jms.DeliveryMode;
  import javax.jms.JMSException;
  import javax.jms.Message;
  import javax.jms.Session;
  import javax.jms.Topic;
  import javax.jms.TopicConnection;
  import javax.jms.TopicPublisher;
  import javax.jms.TopicSession;
  
  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;
  
  /**
   * Abstract JMS message publisher. Use this as a basis for components 
   * that want to publish JMS messages.
   * 
   * <p>Parameters:</p>
   * <table border="1">
   *  <tbody>
   *   <tr>
   *     <th align="left">parameter</th>
   *     <th align="left">required</th>
   *     <th align="left">default</th>
   *     <th align="left">description</th>
   *   </tr>
   *   <tr>
   *     <td valign="top">connection</td>
   *     <td valign="top">yes</td>
   *     <td>&nbsp;</td>
   *     <td valign="top">
   *       Name of the connection registered with 
   *       {@link org.apache.cocoon.components.jms.JMSConnectionManager}. 
   *       This must be a topic connection.
   *     </td>
   *   </tr>
   *   <tr>
   *     <td valign="top">topic</td>
   *     <td valign="top">yes</td>
   *     <td>&nbsp;</td>
   *     <td valign="top">The name of the topic to publish messages to.</td>
   *   </tr>
   *   <tr>
   *     <td valign="top">priority</td>
   *     <td valign="top">no</td>
   *     <td>4</td>
   *     <td valign="top">the priority of the published messages</td>
   *   </tr>
   *   <tr>
   *     <td valign="top">time-to-live</td>
   *     <td valign="top">no</td>
   *     <td>10000</td>
   *     <td valign="top">the message's lifetime in milliseconds</td>
   *   </tr>
   *   <tr>
   *     <td valign="top">persistent-delivery</td>
   *     <td valign="top">no</td>
   *     <td>false</td>
   *     <td valign="top">whether to use persistent delivery mode when publishing messages</td>
   *   </tr>
   *  </tbody>
   * </table>
   * 
   * @version CVS $Id: AbstractMessagePublisher.java,v 1.1 2004/07/01 13:43:00 unico Exp $
   */
  public abstract class AbstractMessagePublisher extends AbstractLogEnabled
  implements Serviceable, Parameterizable, Initializable, Disposable {
  
      // ---------------------------------------------------- Constants
  
      private static final String CONNECTION_PARAM = "connection";
      private static final String TOPIC_PARAM = "topic";
      private static final String PRIORITY_PARAM = "priority";
      private static final String TIME_TO_LIVE_PARAM = "time-to-live";
      private static final String PERSISTENT_DELIVERY_PARAM = "persistent-delivery";
      
      private static final int DEFAULT_PRIORITY = 4;
      private static final int DEFAULT_TIME_TO_LIVE = 10000;
  
      // ---------------------------------------------------- Instance variables
  
      private ServiceManager m_manager;
      private JMSConnectionManager m_connectionManager;
  
      protected TopicSession m_session;
      protected TopicPublisher m_publisher;
  
      private int m_mode;
      private int m_priority;
      private int m_timeToLive;
      private String m_topicName;
      private int m_acknowledgeMode;
  
      private String m_connectionName;
  
      // ---------------------------------------------------- Lifecycle
  
      public AbstractMessagePublisher() {
      }
  
      public void service(ServiceManager manager) throws ServiceException {
          m_manager = manager;
          m_connectionManager = (JMSConnectionManager) m_manager.lookup(JMSConnectionManager.ROLE);
      }
  
      public void parameterize(Parameters parameters) throws ParameterException {
          m_connectionName = parameters.getParameter(CONNECTION_PARAM);
          m_topicName = parameters.getParameter(TOPIC_PARAM);
          m_priority = parameters.getParameterAsInteger(PRIORITY_PARAM, DEFAULT_PRIORITY);
          boolean persistent = parameters.getParameterAsBoolean(PERSISTENT_DELIVERY_PARAM,
false);
          m_mode = (persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT);
          m_timeToLive = parameters.getParameterAsInteger(TIME_TO_LIVE_PARAM, DEFAULT_TIME_TO_LIVE);
      }
  
      public void initialize() throws Exception {
  
          // set the default acknowledge mode
          // concrete implementations may override this
          m_acknowledgeMode = Session.DUPS_OK_ACKNOWLEDGE;
  
          // create the message publisher
          final TopicConnection connection = (TopicConnection) m_connectionManager.getConnection(m_connectionName);
          if (connection != null) {
              m_session = connection.createTopicSession(false, m_acknowledgeMode);
              final Topic topic = m_session.createTopic(m_topicName);
              m_publisher = m_session.createPublisher(topic);
          }
          else {
              if (getLogger().isWarnEnabled()) {
                  getLogger().warn("Could not obtain JMS connection '" + m_connectionName
+ "'");
              }
          }
  
      }
  
      public void dispose() {
          if (m_publisher != null) {
              try {
                  m_publisher.close();
              } catch (JMSException e) {
                  getLogger().error("Error closing publisher.", e);
              }
          }
          if (m_session != null) {
              try {
                  m_session.close();
              }
              catch (JMSException e) {
                  getLogger().warn("Error closing session.", e);
              }
          }
          if (m_manager != null) {
              if (m_connectionManager != null) {
                  m_manager.release(m_connectionManager);
              }
          }
      }
  
      // ---------------------------------------------------- Implementation
  
      /**
       * Concrete classes call this method to publish messages.
       */
      protected synchronized void publishMessage(Message message) throws JMSException {
          if (getLogger().isDebugEnabled()) {
              getLogger().debug("Publishing message '" + message + "'");
          }
          m_publisher.publish(message, m_mode, m_priority, m_timeToLive);
      }
  
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/conf/jms-connection-manager.xconf
  
  Index: jms-connection-manager.xconf
  ===================================================================
  <?xml version="1.0"?>
  <!--
    Copyright 1999-2004 The Apache Software Foundation
  
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
  
        http://www.apache.org/licenses/LICENSE-2.0
  
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->
  <xconf xpath="/cocoon" unless="jms-connection-manager">
    <jms-connection-manager logger="core.jms">
      <topic-connection name="local-topics">
        <!-- +
          | JNDI Parameters must be specified with their literal values here.
          | For example, javax.naming.Context.INITIAL_CONTEXT_FACTORY is 
          | equivalent to "java.naming.factory.initial".  If a jndi.properties 
          | file is on the classpath, jndi-info can be left empty to use those 
          | properties instead.
          + -->
        <parameter name="java.naming.factory.initial" value="org.exolab.jms.jndi.InitialContextFactory"/>
        <parameter name="java.naming.provider.url" value="rmi://localhost:1099/"/>
        <!-- OpenJMS RMI topic connection factory -->
        <parameter name="connection-factory" value="JmsTopicConnectionFactory"/>
        <!-- optional username and password
        <parameter name="username" value="user"/>
        <parameter name="password" value="secret"/>
        -->
      </topic-connection>
    </jms-connection-manager>
  </xconf>
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/conf/jms-connection-manager.xroles
  
  Index: jms-connection-manager.xroles
  ===================================================================
  <?xml version="1.0"?>
  <!--
    Copyright 1999-2004 The Apache Software Foundation
  
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
  
        http://www.apache.org/licenses/LICENSE-2.0
  
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->
  <xroles xpath="/role-list" unless="role[@shorthand='jms-connection-manager']">
  
    <role name="org.apache.cocoon.components.jms.JMSConnectionManager"
          shorthand="jms-connection-manager"
          default-class="org.apache.cocoon.components.jms.JMSConnectionManagerImpl"/>
  
  </xroles>
  
  
  1.1                  cocoon-2.1/src/blocks/eventcache/java/org/apache/cocoon/caching/impl/JMSEventMessageListener.java
  
  Index: JMSEventMessageListener.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */package org.apache.cocoon.caching.impl;
  
  import javax.jms.Message;
  
  import org.apache.avalon.framework.parameters.ParameterException;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.caching.Cache;
  import org.apache.cocoon.caching.EventAware;
  import org.apache.cocoon.caching.validity.Event;
  import org.apache.cocoon.caching.validity.NamedEvent;
  import org.apache.cocoon.components.jms.AbstractMessageListener;
  
  /**
   * 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.
   * 
   * <p>Parameters:</p>
   * <table border="1">
   *  <tbody>
   *   <tr>
   *     <th align="left">parameter</th>
   *     <th align="left">required/default</th>
   *     <th align="left">description</th>
   *   </tr>
   *   <tr>
   *     <td>eventcache-role</td>
   *     <td>(org.apache.cocoon.caching.Cache/EventAware)</td>
   *     <td>The role name to lookup the event cache from the service manager.</td>
   *   </tr>
   *  </tbody>
   * </table>
   */
  public class JMSEventMessageListener extends AbstractMessageListener implements ThreadSafe
{
  
      // ---------------------------------------------------- Constants
  
      private static final String DEFAULT_EVENTCACHE_ROLE = Cache.ROLE + "/EventAware";
      private static final String EVENTCACHE_ROLE_PARAM = "eventcache-role";
  
      // ---------------------------------------------------- Instance variables
  
      private String m_eventAwareRole;
      private EventAware m_eventCache;
  
      // ---------------------------------------------------- Lifecycle
  
      public JMSEventMessageListener() {
      }
  
      public void parameterize(Parameters parameters) throws ParameterException {
          super.parameterize(parameters);
          m_eventAwareRole = parameters.getParameter(EVENTCACHE_ROLE_PARAM, DEFAULT_EVENTCACHE_ROLE);
      }
  
      public void dispose() {
          super.dispose();
          this.m_manager.release(m_eventCache);
      }
  
      /**
       * Notifies the event cache of events occurred.
       */
      public synchronized void onMessage(Message message) {
          if (getLogger().isDebugEnabled()) {
              getLogger().debug("Receiving message: " + message);
          }
          final Event[] events = eventsFromMessage(message);
          for (int i = 0; i < events.length; i++) {
              if (getLogger().isDebugEnabled()) {
                  getLogger().debug("Notifying " + m_eventAwareRole + " of " + events[i]);
              }
              m_eventCache.processEvent(events[i]);
          }
      }
  
      /**
       * Convert the message contents to (a series of) cache event. The default implementation

       * assumes that the message contains the trigger name, a '|', and a table name. 
       * It extracts the tablename and creates a NamedEvent with it. 
       * Override this method to provide a custom message to event mapping.
       * 
       * @param message  the JMS message.
       * @return  the cache event.
       */
      protected Event[] eventsFromMessage(Message message) {
          String name = message.toString();
          int pos = name.indexOf('|');
          return new Event[] { new NamedEvent(name.substring(pos + 1)) };
      }
      
  }
  
  
  
  1.1                  cocoon-2.1/src/blocks/jms/java/org/apache/cocoon/acting/JMSPublisherAction.java
  
  Index: JMSPublisherAction.java
  ===================================================================
  /*
   * Copyright 1999-2004 The Apache Software Foundation.
   * 
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.apache.cocoon.acting;
  
  import java.util.Collections;
  import java.util.Map;
  
  import javax.jms.Message;
  
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.thread.ThreadSafe;
  import org.apache.cocoon.environment.Redirector;
  import org.apache.cocoon.environment.SourceResolver;
  
  import org.apache.cocoon.components.jms.AbstractMessagePublisher;
  
  /**
   * Action to publish TextMessages to a JMS Topic. For description of static
   * parameter configuration see {@link org.apache.cocoon.components.jms.AbstractMessagePublisher}
   * 
   * <p>Sitemap-Parameters:</p>
   * <table>
   *  <tbody>
   *   <tr><td>message</td><td>Content of TextMessage to publish (required,
no default)</td></tr>
   *  </tbody>
   * </table>
   */
  public class JMSPublisherAction extends AbstractMessagePublisher implements Action, ThreadSafe
{
  
      // ---------------------------------------------------- Constants
  
      private static final String MESSAGE_PARAM = "message";
  
      // ---------------------------------------------------- Lifecycle
  
      public JMSPublisherAction () {
      }
  
      // ---------------------------------------------------- Action
  
      public Map act(Redirector redirector,
                     SourceResolver resolver,
                     Map objectModel,
                     String source,
                     Parameters parameters) throws Exception {
  
          Map result = null;
          try {
              // publish the message
              final String event = parameters.getParameter(MESSAGE_PARAM);
              final Message message = m_session.createTextMessage(event);
              publishMessage(message);
              result = Collections.EMPTY_MAP;
          } catch (Exception e) {
              if (getLogger().isWarnEnabled()) {
                  getLogger().warn("Error delivering message.", e);
              }
          }
  
          return result;
      }
  
  }
  
  
  
  1.4       +11 -8     cocoon-2.1/src/blocks/jms/samples/database/sitemap.xmap
  
  Index: sitemap.xmap
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/jms/samples/database/sitemap.xmap,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- sitemap.xmap	11 Mar 2004 16:25:48 -0000	1.3
  +++ sitemap.xmap	1 Jul 2004 13:43:01 -0000	1.4
  @@ -27,14 +27,17 @@
           <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>
  +          <input-module name="request"/>
  +          <parameter-name>serverName</parameter-name>
           </map:matcher>
       </map:matchers>
       <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 name="jmsevent"
  +                  src="org.apache.cocoon.acting.JMSPublisherAction"
  +                  logger="sitemap.actions.jms">
  +        <parameter name="connection" value="local-topics"/>
  +        <parameter name="topic" value="topic1"/>
         </map:action>
       </map:actions>
   
  @@ -58,13 +61,13 @@
       <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: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:transform>
           <map:serialize/>
         </map:match>
       </map:pipeline>
  @@ -88,7 +91,7 @@
       <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:parameter name="message" value="action|{request-param:table}"/>
               </map:act>
               <map:read src="invalidated.xml"/>
           </map:match>
  
  
  
  1.1                  cocoon-2.1/src/blocks/eventcache/conf/jmslistener.xconf
  
  Index: jmslistener.xconf
  ===================================================================
  <?xml version="1.0"?>
  <!--
    Copyright 1999-2004 The Apache Software Foundation
  
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at
  
        http://www.apache.org/licenses/LICENSE-2.0
  
    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
  -->
  <xconf xpath="/cocoon" unless="component[@role='org.apache.cocoon.caching.impl.JMSEventMessageListener']">
  	<component class="org.apache.cocoon.caching.impl.JMSEventMessageListener"
                 role="org.apache.cocoon.caching.impl.JMSEventMessageListener" logger="core.jms">
         <parameter name="connection" value="local-topics"/>
         <parameter name="topic" value="topic1"/>
         <!--
         <parameter name="eventcache-role" value="org.apache.cocoon.caching.Cache/EventAware"/>
         -->
      </component>
  </xconf>
  
  
  
  1.164     +3 -2      cocoon-2.1/gump.xml
  
  Index: gump.xml
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/gump.xml,v
  retrieving revision 1.163
  retrieving revision 1.164
  diff -u -r1.163 -r1.164
  --- gump.xml	1 Jul 2004 07:29:06 -0000	1.163
  +++ gump.xml	1 Jul 2004 13:43:01 -0000	1.164
  @@ -154,6 +154,7 @@
       <depend project="cocoon-block-batik" type="samples"/>
       <depend project="cocoon-block-xsp"/>
       <depend project="cocoon-block-javaflow"/>
  +    <depend project="cocoon-block-repository"/>
   
       <work nested="tools/anttasks"/>
       <home nested="build/cocoon-@@DATE@@"/>
  @@ -912,6 +913,7 @@
       </ant>
   
       <depend project="cocoon" inherit="all"/>
  +    <depend project="cocoon-block-jms"/>
       <depend project="cocoon-block-xsp" type="samples"/>
   
       <work nested="build/cocoon-@@DATE@@/blocks/eventcache/dest"/>
  @@ -1028,7 +1030,6 @@
       </ant>
   
       <depend project="cocoon" inherit="all"/>
  -    <depend project="cocoon-block-eventcache"/>
       <depend project="cocoon-block-databases" type="samples"/>
       <depend project="cocoon-block-hsqldb"/>
   
  
  
  

Mime
View raw message