Package ca.carleton.gcrc.couch.onUpload

Source Code of ca.carleton.gcrc.couch.onUpload.UploadWorkerThread

package ca.carleton.gcrc.couch.onUpload;

import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import ca.carleton.gcrc.couch.client.CouchDesignDocument;
import ca.carleton.gcrc.couch.client.CouchQuery;
import ca.carleton.gcrc.couch.client.CouchQueryResults;
import ca.carleton.gcrc.couch.onUpload.mail.MailNotification;
import ca.carleton.gcrc.olkit.multimedia.file.SystemFile;

public class UploadWorkerThread extends Thread {

  final protected Logger logger = Logger.getLogger(this.getClass());
 
  private boolean isShuttingDown = false;
  private CouchDesignDocument dd;
  private File mediaDir;
  private MailNotification mailNotification;
  private Set<String> docIdsToSkip = new HashSet<String>();
  private List<FileConversionPlugin> fileConverters;
 
  protected UploadWorkerThread(
    CouchDesignDocument dd
    ,File mediaDir
    ,MailNotification mailNotification
    ,List<FileConversionPlugin> fileConverters
    ) {
    this.dd = dd;
    this.mediaDir = mediaDir;
    this.mailNotification = mailNotification;
    this.fileConverters = fileConverters;
  }
 
  public void shutdown() {
   
    logger.info("Shutting down upload worker thread");

    synchronized(this) {
      isShuttingDown = true;
      this.notifyAll();
    }
  }
 
  @Override
  public void run() {
   
    logger.info("Start upload worker thread");
   
    boolean done = false;
    do {
      synchronized(this) {
        done = isShuttingDown;
      }
      if( false == done ) {
        activity();
      }
    } while( false == done );

    logger.info("Upload worker thread exiting");
  }
 
  private void activity() {
    CouchQuery query = new CouchQuery();
    query.setViewName("server_work");
   
    CouchQueryResults results;
    try {
      results = dd.performQuery(query);
    } catch (Exception e) {
      logger.error("Error accessing server",e);
      waitMillis(60 * 1000); // wait a minute
      return;
    }
   
    // Check for work
    String docId = null;
    JSONArray state = null;
    for(JSONObject row : results.getRows()) {
      String id = row.optString("id");
      if( false == docIdsToSkip.contains(id) ) {
        // Found some work
        docId = id;
        state = row.optJSONArray("key");
        break;
      }
    }
   
    if( null == docId ) {
      // Nothing to do, wait 5 secs
      waitMillis(5 * 1000);
      return;
    } else {
      try {
        // Handle this work
        performWork(docId, state);
       
      } catch(Exception e) {
        logger.error("Error processing document "+docId+" ("+state+")",e);
        docIdsToSkip.add(docId);
      }
    }
  }
 
  private void performWork(String docId, JSONArray state) throws Exception {
   
    logger.info("Upload worker thread processing: "+docId+" ("+state+")");
   
    String work = state.getString(0);
   
    if( UploadConstants.UPLOAD_STATUS_SUBMITTED.equals(work) ) {
      String attachmentName = state.getString(1);
      performSubmittedWork(docId, attachmentName);
     
    } else if( UploadConstants.UPLOAD_STATUS_ANALYZED.equals(work) ) {
      String attachmentName = state.getString(1);
      performAnalyzedWork(docId, attachmentName);
     
    } else if( UploadConstants.UPLOAD_STATUS_APPROVED.equals(work) ) {
      String attachmentName = state.getString(1);
      performApprovedWork(docId, attachmentName);
       
    } else {
      throw new Exception("Unrecognized state: "+state);
    }

    logger.info("Upload worker thread completed: "+docId+" ("+state+")");
  }

