Package org.openmhealth.reference.request

Source Code of org.openmhealth.reference.request.DataWriteRequest

/*******************************************************************************
* Copyright 2013 Open mHealth
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.openmhealth.reference.request;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.openmhealth.reference.data.DataSet;
import org.openmhealth.reference.data.Registry;
import org.openmhealth.reference.domain.AuthenticationToken;
import org.openmhealth.reference.domain.Data;
import org.openmhealth.reference.domain.MetaData;
import org.openmhealth.reference.domain.MultiValueResult;
import org.openmhealth.reference.domain.Schema;
import org.openmhealth.reference.domain.User;
import org.openmhealth.reference.exception.InvalidAuthenticationException;
import org.openmhealth.reference.exception.OmhException;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
* <p>
* Stores the given data.
* </p>
*
* @author John Jenkins
*/
public class DataWriteRequest extends Request<Object> {
  /**
   * The JSON factory that is used to create the parser that will be used to
   * parse the data.
   */
  private static final JsonFactory JSON_FACTORY = new MappingJsonFactory();
 
  /**
   * The authentication token for the requesting user.
   */
  private final AuthenticationToken authToken;
  /**
   * The ID of the schema from which the data was generated.
   */
  private final String schemaId;
  /**
   * The version of the schema from which the data was generated.
   */
  private final long version;
  /**
   * The data to validate and store.
   */
  private final String data;
 
  /**
   * Creates a request to store some data.
   *
   * @param authToken
   *        The requesting user's authentication token.
   *
   * @param schemaId
   *        The ID of the schema which should be used to validate the data.
   *
   * @param version
   *        The version of the schema which should be used to validate the
   *        data.
   *
   * @param data
   *        The data to validate and store.
   *
   * @throws OmhException
   *         A parameter was invalid.
   */
  public DataWriteRequest(
    final AuthenticationToken authToken,
    final String schemaId,
    final long version,
    final String data)   
    throws OmhException {
   
    if(authToken == null) {
      throw
        new InvalidAuthenticationException(
          "The authentication token is missing.");
    }
    if(schemaId == null) {
      throw new OmhException("The schema ID is missing.");
    }
    if(data == null) {
      throw new OmhException("The data is missing.");
    }
   
    this.authToken = authToken;
    this.schemaId = schemaId;
    this.version = version;
    this.data = data;
  }

  /**
   * Validates the data and, if valid, stores it.
   */
  @Override
  public void service() throws OmhException {
    // First, short-circuit if this request has already been serviced.
    if(isServiced()) {
      return;
    }
    else {
      setServiced();
    }
   
    // Check to be sure the schema is known.
    MultiValueResult<? extends Schema> schemas =
      Registry.getInstance().getSchemas(schemaId, version, 0, 1);
    if(schemas.count() == 0) {
      throw
        new OmhException(
          "The schema ID, '" +
            schemaId +
            "', and version, '" +
            version +
            "', pair is unknown.");
    }
    Schema schema = schemas.iterator().next();
   
    // Get the user that owns this token.
    User requestingUser = authToken.getUser();
   
    // Parse the data.
    JsonNode dataNode;
    try {
      dataNode =
        JSON_FACTORY
          .createJsonParser(data).readValueAs(JsonNode.class);
    }
    catch(JsonParseException e) {
      throw new OmhException("The data was not well-formed JSON.", e);
    }
    catch(JsonProcessingException e) {
      throw new OmhException("The data was not well-formed JSON.", e);
    }
    catch(IOException e) {
      throw new OmhException("The data could not be read.", e);
    }
   
    // Make sure it is a JSON array.
    if(! (dataNode instanceof ArrayNode)) {
      throw new OmhException("The data was not a JSON array.");
    }
    ArrayNode dataArray = (ArrayNode) dataNode;
   
    // Get the number of data points.
    int numDataPoints = dataArray.size();
   
    // Create the result list of data points.
    List<Data> dataPoints = new ArrayList<Data>(numDataPoints);
   
    // Create a new ObjectMapper that will be used to convert the meta-data
    // node into a MetaData object.
    ObjectMapper mapper = new ObjectMapper();
   
    // For each element in the array, be sure it is a JSON object that
    // represents a valid data point for this schema.
    for(int i = 0; i < numDataPoints; i++) {
      // Get the current data point.
      JsonNode dataPoint = dataArray.get(i);
     
      // Validate that it is a JSON object.
      if(! (dataPoint instanceof ObjectNode)) {
        throw
          new OmhException(
            "A data point was not a JSON object: " + i);
      }
      ObjectNode dataObject = (ObjectNode) dataPoint;
     
      // Attempt to get the meta-data;
      MetaData metaData = null;
      JsonNode metaDataNode = dataObject.get(Data.JSON_KEY_METADATA);
      if(metaDataNode != null) {
        metaData = mapper.convertValue(metaDataNode, MetaData.class);
      }
     
      // Attempt to get the schema data.
      JsonNode schemaData = dataObject.get(Data.JSON_KEY_DATA);
     
      // If the data is missing, fail the request.
      if(schemaData == null) {
        throw
          new OmhException(
            "A data point's '" +
              Data.JSON_KEY_DATA +
              "' field is missing.");
      }
     
      // Create and add the point to the set of data.
      dataPoints
        .add(
          schema
            .validateData(
              requestingUser.getUsername(),
              metaData,
              schemaData));
    }
   
    // Store the data.
    DataSet.getInstance().storeData(dataPoints);
  }
}
TOP

Related Classes of org.openmhealth.reference.request.DataWriteRequest

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.