Skip to content

Commit

Permalink
Implementing drag-and-drop file upload.
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelschoen committed Sep 10, 2022
1 parent 2655d6c commit 8ad5bae
Show file tree
Hide file tree
Showing 4 changed files with 480 additions and 34 deletions.
89 changes: 58 additions & 31 deletions app/src/main/java/org/acme/FloppyImageUploadResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,54 +51,78 @@ public Response uploadFile(MultipartFormDataInput input) {
File finalDir = new File(uploadDir, uuid);
finalDir.mkdirs();

String fileName = "";
String fileName = null;

Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
List<InputPart> inputParts = uploadForm.get("uploadedFile");
boolean isAjax = uploadForm.containsKey("ajax");
for(String key : uploadForm.keySet()) {
System.out.println(">> KEY: " + key);
for(InputPart value : uploadForm.get(key)) {
System.out.println("-----> PART: ");
for(String header : value.getHeaders().keySet()) {
System.out.println("------> header: " + header + ": " + value.getHeaders().get(key));
}
}
}
List<InputPart> inputParts = uploadForm.get("files[]");

for (InputPart inputPart : inputParts) {
MultivaluedMap<String, String> header = inputPart.getHeaders();
fileName = getFileName(header);
if(fileName != null && !fileName.isEmpty()) {
break;
}
}

try {

MultivaluedMap<String, String> header = inputPart.getHeaders();
fileName = getFileName(header);
if (fileName.contains(".")) {

File finalImageFile = new File(finalDir, fileName);
ImageType imageType = ImageType.getTypeFromFile(finalImageFile);

if (imageType != ImageType.unknown) {
if(fileName != null && fileName.contains(".")) {
File finalImageFile = new File(finalDir, fileName);
ImageType imageType = ImageType.getTypeFromFile(finalImageFile);
System.out.println("Image type: " + imageType.name());
if(imageType == ImageType.unknown) {
return Response.status(500).entity("Invalid/unsupported file format").build();
}

// convert the uploaded file to inputstream
InputStream inputStream = inputPart.getBody(InputStream.class, null);
try {
System.out.println("********** FILENAME: " + fileName);
for (InputPart inputPart : inputParts) {
System.out.println("> process part...");
MultivaluedMap<String, String> header = inputPart.getHeaders();

// convert the uploaded file to inputstream
InputStream inputStream = inputPart.getBody(InputStream.class, null);
byte[] bytes = IOUtils.toByteArray(inputStream);
writeFile(bytes, finalImageFile);
}

byte[] bytes = IOUtils.toByteArray(inputStream);

writeFile(bytes, finalImageFile);
File unpackDir = new File(finalDir, fileName + "-unpacked");
unpackDir.mkdirs();

File unpackDir = new File(finalDir, fileName + "-unpacked");
unpackDir.mkdirs();
ImageHandler imageHandler = ImageHandlerFactory.get(imageType);
VirtualDisk virtualDisk = imageHandler.loadImage(finalImageFile);
virtualDisk.exportToDirectory(unpackDir);

ImageHandler imageHandler = ImageHandlerFactory.get(imageType);
VirtualDisk virtualDisk = imageHandler.loadImage(finalImageFile);
virtualDisk.exportToDirectory(unpackDir);
System.out.println("Done");

System.out.println("Done");
URI uri = URI.create("/files/browse?path=" + uuid + "/" + unpackDir.getName() + "&image=" + fileName);

URI uri = URI.create("/files/browse?path=" + uuid + "/" + unpackDir.getName() + "&image=" + fileName);
return Response.status(302).location(uri).build();
System.out.println("------------- IS AJAX CLIENT: " + isAjax);

}
if(!isAjax) {
return Response.status(302).location(uri).build();
} else {
return Response.status(200).entity("{ \"url\": \"" + uri + "\" }").build();
}

return Response.status(500).entity("Invalid/unsupported file format").build();

} catch (Exception e) {
e.printStackTrace();
return Response.status(500).entity("Unknown error: " + e).build();
}
}

} else {
System.err.println("------> Unable to find filename");
}
System.err.println("------> FAILURE");
return Response.status(500).entity("Upload failed.").build();
}

Expand All @@ -117,11 +141,14 @@ private String getFileName(MultivaluedMap<String, String> header) {

String[] name = filename.split("=");

String finalFileName = name[1].trim().replaceAll("\"", "");
return finalFileName;
String finalFileName = name[1].trim().replaceAll("\"", "").trim();
if(!filename.isEmpty()) {
System.out.println(">> Found filename: " + finalFileName);
return finalFileName;
}
}
}
return "unknown";
return null;
}

//save to somewhere
Expand Down
205 changes: 202 additions & 3 deletions app/src/main/resources/META-INF/resources/index.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8">
<title>RetroIO Floppy Image Loader</title>
<link rel="stylesheet" href="retroio.css">

<!-- remove this if you use Modernizr -->
<script>(function(e,t,n){var r=e.querySelectorAll("html")[0];r.className=r.className.replace(/(^|\s)no-js(\s|$)/,"$1js$2")})(document,window,0);</script>

</head>
<body>
<div style="margin: 30px;">
Expand Down Expand Up @@ -44,7 +48,7 @@ <h3>About</h3>
</div>

<h3>File Upload</h3>

<!--
<form action="/handler/upload" enctype="multipart/form-data" method="post">
<p>
Expand All @@ -53,6 +57,201 @@ <h3>File Upload</h3>
<input type="submit" value="Upload Image" />
</form>
</div>
-->

