Package com.apitrary.orm.core

Source Code of com.apitrary.orm.core.ApitraryDaoSupport

/*
* Copyright 2012 Denis Neuling
*
* 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 com.apitrary.orm.core;

import java.lang.reflect.Field;
import java.util.List;

import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;

import com.apitrary.api.client.ApitraryClient;
import com.apitrary.api.client.common.HttpStatus;
import com.apitrary.api.client.exception.CommunicationErrorException;
import com.apitrary.api.client.util.ClassUtil;
import com.apitrary.api.common.status.APIState;
import com.apitrary.api.request.APIStateRequest;
import com.apitrary.api.request.DeleteRequest;
import com.apitrary.api.request.GetRequest;
import com.apitrary.api.request.PostRequest;
import com.apitrary.api.request.PutRequest;
import com.apitrary.api.request.QueriedGetRequest;
import com.apitrary.api.response.APIStateResponse;
import com.apitrary.api.response.DeleteResponse;
import com.apitrary.api.response.GetResponse;
import com.apitrary.api.response.PostResponse;
import com.apitrary.api.response.PutResponse;
import com.apitrary.api.response.QueriedGetResponse;
import com.apitrary.orm.annotations.Entity;
import com.apitrary.orm.annotations.Id;
import com.apitrary.orm.core.cascade.CascadeDeleteCapable;
import com.apitrary.orm.core.exception.ApitraryOrmDeleteException;
import com.apitrary.orm.core.exception.ApitraryOrmException;
import com.apitrary.orm.core.exception.ApitraryOrmIdDefinitionsException;
import com.apitrary.orm.core.exception.ApitraryOrmIdException;
import com.apitrary.orm.core.exception.ApitraryOrmUpdateException;
import com.apitrary.orm.core.exception.DaoSupportUninitializedException;
import com.apitrary.orm.core.exception.MappingException;
import com.apitrary.orm.core.marshalling.PayloadMarshaller;
import com.apitrary.orm.core.unmarshalling.DeleteResponseUnmarshaller;
import com.apitrary.orm.core.unmarshalling.GetResponseUnmarshaller;
import com.apitrary.orm.core.unmarshalling.PostResponseUnmarshaller;
import com.apitrary.orm.core.unmarshalling.PutResponseUnmarshaller;
import com.apitrary.orm.core.unmarshalling.QueriedGetResponseUnmarshaller;
import com.apitrary.orm.core.util.StringUtil;

/**
* <p>
* ApitraryDaoSupport class.
* </p>
*
* @author Denis Neuling (denisneuling@gmail.com)
*
*/
public class ApitraryDaoSupport {
  protected Logger log = Logger.getLogger(getClass());

  protected ApitraryClient apitraryClient;

  /**
   * <p>
   * Constructor for ApitraryDaoSupport.
   * </p>
   */
  public ApitraryDaoSupport() {
  }

  /**
   * <p>
   * Getter for the field <code>apitraryClient</code>.
   * </p>
   *
   * @return a {@link com.apitrary.api.client.ApitraryClient} object.
   */
  public ApitraryClient getApitraryClient() {
    return apitraryClient;
  }

  /**
   * <p>
   * Setter for the field <code>apitraryClient</code>.
   * </p>
   *
   * @param apitraryClient
   *            a {@link com.apitrary.api.client.ApitraryClient} object.
   */
  public void setApitraryClient(ApitraryClient apitraryClient) {
    this.apitraryClient = apitraryClient;
  }

  /**
   * <p>
   * save.
   * </p>
   *
   * @param entity
   *            a T object.
   * @param <T>
   *            a T object.
   * @return a T object.
   */
  @SuppressWarnings("unchecked")
  public <T> T save(T entity) {
    if (entity == null) {
      throw new ApitraryOrmException("Cannot persist null entity");
    }
    log.debug("Saving " + entity.getClass());

    PostRequest request = new PostRequest();
    request.setEntity(resolveApitraryEntity(entity));

    String payload = marshall(entity);

    request.setRequestPayload(payload);

    PostResponse response = resolveApitraryClient().send(request);

    if (HttpStatus.Created.ordinal() == response.getStatusCode()) {
      return (T) new PostResponseUnmarshaller().unMarshall(response, entity);
    } else {
      throw new ApitraryOrmException(response.getResult());
    }
  }

