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 }