blob: 1f56be772ea4ae1ecb86a2c7bb86fcd996cc7e4f [file] [log] [blame]
/*
JSPWiki - a JSP-based WikiWiki clone.
Copyright (C) 2001 Janne Jalkanen (Janne.Jalkanen@iki.fi)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.ecyrd.jspwiki;
import java.io.*;
import org.apache.log4j.Category;
/**
* Generic utilities related to file and stream handling.
*/
public class FileUtil
{
private static final Category log = Category.getInstance(FileUtil.class);
/**
* Makes a new temporary file and writes content into it.
*
* @param content Initial content of the temporary file.
* @param encoding Encoding to use.
* @return The handle to the new temporary file
* @throws IOException If the content creation failed.
*/
public static File newTmpFile( String content, String encoding )
throws IOException
{
Writer out = null;
Reader in = null;
File f = null;
try
{
f = File.createTempFile( "jspwiki", null );
in = new StringReader( content );
out = new OutputStreamWriter( new FileOutputStream( f ),
encoding );
copyContents( in, out );
}
finally
{
if( in != null ) in.close();
if( out != null ) out.close();
}
return f;
}
/** Default encoding is ISO-8859-1 */
public static File newTmpFile( String content )
throws IOException
{
return newTmpFile( content, "ISO-8859-1" );
}
/**
* Runs a simple command in given directory.
* The environment is inherited from the parent process.
*
* @return Standard output from the command.
*/
public static String runSimpleCommand( String command, String directory )
throws IOException,
InterruptedException
{
StringBuffer result = new StringBuffer();
log.info("Running simple command "+command+" in "+directory);
Process process = Runtime.getRuntime().exec( command, null, new File(directory) );
BufferedReader stdout = new BufferedReader( new InputStreamReader(process.getInputStream()) );
BufferedReader stderr = new BufferedReader( new InputStreamReader(process.getErrorStream()) );
String line;
while( (line = stdout.readLine()) != null )
{
result.append( line+"\n");
}
StringBuffer error = new StringBuffer();
while( (line = stderr.readLine()) != null )
{
error.append( line+"\n");
}
if( error.length() > 0 )
{
log.error("Command failed, error stream is: "+error);
}
process.waitFor();
return result.toString();
}
/**
* Just copies all characters from <I>in</I> to <I>out</I>.
*
* @since 1.5.8
*/
// FIXME: Could probably be more optimized
public static void copyContents( Reader in, Writer out )
throws IOException
{
int c;
while( (c = in.read()) != -1 )
{
out.write( c );
}
out.flush();
}
/**
* Just copies all characters from <I>in</I> to <I>out</I>.
*
* @since 1.9.31
*/
// FIXME: Could probably be more optimized
public static void copyContents( InputStream in, OutputStream out )
throws IOException
{
int c;
while( (c = in.read()) != -1 )
{
out.write( c );
}
out.flush();
}
/**
* Is smart and falls back to ISO-8859-1 if you get exceptions.
*/
// FIXME: There is a bad bug here. We cannot guarantee that realinput.available()
// returns anything sane. We don't want to read everything into a byte array
// either, since that would mean having to go through at it again. Byte array
// does not support mark()/reset().
// We get odd exceptions if we don't specify a large enough buffer size.
// We assume that if we get a small number from available() the data is buffered
// and use a minimum buffer size to compensate.
// This may fail in a number of ways, a better way is seriously needed.
private static final int MINBUFSIZ = 32768; // bytes
public static String readContents( InputStream input, String encoding )
throws IOException
{
Reader in = null;
Writer out = null;
BufferedInputStream realinput = new BufferedInputStream( input );
realinput.mark( Math.max( realinput.available() * 2, MINBUFSIZ ) );
try
{
in = new BufferedReader( new InputStreamReader( realinput,
encoding ) );
out = new StringWriter();
copyContents( in, out );
return out.toString();
}
catch( IOException e )
{
//
// The reading should fail with an IOException, if the UTF-8 format
// is damaged, i.e. there is ISO-Latin1 instead of UTF-8.
//
// FIXME: This does NOT work with JDK1.4!
if( !encoding.equals("ISO-8859-1") )
{
// FIXME: The real exceptions we get in case there is a problem with
// encoding are sun.io.MalformedInputExceptions, but they are not
// java standard, so we'd better not catch them.
log.info( "Unable to read stream - odd exception. Assuming this data is ISO-8859-1 and retrying.\n "+e.getMessage() );
log.debug( "Full exception is", e );
// We try again, this time with a more conventional encoding
// for backwards compatibility.
realinput.reset();
return readContents( realinput, "ISO-8859-1" );
}
else
{
throw( e );
}
}
finally
{
try
{
if( in != null ) in.close();
if( out != null ) out.close();
}
catch( Exception e ) {} // FIXME: Log errors.
}
}
/**
* Returns the full contents of the Reader as a String.
*
* @since 1.5.8
*/
public static String readContents( Reader in )
throws IOException
{
Writer out = null;
try
{
out = new StringWriter();
copyContents( in, out );
return out.toString();
}
finally
{
try
{
if( out != null ) out.close();
}
catch( Exception e ) {} // FIXME: Log errors.
}
}
}