package daruma.wfs;

import daruma.wfs.transaction.InsertAnElementHandler;

/* !!! [06/08/22 18:56 I.Noda] !!! 
 * TransactionResultInfo を導入。
 */
import daruma.wfs.TransactionResultInfo ;

import daruma.xml.handler.MispDefaultHandler;
import daruma.xml.Lexicon ;

import daruma.storage_manager.StorageManager;
import daruma.storage_manager.StorageException;
import daruma.storage_manager.BulkInsertBuffer;

import org.xml.sax.XMLReader;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.OutputStream;


public class TransactionInsertHandler extends MispDefaultHandler
{
    private	StorageManager		storage;
    private	TransactionHandler	errorReceiver;

    private     InsertAnElementHandler  insertHandler;
    private	BulkInsertBuffer	bulkInsertBuffer;

    /* !!! [06/08/22 18:56 I.Noda] !!! 
     * TransactionResultInfo を導入。
     */
    private TransactionResultInfo resultInfo ;

    public	TransactionInsertHandler( OutputStream  out ,
					  XMLReader  parser ,
					  boolean  isTopLevelHandler ,
					  StorageManager  storage ,
					  TransactionHandler  errorReceiver,
					  /* !!! [06/08/22 18:56 I.Noda] !!! 
					   * TransactionResultInfo を導入。
					   */
					  TransactionResultInfo resultInfo)
    {
	super( out , parser , isTopLevelHandler );

	this.storage       = storage;
	this.errorReceiver = errorReceiver;

	this.insertHandler = null;
	this.bulkInsertBuffer = new BulkInsertBuffer();

	/* !!! [06/08/22 18:56 I.Noda] !!! 
	 * TransactionResultInfo を導入。
	 */
	this.resultInfo  = resultInfo;
	if(this.resultInfo.countInsert < 0) {
	    this.resultInfo.countInsert = 0 ;
	}

    }

    public	void	xStartElement( String uri ,
				       String localName ,
				       String qName ,
				       Attributes  attrs ) throws SAXException
    {
	assert super.getCurrentLevel() == 1
	    || super.getCurrentLevel() == 2;

	if ( super.getCurrentLevel() == 1 )
	{
	    Lexicon.MispInsert.matchesOrSaxException(uri, null, localName,
						     super.getLocator(),
						     "in Transaction") ;
	    return;
	}
	

	if( this.insertHandler == null )
	{
	    this.insertHandler
		= new InsertAnElementHandler( super.getOutputStream() ,
					      super.getParser() ,
					      false ,
					      this.storage ,
					      this.bulkInsertBuffer ,
					      this.errorReceiver ,
					      this.resultInfo );
	}
	else
	{
	    this.insertHandler.reset();
	}

	super.setContentHandlerDelegator( this.insertHandler,
					  uri, localName, qName, attrs );
    }

    public  void  xEndElement( String uri ,
			       String localName ,
			       String qName ) throws SAXException
    {
	try
	{
	    long nElements = this.bulkInsertBuffer.size();

	    this.storage.bulkInsertElement
		( this.bulkInsertBuffer,
		  super.getTransactionSN() );

	    this.resultInfo.countInsert += nElements;
	}
	catch( StorageException e )
	{
	    this.throwError( new SAXParseException
			     ( e.getMessage(),
			       super.getLocator(),
			       e ) );
	}
    }

    private void throwError( SAXParseException e ) throws SAXException
    {
	this.errorReceiver.notifyError( e );

	throw e;
    }
}
