view src/main/java/de/mpiwg/gazetteer/servlet/SaveResource.java @ 12:c2e2d794847f

new: add config.properties file for gazetteer
author Zoe Hong <zhong@mpiwg-berlin.mpg.de>
date Wed, 30 Sep 2015 13:43:54 +0200
parents
children be7787c36e58
line wrap: on
line source

package de.mpiwg.gazetteer.servlet;

import static edu.harvard.iq.dataverse.util.JsfHelper.JH;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.primefaces.json.JSONException;
import org.primefaces.json.JSONObject;
import org.primefaces.model.UploadedFile;

import edu.harvard.iq.dataverse.DataFile;
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetServiceBean;
import edu.harvard.iq.dataverse.DatasetVersion;
import edu.harvard.iq.dataverse.DatasetVersionServiceBean;
import edu.harvard.iq.dataverse.EjbDataverseEngine;
import edu.harvard.iq.dataverse.UserNotification;
import edu.harvard.iq.dataverse.DatasetPage.EditMode;
import edu.harvard.iq.dataverse.authorization.AuthenticationRequest;
import edu.harvard.iq.dataverse.authorization.exceptions.AuthenticationFailedException;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.engine.command.Command;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.impl.CreateDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.UpdateDatasetCommand;
import edu.harvard.iq.dataverse.ingest.IngestServiceBean;
import edu.harvard.iq.dataverse.util.JsfHelper;


@MultipartConfig 
public class SaveResource extends AbstractMonographServlet {

	private static final long serialVersionUID = 1L;


	private static final String TMP_DIR = "/gazetteer-server/tmp/";


	private int maxFileSize = 100 * 1024;
	private int maxMemSize = 4 * 1024;

	private static final Logger logger = Logger.getLogger("monographs.SaveResource");

	@EJB
    IngestServiceBean ingestService;
	@EJB
    DatasetServiceBean datasetService;
	@EJB
    DatasetVersionServiceBean datasetVersionService;
	@EJB
    EjbDataverseEngine commandEngine;
	
	private DatasetVersion workingVersion;
	private Dataset dataset;
	

	Map<String, String> params = new HashMap<String, String>();
	

	public void init() throws ServletException {
		super.init();
	}


	protected JSONObject saveFile(UpFile upFile) {
		//String datasetGlobalId = "doi:10.5072/FK2/1EWLIR";
		String datasetGlobalId = params.get("datasetGlobalId");
		dataset = datasetService.findByGlobalId(datasetGlobalId);	
        workingVersion = dataset.getEditVersion();
     	
		List<DataFile> dFileList = null;
		try {
	     	String fileContent = upFile.getFileContent();
			String fileName = upFile.getFileName();
			String contentType = upFile.getContentType();
			
			InputStream fileStream = new ByteArrayInputStream(fileContent.getBytes(StandardCharsets.UTF_8));
			dFileList = ingestService.createDataFiles(workingVersion, fileStream, fileName, contentType);
			
		} catch (IOException ioex) {
	        logger.warning("Failed to process and/or save the file " + upFile.getFileName() + "; " + ioex.getMessage());
	        
	    }
		
		
		
        ingestService.addFiles(workingVersion, dFileList);

        JSONObject jsonSavedResult= new JSONObject();
	
        // Use the API to save the dataset: 
        Command<Dataset> cmd;
        try {
            cmd = new UpdateDatasetCommand(dataset, this.authUser);
            dataset = commandEngine.submit(cmd);
            
        } catch (EJBException ex) {
            StringBuilder error = new StringBuilder();
            error.append(ex).append(" ");
            error.append(ex.getMessage()).append(" ");
            Throwable cause = ex;
            while (cause.getCause()!= null) {
                cause = cause.getCause();
                error.append(cause).append(" ");
                error.append(cause.getMessage()).append(" ");
            }
            logger.log(Level.FINE, "Couldn''t save dataset: {0}", error.toString());
            //populateDatasetUpdateFailureMessage();
            try {
				jsonSavedResult.put("status", "error");
				jsonSavedResult.put("message", "Could not save dataset.");
			} catch (JSONException e) {
				
				e.printStackTrace();
			}
            return jsonSavedResult;
        } catch (CommandException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Dataset Save Failed", " - " + ex.toString()));
            logger.severe(ex.getMessage());
            //populateDatasetUpdateFailureMessage();
            try {
				jsonSavedResult.put("status", "error");
				jsonSavedResult.put("message", "Dataset Save Failed");
			} catch (JSONException e) {
				
				e.printStackTrace();
			}
            return jsonSavedResult;
            
        }
      
        // Call Ingest Service one more time, to 
        // queue the data ingest jobs for asynchronous execution: 
        ingestService.startIngestJobs(dataset, (AuthenticatedUser) this.authUser);
        
        
        // returning fields, got after saving to dataset, returning info for the saved file.
        // indicating the file has been published, since the saving is asynchronous execution, cannot get new file id here?

		try {
			jsonSavedResult.put("status", "ok");
			jsonSavedResult.put("message", "Dataset Saved!");
			
			JSONObject fileMetadata = new JSONObject();
			
			System.out.println(dataset.getDisplayName());
			
			fileMetadata.put("datasetTitle", dataset.getDisplayName());
			
			jsonSavedResult.put("fileMetadata", fileMetadata);
			
			
		} catch (JSONException e) {
			e.printStackTrace();
		}
       
		return jsonSavedResult;
	}
	
