/*
* Copyright (c) 2005 Thomas Weise
*
* E-Mail : tweise@gmx.de
* Creation Date : 2005-07-20 16:39:42
* Original Filename: org.sfc.xml.ReferenceCountedSAXSource.java
* Version : 1.0.2
* Last modification: 2006-03-07
* by: Thomas Weise
*
* License : GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
* You should have received a copy of this license along
* with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307, USA or download the license under
* http://www.gnu.org/copyleft/lesser.html.
*
* Warranty : This software is provided "as is" without any
* warranty; without even the implied warranty of
* merchantability or fitness for a particular purpose.
* See the Gnu Lesser General Public License for more
* details.
*/
package org.sfc.xml;
import java.io.IOException;
import javax.xml.transform.Result;
import javax.xml.transform.sax.SAXSource;
import org.xml.sax.InputSource;
import org.sfc.scoped.AlreadyDisposedException;
import org.sfc.scoped.IReferenceCounted;
/**
* A sax-source implementing the IReferenceCounted
-interface.
*
* @author Thomas Weise
*/
public final class ReferenceCountedSAXSource extends SAXSource
implements IReferenceCounted,
Result
{
/**
* The internal reference counter.
*/
private int m_ref_count ;
/**
* true
as long as this object is alive, false
if
* it died.
*/
private boolean m_living ;
/**
* Create a new closeable sax source.
*/
ReferenceCountedSAXSource ()
{
super();
this.m_living = true;
this.m_ref_count = 1;
}
/**
* Increase the reference counter of this object by one.
* You must call add_ref
before you assign a variable to point
* on this object (except when calling the constructor and storing the
* result to exactly one variable).
* @throws AlreadyDisposedException If the object has already been disposed.
*/
public final void add_ref () throws AlreadyDisposedException
{
synchronized(this)
{
if(this.m_living)
{
this.m_ref_count++;
}
else
{
throw new AlreadyDisposedException();
}
}
}
/**
* Copy the data from another sax-source to this one.
* @param p_ss The sax-source to be copied.
*/
public final void set_sax_source(final SAXSource p_ss)
{
InputSource l_x;
ReferenceCountedInputSource l_is;
l_x = p_ss.getInputSource();
if(l_x != null)
{
l_is = new ReferenceCountedInputSource();
l_is.set_input_source(l_x);
super.setInputSource(l_is);
}
else super.setInputSource(null);
this.setSystemId(p_ss.getSystemId());
}
/**
* Decrease the reference counter of this object by one.
* If the reference count reaches zero, the object will automatically
* perform cleanup operations. You must call release
whenever
* you don't need a variable pointing to this object anymore.
* @throws AlreadyDisposedException If the object has already been disposed.
*/
public final void release () throws AlreadyDisposedException
{
this.do_release();
}
/**
* Set the SAX InputSource to be used for the Source.
*
* @param p_input_source A valid InputSource reference.
*/
@Override
public final void setInputSource(final InputSource p_input_source)
{
ReferenceCountedInputSource l_x;
l_x = ((ReferenceCountedInputSource)(this.getInputSource()));
if(l_x != null) l_x.release();
super.setInputSource(XML.get_input_source(p_input_source));
}
/**
* Decrease the reference counter of this object by one.
* If the reference count reaches zero, the object will automatically
* perform cleanup operations. You must call release
whenever
* you don't need a variable pointing to this object anymore.
* @throws AlreadyDisposedException If the object has already been disposed.
* @return The IOException
that was thrown during closing of
* the object, or null
if everything was ok.
*/
final IOException do_release () throws AlreadyDisposedException
{
ReferenceCountedInputSource l_x;
synchronized(this)
{
if(this.m_living)
{
if( (--this.m_ref_count) <= 0)
{
this.m_living = false;
l_x = ((ReferenceCountedInputSource)(this.getInputSource()));
if(l_x != null) return l_x.do_release();
}
}
else
{
throw new AlreadyDisposedException();
}
}
return null;
}
/**
* Returns a new instance of the io object.
* @return Another port to the io object.
*/
@Override
public final Object clone ()
{
this.add_ref();
return this;
}
/**
* Cleanup this input source.
* @throws Throwable From the super implementation.
*/
@Override
protected final void finalize () throws Throwable
{
synchronized(this)
{
if(this.m_living)
{
this.m_ref_count = 1;
this.do_release();
this.m_living = false;
}
this.m_ref_count = 0;
}
super.finalize();
}
}