View Javadoc

    1   /*
    2    * All Rights Reserved.
    3    * Copyright (C) 1999-2005 Tsukuba Bunko.
    4    *
    5    * Licensed under the BSD License ("the License"); you may not use
    6    * this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    *       http://www.tsukuba-bunko.org/licenses/LICENSE.txt
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   * $Id: ResourceLoader.java,v 1.2 2005/07/24 20:55:57 ppoi Exp $
    18   */
    19  package tsukuba_bunko.resource;
    20
    21  import	java.io.IOException;
    22
    23  import	java.net.URL;
    24
    25  import	java.util.Iterator;
    26  import	java.util.List;
    27
    28  import	javax.xml.parsers.ParserConfigurationException;
    29  import	javax.xml.parsers.SAXParserFactory;
    30
    31  import	org.xml.sax.Attributes;
    32  import	org.xml.sax.ContentHandler;
    33  import	org.xml.sax.Locator;
    34  import	org.xml.sax.SAXException;
    35  import	org.xml.sax.XMLReader;
    36
    37
    38  /***
    39   * リソースファイルを読み込む機能を提供します.
    40   * この実装では，マルチスレッドはサポートされません.
    41   * @author	$Author: ppoi $
    42   * @version	$Revision: 1.2 $
    43   */
    44  public class ResourceLoader implements ContentHandler	{
    45
    46  	/***
    47  	 * パースに使用する XMLReader
    48  	 */
    49  	private XMLReader	_parser = null;
    50
    51  	/***
    52  	 * DeserializerMapping
    53  	 */
    54  	private DeserializerMapping	_mapping = DeserializerMapping.newInstance();
    55
    56  	/***
    57  	 * 現在使用中の ResourceDeserializer
    58  	 */
    59  	private ResourceDeserializer	_currentDeserializer = null;
    60
    61  	/***
    62  	 * レベル
    63  	 */
    64  	private int	_level = 0;
    65
    66  	/***
    67  	 * パススタック
    68  	 */
    69  	private List	_stack = null;
    70
    71  	/***
    72  	 * テキストバッファ
    73  	 */
    74  	private StringBuffer	_text = null;
    75
    76
    77  	/***
    78  	 * リソースを管理する Resources
    79  	 */
    80  	private Resources	_resources = null;
    81
    82
    83  	/***
    84  	 * <code>ResourceLoader</code> のインスタンスを作成します.
    85  	 * @exception	ParserConfigurationException	JAXP が正しく構成されていない場合
    86  	 * @exception	SAXException	JAXP が正しく構成されていない場合
    87  	 */
    88  	public ResourceLoader()
    89  		throws ParserConfigurationException, SAXException
    90  	{
    91  		super();
    92
    93  		SAXParserFactory	factory = SAXParserFactory.newInstance();
    94  		factory.setNamespaceAware( true );
    95  		_parser = factory.newSAXParser().getXMLReader();
    96  		_parser.setContentHandler( this );
    97  	}
    98
    99
    100 	/***
    101 	 * リソースの解析に使用する <code>DeserializerMapping</code> を設定します.
    102 	 * @param	mapping	リソースの解析に使用する <code>DeserializerMapping</code>
    103 	 */
    104 	public void setDeserializerMapping( DeserializerMapping mapping )
    105 	{
    106 		_mapping = mapping;
    107 	}
    108
    109 	/***
    110 	 * リソースの解析に使用する <code>DeserializerMapping</code> を取得します.
    111 	 * @return	リソースの解析に使用する <code>DeserializerMapping</code>
    112 	 */
    113 	public DeserializerMapping getDeserializerMapping()
    114 	{
    115 		return _mapping;
    116 	}
    117
    118 	/***
    119 	 * リソースを読み込みます.
    120 	 * @param	resourceURL	リソースファイルの URL
    121 	 * @param	resources	リソースを登録する <code>Resources</code> オブジェクト
    122 	 */
    123 	public void loadResource( URL resourceURL, Resources resources )
    124 		throws IOException, IllegalResourceException
    125 	{
    126 		try	{
    127 			_resources = resources;
    128 			_parser.parse( resourceURL.toString() );
    129 			_resources = null;
    130 		}
    131 		catch( SAXException se )	{
    132 			throw new IllegalResourceException( se );
    133 		}
    134 	}
    135
    136 	/***
    137 	 * ResourceDeserializer を取得します。
    138 	 * @param	namespaceURI	XML namespace URI
    139 	 * @param	localName	tag name (local part)
    140 	 * @param	qName	tag name (quorified name)
    141 	 * @param	attrs	attributes
    142 	 * @throws	SAXException	不正なデータ型を検出した場合
    143 	 */
    144 	protected ResourceDeserializer getResourceDeserializer( String namespaceURI, String localName, String qName, Attributes attrs )
    145 		throws SAXException
    146 	{
    147 		if( _mapping == null )	{
    148 			return null;
    149 		}
    150
    151 		String	dataType = attrs.getValue( "type" );
    152 		if( dataType != null )	{
    153 			ResourceDeserializer	deserializer = _mapping.getResourceDeserializer( dataType );
    154 			if( deserializer == null )	{
    155 				throw new SAXException( "no deserializer for \"" + dataType + "\"" );
    156 			}
    157 			return deserializer;
    158 		}
    159 		else	{
    160 			return null;
    161 		}
    162 	}
    163
    164 	/***
    165 	 * 現在のパスを計算します.
    166 	 * @return	パス
    167 	 */
    168 	protected String getCurrentPath()
    169 	{
    170 		StringBuffer	buffer = new StringBuffer();
    171 		Iterator	itr = _stack.iterator();
    172 		if( itr.hasNext() )	{
    173 			itr.next();
    174 		}
    175
    176 		if( itr.hasNext() )	{
    177 			buffer.append( itr.next() );
    178 		}
    179 		while( itr.hasNext() )	{
    180 			buffer.append( "." );
    181 			buffer.append( itr.next() );
    182 		}
    183 		return new String(buffer);
    184 	}
    185
    186
    187 //
    188 //	ContentHandler の実装
    189 //
    190 	public void setDocumentLocator( Locator locator )
    191 	{
    192 	}
    193
    194 	public void startPrefixMapping( String namespaceURI, String prefix )
    195 		throws SAXException
    196 	{
    197 		if( _currentDeserializer != null )	{
    198 			_currentDeserializer.startPrefixMapping( namespaceURI, prefix );
    199 		}
    200 	}
    201
    202 	public void endPrefixMapping( String namespaceURI )
    203 		throws SAXException
    204 	{
    205 		if( _currentDeserializer != null )	{
    206 			_currentDeserializer.endPrefixMapping( namespaceURI );
    207 		}
    208 	}
    209
    210 	public void startDocument()
    211 	{
    212 		_stack = new java.util.ArrayList();
    213 		if( _mapping == null )	{
    214 			_mapping = DeserializerMapping.newInstance();
    215 		}
    216 	}
    217
    218 	public void endDocument()
    219 	{
    220 		_stack = null;
    221 	}
    222
    223 	public void startElement( String namespaceURI, String localName, String qName, Attributes attrs )
    224 		throws SAXException
    225 	{
    226 		if( _currentDeserializer != null )	{
    227 			_level++;
    228 			_currentDeserializer.startElement( namespaceURI, localName, qName, attrs );
    229 		}
    230 		else	{
    231 			_stack.add( qName );
    232
    233 			ResourceDeserializer	deserializer = getResourceDeserializer( namespaceURI, localName, qName, attrs );
    234 			if( deserializer != null )	{
    235 				_currentDeserializer = deserializer;
    236 				deserializer.setDeserializerMapping( _mapping );
    237 				_level++;
    238 				deserializer.startDocument();
    239 				deserializer.startElement( namespaceURI, localName, qName, attrs );
    240 			}
    241 			else	{
    242 				_text = new StringBuffer();
    243 			}
    244 		}
    245 	}
    246
    247 	public void endElement( String namespaceURI, String localName, String qName )
    248 		throws SAXException
    249 	{
    250 		if( _currentDeserializer != null )	{
    251 			_level--;
    252 			_currentDeserializer.endElement( namespaceURI, localName, qName );
    253 			if( _level == 0 )	{
    254 				_currentDeserializer.endDocument();
    255 				_resources.setResource( getCurrentPath(), _currentDeserializer.getValue() );
    256 				_stack.remove( _stack.size() - 1 );
    257 				_currentDeserializer = null;
    258 				_currentDeserializer = null;
    259 			}
    260 		}
    261 		else if( _text != null )	{
    262 			_resources.setResource( getCurrentPath(), new String(_text) );
    263 			_stack.remove( _stack.size() - 1 );
    264 		}
    265 		else	{
    266 			_stack.remove( _stack.size() - 1 );
    267 		}
    268 		_text = null;
    269 	}
    270
    271 	public void processingInstruction( String target, String data )
    272 		throws SAXException
    273 	{
    274 		if( _currentDeserializer != null )	{
    275 			_currentDeserializer.processingInstruction( target, data );
    276 		}
    277 	}
    278
    279 	public void skippedEntity( String name )
    280 		throws SAXException
    281 	{
    282 		if( _currentDeserializer != null )	{
    283 			_currentDeserializer.skippedEntity( name );
    284 		}
    285 	}
    286
    287 	public void characters( char[] ch, int begin, int length )
    288 		throws SAXException
    289 	{
    290 		if( _currentDeserializer != null )	{
    291 			_currentDeserializer.characters( ch, begin, length );
    292 		}
    293 		else if( _text != null )	{
    294 			_text.append( ch, begin, length );
    295 		}
    296 	}
    297
    298 	public void ignorableWhitespace( char[] ch, int begin, int length )
    299 		throws SAXException
    300 	{
    301 		if( _currentDeserializer != null )	{
    302 			_currentDeserializer.ignorableWhitespace( ch, begin, length );
    303 		}
    304 	}
    305 }