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 */ 016package org.opengion.fukurou.xml; 017 018import javax.xml.transform.TransformerException ; 019import javax.xml.transform.ErrorListener; 020import javax.xml.transform.SourceLocator; 021 022import org.xml.sax.ErrorHandler; 023import org.xml.sax.SAXParseException; 024 025import static org.opengion.fukurou.system.HybsConst.CR; 026import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.4.2.1 (2016/02/05) refactoring 027 028/** 029 * TransformerFactory、Transformer 等で発生するエラーや警告を補足する ErrorListener の実装クラスです。 030 * さらに、XMLReader 等で発生するエラーや警告を補足する ErrorHandler の実装クラスも兼ねています。 031 * 032 * ErrorListener や、ErrorHandler で捕らえたエラーを、内部の StringBuilder に書き出して、 033 * エラー発生時にその内容を、読み出します。 034 * 035 * TransformerFactory と Transformer に、同じオブジェクトを渡すことで、エラー発生時の 036 * 状況に応じて、メッセージが設定されていきます。 037 * 取り出しは、セットしたオブジェクトを、取り出して、toString() するだけにしています。 038 * 039 * @og.rev 6.4.0.2 (2015/12/11) 新規作成 040 * @og.rev 6.4.3.2 (2016/02/19) 新規作成 041 * 042 * @version 6.4 043 * @author Kazuhiko Hasegawa 044 * @since JDK8.0, 045 */ 046public class HybsErrorListener implements ErrorListener , ErrorHandler { 047 // 6.4.3.2 (2016/02/19) 最初から用意しておきます。 048 private final StringBuilder errBuf = new StringBuilder( BUFFER_MIDDLE ) ; 049 050 /** 051 * 引数なしのコンストラクタ。 052 * 053 * @og.rev 6.4.3.2 (2016/02/19) 内部の StringBuilder は、最初から用意しておきます。 054 */ 055 public HybsErrorListener() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 056 057 /** 058 * TransformerFactory,Transformer処理の、警告の通知を受け取ります。 059 * 060 * @param ex Transformer例外にカプセル化されたエラー情報 061 * @see javax.xml.transform.ErrorListener#warning( TransformerException ) 062 */ 063 @Override 064 public void warning( final TransformerException ex ) { errMsg( "Warning:" , ex ); } 065 066 /** 067 * TransformerFactory,Transformer処理の、回復可能なエラーの通知を受け取ります。 068 * 069 * @param ex Transformer例外にカプセル化されたエラー情報 070 * @see javax.xml.transform.ErrorListener#error( TransformerException ) 071 */ 072 @Override 073 public void error( final TransformerException ex ) { errMsg( "Error:" , ex ); } 074 075 /** 076 * TransformerFactory,Transformer処理の、回復できないエラーの通知を受け取ります。 077 * 078 * @param ex Transformer例外にカプセル化されたエラー情報 079 * @see javax.xml.transform.ErrorListener#fatalError( TransformerException ) 080 */ 081 @Override 082 public void fatalError( final TransformerException ex ) { errMsg( "Fatal:" , ex ); } 083 084 /** 085 * XML構文解析エラーまたは警告の、警告の通知を受け取ります。 086 * 087 * @param ex SAXParseException例外にカプセル化されたエラー情報 088 * @see org.xml.sax.ErrorHandler#warning( SAXParseException ) 089 */ 090 @Override 091 public void warning( final SAXParseException ex ) { errMsg( "Warning:" , ex ); } 092 093 /** 094 * XML構文解析エラーまたは警告の、回復可能なエラーの通知を受け取ります。 095 * 096 * @param ex SAXParseException例外にカプセル化されたエラー情報 097 * @see org.xml.sax.ErrorHandler#error( SAXParseException ) 098 */ 099 @Override 100 public void error( final SAXParseException ex ) { errMsg( "Error:" , ex ); } 101 102 /** 103 * XML構文解析エラーまたは警告の、回復できないエラーの通知を受け取ります。 104 * 105 * @param ex SAXParseException例外にカプセル化されたエラー情報 106 * @see org.xml.sax.ErrorHandler#fatalError( SAXParseException ) 107 */ 108 @Override 109 public void fatalError( final SAXParseException ex ) { errMsg( "Fatal:" , ex ); } 110 111 /** 112 * warning,error,fatalErrorの通知を受け取ります。 113 * 114 * @param type 例外の発生元( "Warning:","Error:","Fatal:" ) 115 * @param ex Transformer例外にカプセル化されたエラー情報 116 */ 117 private void errMsg( final String type , final TransformerException ex ) { 118 final SourceLocator locator = ex.getLocator(); // 例外発生元情報の取得 119 if( locator != null ) { 120 errBuf.append( " (" ).append( locator.getLineNumber() ).append( "): " ); 121 } 122 123 final String errMsg = ex.getMessage(); 124 // null という文字列が取得されているようです。 125 if( errMsg != null && !"null".equals( errMsg ) ) { 126 errBuf.append( type ).append( errMsg ).append( CR ); 127 } 128 129 Throwable cause = ex.getException(); // この例外がラップする例外を取得 130 if( cause instanceof TransformerException ) { 131 errMsg( "ラップ:" , (TransformerException)cause ); 132 } 133 134 cause = ex.getCause(); // この例外の原因となる例外を取得 135 if( cause instanceof TransformerException ) { 136 errMsg( "原因:" , (TransformerException)cause ); 137 } 138 } 139 140 /** 141 * warning,error,fatalErrorの通知を受け取ります。 142 * 143 * @param type 例外の発生元( "Warning:","Error:","Fatal:" ) 144 * @param ex SAXParseException例外にカプセル化されたエラー情報 145 */ 146 private void errMsg( final String type , final SAXParseException ex ) { 147 final int lineNo = ex.getLineNumber(); // 発生元テキストの終わりの行番号(最初は1、使用できない場合は、-1 148 if( lineNo >= 0 ) { 149 errBuf.append( " (" ).append( lineNo ).append( "): " ); 150 } 151 152 final String errMsg = ex.getMessage(); 153 // null という文字列が取得されるかどうかは、未確認です。 154 if( errMsg != null && !"null".equals( errMsg ) ) { 155 errBuf.append( type ).append( errMsg ).append( CR ); 156 } 157 158 Throwable cause = ex.getException(); // この例外がラップする例外を取得 159 if( cause instanceof SAXParseException ) { 160 errMsg( "ラップ:" , (SAXParseException)cause ); 161 } 162 163 cause = ex.getCause(); // この例外の原因となる例外を取得 164 if( cause instanceof SAXParseException ) { 165 errMsg( "原因:" , (SAXParseException)cause ); 166 } 167 } 168 169 /** 170 * 内部で保管しているエラーメッセージを返します。 171 * 172 * メソッド的には、getMessage() がよいのですが、ErrorListener のまま、 173 * オブジェクトとして文字列(メッセージ)を取り出すには、Objectから継承している 174 * toString() メソッドが、便利なので、こちらにしておきます。 175 * 176 * @return エラーメッセー 177 */ 178 @Override 179 public String toString() { return errBuf.toString(); } 180}