/*
* Sonar, open source software quality management tool.
* Copyright (C) 2008-2012 SonarSource
* mailto:contact AT sonarsource DOT com
*
* Sonar is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* Sonar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Sonar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cpd;
import com.google.common.io.Closeables;
import java.io.*;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
/**
*
Not intended to be instantiated by clients.
*
* @since 2.2
*/
public class SourceCode {
public static final String EOL = System.getProperty("line.separator", "\n");
public abstract static class CodeLoader {
private SoftReference> code;
public List getCode() {
List c = null;
if (code != null) {
c = code.get();
}
if (c != null) {
return c;
}
this.code = new SoftReference>(load());
return code.get();
}
public abstract String getFileName();
protected abstract Reader getReader() throws Exception;
protected List load() {
LineNumberReader lnr = null;
try {
lnr = new LineNumberReader(getReader());
List lines = new ArrayList();
String currentLine;
while ((currentLine = lnr.readLine()) != null) {
lines.add(currentLine);
}
return lines;
} catch (Exception e) {
throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage(), e);
} finally {
Closeables.closeQuietly(lnr);
}
}
}
public static class FileCodeLoader extends CodeLoader {
private File file;
private String encoding;
public FileCodeLoader(File file, String encoding) {
this.file = file;
this.encoding = encoding;
}
@Override
public Reader getReader() throws Exception {
return new InputStreamReader(new FileInputStream(file), encoding);
}
@Override
public String getFileName() {
return this.file.getAbsolutePath();
}
}
public static class StringCodeLoader extends CodeLoader {
public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING";
private String source_code;
private String name;
public StringCodeLoader(String code) {
this(code, DEFAULT_NAME);
}
public StringCodeLoader(String code, String name) {
this.source_code = code;
this.name = name;
}
@Override
public Reader getReader() {
return new StringReader(source_code);
}
@Override
public String getFileName() {
return name;
}
}
private CodeLoader cl;
public SourceCode(CodeLoader cl) {
this.cl = cl;
}
public List getCode() {
return cl.getCode();
}
public StringBuffer getCodeBuffer() {
StringBuffer sb = new StringBuffer();
List lines = cl.getCode();
for (String line : lines) {
sb.append(line);
sb.append(EOL);
}
return sb;
}
public String getSlice(int startLine, int endLine) {
StringBuffer sb = new StringBuffer();
List lines = cl.getCode();
for (int i = (startLine == 0 ? startLine : startLine - 1); i < endLine && i < lines.size(); i++) {
if (sb.length() != 0) {
sb.append(EOL);
}
sb.append((String) lines.get(i));
}
return sb.toString();
}
/**
* Within Sonar Ecosystem - absolute path to file containing code,
* whereas in fact existence of such file not guaranteed - see {@link StringCodeLoader}.
*/
public String getFileName() {
return cl.getFileName();
}
}