/**
   * The object will contain metadata properties, including object identifier {@code _id}, and
   * object version {@code _rev} to enable optimistic concurrency supported by OrientDB and OpenIDM.
   *
   * @param request the identifier of the object to retrieve from the object set.
   * @throws NotFoundException if the specified object could not be found.
   * @throws ForbiddenException if access to the object is forbidden.
   * @throws BadRequestException if the passed identifier is invalid
   * @return the requested object.
   */
  @Override
  public ResourceResponse read(ReadRequest request) throws ResourceException {
    if (request.getResourcePathObject().size() < 2) {
      throw new NotFoundException(
          "The object identifier did not include sufficient information to determine the object type and identifier of the object to read: "
              + request.getResourcePath());
    }

    final String type = request.getResourcePathObject().parent().toString();
    final String localId = request.getResourcePathObject().leaf();
    ResourceResponse result = null;
    ODatabaseDocumentTx db = getConnection();
    try {
      ODocument doc = predefinedQueries.getByID(localId, type, db);
      if (doc == null) {
        throw new NotFoundException("Object " + localId + " not found in " + type);
      }
      result = DocumentUtil.toResource(doc);
      logger.trace("Completed get for id: {} result: {}", request.getResourcePath(), result);
      return result;
    } finally {
      if (db != null) {
        db.close();
      }
    }
  }