View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.cpd;
5   
6   import java.io.File;
7   import java.io.FileInputStream;
8   import java.io.InputStreamReader;
9   import java.io.LineNumberReader;
10  import java.io.Reader;
11  import java.io.StringReader;
12  import java.lang.ref.SoftReference;
13  import java.util.ArrayList;
14  import java.util.List;
15  
16  import net.sourceforge.pmd.PMD;
17  
18  import org.apache.commons.io.IOUtils;
19  
20  public class SourceCode {
21  
22      public static abstract class CodeLoader {
23  	private SoftReference<List<String>> code;
24  
25  	public List<String> getCode() {
26  	    List<String> c = null;
27  	    if (code != null) {
28  		c = code.get();
29  	    }
30  	    if (c != null) {
31  		return c;
32  	    }
33  	    this.code = new SoftReference<List<String>>(load());
34  	    return code.get();
35  	}
36  
37  	public abstract String getFileName();
38  
39  	protected abstract Reader getReader() throws Exception;
40  
41  	protected List<String> load() {
42  	    LineNumberReader lnr = null;
43  	    try {
44  		lnr = new LineNumberReader(getReader());
45  		List<String> lines = new ArrayList<String>();
46  		String currentLine;
47  		while ((currentLine = lnr.readLine()) != null) {
48  		    lines.add(currentLine);
49  		}
50  		return lines;
51  	    } catch (Exception e) {
52  		e.printStackTrace();
53  		throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
54  	    } finally {
55  	    	IOUtils.closeQuietly(lnr);
56  	    }
57  	}
58      }
59  
60      public static class FileCodeLoader extends CodeLoader {
61  	private File file;
62  	private String encoding;
63  
64  	public FileCodeLoader(File file, String encoding) {
65  	    this.file = file;
66  	    this.encoding = encoding;
67  	}
68  
69  	@Override
70  	public Reader getReader() throws Exception {
71  	    return new InputStreamReader(new FileInputStream(file), encoding);
72  	}
73  
74  	@Override
75  	public String getFileName() {
76  	    return file.getAbsolutePath();
77  	}
78      }
79  
80      public static class StringCodeLoader extends CodeLoader {
81  	public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
82  
83  	private String code;
84  
85  	private String name;
86  
87  	public StringCodeLoader(String code) {
88  	    this(code, DEFAULT_NAME);
89  	}
90  
91  	public StringCodeLoader(String code, String name) {
92  	    this.code = code;
93  	    this.name = name;
94  	}
95  
96  	@Override
97  	public Reader getReader() {
98  	    return new StringReader(code);
99  	}
100 
101 	@Override
102 	public String getFileName() {
103 	    return name;
104 	}
105     }
106 
107 
108 
109     public static class ReaderCodeLoader extends CodeLoader {
110 	    public static final String DEFAULT_NAME = "CODE_LOADED_FROM_READER";
111 
112 	    private Reader code;
113 
114 	    private String name;
115 
116 	    public ReaderCodeLoader(Reader code) {
117 		this(code, DEFAULT_NAME);
118 	    }
119 
120 	    public ReaderCodeLoader(Reader code, String name) {
121 		this.code = code;
122 		this.name = name;
123 	    }
124 
125 	    @Override
126 	    public Reader getReader() {
127 		return code;
128 	    }
129 
130 	    @Override
131 	    public String getFileName() {
132 		return name;
133 	    }
134     }
135 
136 
137 
138     private CodeLoader cl;
139 
140     public SourceCode(CodeLoader cl) {
141 	this.cl = cl;
142     }
143 
144     public List<String> getCode() {
145 	return cl.getCode();
146     }
147 
148     public StringBuilder getCodeBuffer() {
149 	StringBuilder sb = new StringBuilder();
150 	List<String> lines = cl.getCode();
151 	for (String line : lines) {
152 	    sb.append(line).append(PMD.EOL);
153 	}
154 	return sb;
155     }
156 
157     public String getSlice(int startLine, int endLine) {
158 	StringBuilder sb = new StringBuilder();
159 	List<String> lines = cl.getCode();
160         for (int i = startLine == 0 ? startLine :startLine - 1; i < endLine && i < lines.size(); i++) {
161             if (sb.length() != 0) {
162 		sb.append(PMD.EOL);
163 	    }
164 	    sb.append(lines.get(i));
165 	}
166 	return sb.toString();
167     }
168 
169     public String getFileName() {
170 	return cl.getFileName();
171     }
172 }