Skip to content

Commit

Permalink
Merge branch 'development' into feature/onmissingmethod
Browse files Browse the repository at this point in the history
Signed-off-by: Brad Wood <[email protected]>
  • Loading branch information
bdw429s authored Jan 6, 2024
2 parents f31d9d8 + 35b8420 commit 43f0883
Show file tree
Hide file tree
Showing 10 changed files with 1,101 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

package ortus.boxlang.runtime.bifs.global.io;

import java.nio.file.Files;
import java.nio.file.Path;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Argument;
import ortus.boxlang.runtime.types.exceptions.BoxRuntimeException;
import ortus.boxlang.runtime.util.FileSystemUtil;

@BoxBIF

public class DirectoryExists extends BIF {

/**
* Constructor
*/
public DirectoryExists() {
super();
declaredArguments = new Argument[] {
new Argument( true, "string", Key.path ),
new Argument( true, "boolean", Key.allowRealPath, true )
};
}

/**
* Determines whether a directory exists
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.path The directory path
*
* @arguments.allowRealPath Whether to allow an absolute path as the path argument
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
String directoryPath = arguments.getAsString( Key.path );
Boolean allowRealPath = arguments.getAsBoolean( Key.allowRealPath );
if ( !allowRealPath && Path.of( directoryPath ).isAbsolute() ) {
throw new BoxRuntimeException(
"The file or path argument [" + directoryPath + "] is an absolute path. This is disallowed when the allowRealPath argument is set to false."
);
}

return ( Boolean ) FileSystemUtil.exists( directoryPath ) && Files.isDirectory( Path.of( directoryPath ) );
}

}
137 changes: 137 additions & 0 deletions src/main/java/ortus/boxlang/runtime/bifs/global/io/DirectoryList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@

package ortus.boxlang.runtime.bifs.global.io;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.dynamic.casters.ArrayCaster;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Argument;
import ortus.boxlang.runtime.types.Array;
import ortus.boxlang.runtime.types.DateTime;
import ortus.boxlang.runtime.types.Query;
import ortus.boxlang.runtime.types.QueryColumnType;
import ortus.boxlang.runtime.util.FileSystemUtil;

@BoxBIF

public class DirectoryList extends BIF {

/**
* Constructor
*/
public DirectoryList() {
super();
// path=string, recurse=boolean, listInfo=string, filter=any, sort=string, type=string
declaredArguments = new Argument[] {
new Argument( true, "string", Key.path ),
new Argument( true, "boolean", Key.recurse, false ),
new Argument( false, "string", Key.listInfo, "path" ),
new Argument( false, "string", Key.filter, "" ),
new Argument( false, "string", Key.sort, "name" ),
new Argument( false, "string", Key.type, "all" )
};
}

/**
* Describe what the invocation of your bif function does
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.foo Describe any expected arguments
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
// Replace this example function body with your own implementation;
String returnType = arguments.getAsString( Key.listInfo );

Stream<Path> listing = FileSystemUtil.listDirectory(
arguments.getAsString( Key.path ),
arguments.getAsBoolean( Key.recurse ),
arguments.getAsString( Key.filter ),
arguments.getAsString( Key.sort ),
arguments.getAsString( Key.type )
);

switch ( returnType ) {
case "name" :
return listingToNames( listing );
case "query" :
return listingToQuery( listing );
default :
return listingToPaths( listing );
}

}

public Array listingToPaths( Stream<Path> listing ) {
return ArrayCaster.cast( listing.map( item -> ( String ) item.toAbsolutePath().toString() ).toArray() );
}

public Array listingToNames( Stream<Path> listing ) {
return ArrayCaster.cast( listing.map( item -> ( String ) item.getFileName().toString() ).toArray() );
}

public Query listingToQuery( Stream<Path> listing ) {
Query listingQuery = new Query();
listingQuery
.addColumn( Key.of( "name" ), QueryColumnType.VARCHAR )
.addColumn( Key.size, QueryColumnType.BIGINT )
.addColumn( Key.type, QueryColumnType.VARCHAR )
.addColumn( Key.dateLastModified, QueryColumnType.TIMESTAMP )
.addColumn( Key.attributes, QueryColumnType.VARCHAR )
.addColumn( Key.mode, QueryColumnType.VARCHAR )
.addColumn( Key.directory, QueryColumnType.VARCHAR );

listing.forEachOrdered( item -> {
try {
listingQuery.addRow(
new Object[] {
item.getFileName().toString(),
Files.isDirectory( item ) ? 0l : Files.size( item ),
Files.isDirectory( item ) ? "Dir" : "File",
new DateTime( Files.getLastModifiedTime( item ).toString(), "yyyy-MM-dd'T'HH:mm:ss.nX" ),
getAttributes( item ),
"",
item.getParent().toAbsolutePath().toString()
}
);
} catch ( IOException e ) {
throw new RuntimeException( e );
}
} );

return listingQuery;
}

private static String getAttributes( Path file ) {
String attributes = "";

if ( Files.isReadable( file ) ) {
attributes += "R";
}
if ( Files.isWritable( file ) ) {
attributes += "W";
}
if ( Files.isExecutable( file ) ) {
attributes += "X";
}
try {
if ( Files.isHidden( file ) ) {
attributes += "H";
}
} catch ( IOException e ) {
// if we have an exception testing if the file is hidden it is not permissable so clear the attributes
attributes = "";
}

return attributes;
}

}
54 changes: 54 additions & 0 deletions src/main/java/ortus/boxlang/runtime/bifs/global/io/FileExists.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

package ortus.boxlang.runtime.bifs.global.io;

import java.nio.file.Files;
import java.nio.file.Path;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Argument;
import ortus.boxlang.runtime.types.exceptions.BoxRuntimeException;
import ortus.boxlang.runtime.util.FileSystemUtil;

@BoxBIF

public class FileExists extends BIF {

/**
* Constructor
*/
public FileExists() {
super();
declaredArguments = new Argument[] {
new Argument( true, "string", Key.source ),
new Argument( true, "boolean", Key.allowRealPath, true )
};
}

/**
* Determines whether a file exists
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.source The file path
*
* @arguments.allowRealPath Whether to allow an absolute path as the path argument
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
String filePath = arguments.getAsString( Key.source );
Boolean allowRealPath = arguments.getAsBoolean( Key.allowRealPath );

if ( !allowRealPath && Path.of( filePath ).isAbsolute() ) {
throw new BoxRuntimeException(
"The file or path argument [" + filePath + "] is an absolute path. This is disallowed when the allowRealPath argument is set to false."
);
}

return ( Boolean ) FileSystemUtil.exists( filePath ) && !Files.isDirectory( Path.of( filePath ) );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

package ortus.boxlang.runtime.bifs.global.io;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import ortus.boxlang.runtime.bifs.BIF;
import ortus.boxlang.runtime.bifs.BoxBIF;
import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.scopes.ArgumentsScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Argument;
import ortus.boxlang.runtime.types.exceptions.BoxRuntimeException;

@BoxBIF

public class FileGetMimeType extends BIF {

/**
* Constructor
*/
public FileGetMimeType() {
super();
declaredArguments = new Argument[] {
new Argument( true, "string", Key.file ),
new Argument( false, "boolean", Key.strict, true )
};
}

/**
* Describe what the invocation of your bif function does
*
* @param context The context in which the BIF is being invoked.
* @param arguments Argument scope for the BIF.
*
* @argument.foo Describe any expected arguments
*/
public Object invoke( IBoxContext context, ArgumentsScope arguments ) {
Path filePath = Path.of( arguments.getAsString( Key.file ) );
Boolean strict = arguments.getAsBoolean( Key.strict );

String mimeType = null;

if ( strict ) {
try {
if ( !Files.exists( filePath ) ) {
throw new BoxRuntimeException(
"The file ["
+ arguments.getAsString( Key.file )
+ "] does not exist. To retrieve the mimetype of a non-existent file set the strict argument to false."
);
} else if ( Files.size( filePath ) == 0 ) {
throw new BoxRuntimeException(
"The file ["
+ arguments.getAsString( Key.file )
+ "] is empty. To retrieve the mimetype of a empty file set the strict argument to false."
);
}
} catch ( IOException e ) {
throw new RuntimeException( e );
}

}

try {
mimeType = Files.probeContentType( filePath );
if ( mimeType == null ) {
mimeType = "application/octet-stream";
}
} catch ( IOException e ) {
throw new RuntimeException( e );
}

return mimeType;

}

}
Loading

0 comments on commit 43f0883

Please sign in to comment.