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 */ 349 public static void main( final String[] args ) throws Exception { 350 if( args.length < 2 ) { 351 System.out.println( "Usage: JspSaxParser <inFile|inDir> <outFile|outDir> [<JspParserFilter1> ??? ]" ); 352 } 353 354 File in = new File( args[0] ); 355 File out = new File( args[1] ); 356 357 JspSaxParser jsp = new JspSaxParser(); 358 359 if( args.length >= 3 ) { 360 for( int i=2; i<args.length; i++ ) { 361 JspParserFilter filter = (JspParserFilter)Class.forName( args[i] ).newInstance(); 362 jsp.addFilter( filter ); 363 } 364 } 365 366 jsp.copyDirectry( in,out ); 367 } 368 369 /** 370 * 処?のファイルオブジェクトを設定します? 371 * 372 * これは、エラー、ワーニング時?ファイル名を出力するために利用して?す? 373 * 374 * @og.rev 5.1.9.0 (2010/08/01) ? 375 * 376 * @param file 処?のファイルオブジェク? 377 */ 378 // public void setFile( final File file ) { 379 // this.file = file; 380 // } 381 382 // ********************************************************************************************** // 383 // ** ** // 384 // ** ここから下?、DefaultHandler2 の実?なります? ** // 385 // ** ** // 386 // ********************************************************************************************** // 387 388 /** 389 * ?の開始?知を受け取ります? 390 * 391 * インタフェース ContentHandler ?? startDocument 392 * 393 * @see org.xml.sax.helpers.DefaultHandler#startDocument() 394 * @see org.xml.sax.ContentHandler#startDocument() 395 */ 396 @Override 397 public void startDocument() { 398 stack = new Stack<OGNode>(); 399 ele = new OGDocument(); 400 ((OGDocument)ele).setFilename( filename ); 401 402 idMap = new HashMap<String,OGElement>(); // 5.1.9.0 (2010/08/01) 追? 403 404 attTab = ""; // tagBefore の?TEMP 405 inCDATA = false; // CDATA エレメント?中かど?の判? 406 inEntity = false; // Entity の中かど?の判? 407 } 408 409 /** 410 * 要??開始?知を受け取ります? 411 * 412 * インタフェース ContentHandler ?? startElement 413 * 414 * @param uri 名前空????。要?名前空???? を持たな??合?また?名前空間??実行されな??合? null 415 * @param localName 前置修飾子を含まな?ーカル名?名前空間??行われな??合?空?? 416 * @param qName 接頭辞を持つ修飾名?修飾名を使用できな??合?空?? 417 * @param attributes 要?付加された属?。属?が存在しな??合?空の Attributesオブジェク? 418 * 419 * @see org.xml.sax.helpers.DefaultHandler#startElement(String,String,String,Attributes) 420 * @see org.xml.sax.ContentHandler#startElement(String,String,String,Attributes) 421 */ 422 @Override 423 public void startElement( final String uri, final String localName, final String qName, final Attributes attributes ) { 424 425 // OGElement newEle = new OGElement( qName,attTab,attributes,-1 ); 426 OGElement newEle = new OGElement( qName,attributes ); 427 String id = newEle.getId(); 428 if( id != null ) { idMap.put( id,newEle ); } // 5.1.9.0 (2010/08/01) idをMapにキャ?ュ 429 430 ele.addNode( newEle ); 431 stack.push( ele ); 432 ele = newEle ; 433 } 434 435 /** 436 * 要??の?データの通知を受け取ります? 437 * 438 * エン??ー?ど?を判断する、inEntity フラグ?true の間?? 439 * 何も処?ません? 440 * 441 * インタフェース ContentHandler ?? characters 442 * 443 * @param cbuf ?データ配? 444 * @param off ??列?の開始位置 445 * @param len ??列から使用される文字数 446 * 447 * @see org.xml.sax.helpers.DefaultHandler#characters(char[],int,int) 448 * @see org.xml.sax.ContentHandler#characters(char[],int,int) 449 */ 450 @Override 451 public void characters( final char[] cbuf, final int off, final int len ) { 452 if( inEntity ) { return ; } // < ?< に変換される?で、エン???は、なにも??な?? 453 454 String text = toText( cbuf,off,len ); 455 if( inCDATA ) { 456 ele.addNode( text ); 457 return ; 458 } 459 460 OGNode node = new OGNode( text ); 461 ele.addNode( node ); 462 463 // '\r'(CR:復帰)+ '\n'(LF:改?の可能性があるが?'\n'(LF:改?が?より後ろにあるので、これで判定? 464 int lastIdx = text.lastIndexOf( '\n' ); 465 if( lastIdx >= 0 ) { 466 attTab = text.substring( lastIdx+1 ); // 改行から??までの部?字? 467 } 468 else { 469 attTab = text; // 改行がな??で、すべて 470 } 471 } 472 473 /** 474 * CDATA セクションの開始を報告します? 475 * 476 * CDATA セクションのコン???、正規? characters イベントを介して報告されます? 477 * こ?イベント??の報告だけに使用されます? 478 * 479 * インタフェース LexicalHandler ?? startCDATA 480 * 481 * @see org.xml.sax.ext.DefaultHandler2#startCDATA() 482 * @see org.xml.sax.ext.LexicalHandler#startCDATA() 483 */ 484 @Override 485 public void startCDATA() { 486 OGNode node = new OGNode(); 487 node.setNodeType( OGNodeType.Cdata ); 488 489 ele.addNode( node ); 490 stack.push( ele ); 491 ele = node ; 492 inCDATA = true; 493 } 494 495 /** 496 * CDATA セクションの終わりを報告します? 497 * 498 * インタフェース LexicalHandler ?? endCDATA 499 * 500 * @see org.xml.sax.ext.DefaultHandler2#endCDATA() 501 * @see org.xml.sax.ext.LexicalHandler#endCDATA() 502 */ 503 @Override 504 public void endCDATA() { 505 ele = stack.pop(); 506 inCDATA = false; 507 } 508 509 /** 510 * DTD 宣?ある場合?そ?開始を報告します? 511 * 512 * start/endDTD イベント?、ContentHandler の 513 * start/endDocument イベント?の??の startElement イベント?前に出現します? 514 * 515 * インタフェース LexicalHandler ?? startDTD 516 * 517 * @param name ?型名 518 * @param publicId 宣?れた外部 DTD サブセ?の公開識別子? 宣?れて???合? null 519 * @param systemId 宣?れた外部 DTD サブセ?のシス?識別子? 宣?れて???合? null? 520 * ドキュメント?ベ?ス URI に対しては解決されな?とに 注意すること 521 * @see org.xml.sax.ext.DefaultHandler2#startDTD( String , String , String ) 522 * @see org.xml.sax.ext.LexicalHandler#startDTD( String , String , String ) 523 */ 524 @Override 525 public void startDTD( final String name, final String publicId, final String systemId ) { 526 StringBuilder buf = new StringBuilder(); 527 buf.append( "<!DOCTYPE " ).append( name ); 528 if( publicId != null ) { buf.append( " PUBLIC \"" ).append( publicId ).append( "\"" ); } 529 if( systemId != null ) { buf.append( "\"" ).append( systemId).append( "\"" ); } 530 531 OGNode node = new OGNode( buf.toString() ); 532 node.setNodeType( OGNodeType.DTD ); 533 ele.addNode( node ); 534 } 535 536 /** 537 * DTD 宣??終わりを報告します? 538 * 539 * こ?メソ?は、DOCTYPE 宣??終わりを報告するメソ?です? 540 * ここでは、何もしません? 541 * 542 * インタフェース LexicalHandler ?? endDTD 543 * 544 * @see org.xml.sax.ext.DefaultHandler2#endDTD() 545 * @see org.xml.sax.ext.LexicalHandler#endDTD() 546 */ 547 @Override 548 public void endDTD() { 549 // ここでは何もしません? 550 } 551 552 /** 553 * ?および外部の XML エン??ーの?の開始を報告します? 554 * 555 * インタフェース LexicalHandler の記述: 556 * 557 * ※ ここでは?amp;lt; などの??が?lt と?名?エン??ーで 558 * 報告されるため、?の??きの??に復?て?す? 559 * エン??ー?ど?を判断する、inEntity フラグ?true にセ?します? 560 * inEntity=true の間??characters(char[],int,int) は、何も処?ません? 561 * 562 * @param name エン??ーの名前 563 * @see org.xml.sax.ext.LexicalHandler#startEntity(String) 564 */ 565 @Override 566 public void startEntity( final String name ) { 567 String text = "&" + name + ";" ; 568 OGNode node = new OGNode( text ); 569 ele.addNode( node ); 570 inEntity = true; 571 } 572 573 /** 574 * エン??ーの終わりを報告します? 575 * 576 * インタフェース LexicalHandler の記述: 577 * 578 * ※ ここでは、inEntity=false を設定するだけです? 579 * 580 * @param name エン??ーの名前 581 * @see org.xml.sax.ext.LexicalHandler#endEntity(String) 582 */ 583 @Override 584 public void endEntity( final String name ) { 585 inEntity = false; 586 } 587 588 /** 589 * 要?ン??含まれる無視できる空白??通知を受け取ります? 590 * 591 * インタフェース ContentHandler ?? ignorableWhitespace 592 * 593 * @param cbuf ?データ配?(空白?? 594 * @param off ??列?の開始位置 595 * @param len ??列から使用される文字数 596 * 597 * @see org.xml.sax.ContentHandler#ignorableWhitespace(char[],int,int) 598 */ 599 @Override 600 public void ignorableWhitespace( final char[] cbuf, final int off, final int len ) { 601 String text = toText( cbuf,off,len ); 602 OGNode node = new OGNode( text ); 603 ele.addNode( node ); 604 } 605 606 /** 607 * ???任意?位置にある XML コメントを報告します? 608 * 609 * インタフェース LexicalHandler の記述: 610 * 611 * @param cbuf ?データ配?(コメント文? 612 * @param off 配???開始位置 613 * @param len 配?から読み取られる?数 614 * 615 * @see org.xml.sax.helpers.DefaultHandler#characters(char[],int,int) 616 */ 617 @Override 618 public void comment( final char[] cbuf, final int off, final int len ) { 619 String text = toText( cbuf,off,len ); 620 OGNode node = new OGNode( text ); 621 node.setNodeType( OGNodeType.Comment ); 622 ele.addNode( node ); 623 } 624 625 /** 626 * 要??終??知を受け取ります? 627 * 628 * @param uri 名前空????。要?名前空???? を持たな??合?また?名前空間??実行されな??合? null 629 * @param localName 前置修飾子を含まな?ーカル名?名前空間??行われな??合?空?? 630 * @param qName 接頭辞を持つ修飾名?修飾名を使用できな??合?空?? 631 * 632 * @see org.xml.sax.helpers.DefaultHandler#endElement(String,String,String) 633 * @see org.xml.sax.ContentHandler#endElement(String,String,String) 634 */ 635 @Override 636 public void endElement( final String uri, final String localName, final String qName ) { 637 ele = stack.pop(); 638 } 639 640 /** 641 * パ?サー警告?通知を受け取ります? 642 * 643 * インタフェース org.xml.sax.ErrorHandler ?? warning 644 * 645 * ここでは、パーサー警告??を標準エラーに表示します? 646 * 647 * @param ex 例外として符号化された警告情報 648 * @see org.xml.sax.ErrorHandler#warning(SAXParseException) 649 */ 650 @Override 651 public void warning( final SAXParseException ex ) { 652 String errMsg = ex.getMessage() + ":" + ex.getPublicId() 653 + CR + "\t" + filename + " (" + ex.getLineNumber() + ")"; 654 System.err.println( "WARNING:" + errMsg ); 655 } 656 657 /** 658 * ??列から???を作?します?(改行コード?統? 659 * 660 * 処?には、new String( cbuf,off,len ) ですが、XMLでリー? 661 * されたファイルは、改行コードが?\r'(CR:復帰)+ '\n'(LF:改?ではなく? 662 * '\n'(LF:改? のみに処?れます?(されるよ?す?規定不?) 663 * そこで、実行環??改行コー?System.getProperty("line.separator"))と 664 * 置き換えます? 665 * 666 * @param cbuf ?データ配? 667 * @param off 配???開始位置 668 * @param len 配?から読み取られる?数 669 * 670 * @return ?的な、Stringオブジェク? 671 */ 672 private String toText( final char[] cbuf, final int off, final int len ) { 673 String text = new String( cbuf,off,len ); 674 return text.replaceAll( "\n", CR ); 675 } 676 677 /** 678 * OGDocument を取得します? 679 * 680 * @return ?的な、OGNodeオブジェクトに相当しま? 681 */ 682 private OGDocument getDocument() { 683 OGDocument doc = null; 684 if( ele != null && ele.getNodeType() == OGNodeType.Document ) { 685 doc = (OGDocument)ele; 686 doc.setIdMap( idMap ); 687 } 688 return doc; 689 } 690 }