SourceCode.java
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 == ? 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 }