/*
 * This class autogenerated by com.mchange.v2.c3p0.codegen.BeangenDataSourceGenerator.
 * Tue Jan 09 11:50:57 EST 2018
 * DO NOT HAND EDIT!
 */

package com.mchange.v2.c3p0.impl;

import com.mchange.v2.c3p0.C3P0Registry;
import com.mchange.v2.c3p0.cfg.C3P0Config;
import com.mchange.v2.c3p0.impl.C3P0ImplUtils;
import com.mchange.v2.naming.JavaBeanObjectFactory;
import com.mchange.v2.naming.JavaBeanReferenceMaker;
import com.mchange.v2.naming.ReferenceIndirector;
import com.mchange.v2.naming.ReferenceMaker;
import com.mchange.v2.ser.IndirectlySerialized;
import com.mchange.v2.ser.Indirector;
import com.mchange.v2.ser.SerializableUtils;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Hashtable;
import java.util.logging.Logger;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;

/**
 * This class was generated by com.mchange.v2.c3p0.codegen.BeangenDataSourceGenerator.
 */
public class JndiRefDataSourceBase extends IdentityTokenResolvable implements Referenceable, Serializable
{
	protected PropertyChangeSupport pcs = new PropertyChangeSupport( this );
	
	protected PropertyChangeSupport getPropertyChangeSupport()
	{ return pcs; }
	protected VetoableChangeSupport vcs = new VetoableChangeSupport( this );
	
	protected VetoableChangeSupport getVetoableChangeSupport()
	{ return vcs; }
	private boolean caching = true;
	private String factoryClassLocation = C3P0Config.initializeStringPropertyVar("factoryClassLocation", C3P0Defaults.factoryClassLocation());
	private volatile String identityToken;
	private Hashtable jndiEnv;
	private Object jndiName;
	
	public boolean isCaching()
	{ return caching; }
	
	public void setCaching( boolean caching )
	{
		boolean oldVal = this.caching;
		this.caching = caching;
		if ( oldVal != caching )
			pcs.firePropertyChange( "caching", oldVal, caching );
	}
	
	public String getFactoryClassLocation()
	{ return factoryClassLocation; }
	
	public void setFactoryClassLocation( String factoryClassLocation )
	{
		String oldVal = this.factoryClassLocation;
		this.factoryClassLocation = factoryClassLocation;
		if ( ! eqOrBothNull( oldVal, factoryClassLocation ) )
			pcs.firePropertyChange( "factoryClassLocation", oldVal, factoryClassLocation );
	}
	
	public String getIdentityToken()
	{ return identityToken; }
	
	public void setIdentityToken( String identityToken )
	{
		String oldVal = this.identityToken;
		this.identityToken = identityToken;
		if ( ! eqOrBothNull( oldVal, identityToken ) )
			pcs.firePropertyChange( "identityToken", oldVal, identityToken );
	}
	
	public Hashtable getJndiEnv()
	{ return (jndiEnv != null ? (Hashtable) jndiEnv.clone() : null); }
	
	public void setJndiEnv( Hashtable jndiEnv )
	{
		Hashtable oldVal = this.jndiEnv;
		this.jndiEnv = (jndiEnv != null ? (Hashtable) jndiEnv.clone() : null);
		if ( ! eqOrBothNull( oldVal, jndiEnv ) )
			pcs.firePropertyChange( "jndiEnv", oldVal, jndiEnv );
	}
	
	public Object getJndiName()
	{ return (jndiName instanceof Name ? ((Name) jndiName).clone() : jndiName /* String */); }
	
	public void setJndiName( Object jndiName ) throws PropertyVetoException
	{
		Object oldVal = this.jndiName;
		if ( ! eqOrBothNull( oldVal, jndiName ) )
			vcs.fireVetoableChange( "jndiName", oldVal, jndiName );
		this.jndiName = (jndiName instanceof Name ? ((Name) jndiName).clone() : jndiName /* String */);
		if ( ! eqOrBothNull( oldVal, jndiName ) )
			pcs.firePropertyChange( "jndiName", oldVal, jndiName );
	}
	
	public void addPropertyChangeListener( PropertyChangeListener pcl )
	{ pcs.addPropertyChangeListener( pcl ); }
	
	public void addPropertyChangeListener( String propName, PropertyChangeListener pcl )
	{ pcs.addPropertyChangeListener( propName, pcl ); }
	
	public void removePropertyChangeListener( PropertyChangeListener pcl )
	{ pcs.removePropertyChangeListener( pcl ); }
	
	public void removePropertyChangeListener( String propName, PropertyChangeListener pcl )
	{ pcs.removePropertyChangeListener( propName, pcl ); }
	
