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 }