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;
/**
* [EMAIL PROTECTED] 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
* [EMAIL PROTECTED]
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> </td>
* <td valign="top">
* Name of the connection registered with
* [EMAIL PROTECTED]
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> </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="[EMAIL
PROTECTED]'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 [EMAIL PROTECTED]
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 [EMAIL PROTECTED]
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="[EMAIL
PROTECTED]'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"/>