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 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 }