001 /*
002 * Cobertura - http://cobertura.sourceforge.net/
003 *
004 * This file was taken from JavaNCSS
005 * http://www.kclee.com/clemens/java/javancss/
006 * Copyright (C) 2000 Chr. Clemens Lee <clemens a.t kclee d.o.t com>
007 *
008 * Cobertura is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License as published
010 * by the Free Software Foundation; either version 2 of the License,
011 * or (at your option) any later version.
012 *
013 * Cobertura is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016 * General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with Cobertura; if not, write to the Free Software
020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
021 * USA
022 */
023
024 package net.sourceforge.cobertura.javancss;
025
026 import java.io.DataInputStream;
027 import java.io.FileInputStream;
028 import java.io.IOException;
029 import java.util.Enumeration;
030 import java.util.Hashtable;
031 import java.util.Vector;
032
033
034 /**
035 * @author Chr. Clemens Lee, recursive feature by P??????k??? Hannu,
036 * additional javadoc metrics by Emilio Gongora, <emilio@sms.nl>,
037 * and Guillermo Rodriguez, <guille@sms.nl>.
038 */
039 public class Javancss
040 {
041
042 private JavaParser _pJavaParser = null;
043 private Vector _vJavaSourceFiles = new Vector();
044 private String _sErrorMessage = null;
045 private Vector _vMethodComplexities = new Vector();
046 private Hashtable _htProcessedAtFiles = new Hashtable();
047
048 public Javancss(String sJavaSourceFile_)
049 {
050 //System.out.println("Javancss.<init>(String).sJavaSourceFile_: " + sJavaSourceFile_);
051 _sErrorMessage = null;
052 _vJavaSourceFiles = new Vector();
053 _vJavaSourceFiles.addElement(sJavaSourceFile_);
054 try
055 {
056 _measureFiles(_vJavaSourceFiles);
057 }
058 catch (Exception e)
059 {
060 System.out.println("Javancss.<init>(String).e: " + e);
061 }
062 catch (TokenMgrError pError)
063 {
064 System.out.println("Javancss.<init>(String).pError: " + pError);
065 }
066 }
067
068 private void _measureFiles(Vector vJavaSourceFiles_) throws IOException, ParseException,
069 TokenMgrError
070 {
071 // for each file
072 for (Enumeration e = vJavaSourceFiles_.elements(); e.hasMoreElements();)
073 {
074 String sJavaFileName = (String)e.nextElement();
075
076 // if the file specifies other files...
077 if (sJavaFileName.charAt(0) == '@')
078 {
079 if (sJavaFileName.length() > 1)
080 {
081 String sFileName = sJavaFileName.substring(1);
082 sFileName = FileUtil.normalizeFileName(sFileName);
083 if (_htProcessedAtFiles.get(sFileName) != null)
084 {
085 continue;
086 }
087 _htProcessedAtFiles.put(sFileName, sFileName);
088 String sJavaSourceFileNames = null;
089 try
090 {
091 sJavaSourceFileNames = FileUtil.readFile(sFileName);
092 }
093 catch (IOException pIOException)
094 {
095 _sErrorMessage = "File Read Error: " + sFileName;
096
097 throw pIOException;
098 }
099 Vector vTheseJavaSourceFiles = Util.stringToLines(sJavaSourceFileNames);
100 _measureFiles(vTheseJavaSourceFiles);
101 }
102 }
103 else
104 {
105 try
106 {
107 _measureSource(sJavaFileName);
108 }
109 catch (Throwable pThrowable)
110 {
111 // hmm, do nothing? Use getLastError() or so to check for details.
112 }
113 }
114 }
115 }
116
117 private void _measureSource(String sSourceFileName_) throws IOException, ParseException,
118 TokenMgrError
119 {
120 // take user.dir property in account
121 sSourceFileName_ = FileUtil.normalizeFileName(sSourceFileName_);
122
123 DataInputStream disSource = null;
124
125 // opens the file
126 try
127 {
128 disSource = new DataInputStream(new FileInputStream(sSourceFileName_));
129 }
130 catch (IOException pIOException)
131 {
132 if (_sErrorMessage == null)
133 {
134 _sErrorMessage = "";
135 }
136 else
137 {
138 _sErrorMessage += "\n";
139 }
140 _sErrorMessage += "File not found: " + sSourceFileName_;
141
142 throw pIOException;
143 }
144
145 String sTempErrorMessage = _sErrorMessage;
146 try
147 {
148 // the same method but with a DataInputSream
149 _measureSource(disSource);
150 }
151 catch (ParseException pParseException)
152 {
153 if (sTempErrorMessage == null)
154 {
155 sTempErrorMessage = "";
156 }
157 sTempErrorMessage += "ParseException in " + sSourceFileName_
158 + "\nLast useful checkpoint: \"" + _pJavaParser.getLastFunction() + "\"\n";
159 sTempErrorMessage += pParseException.getMessage() + "\n";
160
161 _sErrorMessage = sTempErrorMessage;
162
163 throw pParseException;
164 }
165 catch (TokenMgrError pTokenMgrError)
166 {
167 if (sTempErrorMessage == null)
168 {
169 sTempErrorMessage = "";
170 }
171 sTempErrorMessage += "TokenMgrError in " + sSourceFileName_ + "\n"
172 + pTokenMgrError.getMessage() + "\n";
173 _sErrorMessage = sTempErrorMessage;
174
175 throw pTokenMgrError;
176 }
177 }
178
179 private void _measureSource(DataInputStream disSource_) throws ParseException, TokenMgrError
180 {
181 try
182 {
183 // create a parser object
184 _pJavaParser = new JavaParser(disSource_);
185 // execute the parser
186 _pJavaParser.compilationUnit();
187 //System.out.println("Javancss._measureSource(DataInputStream).SUCCESSFULLY_PARSED");
188 // add new data to global vector
189 _vMethodComplexities.addAll(_pJavaParser.getMethodComplexities());
190 }
191 catch (ParseException pParseException)
192 {
193 if (_sErrorMessage == null)
194 {
195 _sErrorMessage = "";
196 }
197 _sErrorMessage += "ParseException in STDIN";
198 if (_pJavaParser != null)
199 {
200 _sErrorMessage += "\nLast useful checkpoint: \"" + _pJavaParser.getLastFunction()
201 + "\"\n";
202 }
203 _sErrorMessage += pParseException.getMessage() + "\n";
204
205 throw pParseException;
206 }
207 catch (TokenMgrError pTokenMgrError)
208 {
209 if (_sErrorMessage == null)
210 {
211 _sErrorMessage = "";
212 }
213 _sErrorMessage += "TokenMgrError in STDIN\n";
214 _sErrorMessage += pTokenMgrError.getMessage() + "\n";
215
216 throw pTokenMgrError;
217 }
218 }
219
220 public Vector getMethodComplexities()
221 {
222 return (_vMethodComplexities);
223 }
224
225 }