1 /*
2 * Copyright 2003-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.codehaus.groovy.control.io;
17
18 import java.io.BufferedReader;
19 import java.io.IOException;
20
21 import org.codehaus.groovy.control.CompilerConfiguration;
22 import org.codehaus.groovy.control.Janitor;
23
24 /**
25 * For ReaderSources that can choose a parent class, a base that
26 * provides common functionality.
27 *
28 * @author <a href="mailto:cpoirier@dreaming.org">Chris Poirier</a>
29 * @version $Id: AbstractReaderSource.java 16798 2009-06-28 02:13:41Z hamletdrc $
30 */
31
32 public abstract class AbstractReaderSource implements ReaderSource {
33 protected CompilerConfiguration configuration; // Configuration data
34
35 public AbstractReaderSource(CompilerConfiguration configuration) {
36 if (configuration == null) {
37 throw new IllegalArgumentException("Compiler configuration must not be null!");
38 // ... or more relaxed?
39 // configuration = CompilerConfiguration.DEFAULT;
40 }
41 this.configuration = configuration;
42 }
43
44 /**
45 * Returns true if the source can be restarted (ie. if getReader()
46 * will return non-null on subsequent calls.
47 */
48 public boolean canReopenSource() {
49 return true;
50 }
51
52 private BufferedReader lineSource = null; // If set, a reader on the current source file
53 private String line = null; // The last line read from the current source file
54 private int number = 0; // The last line number read
55
56 /**
57 * Returns a line from the source, or null, if unavailable. If
58 * you supply a Janitor, resources will be cached.
59 */
60 public String getLine(int lineNumber, Janitor janitor) {
61 // If the source is already open and is passed the line we
62 // want, close it.
63 if (lineSource != null && number > lineNumber) {
64 cleanup();
65 }
66
67 // If the line source is closed, try to open it.
68 if (lineSource == null) {
69 try {
70 lineSource = new BufferedReader(getReader());
71 } catch (Exception e) {
72 // Ignore
73 }
74 number = 0;
75 }
76
77 // Read until the appropriate line number.
78 if (lineSource != null) {
79 while (number < lineNumber) {
80 try {
81 line = lineSource.readLine();
82 number++;
83 }
84 catch (IOException e) {
85 cleanup();
86 }
87 }
88
89 if (janitor == null) {
90 final String result = line; // otherwise cleanup() will wipe out value
91 cleanup();
92 return result;
93 } else {
94 janitor.register(this);
95 }
96 }
97
98 return line;
99 }
100
101 /**
102 * Cleans up any cached resources used by getLine().
103 */
104 public void cleanup() {
105 if (lineSource != null) {
106 try {
107 lineSource.close();
108 } catch (Exception e) {
109 // Ignore
110 }
111 }
112
113 lineSource = null;
114 line = null;
115 number = 0;
116 }
117
118 }