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 net.sourceforge.pmd.PMD;
7
8 import java.io.File;
9 import java.io.FileReader;
10 import java.io.LineNumberReader;
11 import java.io.Reader;
12 import java.io.StringReader;
13 import java.lang.ref.SoftReference;
14 import java.util.ArrayList;
15 import java.util.List;
16
17 public class SourceCode {
18
19 public static abstract class CodeLoader {
20 private SoftReference code;
21
22 public List getCode() {
23 List c = null;
24 if (code != null) {
25 c = (List) code.get();
26 }
27 if (c != null) {
28 return c;
29 }
30 this.code = new SoftReference(load());
31 return (List) code.get();
32 }
33
34 public abstract String getFileName();
35
36 protected abstract Reader getReader() throws Exception;
37
38 protected List load() {
39 LineNumberReader lnr = null;
40 try {
41 lnr = new LineNumberReader(getReader());
42 List lines = new ArrayList();
43 String currentLine;
44 while ((currentLine = lnr.readLine()) != null) {
45 lines.add(currentLine);
46 }
47 return lines;
48 } catch (Exception e) {
49 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
50 } finally {
51 try {
52 if (lnr != null)
53 lnr.close();
54 } catch (Exception e) {
55 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
56 }
57 }
58 }
59 }
60
61 public static class FileCodeLoader extends CodeLoader {
62 private File file;
63
64 public FileCodeLoader(File file) {
65 this.file = file;
66 }
67
68 public Reader getReader() throws Exception {
69 return new FileReader(file);
70 }
71
72 public String getFileName() {
73 return this.file.getAbsolutePath();
74 }
75 }
76
77 public static class StringCodeLoader extends CodeLoader {
78 public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
79
80 private String source_code;
81
82 private String name;
83
84 public StringCodeLoader(String code) {
85 this(code, DEFAULT_NAME);
86 }
87
88 public StringCodeLoader(String code, String name) {
89 this.source_code = code;
90 this.name = name;
91 }
92
93 public Reader getReader() {
94 return new StringReader(source_code);
95 }
96
97 public String getFileName() {
98 return name;
99 }
100 }
101
102 private CodeLoader cl;
103
104 public SourceCode(CodeLoader cl) {
105 this.cl = cl;
106 }
107
108 public List getCode() {
109 return cl.getCode();
110 }
111
112 public StringBuffer getCodeBuffer() {
113 StringBuffer sb = new StringBuffer();
114 List lines = cl.getCode();
115 for (int i = 0; i < lines.size(); i++) {
116 sb.append((String) lines.get(i));
117 sb.append(PMD.EOL);
118 }
119 return sb;
120 }
121
122 public String getSlice(int startLine, int endLine) {
123 StringBuffer sb = new StringBuffer();
124 List lines = cl.getCode();
125 for (int i = startLine - 1; i < endLine && i < lines.size(); i++) {
126 if (sb.length() != 0) {
127 sb.append(PMD.EOL);
128 }
129 sb.append((String) lines.get(i));
130 }
131 return sb.toString();
132 }
133
134 public String getFileName() {
135 return cl.getFileName();
136 }
137 }