Package ca.carleton.gcrc.couch.submission

Source Code of ca.carleton.gcrc.couch.submission.SubmissionServletActions

package ca.carleton.gcrc.couch.submission;

import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ca.carleton.gcrc.couch.client.CouchAuthenticationContext;
import ca.carleton.gcrc.couch.client.CouchDb;
import ca.carleton.gcrc.couch.client.CouchDesignDocument;
import ca.carleton.gcrc.couch.client.CouchDocumentOptions;
import ca.carleton.gcrc.couch.client.CouchServerVersion;
import ca.carleton.gcrc.couch.utils.CouchNunaliitUtils;
import ca.carleton.gcrc.json.JSONSupport;

public class SubmissionServletActions {
 
  static private Pattern underscorePattern = Pattern.compile("_(.*)");

  final protected Logger logger = LoggerFactory.getLogger(this.getClass());

//  private String atlasName = null;
  private CouchDesignDocument submissionDesign = null;
  private CouchDb documentCouchDb = null;
  private JSONObject cached_welcome;

  public SubmissionServletActions(
      String atlasName
      ,CouchDesignDocument submissionDesign
      ,CouchDb documentCouchDb
    ){
//    this.atlasName = atlasName;
    this.submissionDesign = submissionDesign;
    this.documentCouchDb = documentCouchDb;
  }
 
  synchronized public JSONObject getWelcome() throws Exception{
    if( null == cached_welcome ){
      cached_welcome = new JSONObject();
      cached_welcome.put("SubmissionServlet", true);
     
      if( null != submissionDesign ){
        cached_welcome.put("submissionDbAvailable", true);
      } else {
        cached_welcome.put("submissionDbAvailable", false);
      }
     
      CouchServerVersion version = submissionDesign.getDatabase().getClient().getVersion();
      cached_welcome.put("version", version.getFullVersion());
    }
   
    return cached_welcome;
  }

  public JSONObject getUuids(CouchAuthenticationContext authContext, int count) throws Exception {
    try {
      String[] uuids = submissionDesign.getDatabase().getClient().getUuids(count);
     
      JSONObject result = new JSONObject();
     
      JSONArray jsonUuids = new JSONArray();
      for(int loop=0; loop<uuids.length; ++loop){
        jsonUuids.put(uuids[loop]);
      }
      result.put("uuids", jsonUuids);
     
      return result;
     
    } catch (Exception e) {
      throw new Exception("Error while obtaining uuids",e);
    }
  }

  public JSONObject modifyDocument(
      CouchAuthenticationContext authContext
      ,String dbIdentifier
      ,String docId
      ,JSONObject doc
      ) throws Exception {
   
    if( "submissionDb".equals(dbIdentifier) ) {
      if( null == doc ){
        throw new Exception("Invalid document content (null)");
      }
     
      // Verify that if a _id attribute is provided in the document, that it matches the
      // one given in parameter
      if( JSONSupport.containsKey(doc, "_id") ){
        String id = doc.getString("_id");
        if( false == id.equals(docId) ){
          throw new Exception("Document identifier found in content must match the one found in parameters");
        }
      };
     
      validateLastUpdated(authContext, doc);
     
      JSONObject originalDoc = null;
      if( JSONSupport.containsKey(doc, "_rev") ){
        CouchDocumentOptions options = new CouchDocumentOptions();
        options.setRevision( doc.getString("_rev") );
        originalDoc = documentCouchDb.getDocument(docId, options);
      }
     
      JSONObject submissionRequest = buildSubmissionRequest(authContext, doc, originalDoc);
     
      JSONObject result = submissionDesign.getDatabase().createDocument(submissionRequest);
     
      return result;

    } else {
      throw new Exception("Only operations against 'submissionDb' are accepted");
    }
  }

