001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 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 /** 032 * <p>Not intended to be instantiated by clients.</p> 033 * 034 * @since 2.2 035 */ 036 public class SourceCode { 037 038 public static final String EOL = System.getProperty("line.separator", "\n"); 039 040 public abstract static class CodeLoader { 041 private SoftReference<List<String>> code; 042 043 public List<String> getCode() { 044 List<String> c = null; 045 if (code != null) { 046 c = code.get(); 047 } 048 if (c != null) { 049 return c; 050 } 051 this.code = new SoftReference<List<String>>(load()); 052 return code.get(); 053 } 054 055 public abstract String getFileName(); 056 057 protected abstract Reader getReader() throws Exception; 058 059 protected List<String> load() { 060 LineNumberReader lnr = null; 061 try { 062 lnr = new LineNumberReader(getReader()); 063 List<String> lines = new ArrayList<String>(); 064 String currentLine; 065 while ((currentLine = lnr.readLine()) != null) { 066 lines.add(currentLine); 067 } 068 return lines; 069 } catch (Exception e) { 070 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage(), e); 071 } finally { 072 try { 073 if (lnr != null) { 074 lnr.close(); 075 } 076 } catch (Exception e) { 077 throw new RuntimeException("Problem while reading " + getFileName() + ":" + e.getMessage(), e); 078 } 079 } 080 } 081 } 082 083 public static class FileCodeLoader extends CodeLoader { 084 private File file; 085 private String encoding; 086 087 public FileCodeLoader(File file, String encoding) { 088 this.file = file; 089 this.encoding = encoding; 090 } 091 092 public Reader getReader() throws Exception { 093 return new InputStreamReader(new FileInputStream(file), encoding); 094 } 095 096 public String getFileName() { 097 return this.file.getAbsolutePath(); 098 } 099 } 100 101 public static class StringCodeLoader extends CodeLoader { 102 public static final String DEFAULT_NAME = "CODE_LOADED_FROM_STRING"; 103 104 private String source_code; 105 106 private String name; 107 108 public StringCodeLoader(String code) { 109 this(code, DEFAULT_NAME); 110 } 111 112 public StringCodeLoader(String code, String name) { 113 this.source_code = code; 114 this.name = name; 115 } 116 117 public Reader getReader() { 118 return new StringReader(source_code); 119 } 120 121 public String getFileName() { 122 return name; 123 } 124 } 125 126 private CodeLoader cl; 127 128 public SourceCode(CodeLoader cl) { 129 this.cl = cl; 130 } 131 132 public List<String> getCode() { 133 return cl.getCode(); 134 } 135 136 public StringBuffer getCodeBuffer() { 137 StringBuffer sb = new StringBuffer(); 138 List<String> lines = cl.getCode(); 139 for (String line : lines) { 140 sb.append(line); 141 sb.append(EOL); 142 } 143 return sb; 144 } 145 146 public String getSlice(int startLine, int endLine) { 147 StringBuffer sb = new StringBuffer(); 148 List lines = cl.getCode(); 149 for (int i = (startLine == 0 ? startLine : startLine - 1); i < endLine && i < lines.size(); i++) { 150 if (sb.length() != 0) { 151 sb.append(EOL); 152 } 153 sb.append((String) lines.get(i)); 154 } 155 return sb.toString(); 156 } 157 158 /** 159 * Within Sonar Ecosystem - absolute path to file containing code, 160 * whereas in fact existence of such file not guaranteed - see {@link StringCodeLoader}. 161 */ 162 public String getFileName() { 163 return cl.getFileName(); 164 } 165 }