001package components.simplewriter;
002
003import java.io.BufferedWriter;
004import java.io.FileWriter;
005import java.io.IOException;
006import java.io.OutputStreamWriter;
007import java.io.PrintWriter;
008
009/**
010 * {@code SimpleWriter} represented as {@link java.io.PrintWriter
011 * java.io.PrintWriter} with implementations of primary methods.
012 *
013 * @correspondence <pre>
014 * this.is_open = [$this.rep is open] and
015 *  this.ext_name = $this.name and
016 *  this.contents = [the contents of $this.rep]
017 * </pre>
018 * @convention [$this.rep is not null when the stream is open]
019 */
020public class SimpleWriter1L extends SimpleWriterSecondary {
021
022    /*
023     * Private members --------------------------------------------------------
024     */
025
026    /**
027     * The output stream.
028     */
029    private PrintWriter rep;
030    /**
031     * The stream name.
032     */
033    private String name;
034
035    /**
036     * Creator of initial representation.
037     */
038    private void createNewRep() {
039        this.rep = new PrintWriter(
040                new BufferedWriter(new OutputStreamWriter(System.out)));
041        this.name = "";
042    }
043
044    /*
045     * Constructors -----------------------------------------------------------
046     */
047
048    /**
049     * No-argument constructor (for output to stdout).
050     */
051    public SimpleWriter1L() {
052        this.createNewRep();
053    }
054
055    /**
056     * Constructor for output to given file.
057     *
058     * @param fileName
059     *            the name of the file to output to
060     */
061    public SimpleWriter1L(String fileName) {
062        try {
063            this.rep = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
064            this.name = fileName;
065        } catch (IOException e) {
066            throw new AssertionError("Violation of: " + fileName + " can be opened");
067        }
068    }
069
070    /*
071     * Standard methods -------------------------------------------------------
072     */
073
074    @Override
075    public final SimpleWriter newInstance() {
076        try {
077            return this.getClass().getConstructor().newInstance();
078        } catch (ReflectiveOperationException e) {
079            throw new AssertionError(
080                    "Cannot construct object of type " + this.getClass());
081        }
082    }
083
084    @Override
085    public final void clear() {
086        this.createNewRep();
087    }
088
089    @Override
090    public final void transferFrom(SimpleWriter source) {
091        assert source != null : "Violation of: source is not null";
092        assert source != this : "Violation of: source is not this";
093        assert source instanceof SimpleWriter1L
094                : "Violation of: source is of dynamic type SimpleWriter1L";
095        /*
096         * This cast cannot fail since the assert above would have stopped
097         * execution in that case.
098         */
099        SimpleWriter1L localSource = (SimpleWriter1L) source;
100        this.rep = localSource.rep;
101        this.name = localSource.name;
102        localSource.createNewRep();
103    }
104
105    /*
106     * Kernel methods ---------------------------------------------------------
107     */
108
109    @Override
110    public final void print(String s) {
111        assert s != null : "Violation of: s is not null";
112        assert this.rep != null : "Violation of: this is open";
113        this.rep.print(s);
114        this.rep.flush();
115    }
116
117    @Override
118    public final void print(int i) {
119        assert this.rep != null : "Violation of: this is open";
120        this.rep.print(i);
121        this.rep.flush();
122    }
123
124    @Override
125    public final void print(long x) {
126        assert this.rep != null : "Violation of: this is open";
127        this.rep.print(x);
128        this.rep.flush();
129    }
130
131    @Override
132    public final void print(double d) {
133        assert this.rep != null : "Violation of: this is open";
134        this.rep.print(d);
135        this.rep.flush();
136    }
137
138    @Override
139    public final void print(double d, int precision, boolean scientific) {
140        assert this.rep != null : "Violation of: this is open";
141        assert precision >= 0 : "Violation of: precision >= 0";
142        if (scientific) {
143            this.rep.printf("%." + precision + "e", d);
144        } else {
145            this.rep.printf("%." + precision + "f", d);
146        }
147        this.rep.flush();
148    }
149
150    @Override
151    public final void print(boolean b) {
152        assert this.rep != null : "Violation of: this is open";
153        this.rep.print(b);
154        this.rep.flush();
155    }
156
157    @Override
158    public final void print(char c) {
159        assert this.rep != null : "Violation of: this is open";
160        this.rep.print(c);
161        this.rep.flush();
162    }
163
164    @Override
165    public final void print(Object o) {
166        assert o != null : "Violation of: o is not null";
167        assert this.rep != null : "Violation of: this is open";
168        this.rep.print(o);
169        this.rep.flush();
170    }
171
172    @Override
173    public final void println(String s) {
174        assert s != null : "Violation of: s is not null";
175        assert this.rep != null : "Violation of: this is open";
176        this.rep.println(s);
177        this.rep.flush();
178    }
179
180    @Override
181    public final void println(int i) {
182        assert this.rep != null : "Violation of: this is open";
183        this.rep.println(i);
184        this.rep.flush();
185    }
186
187    @Override
188    public final void println(long x) {
189        assert this.rep != null : "Violation of: this is open";
190        this.rep.println(x);
191        this.rep.flush();
192    }
193
194    @Override
195    public final void println(double d) {
196        assert this.rep != null : "Violation of: this is open";
197        this.rep.println(d);
198        this.rep.flush();
199    }
200
201    @Override
202    public final void println(double d, int precision, boolean scientific) {
203        assert this.rep != null : "Violation of: this is open";
204        assert precision >= 0 : "Violation of: precision >= 0";
205        if (scientific) {
206            this.rep.printf("%." + precision + "e", d);
207        } else {
208            this.rep.printf("%." + precision + "f", d);
209        }
210        this.rep.println();
211        this.rep.flush();
212    }
213
214    @Override
215    public final void println(boolean b) {
216        assert this.rep != null : "Violation of: this is open";
217        this.rep.println(b);
218        this.rep.flush();
219    }
220
221    @Override
222    public final void println(char c) {
223        assert this.rep != null : "Violation of: this is open";
224        this.rep.println(c);
225        this.rep.flush();
226    }
227
228    @Override
229    public final void println() {
230        assert this.rep != null : "Violation of: this is open";
231        this.rep.println();
232        this.rep.flush();
233    }
234
235    @Override
236    public final void println(Object o) {
237        assert o != null : "Violation of: o is not null";
238        assert this.rep != null : "Violation of: this is open";
239        this.rep.println(o);
240        this.rep.flush();
241    }
242
243    @Override
244    public final void write(char c) {
245        assert this.rep != null : "Violation of: this is open";
246        this.rep.write(c);
247    }
248
249    @Override
250    public final String name() {
251        return this.name;
252    }
253
254    @Override
255    public final boolean isOpen() {
256        return this.rep != null;
257    }
258
259    @Override
260    public final void close() {
261        assert this.rep != null : "Violation of: this is open";
262        /*
263         * Flush stream before closing just in case the last output was with the
264         * write method which does not flush by default. It is possible (likely)
265         * that close would flush anyway, but at least in the case of System.out
266         * where we are not calling close, flush may still be needed.
267         */
268        this.rep.flush();
269        /*
270         * Close stream only if it is not connected to System.out.
271         */
272        if (!this.name.equals("")) {
273            this.rep.close();
274        }
275        this.rep = null;
276    }
277
278}