Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Switch back to a synchronous (but fully streamed) revision of the TM …
Browse files Browse the repository at this point in the history
…file upload service.
  • Loading branch information
Carlos A. Munoz committed Aug 2, 2013
1 parent 27bd898 commit f3592a8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 107 deletions.
Expand Up @@ -20,19 +20,14 @@
*/
package org.zanata.rest.service;

import java.io.InputStream;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.seam.Component;
import org.jboss.seam.annotations.In;
Expand All @@ -43,12 +38,10 @@
import org.zanata.common.MergeType;
import org.zanata.dao.DocumentDAO;
import org.zanata.dao.ProjectIterationDAO;
import org.zanata.dao.TransMemoryDAO;
import org.zanata.lock.LockNotAcquiredException;
import org.zanata.model.HDocument;
import org.zanata.model.HProject;
import org.zanata.model.HProjectIteration;
import org.zanata.model.tm.TransMemory;
import org.zanata.process.MessagesProcessHandle;
import org.zanata.process.ProcessHandle;
import org.zanata.process.RunnableProcess;
Expand All @@ -64,9 +57,6 @@
import org.zanata.service.TranslationService;
import org.zanata.service.impl.DocumentServiceImpl;
import org.zanata.service.impl.TranslationServiceImpl;
import org.zanata.tmx.TMXParser;

import com.google.common.base.Optional;

import lombok.extern.slf4j.Slf4j;

Expand Down Expand Up @@ -300,31 +290,6 @@ protected void handleThrowable(MessagesProcessHandle handle, Throwable t)
}
}

// @Override
public ProcessStatus updateTranslationMemory(@PathParam("slug") final String slug, MultipartFormDataInput input) throws Exception
{
MessagesProcessHandle handle = new MessagesProcessHandle();
for(InputPart inputPart : input.getFormDataMap().get("uploadedFile"))
{
final InputStream inputStream = inputPart.getBody(InputStream.class, null);

RunnableProcess<ProcessHandle> process = new RunnableProcess<ProcessHandle>()
{
@Override
protected void run(ProcessHandle handle) throws Throwable
{
TransMemoryDAO transMemoryDAO = (TransMemoryDAO)Component.getInstance(TransMemoryDAO.class);
Optional<TransMemory> tm = transMemoryDAO.getBySlug(slug);
TMXParser parser = (TMXParser)Component.getInstance(TMXParser.class);
parser.parseAndSaveTMX(inputStream, tm.get());
}
};
processManagerServiceImpl.startProcess(process, handle);
}
ProcessStatus processStatus = getProcessStatus(handle.getId());
return processStatus;
}

