001 /**
002 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003 */
004 package net.sourceforge.pmd.cpd;
005
006 import java.io.File;
007 import java.io.FileInputStream;
008 import java.io.InputStreamReader;
009 import java.io.LineNumberReader;
010 import java.io.Reader;
011 import java.io.StringReader;
012 import java.lang.ref.SoftReference;
013 import java.util.ArrayList;
014 import java.util.List;
015
016 import net.sourceforge.pmd.PMD;
017
018 public class SourceCode {
019
020 public static abstract class CodeLoader {
021 private SoftReference<List<String>> code;
022
023 public List<String> getCode() {
024 List<String> c = null;
025 if (code != null) {
026 c = code.get();
027 }
028 if (c != null) {
029 return c;
030 }
031 this.code = new SoftReference<List<String>>(load());
032 return code.get();
033 }
034
035 public abstract String getFileName();
036
037 protected abstract Reader getReader() throws Exception;
038
039 protected List<String> load() {
040 LineNumberReader lnr = null;
041 try {
042 lnr = new LineNumberReader(getReader());
043 List<String> lines = new ArrayList<String>();
044 String currentLine;
045 while ((currentLine = lnr.readLine()) != null) {
046 lines.add(currentLine);
047 }
048 return lines;
049 } catch (Exception e) {
050 e.printStackTrace();
051 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
052 } finally {
053 try {
054 if (lnr != null) {
055 lnr.close();
056 }
057 } catch (Exception e) {
058 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
059 }
060 }
061 }
062 }
063
064 public static class FileCodeLoader extends CodeLoader {
065 private File file;
066 private String encoding;
067
068 public FileCodeLoader(File file, String encoding) {
069 this.file = file;
070 this.encoding = encoding;
071 }
072
073 @Override
074 public Reader getReader() throws Exception {
075 return new InputStreamReader(new FileInputStream(file), encoding);
076 }
077
078 @Override
079 public String getFileName() {
080 return this.file.getAbsolutePath();
081 }
082 }
083
084 public static class StringCodeLoader extends CodeLoader {
085 public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
086
087 private String code;
088
089 private String name;
090
091 public StringCodeLoader(String code) {
092 this(code, DEFAULT_NAME);
093 }
094
095 public StringCodeLoader(String code, String name) {
096 this.code = code;
097 this.name = name;
098 }
099
100 @Override
101 public Reader getReader() {
102 return new StringReader(code);
103 }
104
105 @Override
106 public String getFileName() {
107 return name;
108 }
109 }
110
111 private CodeLoader cl;
112
113 public SourceCode(CodeLoader cl) {
114 this.cl = cl;
115 }
116
117 public List<String> getCode() {
118 return cl.getCode();
119 }
120
121 public StringBuffer getCodeBuffer() {
122 StringBuffer sb = new StringBuffer();
123 List<String> lines = cl.getCode();
124 for (String line : lines) {
125 sb.append(line);
126 sb.append(PMD.EOL);
127 }
128 return sb;
129 }
130
131 public String getSlice(int startLine, int endLine) {
132 StringBuffer sb = new StringBuffer();
133 List<String> lines = cl.getCode();
134 for (int i = startLine == 0 ? startLine :startLine - 1; i < endLine && i < lines.size(); i++) {
135 if (sb.length() != 0) {
136 sb.append(PMD.EOL);
137 }
138 sb.append(lines.get(i));
139 }
140 return sb.toString();
141 }
142
143 public String getFileName() {
144 return cl.getFileName();
145 }
146 }
|