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    }