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