  public JSONObject deleteDocument(
      CouchAuthenticationContext authContext
      ,String dbIdentifier
      ,String docId
      ,String rev
      ) throws Exception {
   
    if( "submissionDb".equals(dbIdentifier) ) {
      if( null == docId || null == rev ){
        throw new Exception("Document identifier and revision must be specified");
      }
     
      JSONObject originalDoc = null;
      {
        CouchDocumentOptions options = new CouchDocumentOptions();
        options.setRevision( rev );
        originalDoc = documentCouchDb.getDocument(docId, options);
      }
     
      JSONObject submissionRequest = buildSubmissionRequest(authContext, null, originalDoc);
     
      JSONObject result = submissionDesign.getDatabase().createDocument(submissionRequest);
     
      return result;

    } else {
      throw new Exception("Only operations against 'submissionDb' are accepted");
    }
  }

  private void validateLastUpdated(CouchAuthenticationContext authContext, JSONObject doc) throws Exception{
    JSONObject lastUpdated = doc.optJSONObject("nunaliit_last_updated");
    if( null == lastUpdated ){
      throw new Exception("Document does not contain a 'nunaliit_last_updated' field");
    }
   
    String userId = lastUpdated.optString("name");
    if( null == userId ){
      throw new Exception("Document contains a 'nunaliit_last_updated' structure with a missing 'name' field");
    }
   
    if( false == userId.equals(authContext.getName()) ){
      throw new Exception("Identifier found in the 'nunaliit_last_updated' does not match authenticated user");
    }
  }

  private JSONObject buildSubmissionRequest(
      CouchAuthenticationContext authContext
      ,JSONObject doc
      ,JSONObject original
      ) throws Exception{
    JSONObject submissionRequest = new JSONObject();
   
    submissionRequest.put("nunaliit_type", "document_submission");
   
    JSONObject submissionStructure = new JSONObject();
    submissionRequest.put("nunaliit_submission", submissionStructure);
    submissionStructure.put("state", "submitted");
   
    // Submitter
    {
      submissionStructure.put("submitter_name", authContext.getName());
      JSONArray roles = new JSONArray();
      for(String role : authContext.getRoles()){
        roles.put(role);
      }
      submissionStructure.put("submitter_roles", roles);
    }
   
    // Submitted
    if( null != doc ){
      JSONObject submittedDoc = new JSONObject();
      submissionStructure.put("submitted_doc", submittedDoc);
      JSONObject submittedReserved = new JSONObject();
      submissionStructure.put("submitted_reserved", submittedReserved);
     
      Iterator<?> it = doc.keys();
      while( it.hasNext() ){
        Object keyObj = it.next();
        if( keyObj instanceof String ){
          String key = (String)keyObj;
          Object value = doc.get(key);
         
          Matcher matcher = underscorePattern.matcher(key);
          if( matcher.matches() ){
            String reservedKey = matcher.group(1);
            submittedReserved.put(reservedKey, value);
          } else {
            submittedDoc.put(key, value);
          }
        }
      }
    } else {
      submissionStructure.put("deletion", true);
    }
   
    // Original
    if( null != original ){
      JSONObject originalDoc = new JSONObject();
      submissionStructure.put("original_doc", originalDoc);
      JSONObject originalReserved = new JSONObject();
      submissionStructure.put("original_reserved", originalReserved);
     
      Iterator<?> it = original.keys();
      while( it.hasNext() ){
        Object keyObj = it.next();
        if( keyObj instanceof String ){
          String key = (String)keyObj;
          Object value = original.get(key);
         
          Matcher matcher = underscorePattern.matcher(key);
          if( matcher.matches() ){
            String reservedKey = matcher.group(1);
            originalReserved.put(reservedKey, value);
          } else {
            originalDoc.put(key, value);
          }
        }
      }
    }
   
    CouchNunaliitUtils.adjustDocumentForStorage(submissionRequest, authContext);
   
    return submissionRequest;
  }
}
TOP

Related Classes of ca.carleton.gcrc.couch.submission.SubmissionServletActions

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.