001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2008-2011 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020
021 /**
022 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
023 */
024 package net.sourceforge.pmd.cpd;
025
026 import java.io.*;
027 import java.lang.ref.SoftReference;
028 import java.util.ArrayList;
029 import java.util.List;
030
031 public class SourceCode {
032
033 public static final String EOL = System.getProperty("line.separator", "\n");
034
035 public static abstract class CodeLoader {
036 private SoftReference<List<String>> code;
037
038 public List<String> getCode() {
039 List<String> c = null;
040 if (code != null) {
041 c = code.get();
042 }
043 if (c != null) {
044 return c;
045 }
046 this.code = new SoftReference<List<String>>(load());
047 return code.get();
048 }
049
050 public abstract String getFileName();
051
052 protected abstract Reader getReader() throws Exception;
053
054 protected List<String> load() {
055 LineNumberReader lnr = null;
056 try {
057 lnr = new LineNumberReader(getReader());
058 List<String> lines = new ArrayList<String>();
059 String currentLine;
060 while ((currentLine = lnr.readLine()) != null) {
061 lines.add(currentLine);
062 }
063 return lines;
064 } catch (Exception e) {
065 e.printStackTrace();
066 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
067 } finally {
068 try {
069 if (lnr != null)
070 lnr.close();
071 } catch (Exception e) {
072 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage());
073 }
074 }
075 }
076 }
077
078 public static class FileCodeLoader extends CodeLoader {
079 private File file;
080 private String encoding;
081
082 public FileCodeLoader(File file, String encoding) {
083 this.file = file;
084 this.encoding = encoding;
085 }
086
087 public Reader getReader() throws Exception {
088 return new InputStreamReader(new FileInputStream(file), encoding);
089 }
090
091 public String getFileName() {
092 return this.file.getAbsolutePath();
093 }
094 }
095
096 public static class StringCodeLoader extends CodeLoader {
097 public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
098
099 private String source_code;
100
101 private String name;
102
103 public StringCodeLoader(String code) {
104 this(code, DEFAULT_NAME);
105 }
106
107 public StringCodeLoader(String code, String name) {
108 this.source_code = code;
109 this.name = name;
110 }
111
112 public Reader getReader() {
113 return new StringReader(source_code);
114 }
115
116 public String getFileName() {
117 return name;
118 }
119 }
120
121 private CodeLoader cl;
122
123 public SourceCode(CodeLoader cl) {
124 this.cl = cl;
125 }
126
127 public List<String> getCode() {
128 return cl.getCode();
129 }
130
131 public StringBuffer getCodeBuffer() {
132 StringBuffer sb = new StringBuffer();
133 List<String> lines = cl.getCode();
134 for ( String line : lines ) {
135 sb.append(line);
136 sb.append(EOL);
137 }
138 return sb;
139 }
140
141 public String getSlice(int startLine, int endLine) {
142 StringBuffer sb = new StringBuffer();
143 List lines = cl.getCode();
144 for (int i = (startLine == 0 ? startLine :startLine - 1); i < endLine && i < lines.size(); i++) {
145 if (sb.length() != 0) {
146 sb.append(EOL);
147 }
148 sb.append((String) lines.get(i));
149 }
150 return sb.toString();
151 }
152
153 public String getFileName() {
154 return cl.getFileName();
155 }
156 }