  private void performSubmittedWork(String docId, String attachmentName) throws Exception {
    JSONObject doc = dd.getDatabase().getDocument(docId);

    FileConversionContext conversionContext =
      new FileConversionContext(doc,dd,attachmentName,mediaDir);
    JSONObject submittedObj = conversionContext.getAttachmentDescription();
   
    if( null == submittedObj) {
      logger.info("Submission can not be found");

    } else if( false == UploadConstants.UPLOAD_STATUS_SUBMITTED.equals( submittedObj.optString(UploadConstants.UPLOAD_STATUS_KEY) ) ) {
      logger.info("File not in submit state");
     
    } else {
      JSONObject originalObj = submittedObj.optJSONObject("original");
     
      if( null == originalObj) {
        logger.error("Submission does not contain original");
        throw new Exception("Submission does not contain original");
     

      // Set file size
      File file = conversionContext.getOriginalFile();
      long fileSize = file.length();
      originalObj.put(UploadConstants.SIZE_KEY, fileSize);

      // Mime type, encoding type and file class
      boolean pluginFound = false;
      String mimeType = null;
      String mimeEncoding = null;
      String fileClass = null;
      for(FileConversionPlugin fcp : this.fileConverters) {
        FileConversionMetaData md = fcp.getFileMetaData(file);
        if( md.isFileConvertable() ) {
          mimeType = md.getMimeType();
          fileClass = md.getFileClass();
          mimeEncoding = md.getMimeEncoding();
 
          pluginFound = true;
          break;
        }
      }
      if( false == pluginFound ) {
        logger.info("No plugin found for uploaded file");
       
        SystemFile sf = SystemFile.getSystemFile(file);
        mimeType = sf.getMimeType();
        mimeEncoding = sf.getMimeEncoding();
      }
      if( null != mimeType ) {
        originalObj.put(UploadConstants.MIME_KEY, mimeType);
      }
      if( null != mimeEncoding ) {
        originalObj.put(UploadConstants.ENCODING_KEY, mimeEncoding);
      }
      if( null != fileClass ){
        submittedObj.put(UploadConstants.MIME_CLASS_KEY, fileClass);
      }

      // Update status
      conversionContext.setStatus(UploadConstants.UPLOAD_STATUS_ANALYZED);
      conversionContext.saveDocument();
    }
  }

  private void performAnalyzedWork(String docId, String attachmentName) throws Exception {
    JSONObject doc = dd.getDatabase().getDocument(docId);

    FileConversionContext conversionContext =
      new FileConversionContext(doc,dd,attachmentName,mediaDir);
    JSONObject analyzedObj = conversionContext.getAttachmentDescription();
   
    if( null == analyzedObj ) {
      logger.info("Analysis object not found");

    } else if( false == UploadConstants.UPLOAD_STATUS_ANALYZED.equals( analyzedObj.optString(UploadConstants.UPLOAD_STATUS_KEY) ) ) {
      logger.info("File not in analyzed state");
     
    } else {
      JSONObject originalObj = analyzedObj.optJSONObject("original");
      if( null == originalObj ) {
        logger.error("Analysis required but original object is not present");
        throw new Exception("Analysis required but original object is not present");
      }

      boolean pluginFound = false;
      String fileClass = conversionContext.getFileClass();
      for(FileConversionPlugin fcp : this.fileConverters) {
        if( fcp.handlesFileClass(fileClass) ) {
          fcp.analyzeFile(conversionContext);
          pluginFound = true;
          break;
        }
      }
      if( false == pluginFound ) {
        logger.info("No plugin found to analyze file class: "+fileClass);
       
        // By default, original file is used
        analyzedObj.put(UploadConstants.MEDIA_FILE_KEY, originalObj.opt(UploadConstants.MEDIA_FILE_KEY));
        analyzedObj.put(UploadConstants.MIME_KEY, originalObj.opt(UploadConstants.MIME_KEY));
        analyzedObj.put(UploadConstants.ENCODING_KEY, originalObj.opt(UploadConstants.ENCODING_KEY));
        analyzedObj.put(UploadConstants.SIZE_KEY, originalObj.opt(UploadConstants.SIZE_KEY));
      }
     
      // Update document
      conversionContext.setStatus(UploadConstants.UPLOAD_STATUS_WAITING_FOR_APPROVAL);
      conversionContext.saveDocument();
     
      // Notify that upload is available
      sendContributionApprovalRequest(docId, doc, attachmentName);
    }
  }

  private void performApprovedWork(String docId, String attachmentName) throws Exception {
    JSONObject doc = dd.getDatabase().getDocument(docId);
   
    FileConversionContext conversionContext =
      new FileConversionContext(doc,dd,attachmentName,mediaDir);
    JSONObject approvedObj = conversionContext.getAttachmentDescription();

    if( null == approvedObj ) {
      logger.info("Approved object not found");

    } else if( false == UploadConstants.UPLOAD_STATUS_APPROVED.equals( approvedObj.optString(UploadConstants.UPLOAD_STATUS_KEY) ) ) {
      logger.info("File not in analyzed state");
     
    } else {

      boolean pluginFound = false;
      String fileClass = conversionContext.getFileClass();
      for(FileConversionPlugin fcp : this.fileConverters) {
        if( fcp.handlesFileClass(fileClass) ) {
          fcp.approveFile(conversionContext);
          pluginFound = true;
          break;
        }
      }
      if( false == pluginFound ) {
        logger.info("No plugin found for uploaded file class: "+fileClass);
       
        String mimeType = conversionContext.getContentType();
        if( null == mimeType ) {
          mimeType = "application/octet-stream";
        }
       
        // By default, upload original file
        conversionContext.uploadFile(
          conversionContext.getAttachmentName()
          ,conversionContext.getFile()
          ,mimeType
          );
      }

      // Update status
      conversionContext.setStatus(UploadConstants.UPLOAD_STATUS_ATTACHED);
      conversionContext.saveDocument();
    }
  }
 
  private void sendContributionApprovalRequest(String docId, JSONObject doc, String attachmentName) {
    // Notify that upload is available
    try {
      String title = "[not set]";
      String description = "[not set]";
     
      JSONObject contributionObj = doc.optJSONObject("nunaliit_contribution");
      if( null != contributionObj ) {
        if( contributionObj.has("title") ) {
          title = contributionObj.getString("title");
        }
        if( contributionObj.has("description") ) {
          description = contributionObj.getString("description");
        }
      }
     
      mailNotification.uploadNotification(docId, title, description, attachmentName);
     
    } catch(Exception e) {
      logger.error("Failed mail notification",e);
    }
  }

  private boolean waitMillis(int millis) {
    synchronized(this) {
      if( true == isShuttingDown ) {
        return false;
      }
     
      try {
        this.wait(millis);
      } catch (InterruptedException e) {
        // Interrupted
        return false;
      }
    }
   
    return true;
  }
}
TOP

Related Classes of ca.carleton.gcrc.couch.onUpload.UploadWorkerThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.