1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
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 }