001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is the reusable ccl java library
015 * (http://www.kclee.com/clemens/java/ccl/).
016 *
017 * The Initial Developer of the Original Code is
018 * Chr. Clemens Lee.
019 * Portions created by Chr. Clemens Lee are Copyright (C) 2002
020 * Chr. Clemens Lee. All Rights Reserved.
021 *
022 * Contributor(s): Chr. Clemens Lee <clemens@kclee.com>
023 *
024 * Alternatively, the contents of this file may be used under the terms of
025 * either the GNU General Public License Version 2 or later (the "GPL"), or
026 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
027 * in which case the provisions of the GPL or the LGPL are applicable instead
028 * of those above. If you wish to allow use of your version of this file only
029 * under the terms of either the GPL or the LGPL, and not to allow others to
030 * use your version of this file under the terms of the MPL, indicate your
031 * decision by deleting the provisions above and replace them with the notice
032 * and other provisions required by the GPL or the LGPL. If you do not delete
033 * the provisions above, a recipient may use your version of this file under
034 * the terms of any one of the MPL, the GPL or the LGPL.
035 *
036 * ***** END LICENSE BLOCK ***** */
037
038package net.sourceforge.cobertura.javancss.ccl;
039
040import java.io.BufferedReader;
041import java.io.File;
042import java.io.FileNotFoundException;
043import java.io.FileReader;
044import java.io.IOException;
045
046/**
047 * Utility class for file operations.<p>
048 *
049 * Simple but most commonly used methods of this class are:<br>
050 * - {@link #readFile(java.lang.String) readFile}<br>
051 * - {@link #concatPath(java.lang.String, java.lang.String) concatPath}<br>
052 *
053 * Other less frequently used but still handy methods are:<br>
054 * - {@link #normalizeFileName(java.lang.String) normalizeFileName} to take the current user directory into account via the 'user.dir' system property<br>
055 *
056 * @version  $Id: FileUtil.java 384 2006-03-17 20:10:49Z thekingant $
057 * @author <a href="http://www.kclee.com/clemens/">
058 *         Chr. Clemens Lee</a>
059 *         &lt;<a href="mailto:clemens@kclee.com">
060 *         clemens@kclee.com
061 *         </a>>
062 */
063/*
064 * cobertura - this file was moved from net.sourceforge.cobertura.javancss package.
065 * Mark Doliner apparently got the source from somewhere, but it is not available now.
066 */
067public class FileUtil
068{
069
070        /**
071         * Utility class which should never instanciate itself.
072         */
073        private FileUtil()
074        {
075                super();
076        }
077
078        /**
079         * Concatenates a file path with the file name. If 
080         * necessary it adds a File.separator between the path
081         * and file name. For example "/home" or "/home/" and "clemens" both
082         * become "/home/clemens".<p>
083         *
084         * This method is inspired from the FrIJDE project out
085         * of the gCollins.File.FileTools class.<p>
086         *
087         * FrIJDE Homepage:
088         * http://amber.wpi.edu/~thethe/Document/Besiex/Java/FrIJDE/
089         *
090         * @param    sPath_   a directory path. Is not allowed to be null.
091         * @param    sFile_   the base name of a file.
092         *
093         * @return            sPath_ if sFile_ is empty.
094         */
095        public static String concatPath(String sPath_, String sFile_)
096        {
097                Util.panicIf(sPath_ == null);
098                //System.out.println("ccl.util.FileUtil.concatPath(..).sPath_: --->" + sPath_ + "<---");
099                //System.out.println("ccl.util.FileUtil.concatPath(..).sFile_: " + sFile_);
100
101                String sRetVal = sPath_;
102
103                if (!Util.isEmpty(sFile_))
104                {
105                        if (sPath_.length() > 0 && !sPath_.endsWith(File.separator))
106                        {
107                                sRetVal += File.separator;
108                        }
109
110                        sRetVal += sFile_;
111                }
112
113                return sRetVal;
114        }
115
116        /**
117         * Reads a File and returns the content in a String.
118         * CRLF -> LF conversion takes place. This is a convenience method so you don't
119         * need to bother creating a file reader object and closing it after it has
120         * been used.
121         *
122         * @param    sFileName_   the name of the file to read.
123         *
124         * @return                a string with the content of the file but without 
125         *                        any CR characters.
126         *
127         * @throws   FileNotFoundException   if file does not exist.
128         * @throws   IOException             if any file operation fails.
129         */
130        public static String readFile(String sFileName_) throws IOException, FileNotFoundException
131        {
132                StringBuffer sFileContent = new StringBuffer(100000);
133
134                try
135                {
136                        FileReader frIni = new FileReader(sFileName_);
137                        if (frIni != null)
138                        {
139                                BufferedReader brIni = new BufferedReader(frIni);
140                                if (brIni != null)
141                                {
142                                        while (brIni.ready())
143                                        {
144                                                String sLine = brIni.readLine();
145                                                if (sLine == null)
146                                                {
147                                                        break;
148                                                }
149                                                sFileContent.append(sLine).append('\n');
150                                        }
151                                        brIni.close();
152                                }
153                                frIni.close();
154                        }
155                }
156                catch (FileNotFoundException fileNotFoundException)
157                {
158                        throw new FileNotFoundException("No such file: '" + sFileName_ + "'");
159                }
160
161                return sFileContent.toString();
162        }
163
164        /**
165         * @return It's the canonical path of sFileName_.
166         */
167        public static String getAbsoluteFileName(String sFileName_)
168        {
169                String sRetVal = null;
170
171                try
172                {
173                        File pFile = new File(sFileName_);
174                        sRetVal = pFile.getCanonicalPath();
175                }
176                catch (Exception e)
177                {
178                        return null;
179                }
180
181                return sRetVal;
182        }
183
184        /**
185         * This method returns an absolute (canonical)
186         * file name. The difference to getAbsoluteFileName
187         * is that this method uses the system property
188         * "user.dir" instead of the native system's current 
189         * directory. This way you get a chance of changing
190         * the current directory inside Java and let your 
191         * program reflect that change.
192         */
193        public static String normalizeFileName(String sFile)
194        {
195                return normalizeFileName(sFile, (String)System.getProperties().get("user.dir"));
196        }
197
198        /**
199         * This method returns an absolute (canonical)
200         * file name. The difference to getAbsoluteFileName
201         * is that this method uses the system property
202         * sUserDir instead of the native system's current 
203         * directory. This way you get a chance of changing
204         * the current directory inside Java and let your 
205         * program reflect that change.
206         */
207        private static String normalizeFileName(String sFile, String sUserDir)
208        {
209                sFile = sFile.trim();
210                if (Util.isEmpty(sFile) || sFile.equals("."))
211                {
212                        sFile = sUserDir;
213                }
214                else if (!FileUtil.isAbsolute(sFile))
215                {
216                        sFile = FileUtil.concatPath(sUserDir, sFile);
217                }
218                sFile = FileUtil.getAbsoluteFileName(sFile);
219
220                return sFile;
221        }
222
223        /**
224         * Tests if the file represented by this File object is an absolute 
225         * pathname. The definition of an absolute pathname is system
226         * dependent. For example, on UNIX, a pathname is absolute if its first
227         * character is the separator character. On Windows
228         * platforms, a pathname is absolute if its first character is an 
229         * ASCII '\' or '/', or if it begins with a letter followed by a colon. 
230         */
231        private static boolean isAbsolute(String sFileName_)
232        {
233                return new File(sFileName_).isAbsolute();
234        }
235
236}