// 2012-12-05 johnpfeiffer
// TODO: runSystemCommand in a separate class?
package net.kittyandbear.util;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
public class FileSystem {
public static final String CLASSVERSION = "0.80";
private enum OSTYPE {
LINUX,
MAC,
WINDOWS,
OTHER
}
private OSTYPE os = OSTYPE.OTHER;
private String osName;
private String fileSeparator;
private String lineSeparator;
private List<File> rootLocations;
private String tempDirectory;
public FileSystem( Properties currentSystem ) {
if( currentSystem == null ) {
throw new IllegalArgumentException( "ERROR: properties cannot be null" );
}
osName = currentSystem.getProperty( "os.name" );
fileSeparator = currentSystem.getProperty( "file.separator" );
lineSeparator = currentSystem.getProperty( "line.separator" );
tempDirectory = currentSystem.getProperty( "java.io.tmpdir" );
rootLocations = initializeRoots();
if( osName != null ) {
osName = osName.toLowerCase();
if( osName.contains( "linux" ) ) {
os = OSTYPE.LINUX;
} else if( osName.contains( "mac" ) ) {
os = OSTYPE.MAC;
} else if( osName.contains( "windows" ) ) {
os = OSTYPE.WINDOWS;
}
}
}
protected List<File> initializeRoots() {
return Arrays.asList( java.io.File.listRoots() );
}
public List<File> getRoots() {
return rootLocations;
}
public String getRootsAsString() {
StringBuilder strb = new StringBuilder();
for( File f : rootLocations ) {
strb.append( f.getAbsolutePath() );
}
return strb.toString();
}
// helper method that should be moved?
public String runSystemCommand( String command ) throws NullPointerException {
StringBuilder strb = new StringBuilder();
if( command == null ) {
throw new NullPointerException( "ERROR: command cannot be null" );
} else {
if( !command.isEmpty() ) {
try {
Runtime myRuntime = Runtime.getRuntime();
Process myProcess = myRuntime.exec( command );
InputStreamReader myInputStreamReader = new InputStreamReader( myProcess.getInputStream() );
BufferedReader myBufferedReader = new BufferedReader( myInputStreamReader );
String line = null;
while( (line = myBufferedReader.readLine()) != null ) {
strb.append( line ); // should the newline be appended back?
}
} catch( NullPointerException npe ) {
npe.printStackTrace();
} catch( Exception e ) {
e.printStackTrace();
}
}
}
return strb.toString();
}
public String getLineSeparator() {
return lineSeparator;
}
public String getFileSeparator() {
return fileSeparator;
}
public String getTempDirectory() {
return tempDirectory;
}
public boolean isLinux() {
boolean result = false;
if( os == OSTYPE.LINUX ) {
result = true;
}
return result;
}
public boolean isMac() {
boolean result = false;
if( os == OSTYPE.MAC ) {
result = true;
}
return result;
}
public boolean isWindows() {
boolean result = false;
if( os == OSTYPE.WINDOWS ) {
result = true;
}
return result;
}
public boolean isOther() {
boolean result = false;
if( os == OSTYPE.OTHER ) {
result = true;
}
return result;
}
// TODO: unnecessary in Java7 , use Path instead
// returns empty string if unsuccessful
public String OLDconvertFileSystemPath( String path ) throws IllegalArgumentException, IOException, SecurityException {
String converted = "";
if( path == null ) {
throw new IllegalArgumentException( "ERROR: path cannot be null" );
}
if( path.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: path cannot be empty" + path );
}
File original = new File( path );
if( original.isFile() ) {
converted = original.getCanonicalFile().toString();
} else if( original.isDirectory() ) {
converted = original.getCanonicalPath();
if( path.endsWith( "\\" ) || path.endsWith( "/" ) ) // since converting a path "fileSeparator" is only the current system
{
converted = converted + fileSeparator;
}
}
return converted;
}
// TODO: cover more edge cases of Windows path
// TODO: thankfully Java7 makes this obsolete
public String convertFileSystemPath( final String path ) throws IllegalArgumentException {
String convertedPath = "";
if( path == null ) {
throw new IllegalArgumentException( "ERROR: path cannot be null" );
}
if( path.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: path cannot be empty" + path );
}
if( os == OSTYPE.MAC || os == OSTYPE.LINUX ) {
if( path.length() > 1 ) {
char firstCharacter = path.charAt( 0 );
char secondCharacter = path.charAt( 1 );
if( Character.isLetter( firstCharacter ) && secondCharacter == ':' ) {
convertedPath = path.substring( 2, path.length() ); // remove windows style root C:
convertedPath = convertedPath.replace( "\\", "/" );
} else {
convertedPath = path.replace( "\\", "/" );
}
}
} else if( os == OSTYPE.WINDOWS ) {
String correctRoot = ""; // first choice - don't change the root
if( path.startsWith( "/" ) ) {
correctRoot = "c:"; // second choice - append the most common default
if( tempDirectory.length() > 1 ) // third choice - use a potentially more accurate root
{
String tempRoot = tempDirectory.substring( 0, 2 );
if( getRootsAsString().contains( tempRoot ) ) {
correctRoot = tempRoot.toLowerCase();
}
}
}
convertedPath = correctRoot + path.replace( "/", "\\" );
} else {
System.out.println( "Current OS is unknown " );
}
return convertedPath;
}
public void writeStringToFile( String content, String pathfile ) throws IllegalArgumentException , IOException {
if( content == null ) {
throw new IllegalArgumentException( "ERROR: content cannot be null" );
}
if( pathfile == null ) {
throw new IllegalArgumentException( "ERROR: path cannot be null" );
}
if( pathfile.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: path cannot be empty" );
}
File f = new File( pathfile );
if( !f.canWrite() ) {
throw new IOException( "ERROR: cannot write to " + pathfile );
}
FileWriter fw = new FileWriter( f );
PrintWriter out = new PrintWriter( new BufferedWriter( fw ) );
out.print( content );
out.close();
}
public String stringFromFile( String pathfile ) throws IllegalArgumentException, IOException {
StringBuilder str = new StringBuilder();
if( pathfile == null ) {
throw new IllegalArgumentException( "ERROR: path cannot be null" );
}
if( pathfile.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: path cannot be empty" );
}
pathfile = convertFileSystemPath( pathfile );
InputStreamReader in = null;
try {
FileInputStream fileInputStream = new FileInputStream( pathfile );
in = new InputStreamReader( fileInputStream );
int character; // character buffer[1024] ?
while( (character = in.read()) != -1 ) {
str.append( (char) character );
}
} finally {
if( in != null ) {
in.close();
}
}
return str.toString();
}
// TODO: THIS ONLY DETECTS LINE ENDINGS THAT ARE GIVEN (SO NEED TO DETERMINE WHAT FORMAT FILE IS IN!)
public ArrayList<String> delimitedListFromFile( String delimiter, String pathfile ) throws IllegalArgumentException, IOException {
if( delimiter == null ) {
throw new IllegalArgumentException( "ERROR: delimiter cannot be null" );
}
if( delimiter.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: delimiter cannot be empty" );
}
if( pathfile == null ) {
throw new IllegalArgumentException( "ERROR: path cannot be null" );
}
if( pathfile.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: path cannot be empty" );
}
pathfile = convertFileSystemPath( pathfile );
ArrayList<String> tokenList = new ArrayList<String>();
InputStreamReader in = null;
try {
FileInputStream fileInputStream = new FileInputStream( pathfile );
in = new InputStreamReader( fileInputStream );
StringBuilder token = new StringBuilder();
int character;
while( (character = in.read()) != -1 ) {
token.append( (char) character );
if( token.toString().endsWith( delimiter ) ) {
tokenList.add( token.toString() );
token = new StringBuilder();
}
}
if( !token.toString().isEmpty() ) {
tokenList.add( token.toString() ); // the last token does not end with a delimiter
}
} finally {
if( in != null ) {
in.close();
}
}
return tokenList;
}
// only works with /n and /r/n line endings, ignores the /r line endings
public ArrayList<String> listOfLinesFromFile( String pathfile ) throws IllegalArgumentException, IOException {
if( pathfile == null ) {
throw new IllegalArgumentException( "ERROR: path cannot be null" );
}
if( pathfile.isEmpty() ) {
throw new IllegalArgumentException( "ERROR: path cannot be empty" );
}
pathfile = convertFileSystemPath( pathfile );
ArrayList<String> tokenList = new ArrayList<String>();
InputStreamReader in = null;
try {
FileInputStream fileInputStream = new FileInputStream( pathfile );
in = new InputStreamReader( fileInputStream );
StringBuilder token = new StringBuilder();
int intCharacter = -1;
Character current;
Character previous;
// initialize current and previous
if( (intCharacter = in.read()) != -1 ) {
char c = (char) intCharacter;
current = new Character( c );
previous = current;
if( current.equals( '\n' ) ) // edge case , begins with \n
{
// System.out.println( "DEBUG begins with n ending" );
tokenList.add( current.toString() );
} else {
token.append( current );
}
while( (intCharacter = in.read()) != -1 ) {
current = new Character( (char) intCharacter );
if( previous.equals( '\r' ) && current.equals( '\n' ) ) {
token.append( current );
tokenList.add( token.toString() );
// System.out.println( "DEBUG rn ending for: " + token.toString() );
token = new StringBuilder();
} else if( current.equals( '\n' ) ) {
token.append( current );
tokenList.add( token.toString() );
// System.out.println( "DEBUG n ending for: " + token.toString() );
token = new StringBuilder();
} else {
token.append( current );
}
previous = current;
}
// edge case last line does not end with newline
if( !token.toString().isEmpty() && !token.toString().endsWith( "\n" ) && !token.toString().endsWith( "\r\n" ) ) {
tokenList.add( token.toString() );
// System.out.println( "DEBUG last line does not have a newline: " + token.toString() );
}
} else { // edge case empty file returns empty list
}
} finally {
if( in != null ) {
in.close();
}
}
return tokenList;
}
} // end class