@Override
public ProcessStatus getProcessStatus(@PathParam("processId") String processId)
{
Expand Down
Expand Up @@ -21,15 +21,12 @@
package org.zanata.rest.service;

import java.io.InputStream;
import java.util.Iterator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;

import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.TransactionPropagationType;
Expand All @@ -44,12 +41,11 @@
import org.zanata.model.HProjectIteration;
import org.zanata.model.HTextFlow;
import org.zanata.model.ITextFlow;
import org.zanata.model.tm.TransMemoryUnit;
import org.zanata.model.tm.TransMemory;
import org.zanata.model.tm.TransMemoryUnit;
import org.zanata.service.LocaleService;
import org.zanata.tmx.TMXParser;
import org.zanata.util.CloseableIterator;

import com.google.common.base.Optional;

import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -133,15 +129,10 @@ public Response getTranslationMemory(@Nonnull String slug)

@Override
@Restrict("#{s:hasRole('admin')}")
public Response updateTranslationMemory(String slug, MultipartFormDataInput input) throws Exception
public Response updateTranslationMemory(String slug, InputStream input) throws Exception
{
for(InputPart inputPart : input.getFormDataMap().get("uploadedFile"))
{
InputStream inputStream = inputPart.getBody(InputStream.class, null);

Optional<TransMemory> tm = transMemoryDAO.getBySlug(slug);
tmxParser.parseAndSaveTMX(inputStream, getTM(tm, slug));
}
Optional<TransMemory> tm = transMemoryDAO.getBySlug(slug);
tmxParser.parseAndSaveTMX(input, getTM(tm, slug));
return Response.status(200).build();
}

Expand Down
91 changes: 32 additions & 59 deletions zanata-war/src/main/webapp/tm/home.xhtml
Expand Up @@ -16,7 +16,7 @@
<a4j:jsFunction name="refreshDataTable" render="tmList"/>
<script type="text/javascript">
function showUploadPanel(tmSlug) {
var formAction = "#{request.contextPath}/rest/async/tm/" + tmSlug;
var formAction = "#{request.contextPath}/rest/tm/" + tmSlug;
jQuery("#uploadFileForm").attr("action", formAction);
jQuery("#uploadProgress").html("");
#{rich:component("uploadFilePanel")}.show();
Expand All @@ -33,67 +33,33 @@
}

function submitUpload() {
disableUploadDialog();
var uploadForm = jQuery("#uploadFileForm");
// Only HTML 5
var formData = new FormData(uploadForm[0]);

jQuery.ajax({
type: "POST",
url: uploadForm.attr("action"),
/*xhr: function() {
var myXhr = jQuery.ajaxSettings.xhr();
if(myXhr.upload){ // check if upload property exists
myXhr.upload.addEventListener('progress', handleUploadProgress, false); // for handling the progress of the upload
}
return myXhr;
},*/
data: formData,
cache: false,
contentType: false, // If not there, boundary marker is not set. See: http://stackoverflow.com/a/5976031/33080
processData:false,
beforeSend: function() {
jQuery("#uploadProgress").html("Uploading...");
jQuery("[name='uploadBtn']").hide();
jQuery("[name='cancelBtn']").hide();
jQuery("[name='uploadedFile']").prop('disabled', true);
},
success: function(data) {
var pid = jQuery(data).find('url').text();
poll(pid);
},
error: function(data) {
alert("There was an error uploading the file.");
var req = new XMLHttpRequest();
req.open("POST", uploadForm.attr("action"), true);
req.setRequestHeader("Content-Type", "*/*");
req.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable)
{
var percentComplete = (evt.loaded / evt.total)*100;
jQuery("#uploadProgress").html("Uploading... " + Math.round(percentComplete*100)/100 + "%");
}
});
return false;
}

function poll(pId) {
jQuery.ajax({
type: "GET",
url: "#{request.contextPath}/rest/async/" + pId,
complete: function(data) {
handlePollStatus(pId, data);
},
false);
req.onreadystatechange = function() {
if (req.readyState != 4) { return; }
if (req.status != 200) {
alert("There was an error uploading the file: " + req.statusText + " (" + req.status + ")");
return;
}
});
}

function handlePollStatus(pId, data) {
var status = jQuery(data.responseText).find('statusCode').text();
var message = jQuery(data.responseText).find('message').text();

if( status == 'Finished' ) {
refreshDataTable();
resetUploadDialog();
}
else if( status == "NotAccepted" || status == "Failed" ) {
alert("There was an error processing the file.");
resetUploadDialog();
}
else {
jQuery("#uploadProgress").html(message);
setTimeout(function(){ poll(pId) }, 2000);
}
else {
alert("Successfully imported the file");
}
};
var file = uploadForm.find("input[name = 'uploadedFile']")[0].files[0];
req.send(file);
return false;
}

function resetUploadDialog() {
Expand All @@ -103,6 +69,13 @@
hideUploadPanel();
jQuery("#uploadProgress").html("");
}

function disableUploadDialog() {
jQuery("#uploadProgress").html("Uploading...");
jQuery("[name='uploadBtn']").hide();
jQuery("[name='cancelBtn']").hide();
jQuery("[name='uploadedFile']").prop('disabled', true);
}
</script>
</ui:define>

Expand Down Expand Up @@ -174,7 +147,7 @@

<rich:popupPanel id="uploadFilePanel"
autosized="true">
<form id="uploadFileForm" action="/" method="post" enctype="multipart/form-data" >
<form id="uploadFileForm" action="/" method="post">
<input type="file" name="uploadedFile"/>
<div>
<input type="button" name="uploadBtn" value="#{messages['jsf.Upload']}" onclick="submitUpload()"/>
Expand Down

0 comments on commit f3592a8

Please sign in to comment.