001 /* 002 * Common usable utilities 003 * 004 * Copyright (c) 2006 Petr Hadraba <hadrabap@gmail.com> 005 * 006 * Author: Petr Hadraba 007 * 008 * -- 009 * 010 * XML Utilities 011 */ 012 013 package global.sandbox.xmlutilities; 014 015 import java.io.ByteArrayOutputStream; 016 import java.io.OutputStreamWriter; 017 import java.io.PrintStream; 018 import java.io.PrintWriter; 019 import java.nio.charset.Charset; 020 import java.util.Iterator; 021 import java.util.List; 022 import java.util.concurrent.CopyOnWriteArrayList; 023 024 /** 025 * Common exception related to XML Utilities. 026 * 027 * @author Petr Hadraba 028 * 029 * @since 1.2 030 */ 031 public class XmlUtilitiesException extends Exception implements Iterable<Throwable> { 032 033 private static final long serialVersionUID = 1L; 034 035 /** 036 * Consequent exception; usually finally block. 037 */ 038 private final List<Throwable> consequents = new CopyOnWriteArrayList<Throwable>(); 039 040 public XmlUtilitiesException() { 041 } 042 043 public XmlUtilitiesException(String message) { 044 super(message); 045 } 046 047 public XmlUtilitiesException(Throwable cause) { 048 super(cause); 049 } 050 051 public XmlUtilitiesException(String message, Throwable cause) { 052 super(message, cause); 053 } 054 055 private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[] {}; 056 057 public Throwable[] getConsequent() { 058 return consequents.toArray(EMPTY_THROWABLE_ARRAY); 059 } 060 061 public void addConsequent(Throwable consequent) { 062 this.consequents.add(consequent); 063 } 064 065 private static final String INTERNAL_ENCODING = "UTF-8"; 066 067 private static final Charset INTERNAL_CHARSET; 068 069 static { 070 INTERNAL_CHARSET = Charset.forName(INTERNAL_ENCODING); 071 } 072 073 private static final String CONSEQUENT_CAPTION = "By consequent: "; 074 075 @Override 076 public void printStackTrace(PrintStream s) { 077 printStackTrace(new WrappedPrintStream(s)); 078 } 079 080 @Override 081 public void printStackTrace(PrintWriter s) { 082 printStackTrace(new WrappedPrintWriter(s)); 083 } 084 085 @Override 086 public void printStackTrace() { 087 printStackTrace(System.err); 088 } 089 090 @Override 091 public Iterator<Throwable> iterator() { 092 return consequents.iterator(); 093 } 094 095 private void printStackTrace(PrintStreamOrWriter s) { 096 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 097 OutputStreamWriter osw = new OutputStreamWriter(baos, INTERNAL_CHARSET); 098 PrintWriter pw = new PrintWriter(osw); 099 super.printStackTrace(pw); 100 pw.flush(); 101 s.print(new String(baos.toByteArray(), INTERNAL_CHARSET)); 102 103 for (Throwable consequent : consequents) { 104 s.print(CONSEQUENT_CAPTION); 105 s.printStackTrace(consequent); 106 } 107 s.flush(); 108 } 109 110 private static interface PrintStreamOrWriter { 111 112 abstract void print(String text); 113 114 abstract void println(String text); 115 116 abstract void flush(); 117 118 abstract void printStackTrace(Throwable t); 119 120 } 121 122 private static class WrappedPrintWriter implements PrintStreamOrWriter { 123 124 private final PrintWriter printWriter; 125 126 WrappedPrintWriter(PrintWriter printWriter) { 127 this.printWriter = printWriter; 128 } 129 130 @Override 131 public void print(String text) { 132 printWriter.print(text); 133 } 134 135 @Override 136 public void println(String text) { 137 printWriter.println(text); 138 } 139 140 @Override 141 public void flush() { 142 printWriter.flush(); 143 } 144 145 @Override 146 public void printStackTrace(Throwable t) { 147 t.printStackTrace(printWriter); 148 } 149 150 } 151 152 private static class WrappedPrintStream implements PrintStreamOrWriter { 153 154 private final PrintStream printStream; 155 156 WrappedPrintStream(PrintStream printStream) { 157 this.printStream = printStream; 158 } 159 160 @Override 161 public void print(String text) { 162 printStream.print(text); 163 } 164 165 @Override 166 public void println(String text) { 167 printStream.println(text); 168 } 169 170 @Override 171 public void flush() { 172 printStream.flush(); 173 } 174 175 @Override 176 public void printStackTrace(Throwable t) { 177 t.printStackTrace(printStream); 178 } 179 180 } 181 182 }