001 /*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016 package org.opengion.fukurou.xml;
017
018 import org.opengion.fukurou.util.Closer ;
019 import org.opengion.fukurou.util.FileUtil ;
020
021 import java.io.PrintWriter ;
022 import java.io.BufferedWriter ;
023 import java.io.OutputStreamWriter ;
024 import java.io.FileOutputStream ;
025 import java.io.IOException ;
026 import java.io.File;
027 import java.io.StringReader ;
028 import java.io.FileNotFoundException ;
029 import java.io.UnsupportedEncodingException;
030 import java.util.Stack;
031 import java.util.List;
032 import java.util.ArrayList;
033 import java.util.Map;
034 import java.util.HashMap;
035
036 import org.xml.sax.Attributes;
037 import org.xml.sax.ext.DefaultHandler2;
038 import org.xml.sax.InputSource ;
039 import org.xml.sax.SAXException;
040 import org.xml.sax.SAXParseException;
041 import javax.xml.parsers.SAXParserFactory;
042 import javax.xml.parsers.SAXParser;
043 import javax.xml.parsers.ParserConfigurationException;
044
045 /**
046 * JSP/XMLファイルを読み取って、OGNode/OGElement オブジェクトを取得するã?パã?サークラスですã?
047 *
048 * 自åˆ??身がã?DefaultHandler2 を拡張してã�?�¾すã?で、パーサー本体になりますã?
049 * javax.xml.parsers および、org.w3c.dom の簡易å?ç�?‚’行いますã?
050 * read で、トãƒ??レベルの OGNode を読み込み、write で、ファイルに書きå?しますã?
051 * 通常の W3C 系の オブジェクトを利用しなã�??は、属æ?の並びé ?‚’保障するためですã?
052 * ただしã?属æ?のタブã?改行ã?失われますã?
053 * またã?属æ?値に含まれるCR(復帰), LF(改è¡?, TAB(タãƒ?はã€?半角スペã?スに置き換えられますã?
054 * これは、SAXParser 側での XML の仕様ã?関係で、属æ?は、正規化されるためですã?
055 *
056 * @og.rev 5.1.8.0 (2010/07/01) 新規作æ?
057 * @og.rev 5.1.9.0 (2010/08/01) static メソãƒ?ƒ‰をå»?¢。é?常のオブジェクトクラスとして扱ã�?�¾すã?
058 *
059 * @version 5.0
060 * @author Kazuhiko Hasegawa
061 * @since JDK6.0,
062 */
063 public class JspSaxParser extends DefaultHandler2 {
064 public static final String CR = System.getProperty("line.separator");
065
066 private final List<JspParserFilter> filters = new ArrayList<JspParserFilter>(); // 5.1.9.0 (2010/08/01)
067 private SAXParser parser = null;
068
069 // 以下ã?パã?ス時に使用する変数ã€?パã?ス毎に初期化するã?)
070 private Map<String,OGElement> idMap = null; // 5.1.9.0 (2010/08/01)
071 private Stack<OGNode> stack = null;
072
073 private OGNode ele = null; // 現時点のエレメントノーãƒ?
074 private String attTab = ""; // tagBefore のä¸?¬¡TEMP
075 private boolean inCDATA = false; // CDATA エレメントã?中かどã�?�‹の判å®?
076 private boolean inEntity = false; // Entity の中かどã�?�‹の判å®?
077 // private File file = null; // 処ç�?®Ÿ行中のファイルå�?
078 private String filename = null; // 処ç�?®Ÿ行中のファイルå�?
079
080 /**
081 * XMLファイルを読み込み、OGDocument を返しますã?
082 *
083 * å†?ƒ¨çš?�«は、SAXParserFactory から、SAXParser を構築し、Property にã€?
084 * http://xml.org/sax/properties/lexical-handler を設定してã�?�¾すã?
085 * コメントノードを処ç�?�™るためですã?
086 *
087 * @og.rev 5.1.9.0 (2010/08/01) static からノã?マルに変更
088 *
089 * @param aFile XMLファイル
090 *
091 * @return ファイルから読み取って構築したOGDocumentオブジェクãƒ?
092 */
093 public OGDocument read( final File aFile ) {
094
095 // JspSaxParser sxp = new JspSaxParser();
096 // sxp.setFile( aFile );
097 filename = aFile.getAbsolutePath() ;
098
099 try {
100 if( parser == null ) {
101 // SAXパã?サーファクトリを生æˆ?
102 SAXParserFactory spfactory = SAXParserFactory.newInstance();
103
104 // SAXパã?サーを生æˆ?
105 parser = spfactory.newSAXParser();
106
107 parser.setProperty("http://xml.org/sax/properties/lexical-handler", this); // LexicalHandler として
108 }
109 // XMLファイルを指定されたハンドラーで処ç�?�—まã�?
110 parser.parse( aFile, this );
111
112 } catch ( ParserConfigurationException ex ) {
113 String errMsg = "重大な構æ?エラーが発生しましたã€?
114 + CR + "\t" + ex.getMessage()
115 + CR + "\t" + aFile ;
116 throw new RuntimeException( errMsg,ex );
117 // 5.1.9.0 (2010/08/01) å»?¢
118 // } catch ( SAXNotRecognizedException ex ) {
119 // String errMsg = "XMLReader は、認識されなã�?©Ÿè?またã?プロパティー識別子を検å?しましたã€?
120 // + CR + "\t" + ex.getMessage()
121 // + CR + "\t" + aFile ;
122 // if( ex2 != null ) { errMsg = errMsg + CR + "\t" + ex2.getMessage(); }
123 // throw new RuntimeException( errMsg,ex );
124 // } catch ( SAXNotSupportedException ex ) {
125 // String errMsg = "XMLReader は、要求された操ä½?(状態またã?値の設å®? を実行できませんでしたã€?
126 // + CR + "\t" + ex.getMessage()
127 // + CR + "\t" + aFile ;
128 // if( ex2 != null ) { errMsg = errMsg + CR + "\t" + ex2.getMessage(); }
129 // throw new RuntimeException( errMsg,ex );
130 } catch ( SAXException ex ) {
131 String errMsg = "SAX のä¸?ˆ¬çš?�ªエラーが発生しましたã€?
132 + CR + "\t" + ex.getMessage()
133 + CR + "\t" + aFile ;
134 Exception ex2 = ex.getException();
135 if( ex2 != null ) { errMsg = errMsg + CR + "\t" + ex2.getMessage(); }
136 throw new RuntimeException( errMsg,ex );
137 } catch ( IOException ex ) {
138 String errMsg = "ファイル読取時にエラーが発生しましたã€?
139 + CR + "\t" + ex.getMessage()
140 + CR + "\t" + aFile ;
141 throw new RuntimeException( errMsg,ex );
142 // 5.1.9.0 (2010/08/01) å»?¢
143 // } catch( RuntimeException ex ) {
144 // String errMsg = "実行時エラーが発生しましたã€?
145 // + CR + "\t" + ex.getMessage()
146 // + CR + "\t" + aFile ;
147 // throw new RuntimeException( errMsg,ex );
148 }
149
150 return getDocument() ;
151 }
152
153 /**
154 * XML形式で表現されたã?æ–?—å?(String) から、OGDocument を構築しますã?
155 *
156 * 処ç�?š„にはã€?read( File ) と同じで、取りå?すå?がã?æ–?—å?とã�?�†ã�?�‘ですã?
157 * XMLファイルからの読み込みと異なりã?通常は、Element を表現したæ–?—å?が作æ?されますがã€?
158 * 返されるのは、OGDocument オブジェクトですã?
159 *
160 * @og.rev 5.1.9.0 (2010/08/01) static からノã?マルに変更
161 *
162 * @param str XML形式で表現された文字å?
163 *
164 * @return ファイルから読み取って構築しã�?OGDocumentオブジェクãƒ?
165 */
166 public OGDocument string2Node( final String str ) {
167
168 // JspSaxParser sxp = new JspSaxParser();
169 filename = null ;
170
171 try {
172 if( parser == null ) {
173 // SAXパã?サーファクトリを生æˆ?
174 SAXParserFactory spfactory = SAXParserFactory.newInstance();
175 // SAXパã?サーを生æˆ?
176 parser = spfactory.newSAXParser();
177
178 parser.setProperty("http://xml.org/sax/properties/lexical-handler", this); // LexicalHandler として
179 }
180
181 // XMLファイルを指定されたãƒ?ƒ•ォルトハンドラーで処ç�?�—まã�?
182 InputSource source = new InputSource( new StringReader( str ) );
183 parser.parse( source, this );
184
185 } catch ( ParserConfigurationException ex ) {
186 String errMsg = "重大な構æ?エラーが発生しましたã€?
187 + CR + ex.getMessage();
188 throw new RuntimeException( errMsg,ex );
189 // 5.1.9.0 (2010/08/01) å»?¢
190 // } catch ( SAXNotRecognizedException ex ) {
191 // String errMsg = "XMLReader は、認識されなã�?©Ÿè?またã?プロパティー識別子を検å?しましたã€?
192 // + CR + ex.getMessage();
193 // Exception ex2 = ex.getException();
194 // if( ex2 != null ) { errMsg = errMsg + CR + "\t" + ex2.getMessage(); }
195 // throw new RuntimeException( errMsg,ex );
196 } catch ( SAXException ex ) {
197 String errMsg = "SAX のä¸?ˆ¬çš?�ªエラーが発生しましたã€?
198 + CR + ex.getMessage();
199 Exception ex2 = ex.getException();
200 if( ex2 != null ) { errMsg = errMsg + CR + "\t" + ex2.getMessage(); }
201 throw new RuntimeException( errMsg,ex );
202 } catch ( IOException ex ) {
203 String errMsg = "ストリーãƒ?‚ªブジェクト作æ?時にエラーが発生しましたã€?
204 + CR + ex.getMessage();
205 throw new RuntimeException( errMsg,ex );
206 // 5.1.9.0 (2010/08/01) å»?¢
207 // } catch( RuntimeException ex ) {
208 // String errMsg = "実行時エラーが発生しましたã€?
209 // + CR + ex.getMessage();
210 // throw new RuntimeException( errMsg,ex );
211 }
212
213 return getDocument() ;
214 }
215
216 /**
217 * OGDocument を所定ã?ファイルに、XML形式で書きå?しますã?
218 *
219 * ここでは、UTF-8 æ–?—コードでの書きå?しですã?
220 *
221 * @og.rev 5.1.9.0 (2010/08/01) static からノã?マルに変更
222 *
223 * @param aFile 書きå?すファイル
224 * @param node 書きå?ã�?OGDocument
225 */
226 // public void write( final File aFile, final OGDocument node ) {
227 // write( aFile,node,"UTF-8" );
228 // }
229
230 /**
231 * OGDocument を所定ã?ファイルに、XML形式で書きå?しますã?
232 *
233 * @param aFile 書きå?すファイル
234 * @param node 書きå?ã�?OGDocument
235 */
236 public void write( final File aFile, final OGDocument node ) {
237 PrintWriter out = null;
238 String encode = node.getEncode();
239 try {
240 out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( new FileOutputStream(aFile),encode )));
241 // out.println( "<?xml version=\"1.0\" encoding=\"" + encode + "\"?>" );
242 out.println( node.toString() );
243 } catch ( FileNotFoundException ex ) {
244 String errMsg = "æŒ?®šされたパス名で示されるファイルが存在しませんでしたã€?
245 + CR + "\t" + ex.getMessage()
246 + CR + "\t" + aFile ;
247 throw new RuntimeException( errMsg,ex );
248 } catch ( UnsupportedEncodingException ex ) {
249 String errMsg = "æ–?—ã?エンコーãƒ?‚£ング(" + encode + ")がサポã?トされてã�?�¾せんã€?
250 + CR + "\t" + ex.getMessage()
251 + CR + "\t" + aFile ;
252 throw new RuntimeException( errMsg,ex );
253 // 5.1.9.0 (2010/08/01) å»?¢
254 // } catch( RuntimeException ex ) {
255 // String errMsg = "実行時エラーが発生しましたã€?
256 // + CR + "\t" + ex.getMessage()
257 // + CR + "\t" + aFile ;
258 // throw new RuntimeException( errMsg,ex );
259 }
260 finally {
261 Closer.ioClose( out );
262 }
263 }
264
265 /**
266 * ãƒ?‚£レクトリの再帰処ç�?�§パã?ス処ç�?‚’行いますã?
267 *
268 * @og.rev 5.1.9.0 (2010/08/01) static からノã?マルに変更
269 *
270 * @param fromFile 読み取りもとのファイル/フォルãƒ?
271 * @param toFile 書き込み先ã?ファイル/フォルãƒ?
272 */
273 public void copyDirectry( final File fromFile, final File toFile ) {
274 // コピã?å…?�Œファイルの場合ã?コピã?して、終äº?�™るã?
275 if( fromFile.exists() && fromFile.isFile() ) {
276 boolean isOK = false;
277 String name = fromFile.getName();
278 if( name.endsWith( ".jsp" ) || name.endsWith( ".xml" ) ) {
279 try {
280 OGDocument doc = read( fromFile );
281 if( doc != null && !filters.isEmpty() ) {
282 for( JspParserFilter filter: filters ) {
283 doc = filter.filter( doc );
284 if( doc == null ) { break; } // エラー、またã?処ç�??中止
285 }
286 }
287 if( doc != null ) {
288 write( toFile,doc );
289 isOK = true;
290 }
291 }
292 catch( RuntimeException ex ) {
293 // ex.printStackTrace();
294 System.out.println( ex.getMessage() );
295 }
296 }
297
298 // JSPやXMLでなã�??パã?スエラー、書きå?しエラーなど正常終äº?�§きなかったå?合ã?、バイナリコピã?
299 if( !isOK ) {
300 FileUtil.copy( fromFile,toFile,true );
301 }
302 return ;
303 }
304
305 // コピã?先ディレクトリが存在しなければ、作æ?する
306 if( !toFile.exists() ) {
307 if( !toFile.mkdirs() ) {
308 System.err.println( toFile + " の ãƒ?‚£レクトリ作æ?に失敗しましたã€? );
309 return ;
310 }
311 }
312
313 // ãƒ?‚£レクトリå†??ファイルをすべて取得すã‚?
314 File[] files = fromFile.listFiles();
315
316 // ãƒ?‚£レクトリå†??ファイルに対しコピã?処ç�?‚’行う
317 for( int i = 0; i<files.length; i++ ){
318 copyDirectry( files[i], new File( toFile, files[i].getName()) );
319 }
320 }
321
322 /**
323 * copyDirectry 処ç�?�§、OGDocument をフィルター処ç�?�™るオブジェクトを登録しますã?
324 *
325 * å†?ƒ¨リストへフィルターを追åŠ?�—ますã?
326 * フィルター処ç�??、追åŠ?�•れたé ?�«行われますã?
327 * å†?ƒ¨リストへの追åŠ??できますが、削除はできませんã€?
328 *
329 * @og.rev 5.1.9.0 (2010/08/01) 新規追åŠ?
330 *
331 * @param filter フィルターオブジェクãƒ?
332 */
333 public void addFilter( final JspParserFilter filter ) {
334 filters.add( filter );
335 }
336
337 /**
338 * サンプルプログラãƒ?�§すã?
339 *
340 * 引数の IN がファイルの場合ã?、OUTもファイルとして扱ã�?�¾すã?
341 * IN がフォルãƒ??場合ã?ã€?šŽ層にしたがって、å?帰çš?�«処ç�?‚’行い、OUT に出力しますã?
342 * フォルãƒ?šŽ層をパースしてã�?‚‹æœ?¸に、XMLとして処ç�?�§きなã�??処ç�?¸にエラーが発生しã�?
343 * などの場合ã?、バイナリコピã?を行いますã?
344 *
345 * "Usage: JspSaxParser <inFile|inDir> <outFile|outDir> [<JspParserFilter1> ?¥?¥?¥ ]"
346 *
347 * @param args コマンド引数配å?
348 * @throws Exception なんらかã?エラーが発生したå?å�?
349 */
350 public static void main( final String[] args ) throws Exception {
351 if( args.length < 2 ) {
352 System.out.println( "Usage: JspSaxParser <inFile|inDir> <outFile|outDir> [<JspParserFilter1> ?¥?¥?¥ ]" );
353 }
354
355 File in = new File( args[0] );
356 File out = new File( args[1] );
357
358 JspSaxParser jsp = new JspSaxParser();
359
360 if( args.length >= 3 ) {
361 for( int i=2; i<args.length; i++ ) {
362 JspParserFilter filter = (JspParserFilter)Class.forName( args[i] ).newInstance();
363 jsp.addFilter( filter );
364 }
365 }
366
367 jsp.copyDirectry( in,out );
368 }
369
370 /**
371 * 処ç�?¸のファイルオブジェクトを設定しますã?
372 *
373 * これは、エラー、ワーニング時ã?ファイル名を出力するために利用してã�?�¾すã?
374 *
375 * @og.rev 5.1.9.0 (2010/08/01) å»?¢
376 *
377 * @param file 処ç�?¸のファイルオブジェクãƒ?
378 */
379 // public void setFile( final File file ) {
380 // this.file = file;
381 // }
382
383 // ********************************************************************************************** //
384 // ** ** //
385 // ** ここから下ã?、DefaultHandler2 の実è£?�«なりますã? ** //
386 // ** ** //
387 // ********************************************************************************************** //
388
389 /**
390 * æ–?›¸の開始é?知を受け取りますã?
391 *
392 * インタフェース ContentHandler å†?? startDocument
393 *
394 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
395 * @see org.xml.sax.ContentHandler#startDocument()
396 */
397 @Override
398 public void startDocument() {
399 stack = new Stack<OGNode>();
400 ele = new OGDocument();
401 ((OGDocument)ele).setFilename( filename );
402
403 idMap = new HashMap<String,OGElement>(); // 5.1.9.0 (2010/08/01) 追åŠ?
404
405 attTab = ""; // tagBefore のä¸?¬¡TEMP
406 inCDATA = false; // CDATA エレメントã?中かどã�?�‹の判å®?
407 inEntity = false; // Entity の中かどã�?�‹の判å®?
408 }
409
410 /**
411 * 要ç´??開始é?知を受け取りますã?
412 *
413 * インタフェース ContentHandler å†?? startElement
414 *
415 * @param uri 名前空é–??µ?²?©。要ç´?�Œ名前空é–??µ?²?© を持たなã�??合ã?またã?名前空間å?ç�?�Œ実行されなã�??合ã? null
416 * @param localName 前置修飾子を含まなã�?ƒーカル名ã?名前空間å?ç�?�Œ行われなã�??合ã?空æ–?—å?
417 * @param qName 接頭辞を持つ修飾名ã?修飾名を使用できなã�??合ã?空æ–?—å?
418 * @param attributes 要ç´?�«付加された属æ?。属æ?が存在しなã�??合ã?空の Attributesオブジェクãƒ?
419 *
420 * @see org.xml.sax.helpers.DefaultHandler#startElement(String,String,String,Attributes)
421 * @see org.xml.sax.ContentHandler#startElement(String,String,String,Attributes)
422 */
423 @Override
424 public void startElement( final String uri, final String localName, final String qName, final Attributes attributes ) {
425
426 // OGElement newEle = new OGElement( qName,attTab,attributes,-1 );
427 OGElement newEle = new OGElement( qName,attributes );
428 String id = newEle.getId();
429 if( id != null ) { idMap.put( id,newEle ); } // 5.1.9.0 (2010/08/01) idをMapにキャãƒ?‚·ュ
430
431 ele.addNode( newEle );
432 stack.push( ele );
433 ele = newEle ;
434 }
435
436 /**
437 * 要ç´??のæ–?—データの通知を受け取りますã?
438 *
439 * エンãƒ?‚£ãƒ?‚£ーå†?�‹どã�?�‹を判断する、inEntity フラグã�?true の間ã?ã€?
440 * 何も処ç�?�—ませんã€?
441 *
442 * インタフェース ContentHandler å†?? characters
443 *
444 * @param cbuf æ–?—データ配å?
445 * @param off æ–?—é?列å?の開始位置
446 * @param len æ–?—é?列から使用される文字数
447 *
448 * @see org.xml.sax.helpers.DefaultHandler#characters(char[],int,int)
449 * @see org.xml.sax.ContentHandler#characters(char[],int,int)
450 */
451 @Override
452 public void characters( final char[] cbuf, final int off, final int len ) {
453 if( inEntity ) { return ; } // < â‡?< に変換されるã?で、エンãƒ?‚£ãƒ?‚£å†?�§は、なにもå?ç�?�—なã�??
454
455 String text = toText( cbuf,off,len );
456 if( inCDATA ) {
457 ele.addNode( text );
458 return ;
459 }
460
461 OGNode node = new OGNode( text );
462 ele.addNode( node );
463
464 // '\r'(CR:復帰)+ '\n'(LF:改è¡?の可能性があるがã€?'\n'(LF:改è¡?がã?より後ろにあるので、これで判定ã?
465 int lastIdx = text.lastIndexOf( '\n' );
466 if( lastIdx >= 0 ) {
467 attTab = text.substring( lastIdx+1 ); // 改行からã?æœ?¾Œまでの部åˆ?–‡字å?
468 }
469 else {
470 attTab = text; // 改行がなã�??で、すべて
471 }
472 }
473
474 /**
475 * CDATA セクションの開始を報告しますã?
476 *
477 * CDATA セクションのコンãƒ?ƒ³ãƒ??、正規ã? characters イベントを介して報告されますã?
478 * こã?イベントã?å¢?•Œの報告だけに使用されますã?
479 *
480 * インタフェース LexicalHandler å†?? startCDATA
481 *
482 * @see org.xml.sax.ext.DefaultHandler2#startCDATA()
483 * @see org.xml.sax.ext.LexicalHandler#startCDATA()
484 */
485 @Override
486 public void startCDATA() {
487 OGNode node = new OGNode();
488 node.setNodeType( OGNodeType.Cdata );
489
490 ele.addNode( node );
491 stack.push( ele );
492 ele = node ;
493 inCDATA = true;
494 }
495
496 /**
497 * CDATA セクションの終わりを報告しますã?
498 *
499 * インタフェース LexicalHandler å†?? endCDATA
500 *
501 * @see org.xml.sax.ext.DefaultHandler2#endCDATA()
502 * @see org.xml.sax.ext.LexicalHandler#endCDATA()
503 */
504 @Override
505 public void endCDATA() {
506 ele = stack.pop();
507 inCDATA = false;
508 }
509
510 /**
511 * DTD 宣è¨?�Œある場合ã?そã?開始を報告しますã?
512 *
513 * start/endDTD イベントã?、ContentHandler の
514 * start/endDocument イベントå?のæœ??の startElement イベントã?前に出現しますã?
515 *
516 * インタフェース LexicalHandler å†?? startDTD
517 *
518 * @param name æ–?›¸型名
519 * @param publicId 宣è¨?�•れた外部 DTD サブセãƒ?ƒˆの公開識別子ã? 宣è¨?�•れてã�?�ªã�??合ã? null
520 * @param systemId 宣è¨?�•れた外部 DTD サブセãƒ?ƒˆのシスãƒ?ƒ 識別子ã? 宣è¨?�•れてã�?�ªã�??合ã? nullã€?
521 * ドキュメントã?ベã?ス URI に対しては解決されなã�?�“とに 注意すること
522 * @see org.xml.sax.ext.DefaultHandler2#startDTD( String , String , String )
523 * @see org.xml.sax.ext.LexicalHandler#startDTD( String , String , String )
524 */
525 @Override
526 public void startDTD( final String name, final String publicId, final String systemId ) {
527 StringBuilder buf = new StringBuilder();
528 buf.append( "<!DOCTYPE " ).append( name );
529 if( publicId != null ) { buf.append( " PUBLIC \"" ).append( publicId ).append( "\"" ); }
530 if( systemId != null ) { buf.append( "\"" ).append( systemId).append( "\"" ); }
531
532 OGNode node = new OGNode( buf.toString() );
533 node.setNodeType( OGNodeType.DTD );
534 ele.addNode( node );
535 }
536
537 /**
538 * DTD 宣è¨??終わりを報告しますã?
539 *
540 * こã?メソãƒ?ƒ‰は、DOCTYPE 宣è¨??終わりを報告するメソãƒ?ƒ‰ですã?
541 * ここでは、何もしませんã€?
542 *
543 * インタフェース LexicalHandler å†?? endDTD
544 *
545 * @see org.xml.sax.ext.DefaultHandler2#endDTD()
546 * @see org.xml.sax.ext.LexicalHandler#endDTD()
547 */
548 @Override
549 public void endDTD() {
550 // ここでは何もしませんã€?
551 }
552
553 /**
554 * å†?ƒ¨および外部の XML エンãƒ?‚£ãƒ?‚£ーのä¸?ƒ¨の開始を報告しますã?
555 *
556 * インタフェース LexicalHandler の記述:
557 *
558 * ※ ここではã€?amp;lt; などのæ–?—å?がã?lt とã�?�†名ã?エンãƒ?‚£ãƒ?‚£ーで
559 * 報告されるため、å?の??»˜きのæ–?—å?に復å…?�—てã�?�¾すã?
560 * エンãƒ?‚£ãƒ?‚£ーå†?�‹どã�?�‹を判断する、inEntity フラグã‚?true にセãƒ?ƒˆしますã?
561 * inEntity=true の間ã?ã€?characters(char[],int,int) は、何も処ç�?�—ませんã€?
562 *
563 * @param name エンãƒ?‚£ãƒ?‚£ーの名前
564 * @see org.xml.sax.ext.LexicalHandler#startEntity(String)
565 */
566 @Override
567 public void startEntity( final String name ) {
568 String text = "&" + name + ";" ;
569 OGNode node = new OGNode( text );
570 ele.addNode( node );
571 inEntity = true;
572 }
573
574 /**
575 * エンãƒ?‚£ãƒ?‚£ーの終わりを報告しますã?
576 *
577 * インタフェース LexicalHandler の記述:
578 *
579 * ※ ここでは、inEntity=false を設定するだけですã?
580 *
581 * @param name エンãƒ?‚£ãƒ?‚£ーの名前
582 * @see org.xml.sax.ext.LexicalHandler#endEntity(String)
583 */
584 @Override
585 public void endEntity( final String name ) {
586 inEntity = false;
587 }
588
589 /**
590 * 要ç´?‚³ンãƒ?ƒ³ãƒ?�«含まれる無視できる空白æ–?—ã?通知を受け取りますã?
591 *
592 * インタフェース ContentHandler å†?? ignorableWhitespace
593 *
594 * @param cbuf æ–?—データ配å?(空白æ–??
595 * @param off æ–?—é?列å?の開始位置
596 * @param len æ–?—é?列から使用される文字数
597 *
598 * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[],int,int)
599 */
600 @Override
601 public void ignorableWhitespace( final char[] cbuf, final int off, final int len ) {
602 String text = toText( cbuf,off,len );
603 OGNode node = new OGNode( text );
604 ele.addNode( node );
605 }
606
607 /**
608 * æ–?›¸å†??任意ã?位置にある XML コメントを報告しますã?
609 *
610 * インタフェース LexicalHandler の記述:
611 *
612 * @param cbuf æ–?—データ配å?(コメント文å?
613 * @param off 配å?å†??開始位置
614 * @param len 配å?から読み取られるæ–?—数
615 *
616 * @see org.xml.sax.helpers.DefaultHandler#characters(char[],int,int)
617 */
618 @Override
619 public void comment( final char[] cbuf, final int off, final int len ) {
620 String text = toText( cbuf,off,len );
621 OGNode node = new OGNode( text );
622 node.setNodeType( OGNodeType.Comment );
623 ele.addNode( node );
624 }
625
626 /**
627 * 要ç´??終äº??知を受け取りますã?
628 *
629 * @param uri 名前空é–??µ?²?©。要ç´?�Œ名前空é–??µ?²?© を持たなã�??合ã?またã?名前空間å?ç�?�Œ実行されなã�??合ã? null
630 * @param localName 前置修飾子を含まなã�?ƒーカル名ã?名前空間å?ç�?�Œ行われなã�??合ã?空æ–?—å?
631 * @param qName 接頭辞を持つ修飾名ã?修飾名を使用できなã�??合ã?空æ–?—å?
632 *
633 * @see org.xml.sax.helpers.DefaultHandler#endElement(String,String,String)
634 * @see org.xml.sax.ContentHandler#endElement(String,String,String)
635 */
636 @Override
637 public void endElement( final String uri, final String localName, final String qName ) {
638 ele = stack.pop();
639 }
640
641 /**
642 * パã?サー警告ã?通知を受け取りますã?
643 *
644 * インタフェース org.xml.sax.ErrorHandler å†?? warning
645 *
646 * ここでは、パーサー警告ã?å†?®¹を標準エラーに表示しますã?
647 *
648 * @param ex 例外として符号化された警告情報
649 * @see org.xml.sax.ErrorHandler#warning(SAXParseException)
650 */
651 @Override
652 public void warning( final SAXParseException ex ) {
653 String errMsg = ex.getMessage() + ":" + ex.getPublicId()
654 + CR + "\t" + filename + " (" + ex.getLineNumber() + ")";
655 System.err.println( "WARNING:" + errMsg );
656 }
657
658 /**
659 * æ–?—é?列からã?æ–?—å?を作æ?しますã?(改行コードã?統ä¸?
660 *
661 * 処ç�?š„には、new String( cbuf,off,len ) ですが、XMLでリーãƒ?
662 * されたファイルは、改行コードがã€?\r'(CR:復帰)+ '\n'(LF:改è¡?ではなくã?
663 * '\n'(LF:改è¡? のみに処ç�?�•れますã?(されるよã�?�§すã?規定不æ?)
664 * そこで、実行環å¢??改行コーãƒ?System.getProperty("line.separator"))と
665 * 置き換えますã?
666 *
667 * @param cbuf æ–?—データ配å?
668 * @param off 配å?å†??開始位置
669 * @param len 配å?から読み取られるæ–?—数
670 *
671 * @return æœ?µ‚的な、Stringオブジェクãƒ?
672 */
673 private String toText( final char[] cbuf, final int off, final int len ) {
674 String text = new String( cbuf,off,len );
675 return text.replaceAll( "\n", CR );
676 }
677
678 /**
679 * OGDocument を取得しますã?
680 *
681 * @return æœ?µ‚的な、OGNodeオブジェクトに相当しまã�?
682 */
683 private OGDocument getDocument() {
684 OGDocument doc = null;
685 if( ele != null && ele.getNodeType() == OGNodeType.Document ) {
686 doc = (OGDocument)ele;
687 doc.setIdMap( idMap );
688 }
689 return doc;
690 }
691 }