<form method="post" action="/handler/upload" enctype="multipart/form-data" novalidate class="box">


<div class="box__input">
<input type="file" name="files[]" id="file" class="box__file" data-multiple-caption="{count} files selected" />
<label for="file"><strong>Choose a file</strong><span class="box__dragndrop"> or drag it here</span>.</label>
<button type="submit" class="box__button">Upload</button>
</div>


<div class="box__uploading">Uploading&hellip;</div>
<div class="box__success">Done! <a href="https://css-tricks.com/examples/DragAndDropFileUploading//?" class="box__restart" role="button">Upload more?</a></div>
<div class="box__error">Error! <span></span>. <a href="https://css-tricks.com/examples/DragAndDropFileUploading//?" class="box__restart" role="button">Try again!</a></div>
</form></div>



<!--
JQUERY DEPENDENCY
-->
<script src="jquery-3.6.1.min.js"></script>
<script>

'use strict';

;( function( $, window, document, undefined )
{
// feature detection for drag&drop upload

var isAdvancedUpload = function()
{
var div = document.createElement( 'div' );
return ( ( 'draggable' in div ) || ( 'ondragstart' in div && 'ondrop' in div ) ) && 'FormData' in window && 'FileReader' in window;
}();


// applying the effect for every form

$( '.box' ).each( function()
{
var $form = $( this ),
$input = $form.find( 'input[type="file"]' ),
$label = $form.find( 'label' ),
$errorMsg = $form.find( '.box__error span' ),
$restart = $form.find( '.box__restart' ),
droppedFiles = false,
showFiles = function( files )
{
$label.text( files.length > 1 ? ( $input.attr( 'data-multiple-caption' ) || '' ).replace( '{count}', files.length ) : files[ 0 ].name );
};

// letting the server side to know we are going to make an Ajax request
$form.append( '<input type="hidden" name="ajax" value="1" />' );

// automatically submit the form on file select
$input.on( 'change', function( e )
{
showFiles( e.target.files );


$form.trigger( 'submit' );


});


// drag&drop files if the feature is available
if( isAdvancedUpload )
{
$form
.addClass( 'has-advanced-upload' ) // letting the CSS part to know drag&drop is supported by the browser
.on( 'drag dragstart dragend dragover dragenter dragleave drop', function( e )
{
// preventing the unwanted behaviours
e.preventDefault();
e.stopPropagation();
})
.on( 'dragover dragenter', function() //
{
$form.addClass( 'is-dragover' );
})
.on( 'dragleave dragend drop', function()
{
$form.removeClass( 'is-dragover' );
})
.on( 'drop', function( e )
{
droppedFiles = e.originalEvent.dataTransfer.files; // the files that were dropped
showFiles( droppedFiles );


$form.trigger( 'submit' ); // automatically submit the form on file drop


});
}


// if the form was submitted

$form.on( 'submit', function( e )
{
// preventing the duplicate submissions if the current one is in progress
if( $form.hasClass( 'is-uploading' ) ) return false;

$form.addClass( 'is-uploading' ).removeClass( 'is-error' );

if( isAdvancedUpload ) // ajax file upload for modern browsers
{
e.preventDefault();

// gathering the form data
var ajaxData = new FormData( $form.get( 0 ) );
if( droppedFiles )
{
$.each( droppedFiles, function( i, file )
{
ajaxData.append( $input.attr( 'name' ), file );
});
}

// ajax request
$.ajax(
{
url: $form.attr( 'action' ),
type: $form.attr( 'method' ),
data: ajaxData,
dataType: 'json',
cache: false,
contentType: false,
processData: false,
complete: function()
{
$form.removeClass( 'is-uploading' );
},
success: function( data )
{
window.location.href = data.url;
},
error: function()
{
alert( 'Error. Please, contact the webmaster!' );
/*
if (data.redirect) {
// data.redirect contains the string URL to redirect to
alert( 'Redirect to:' + data.redirect );
window.location.href = data.redirect;
} else {
alert( 'Error. Please, contact the webmaster!' );
}
*/
}
});
}
else // fallback Ajax solution upload for older browsers
{
var iframeName = 'uploadiframe' + new Date().getTime(),
$iframe = $( '<iframe name="' + iframeName + '" style="display: none;"></iframe>' );

$( 'body' ).append( $iframe );
$form.attr( 'target', iframeName );

$iframe.one( 'load', function()
{
var data = $.parseJSON( $iframe.contents().find( 'body' ).text() );
$form.removeClass( 'is-uploading' ).addClass( data.success == true ? 'is-success' : 'is-error' ).removeAttr( 'target' );
if( !data.success ) $errorMsg.text( data.error );
$iframe.remove();
});
}
});


// restart the form if has a state of error/success

$restart.on( 'click', function( e )
{
e.preventDefault();
$form.removeClass( 'is-error is-success' );
$input.trigger( 'click' );
});

// Firefox focus bug fix for file input
$input
.on( 'focus', function(){ $input.addClass( 'has-focus' ); })
.on( 'blur', function(){ $input.removeClass( 'has-focus' ); });
});

})( jQuery, window, document );

</script>

</body>
</html>
2 changes: 2 additions & 0 deletions app/src/main/resources/META-INF/resources/jquery-3.6.1.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 8ad5bae

Please sign in to comment.