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