@Override
  public AllowableActions getAllowableActions(
      CallContext callContext, String repositoryId, String objectId) {

    exceptionService.invalidArgumentRequired("objectId", objectId);

    Lock lock = threadLockService.getReadLock(repositoryId, objectId);

    try {
      lock.lock();

      // //////////////////
      // General Exception
      // //////////////////
      Content content = contentService.getContent(repositoryId, objectId);
      exceptionService.objectNotFound(DomainType.OBJECT, content, objectId);
      // NOTE: The permission key doesn't exist according to CMIS
      // specification.

      // //////////////////
      // Body of the method
      // //////////////////
      return compileService.compileAllowableActions(callContext, repositoryId, content);

    } finally {
      lock.unlock();
    }
  }
  @Override
  public ObjectData getObject(
      CallContext callContext,
      String repositoryId,
      String objectId,
      String filter,
      Boolean includeAllowableActions,
      IncludeRelationships includeRelationships,
      String renditionFilter,
      Boolean includePolicyIds,
      Boolean includeAcl,
      ExtensionsData extension) {

    exceptionService.invalidArgumentRequired("objectId", objectId);

    Lock lock = threadLockService.getReadLock(repositoryId, objectId);
    try {
      lock.lock();

      // //////////////////
      // General Exception
      // //////////////////
      Content content = contentService.getContent(repositoryId, objectId);
      // WORK AROUND: getObject(versionSeriesId) is interpreted as
      // getDocumentOflatestVersion
      if (content == null) {
        VersionSeries versionSeries = contentService.getVersionSeries(repositoryId, objectId);
        if (versionSeries != null) {
          content = contentService.getDocumentOfLatestVersion(repositoryId, objectId);
        }
      }
      exceptionService.objectNotFound(DomainType.OBJECT, content, objectId);
      exceptionService.permissionDenied(
          callContext, repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content);

      // //////////////////
      // Body of the method
      // //////////////////
      ObjectData object =
          compileService.compileObjectData(
              callContext,
              repositoryId,
              content,
              filter,
              includeAllowableActions,
              includeRelationships,
              null,
              includeAcl);

      return object;
    } finally {
      lock.unlock();
    }
  }
  @Override
  public ObjectData getObjectByPath(
      CallContext callContext,
      String repositoryId,
      String path,
      String filter,
      Boolean includeAllowableActions,
      IncludeRelationships includeRelationships,
      String renditionFilter,
      Boolean includePolicyIds,
      Boolean includeAcl,
      ExtensionsData extension) {
    // //////////////////
    // General Exception
    // //////////////////
    exceptionService.invalidArgumentRequired("objectId", path);
    // FIXME path is not preserved in db.
    Content content = contentService.getContentByPath(repositoryId, path);

    // TODO create objectNotFoundByPath method
    exceptionService.objectNotFoundByPath(DomainType.OBJECT, content, path);

    Lock lock = threadLockService.getReadLock(repositoryId, content.getId());
    try {
      lock.lock();

      exceptionService.permissionDenied(
          callContext, repositoryId, PermissionMapping.CAN_GET_PROPERTIES_OBJECT, content);

      // //////////////////
      // Body of the method
      // //////////////////
      return compileService.compileObjectData(
          callContext,
          repositoryId,
          content,
          filter,
          includeAllowableActions,
          includeRelationships,
          renditionFilter,
          includeAcl);
    } finally {
      lock.unlock();
    }
  }
  @Override
  public ObjectData create(
      CallContext callContext,
      String repositoryId,
      Properties properties,
      String folderId,
      ContentStream contentStream,
      VersioningState versioningState,
      List<String> policies,
      ExtensionsData extension) {

    String typeId = DataUtil.getObjectTypeId(properties);
    TypeDefinition type = typeManager.getTypeDefinition(repositoryId, typeId);
    if (type == null) {
      throw new CmisObjectNotFoundException("Type '" + typeId + "' is unknown!");
    }

    String objectId = null;
    // TODO ACE can be set !
    if (type.getBaseTypeId() == BaseTypeId.CMIS_DOCUMENT) {
      objectId =
          createDocument(
              callContext,
              repositoryId,
              properties,
              folderId,
              contentStream,
              versioningState,
              null,
              null,
              null);
    } else if (type.getBaseTypeId() == BaseTypeId.CMIS_FOLDER) {
      objectId =
          createFolder(
              callContext, repositoryId, properties, folderId, policies, null, null, extension);
    } else if (type.getBaseTypeId() == BaseTypeId.CMIS_RELATIONSHIP) {
      objectId =
          createRelationship(
              callContext, repositoryId, properties, policies, null, null, extension);
    } else if (type.getBaseTypeId() == BaseTypeId.CMIS_POLICY) {
      objectId =
          createPolicy(
              callContext, repositoryId, properties, folderId, policies, null, null, extension);
    } else if (type.getBaseTypeId() == BaseTypeId.CMIS_ITEM) {
      objectId =
          createItem(
              callContext, repositoryId, properties, folderId, policies, null, null, extension);
    } else {
      throw new CmisObjectNotFoundException("Cannot create object of type '" + typeId + "'!");
    }

    ObjectData object =
        compileService.compileObjectData(
            callContext,
            repositoryId,
            contentService.getContent(repositoryId, objectId),
            null,
            false,
            IncludeRelationships.NONE,
            null,
            false);

    return object;
  }