//
// JmsaCF.java - JMS Adapter ConnectionFactory base class
//
// JmsaCFs are "administered" objects and can be registered in JNDI.
// Some JNDI implementation use serialization to do this.
// Other implementations (such as the filesystem one) use the Referenceable
// mechanism, and if this is used, we arrange that the Reference includes a
// byte buffer containing serialised properties, and the name of a
// object factory which is able to unserialise and reconstruct the object.
//

package nyangau.jmsadapter;

import java.util.*;
import java.io.*;
import javax.naming.*;
import javax.jms.*;

public class JmsaCF implements Serializable, Referenceable
  {
  protected HashMap<String,Object> properties;
  protected transient FlowProcessor fp;
//...sJmsaCF:2:
public JmsaCF() {} // to allow deserialisation only
public JmsaCF(Map<String,Object> map)
  {
  properties = new HashMap<String,Object>();
  if ( map != null )
    properties.putAll(map);
  fp = null;
  }
public JmsaCF(Map<String,Object> map, Map<String,Object> map2)
  {
  properties = new HashMap<String,Object>();
  if ( map != null )
    properties.putAll(map);
  if ( map2 != null )
    properties.putAll(map2);
  fp = null;
  }
//...e
//...sgetReference:2:
public Reference getReference()
  throws NamingException
  {
  Reference r = new Reference( 
    getClass().getName(),
    JmsaCFObjectFactory.class.getName(),
    null // factoryLocation
    );
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  try
    {
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    oos.writeObject(properties);
    oos.flush();
    }
  catch ( IOException e )
    {
    throw new NamingException("Cannot serialize properties to make a reference");
    }
  r.add(new BinaryRefAddr("properties", baos.toByteArray()));
  return r;
  }
//...e
//...sfindFactory:2:
// Caller will cast to appropriate factory type.
// We don't cast to a base class here, as there is no single common class.

protected Object findFactory()
  throws JMSException
  {
  String n = (String) properties.get(Jmsa.UNDERLYING_CONNECTION_FACTORY);
  if ( n == null )
    throw new JMSException("undefined underlying factory");
  try
    {
    Hashtable<String,Object> env = new Hashtable<String,Object>(properties);
    Context ctx = new InitialContext(env);
    return ctx.lookup(n);
    }
  catch ( NamingException e )
    {
    JMSException je = new JMSException("cannot lookup underlying factory " + n); 
    je.setLinkedException(e);
    throw je;
    }
  }
//...e
//...sgetFlowProcessor:2:
protected FlowProcessor getFlowProcessor()
  throws JMSException
  {
  if ( fp == null )
    try
      {
      fp = new FlowProcessor(properties);
      }
    catch ( FlowProcessorException e )
      {
      JMSException je = new JMSException("can't create FlowProcessor");
      je.setLinkedException(e);
      throw je;
      }
  return fp;
  }
//...e
  }