	public PropertyChangeListener[] getPropertyChangeListeners()
	{ return pcs.getPropertyChangeListeners(); }
	
	public void addVetoableChangeListener( VetoableChangeListener vcl )
	{ vcs.addVetoableChangeListener( vcl ); }
	
	public void removeVetoableChangeListener( VetoableChangeListener vcl )
	{ vcs.removeVetoableChangeListener( vcl ); }
	
	public VetoableChangeListener[] getVetoableChangeListeners()
	{ return vcs.getVetoableChangeListeners(); }
	private boolean eqOrBothNull( Object a, Object b )
	{
		return
			a == b ||
			(a != null && a.equals(b));
	}
	
	private static final long serialVersionUID = 1;
	private static final short VERSION = 0x0001;
	
	private void writeObject( ObjectOutputStream oos ) throws IOException
	{
		oos.writeShort( VERSION );
		oos.writeBoolean(caching);
		oos.writeObject( factoryClassLocation );
		oos.writeObject( identityToken );
		oos.writeObject( jndiEnv );
		try
		{
			//test serialize
			SerializableUtils.toByteArray(jndiName);
			oos.writeObject( jndiName );
		}
		catch (NotSerializableException nse)
		{
			com.mchange.v2.log.MLog.getLogger( this.getClass() ).log(com.mchange.v2.log.MLevel.FINE, "Direct serialization provoked a NotSerializableException! Trying indirect.", nse);
			try
			{
				Indirector indirector = new com.mchange.v2.naming.ReferenceIndirector();
				oos.writeObject( indirector.indirectForm( jndiName ) );
			}
			catch (IOException indirectionIOException)
			{ throw indirectionIOException; }
			catch (Exception indirectionOtherException)
			{ throw new IOException("Problem indirectly serializing jndiName: " + indirectionOtherException.toString() ); }
		}
	}
	
	private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException
	{
		short version = ois.readShort();
		switch (version)
		{
			case VERSION:
				this.caching = ois.readBoolean();
				this.factoryClassLocation = (String) ois.readObject();
				this.identityToken = (String) ois.readObject();
				this.jndiEnv = (Hashtable) ois.readObject();
				// we create an artificial scope so that we can use the name o for all indirectly serialized objects.
				{
					Object o = ois.readObject();
					if (o instanceof IndirectlySerialized) o = ((IndirectlySerialized) o).getObject();
					this.jndiName = (Object) o;
				}
				this.pcs = new PropertyChangeSupport( this );
				this.vcs = new VetoableChangeSupport( this );
				break;
			default:
				throw new IOException("Unsupported Serialized Version: " + version);
		}
	}
	
	// JDK7 add-on
	public Logger getParentLogger() throws SQLFeatureNotSupportedException
	{ return C3P0ImplUtils.PARENT_LOGGER;}
	
	public String toString()
	{
		StringBuffer sb = new StringBuffer();
		sb.append( super.toString() );
		sb.append(" [ ");
		sb.append( "caching -> " + caching );
		sb.append( ", ");
		sb.append( "factoryClassLocation -> " + factoryClassLocation );
		sb.append( ", ");
		sb.append( "identityToken -> " + identityToken );
		sb.append( ", ");
		sb.append( "jndiEnv -> " + jndiEnv );
		sb.append( ", ");
		sb.append( "jndiName -> " + jndiName );
		
		String extraToStringInfo = this.extraToStringInfo();
		if (extraToStringInfo != null)
			sb.append( extraToStringInfo );
		sb.append(" ]");
		return sb.toString();
	}
	
	protected String extraToStringInfo()
	{ return null; }
	
	final static JavaBeanReferenceMaker referenceMaker = new com.mchange.v2.naming.JavaBeanReferenceMaker();
	
	static
	{
		referenceMaker.setFactoryClassName( "com.mchange.v2.c3p0.impl.C3P0JavaBeanObjectFactory" );
		referenceMaker.addReferenceProperty("caching");
		referenceMaker.addReferenceProperty("factoryClassLocation");
		referenceMaker.addReferenceProperty("identityToken");
		referenceMaker.addReferenceProperty("jndiEnv");
		referenceMaker.addReferenceProperty("jndiName");
	}
	
	public Reference getReference() throws NamingException
	{
		return referenceMaker.createReference( this );
	}
	
	private JndiRefDataSourceBase()
	{}
	
	public JndiRefDataSourceBase( boolean autoregister )
	{
		if (autoregister)
		{
			this.identityToken = C3P0ImplUtils.allocateIdentityToken( this );
			C3P0Registry.reregister( this );
		}
	}
}