	private void loadParameters(HttpServletRequest request) {	
		
		params.put("user", request.getParameter("user"));
		params.put("password", request.getParameter("password"));
		params.put("datasetGlobalId", request.getParameter("datasetGlobalId"));
		
		return;
	}
	
	private class UpFile {
		public String fileName;
		public String fileContent;
		public String contentType;

		public UpFile (String fileName, String fileContent, String contentType) {
			this.fileName = fileName;
			this.fileContent = fileContent;
			this.contentType = contentType;
		}

		public String getFileName() {
			return fileName;
		}
		public void setFileName(String fileName) {
			this.fileName = fileName;
		}
		public String getFileContent() {
			return fileContent;
		}

		public void setFileContent(String fileContent) {
			this.fileContent = fileContent;
		}

		public String getContentType() {
			return contentType;
		}

		public void setContentType(String contentType) {
			this.contentType = contentType;
		}
		
	}
	
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) {

		try {
			response.setContentType("application/json");
			JSONObject jsonResponse = new JSONObject();
				
			loadParameters(request);
			UpFile upFile = getFile(request);
			
			String fileName = upFile.getFileName();
			String fileContent = upFile.getFileContent();
			
			if(StringUtils.isNotEmpty(fileContent) && StringUtils.isNotEmpty(fileName)){
				
				String datasetGlobalId = params.get("datasetGlobalId");	
				String user = params.get("user");
				String password = params.get("password");
				
				if(StringUtils.isNotEmpty(datasetGlobalId) && StringUtils.isNotEmpty(user) && StringUtils.isNotEmpty(password)){
							
					AuthenticationRequest authReq = new AuthenticationRequest();
					
				    authReq.putCredential("Username", user);
				    authReq.putCredential("Password", password);
				    try {
				        String credentialsAuthProviderId = "builtin";
				        this.authUser = authSvc.authenticate(credentialsAuthProviderId, authReq);
				        System.out.println("User authenticated: " + authUser.getIdentifier()); 
				    } catch (AuthenticationFailedException ex) {
				       ex.printStackTrace();
				    }
				    
				
					JSONObject jsonSavedResult = saveFile(upFile);
					jsonResponse.put("status", jsonSavedResult.getString("status"));
					jsonResponse.put("message", jsonSavedResult.getString("message"));
					if (jsonSavedResult.has("fileMetadata")) {
						jsonResponse.put("fileMetadata", jsonSavedResult.getJSONObject("fileMetadata"));
					}
					
								
				}else{
					jsonResponse.put("status", "error");
					jsonResponse.put("error", "The parameters studyId, user and password.");
					jsonResponse.put("datasetGlobalId", datasetGlobalId);
					jsonResponse.put("user", user);
					jsonResponse.put("password", password);
					//jsonResponse.put("fileLabel", fileLabel);
				}

			}else if(StringUtils.isNotEmpty(fileName)){
				jsonResponse.put("status", "error");
				jsonResponse.put("message", "A file has been found as parameter, however it was empty. Check the temporal folder configured in Dataverse. " + TMP_DIR);
			
			}else {
				jsonResponse.put("status", "error");
				jsonResponse.put("message", "No file found in the request.");
			}
			
			java.io.PrintWriter out = response.getWriter();
			out.print(jsonResponse);
			out.flush();
		} catch (Exception e) {	
			e.printStackTrace();
		}
	}
	



	private UpFile getFile(HttpServletRequest request) throws IOException {
		JSONObject fileObj;
		try {
			fileObj = new JSONObject(request.getParameter("file"));
			
			String contentType = "text/plain; charset=UTF-8";

			Iterator keys = fileObj.keys(); //gets all the keys
			while (keys.hasNext()) {
				String fileName = (String) keys.next();
			    String fileTable = fileObj.getString(fileName);
	
				UpFile upFile = new UpFile(fileName, fileTable, contentType);
				
				return upFile;
			}
	
		} catch (JSONException e) {
			
			e.printStackTrace();
		} 
		return null;

	}
	


    // delete this
	private File getFile_old(HttpServletRequest request, HttpServletResponse response) throws IOException {
		File file = null;
		boolean isMultipart = ServletFileUpload.isMultipartContent(request);		
	
		if(isMultipart){
			DiskFileItemFactory factory = new DiskFileItemFactory();
			// maximum size that will be stored in memory
			factory.setSizeThreshold(maxMemSize);
			// Location to save data that is larger than maxMemSize.
			factory.setRepository(new File(TMP_DIR));

			// Create a new file upload handler
			ServletFileUpload upload = new ServletFileUpload(factory);
			// maximum file size to be uploaded.
			upload.setSizeMax(maxFileSize);
			upload.setFileSizeMax(maxFileSize);
			upload.setHeaderEncoding("UTF-8");
			
			StringBuilder sb = new StringBuilder();
			try {
				// Parse the request to get file items.
				List<FileItem> fileItems = upload.parseRequest(request); 
				
				// Process the uploaded file items
				Iterator<FileItem> i = fileItems.iterator();

				while (i.hasNext()) {
					FileItem fi = (FileItem) i.next();
					
					sb.append(fi.getFieldName());
					
					if(fi.isFormField()){
						sb.append(" is Field");
						params.put(fi.getFieldName(), fi.getString());
					} else {
						sb.append(" is FILE ***");
						// Get the uploaded file parameters
						String fileName = fi.getName();
						// Write the file
						if (fileName.lastIndexOf("\\") >= 0) {
							file = new File(TMP_DIR + fileName.substring(fileName.lastIndexOf("\\")));
						} else {
							file = new File(TMP_DIR + fileName.substring(fileName.lastIndexOf("\\") + 1));
						}
						fi.write(file);
						sb.append(" Size: " + file.length());
					}
					sb.append("\n");
				}

			} catch (Exception ex) {
				ex.printStackTrace();
			}
			
			sb.append((file == null) ? "File is null" + ".\nWhen the file is empty, maybe the tmp folder is wrong configured.\nTMP_DIR: " + TMP_DIR : "File Size=" + file.length() );
			logger.log(Level.INFO, "getFile Information:\n" + sb.toString());
			
			return file;	
		}
		
		return null;
	}
	



}