001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm; 014 015 import java.io.PrintStream; 016 import java.io.PrintWriter; 017 import org.jikesrvm.classloader.Atom; 018 import org.jikesrvm.classloader.RVMMember; 019 020 /** 021 * The subclasses of PrintContainer all implement the {@link PrintLN} 022 * interface. They are used by our {@link java.lang.Throwable} to print stack 023 * traces; it lets one use a single class to operate on {@link PrintWriter} 024 * and {@link PrintStream} output streams and for the {@link VM#sysWrite} 025 * output method. 026 * 027 * <p> We use it so we can print stack traces without having to provide 028 * multiple versions of each method, one for each kind of output stream. 029 */ 030 public final class PrintContainer { 031 /** Can not be instantiated. */ 032 private PrintContainer() {} 033 034 /** Print via PrintWriter */ 035 private static class WithPrintWriter extends PrintLN { 036 private PrintWriter out; 037 038 WithPrintWriter(PrintWriter out) { 039 this.out = out; 040 } 041 042 @Override 043 public void flush() { 044 out.flush(); 045 } 046 047 @Override 048 public void println() { 049 out.println(); 050 } 051 052 @Override 053 public void print(String s) { 054 if (s == null) { 055 s = "(*null String pointer*)"; 056 } 057 out.print(s); 058 } 059 060 @Override 061 public void print(char c) { 062 out.print(c); 063 } 064 } 065 066 /** Print via PrintStream */ 067 private static class WithPrintStream extends PrintLN { 068 private PrintStream out; 069 070 WithPrintStream(PrintStream out) { 071 this.out = out; 072 } 073 074 @Override 075 public boolean isSystemErr() { 076 return this.out == System.err; 077 } 078 079 @Override 080 public void flush() { 081 out.flush(); 082 } 083 084 @Override 085 public void println() { 086 out.println(); 087 } 088 089 @Override 090 public void print(String s) { 091 if (s == null) { 092 s = "(*null String pointer*)"; 093 } 094 out.print(s); 095 } 096 097 @Override 098 public void print(char c) { 099 out.print(c); 100 } 101 } 102 103 public static PrintLN get(PrintStream out) { 104 return new WithPrintStream(out); 105 } 106 107 public static PrintLN get(PrintWriter out) { 108 return new WithPrintWriter(out); 109 } 110 111 // Keep this one ready to go at all times :) 112 public static final PrintLN readyPrinter = new WithSysWrite(); 113 114 /** This (nested) class does printing via {@link VM#sysWrite} */ 115 private static class WithSysWrite extends PrintLN { 116 /** This doesn't carry any state, but we have a constructor so that we can 117 * pass an instance of this to something expecting a {@link PrintLN} . */ 118 WithSysWrite() {} 119 120 @Override 121 public boolean isSysWrite() { 122 return true; 123 } 124 125 @Override 126 public void flush() { 127 } 128 129 @Override 130 public void println() { 131 VM.sysWriteln(); 132 } 133 134 @Override 135 public void print(String s) { 136 if (s == null) { 137 s = "(*null String pointer*)"; 138 } 139 140 VM.sysWrite(s); 141 } 142 143 @Override 144 public void println(String s) { 145 print(s); 146 println(); 147 } 148 149 @Override 150 public void print(int i) { 151 VM.sysWrite(i); 152 } 153 154 @Override 155 public void printHex(int i) { 156 VM.sysWriteHex(i); 157 } 158 159 @Override 160 public void print(char c) { 161 VM.sysWrite(c); 162 } 163 164 @Override 165 public void print(RVMMember m) { 166 VM.sysWrite(m); 167 } 168 169 @Override 170 public void print(Atom a) { 171 VM.sysWrite(a); 172 } 173 } 174 } 175