/*
*
* Copyright (c) void.fm
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* 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.
*
* Neither the name void.fm nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS 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 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* 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.
*
*/
package etm.contrib.integration.jca;
import etm.core.configuration.EtmManager;
import etm.core.configuration.EtmMonitorConfig;
import etm.core.configuration.EtmMonitorFactory;
import etm.core.configuration.XmlConfigParser;
import etm.core.configuration.XmlEtmConfigurator;
import etm.core.monitor.EtmMonitor;
import etm.core.util.Log;
import etm.core.util.LogAdapter;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.resource.Referenceable;
import javax.resource.ResourceException;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ResourceAdapter;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.transaction.xa.XAResource;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
/**
* A JCA connector that may be used to initialize and shutdown a JETM runtime within a Java EE environment.
* Supports both static or JNDI name exposal.
*
* @author void.fm
* @version $Revision$
* @since 1.2.2
*/
public class EtmMonitorConnector implements ResourceAdapter, Referenceable, Serializable {
private static final LogAdapter LOG = Log.getLog(EtmMonitorConnector.class);
private static final String DEFAULT_CONFIG_FILE_NAME = "jetm-config.xml";
private String configFileName = DEFAULT_CONFIG_FILE_NAME;
// null value jndi name indicates that JNDI registration is not required
private String jndiName;
private Reference reference;
public void setConfigFile(String fileName) {
configFileName = fileName;
}
public void setJndiName(String aJndiName) {
jndiName = aJndiName;
}
public void start(BootstrapContext aBootstrapContext) throws ResourceAdapterInternalException {
ClassLoader loader = EtmMonitor.class.getClassLoader();
URL resource = loader.getResource(configFileName);
if (resource == null) {
throw new ResourceAdapterInternalException("Unable to locate JETM config file " + configFileName + " in classpath.");
}
LOG.debug("Using JETM configuration file " + resource);
if (jndiName == null) {
// static usage
XmlEtmConfigurator.configure(resource);
EtmManager.getEtmMonitor().start();
} else {
// jndi usage
InputStream in = null;
InitialContext ctx = null;
try {
in = resource.openStream();
EtmMonitorConfig monitorConfig = XmlConfigParser.extractConfig(in);
EtmMonitor monitor = EtmMonitorFactory.createEtmMonitor(monitorConfig);
ctx = new InitialContext();
// todo this may not work due to missing sub contexts
EtmMonitorReference etmMonitorReference = new EtmMonitorReference();
etmMonitorReference.setReference(resource.toString());
ctx.bind(jndiName, etmMonitorReference);
EtmMonitorRepository.register(resource.toString(), monitor);
monitor.start();
} catch (Exception e) {
throw new ResourceAdapterInternalException(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// ignored
}
}
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
// ignored
}
}
}
}
reference = new Reference(EtmMonitorConnector.class.getName(), new StringRefAddr("configfile", resource.toString()));
}
public void stop() {
if (jndiName == null) {
EtmManager.getEtmMonitor().stop();
} else {
EtmMonitor monitor = EtmMonitorRepository.getMonitor((String) reference.get("configfile").getContent());
monitor.stop();
InitialContext ctx = null;
try {
ctx = new InitialContext();
ctx.unbind(jndiName);
} catch (NameNotFoundException e) {
// ignore
} catch (Exception e) {
LOG.warn("Unable to deregister JETM monitor " + jndiName + " from JNDI tree", e);
} finally {
if (ctx != null) {
try {
ctx.close();
} catch (NamingException e) {
// ignored
}
}
}
}
}
public void endpointActivation(MessageEndpointFactory aMessageEndpointFactory, ActivationSpec aActivationSpec) throws ResourceException {
}
public void endpointDeactivation(MessageEndpointFactory aMessageEndpointFactory, ActivationSpec aActivationSpec) {
}
public XAResource[] getXAResources(ActivationSpec[] aActivationSpecs) throws ResourceException {
return null;
}
public Reference getReference() throws NamingException {
return reference;
}
public void setReference(Reference aReference) {
throw new UnsupportedOperationException("Not supported.");
}
}