/*
 * Common Library for TBAS Softwares
 * Language: Java
 *
 * All Rights Reserved.
 * (c) Copyright 2002 by Tsukuba Bunko.
 *
 * $Id: ListDeserializer.java,v 1.1 2003/08/31 08:20:49 ppoi Exp $
 */
package tsukuba_bunko.resource;

import	java.util.List;

import	org.xml.sax.Attributes;
import	org.xml.sax.ContentHandler;
import	org.xml.sax.SAXException;


/**
 * List 構造を取得する <code>ValueDescerializer</code> です.
 * @author	$Author: ppoi $
 */
public class ListDeserializer	extends BasicDeserializer	{

	/**
	 * リスト
	 */
	private	List	_list = null;

	/**
	 * 要素を解析するための ResourceDeserializer
	 */
	private ResourceDeserializer	_itemDeserializer = null;

	/**
	 * 要素を解析するための ContentHandler
	 */
	private ContentHandler	_itemHandler = null;

	/**
	 * リスト要素のデータ型
	 */
	private String	_itemType = null;

	/**
	 * レベル
	 */
	private int	_level = 0;


	/**
	 * <code>ListDeserializer</code> のインスタンスを作成します.
	 */
	public ListDeserializer()
	{
		super();
	}


//
//	BasicDeserialzier の実装
//
	public void setTypeName( String typeName )
	{
		super.setTypeName( typeName );
		int	index = typeName.indexOf( '/' );
		if( index == -1 )	{
			throw new IllegalArgumentException( "illegal list item type. \"" + typeName + "\"" );
		}
		else	{
			_itemType = typeName.substring( index + 1 );
		}
	}


//
//	ContentHandler の実装
//
	public void startDocument()
	{
		_list = null;
		_level = 0;
	}

	public void endDocument()
	{
		setValue( _list );
		_list = null;
	}

	public void startPrefixMapping( String namespaceURI, String prefix )
		throws SAXException
	{
		if( _itemHandler != null )	{
			_itemHandler.startPrefixMapping( namespaceURI, prefix );
		}
	}

	public void endPrefixMapping( String namespaceURI )
		throws SAXException
	{
		if( _itemHandler != null )	{
			_itemHandler.endPrefixMapping( namespaceURI );
		}
	}

	public void startElement( String namespaceURI, String localName, String qName, Attributes attrs )
		throws SAXException
	{
		if( _list == null )	{
			_list = new java.util.ArrayList();
			_itemDeserializer = _mapping.getResourceDeserializer( _itemType );
			if( _itemDeserializer == null )	{
				throw new SAXException( "no deserializer for \"" + _itemType + "\"" );
			}
		}
		else if( _itemHandler == null )	{
			if( localName.equals("item") )	{
				_level++;
				_itemHandler = _itemDeserializer;
				_itemHandler.startElement( namespaceURI, localName, qName, attrs );
			}
			else	{
				throw new SAXException( "illegal structure. : non-item element \"" + qName + "\"" );
			}
		}
		else	{
			_level++;
			_itemHandler.startElement( namespaceURI, localName, qName, attrs );
		}
	}

	public void endElement( String namespaceURI, String localName, String qName )
		throws SAXException
	{
		try	{
		if( _itemHandler != null )	{
			_level--;
			_itemHandler.endElement( namespaceURI, localName, qName );
			if( _level == 0 )	{
				_list.add( _itemDeserializer.getValue() );
				_itemHandler = null;
			}
		}
		}catch( Exception e	)	{
			e.printStackTrace();
		}
	}

	public void processingInstruction( String target, String data )
		throws SAXException
	{
		if( _itemHandler != null )	{
			_itemHandler.processingInstruction( target, data );
		}
	}

	public void skippedEntity( String name )
		throws SAXException
	{
		if( _itemHandler != null )	{
			_itemHandler.skippedEntity( name );
		}
	}

	public void characters( char[] ch, int begin, int length )
		throws SAXException
	{
		if( _itemHandler != null )	{
			_itemHandler.characters( ch, begin, length );
		}
	}

	public void ignorableWhitespace( char[] ch, int begin, int length )
		throws SAXException
	{
		if( _itemHandler != null )	{
			_itemHandler.ignorableWhitespace( ch, begin, length );
		}
	}
}
