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