  /**
   * <p>
   * update.
   * </p>
   *
   * @param entity
   *            a T object.
   * @param <T>
   *            a T object.
   * @return a T object.
   */
  public <T> T update(T entity) {
    if (entity == null) {
      throw new ApitraryOrmException("Cannot update null entity");
    }

    log.debug("Updating " + entity.getClass());

    PutRequest request = new PutRequest();
    request.setEntity(resolveApitraryEntity(entity));
    request.setId(resolveApitraryEntityId(entity));

    String payload = marshall(entity);

    request.setRequestPayload(payload);

    PutResponse response = resolveApitraryClient().send(request);

    if (HttpStatus.No_Content.ordinal() != response.getStatusCode()) {
      if (HttpStatus.Not_Found.ordinal() == response.getStatusCode()) {
        throw new ApitraryOrmUpdateException("Cannot update object: object with given id does not exist.");
      } else {
        String statusMessage = (String) new PutResponseUnmarshaller().unMarshall(response, entity);
        throw new ApitraryOrmUpdateException(statusMessage);
      }
    }
    return entity;
  }

  /**
   * <p>
   * delete.
   * </p>
   *
   * @param entity
   *            a T object.
   * @param <T>
   *            a T object.
   */
  public <T> void delete(T entity) {
    if (entity == null) {
      throw new ApitraryOrmException("Cannot delete null entity");
    }

    log.debug("Deleting " + entity.getClass());

    DeleteRequest request = new DeleteRequest();
    request.setEntity(resolveApitraryEntity(entity));
    String id = resolveApitraryEntityId(entity);
    request.setId(id);

    new CascadeDeleteCapable(this).deleteCascades(entity);

    DeleteResponse response = resolveApitraryClient().send(request);
    if (HttpStatus.OK.ordinal() != response.getStatusCode()) {
      if (HttpStatus.Not_Found.ordinal() == response.getStatusCode()) {
        throw new ApitraryOrmDeleteException("Object with id " + id + " does not exist.");
      } else {
        String statusMessage = (String) new DeleteResponseUnmarshaller().unMarshall(response, entity);
        throw new ApitraryOrmDeleteException(statusMessage);
      }
    }
  }

  /**
   * <p>
   * findById.
   * </p>
   *
   * @param id
   *            a {@link java.lang.String} object.
   * @param entity
   *            a {@link java.lang.Class} object.
   * @param <T>
   *            a T object.
   * @return a T object.
   */
  @SuppressWarnings("unchecked")
  public <T> T findById(String id, Class<T> entity) {
    if (entity == null) {
      throw new ApitraryOrmException("Cannot access null entity");
    }
    if (id == null || id.isEmpty()) {
      return null;
    }

    log.debug("Searching " + entity + " " + id);

    GetRequest request = new GetRequest();
    request.setEntity(resolveApitraryEntity(entity));
    request.setId(id);
    GetResponse response = resolveApitraryClient().send(request);

    T result = (T) new GetResponseUnmarshaller(this).unMarshall(response, entity);

    if (result != null) {
      List<Field> fields = ClassUtil.getAnnotatedFields(entity, Id.class);
      if (fields.isEmpty() || fields.size() > 1) {
        throw new ApitraryOrmIdException("Illegal amount of annotated id properties of class " + entity.getClass().getName());
      } else {
        ClassUtil.setSilent(result, fields.get(0).getName(), id);
      }
    }
    return result;
  }

  /**
   * <p>
   * find.
   * </p>
   *
   * @param riakQuery
   *            a {@link java.lang.String} object.
   * @param entity
   *            a {@link java.lang.Class} object.
   * @param <T>
   *            a T object.
   * @return a {@link java.util.List} object.
   */
  @SuppressWarnings("unchecked")
  public <T> List<T> find(String riakQuery, Class<T> entity) {
    if (entity == null) {
      throw new ApitraryOrmException("Cannot access null entity");
    }
    log.debug("Searching " + entity + " " + riakQuery);

    QueriedGetRequest request = new QueriedGetRequest();
    request.setEntity(resolveApitraryEntity(entity));
    request.setQuery(riakQuery);
    QueriedGetResponse response = resolveApitraryClient().send(request);

    return (List<T>) new QueriedGetResponseUnmarshaller(this).unMarshall(response, entity);
  }

