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