@Override
  @TransactionAttribute(TransactionAttributeType.REQUIRED)
  public void deleteName(String path) throws GreetingServiceException {
    logger.info("deleteName(...) called");
    logger.debug("params : path=" + path);

    try {
      // Checking if the connected user has the permission to delete the resource giving pep :
      String caller = membership.getProfilePathForConnectedIdentifier();
      pep.checkSecurity(caller, path, "delete");

      // Performing a lookup in the naming to recover the Resource Identifier
      FactoryResourceIdentifier identifier = binding.lookup(path);

      // Checking if this resource identifier is really a resource managed by this service (a Hello
      // resource)
      checkResourceType(identifier, Name.RESOURCE_NAME);

      // STARTING SPECIFIC EXTERNAL SERVICE RESOURCE LOADING OR METHOD CALLS
      Name name = em.find(Name.class, identifier.getId());
      if (name == null) {
        throw new GreetingServiceException("unable to find a name for id " + identifier.getId());
      }
      em.remove(name);
      // END OF EXTERNAL SERVICE INVOCATION

      // Removing the security policy of this node :
      String policyId = binding.getProperty(path, FactoryResourceProperty.POLICY_ID, false);
      pap.deletePolicy(policyId);

      // Unbinding the resource from this path :
      binding.unbind(path);

      // Using the notification service to throw an event :
      notification.throwEvent(
          new Event(
              path,
              caller,
              Name.RESOURCE_NAME,
              Event.buildEventType(GreetingService.SERVICE_NAME, Name.RESOURCE_NAME, "delete"),
              ""));

      // Using the indexing service to unindex the name
      indexing.remove(getServiceName(), path);

    } catch (Exception e) {
      // ctx.setRollbackOnly();
      logger.error("unable to delete the name at path " + path, e);
      throw new GreetingServiceException("unable to delete the name at path " + path, e);
    }
  }
  @Override
  @TransactionAttribute(TransactionAttributeType.REQUIRED)
  public void updateName(String path, String value) throws GreetingServiceException {
    logger.info("updateName(...) called");
    logger.debug("params : path=" + path + ", value=" + value);

    try {
      // Checking if the connected user has the permission to update the resource giving pep :
      String caller = membership.getProfilePathForConnectedIdentifier();
      pep.checkSecurity(caller, path, "update");

      // Performing a lookup in the naming to recover the Resource Identifier
      FactoryResourceIdentifier identifier = binding.lookup(path);

      // Checking if this resource identifier is really a resource managed by this service (a Hello
      // resource)
      checkResourceType(identifier, Name.RESOURCE_NAME);

      // STARTING SPECIFIC EXTERNAL SERVICE RESOURCE LOADING OR METHOD CALLS
      Name name = em.find(Name.class, identifier.getId());
      if (name == null) {
        throw new GreetingServiceException("unable to find a name for id " + identifier.getId());
      }
      name.setValue(value);
      em.merge(name);
      // END OF EXTERNAL SERVICE INVOCATION

      // Need to set some properties on the node :
      binding.setProperty(
          path, FactoryResourceProperty.LAST_UPDATE_TIMESTAMP, System.currentTimeMillis() + "");

      // Using the notification service to throw an event :
      notification.throwEvent(
          new Event(
              path,
              caller,
              Name.RESOURCE_NAME,
              Event.buildEventType(GreetingService.SERVICE_NAME, Name.RESOURCE_NAME, "update"),
              ""));

      // Using the indexing service to reindex the name newly updated
      indexing.reindex(getServiceName(), path);

    } catch (Exception e) {
      //   ctx.setRollbackOnly();
      logger.error("unable to update the name at path " + path, e);
      throw new GreetingServiceException("unable to update the name at path " + path, e);
    }
  }
  @Override
  @TransactionAttribute(TransactionAttributeType.REQUIRED)
  public void createName(String path, String value) throws GreetingServiceException {

    logger.info("createName(...) called");
    logger.debug("params : path=" + path + ", value=" + value);

    try {
      // Checking if the connected user has the permission to create a resource giving pep :
      //  - the profile path of the connected user (caller)
      //  - the parent of the path (we check the 'create' permission on the parent of the given
      // path)
      //  - the name of the permission to check ('create')
      String caller = membership.getProfilePathForConnectedIdentifier();
      pep.checkSecurity(caller, PathHelper.getParentPath(path), "create");

      // STARTING SPECIFIC EXTERNAL SERVICE RESOURCE CREATION OR METHOD CALL
      Name name = new Name();
      name.setId(UUID.randomUUID().toString());
      name.setValue(value);
      em.persist(name);
      // END OF EXTERNAL INVOCATION

      // Binding the external resource in the naming using the generated resource ID :
      binding.bind(name.getFactoryResourceIdentifier(), path);

      // Need to set some properties on the node :
      binding.setProperty(
          path, FactoryResourceProperty.CREATION_TIMESTAMP, "" + System.currentTimeMillis());
      binding.setProperty(
          path, FactoryResourceProperty.LAST_UPDATE_TIMESTAMP, "" + System.currentTimeMillis());
      binding.setProperty(path, FactoryResourceProperty.AUTHOR, caller);

      // Need to create a new security policy for this resource :
      // Giving the caller the Owner permission (aka all permissions)
      String policyId = UUID.randomUUID().toString();
      pap.createPolicy(policyId, PAPServiceHelper.buildOwnerPolicy(policyId, caller, path));
      pap.createPolicy(
          UUID.randomUUID().toString(),
          PAPServiceHelper.buildPolicy(policyId, caller, path, new String[] {"read"}));

      // Setting security properties on the node :
      binding.setProperty(path, FactoryResourceProperty.OWNER, caller);
      binding.setProperty(path, FactoryResourceProperty.POLICY_ID, policyId);

      // Using the notification service to throw an event :
      notification.throwEvent(
          new Event(
              path,
              caller,
              Name.RESOURCE_NAME,
              Event.buildEventType(GreetingService.SERVICE_NAME, Name.RESOURCE_NAME, "create"),
              ""));

      // Using the indexing service to index the name newly created
      indexing.index(getServiceName(), path);
    } catch (Exception e) {
      ctx.setRollbackOnly();
      logger.error("unable to create the name at path " + path, e);
      throw new GreetingServiceException("unable to create the name at path " + path, e);
    }
  }