  /**
   * <p>
   * findAll.
   * </p>
   *
   * @param entity
   *            a {@link java.lang.Class} object.
   * @param <T>
   *            a T object.
   * @return a {@link java.util.List} object.
   */
  @SuppressWarnings("unchecked")
  public <T> List<T> findAll(Class<T> entity) {
    if (entity == null) {
      throw new ApitraryOrmException("Cannot access null entity");
    }

    log.debug("Loading all " + entity);

    QueriedGetRequest request = new QueriedGetRequest();
    request.setEntity(resolveApitraryEntity(entity));
    QueriedGetResponse response = resolveApitraryClient().send(request);

    if (HttpStatus.OK.ordinal() == response.getStatusCode()) {
      return (List<T>) new QueriedGetResponseUnmarshaller(this).unMarshall(response, entity);
    } else {
      /*
       * happens more often than expected...
       */
      // if(HttpStatus.Internal_Server_Error.ordinal() ==
      // response.getStatusCode()){
      // throw new
      // CommunicationErrorException(HttpStatus.Internal_Server_Error);
      // }
      throw new CommunicationErrorException(HttpStatus.getStatus(response.getStatusCode()));
    }
  }

  /**
   * <p>
   * getAPIState.
   * </p>
   *
   * @return a {@link com.apitrary.orm.core.internal.model.APIState} object.
   */
  public APIState getAPIState() {
    APIStateRequest request = new APIStateRequest();
    APIStateResponse response = resolveApitraryClient().send(request);

    APIState apiState = null;
    if (HttpStatus.OK.ordinal() == response.getStatusCode()) {
      String result = response.getResult();

      ObjectMapper objectMapper = new ObjectMapper();
      try {
        apiState = objectMapper.readValue(result, APIState.class);
      } catch (Exception e) {
        throw new MappingException(e);
      }
    } else {
      throw new CommunicationErrorException(HttpStatus.getStatus(response.getStatusCode()));
    }
    return apiState;
  }

  /**
   * <p>
   * resolveApitraryEntityId.
   * </p>
   *
   * @param entity
   *            a T object.
   * @param <T>
   *            a T object.
   * @return a {@link java.lang.String} object.
   */
  public <T> String resolveApitraryEntityId(T entity) {
    if (entity == null) {
      throw new ApitraryOrmIdDefinitionsException("Apitrary entity has not to be null.");
    }
    List<java.lang.reflect.Field> fields = ClassUtil.getAnnotatedFields(entity.getClass(), Id.class);
    if (fields.isEmpty()) {
      throw new ApitraryOrmIdDefinitionsException("Apitrary entity must own an annotated ID field.");
    }
    if (fields.size() > 1) {
      throw new ApitraryOrmIdDefinitionsException("Apitrary entity can not have more than one ID field.");
    }

    java.lang.reflect.Field field = fields.get(0);
    String id = ClassUtil.getValueOf(field, entity, entity.getClass(), String.class);
    if (id == null || id.isEmpty()) {
      throw new ApitraryOrmIdException("Entity lacks ID and is probably not persisted.");
    }
    return id;
  }

  /**
   * <p>
   * resolveApitraryEntity.
   * </p>
   *
   * @param entity
   *            a T object.
   * @param <T>
   *            a T object.
   * @return a {@link java.lang.String} object.
   */
  protected <T> String resolveApitraryEntity(T entity) {
    String entityName = ClassUtil.getClassAnnotationValue(entity.getClass(), Entity.class, "value", String.class);
    if (entityName == null || entityName.isEmpty()) {
      entityName = StringUtil.toVerb(entity.getClass().getSimpleName());
    }
    return entityName;
  }

  /**
   * <p>
   * resolveApitraryEntity.
   * </p>
   *
   * @param entity
   *            a {@link java.lang.Class} object.
   * @param <T>
   *            a T object.
   * @return a {@link java.lang.String} object.
   */
  protected <T> String resolveApitraryEntity(Class<T> entity) {
    String entityName = ClassUtil.getClassAnnotationValue(entity, Entity.class, "value", String.class);
    if (entityName == null || entityName.isEmpty()) {
      entityName = StringUtil.toVerb(entity.getSimpleName());
    }
    return entityName;
  }

  /**
   * <p>
   * marshall.
   * </p>
   *
   * @param entity
   *            a T object.
   * @param <T>
   *            a T object.
   * @return a {@link java.lang.String} object.
   */
  protected <T> String marshall(T entity) {
    return new PayloadMarshaller(this).marshall(entity);
  }

  private ApitraryClient resolveApitraryClient() {
    if (apitraryClient == null) {
      throw new DaoSupportUninitializedException("ApitraryClient was not set.");
    }
    return apitraryClient;
  }
}
TOP

Related Classes of com.apitrary.orm.core.ApitraryDaoSupport

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.