/*
   * (non-Javadoc)
   *
   * @see org.alfresco.repo.audit.AuditComponent#beforeMethodCallManualAudit(org.aopalliance.intercept.MethodInvocation)
   */
  @SuppressWarnings("unchecked")
  public void beforeMethodCallManualAudit(
      Class clazz, Object target, String methodName, Object... args) {
    Class[] argTypes = new Class[args.length];
    for (int i = 0; i < args.length; i++) {
      argTypes[i] = args[i].getClass();
    }
    Method method;
    try {
      method = clazz.getMethod(methodName, argTypes);
    } catch (SecurityException e1) {
      return;
    } catch (NoSuchMethodException e1) {
      return;
    }
    MethodInvocation methodInvocation =
        new ReflectiveMethodInvocation(null, target, method, args, null, null) {};
    if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue())) {
      if (auditModel instanceof AuditEntry
          && ((AuditEntry) auditModel).getEnabled() == TrueFalseUnset.TRUE) {
        boolean auditInternal =
            (auditModel.getAuditInternalServiceMethods(methodInvocation) == TrueFalseUnset.TRUE);
        try {
          String serviceName = publicServiceIdentifier.getPublicServiceName(methodInvocation);

          if (!auditInternal) {
            auditFlag.set(Boolean.TRUE);
          } else {
            if (logger.isDebugEnabled()) {
              logger.debug(
                  "Auditing internal service use for  - " + serviceName + "." + methodName);
            }
          }

          if (method.isAnnotationPresent(Auditable.class)) {

            if (serviceName != null) {
              if (logger.isDebugEnabled()) {
                logger.debug("Auditing - " + serviceName + "." + methodName);
              }
              try {
                auditImpl(methodInvocation, false);
              } catch (Throwable e) {

              }
            } else {
              if (logger.isDebugEnabled()) {
                logger.debug("UnknownService." + methodName);
              }
              try {
                auditImpl(methodInvocation, false);
              } catch (Throwable e) {

              }
            }

          } else if (method.isAnnotationPresent(NotAuditable.class)) {
            if (logger.isDebugEnabled()) {
              logger.debug("Not Audited. " + serviceName + "." + methodName);
            }
          } else {
            if (logger.isDebugEnabled()) {
              logger.debug("Unannotated service method " + serviceName + "." + methodName);
            }
            if (method.getDeclaringClass().isInterface()
                && method.getDeclaringClass().isAnnotationPresent(PublicService.class)) {
              throw new RuntimeException(
                  "Unannotated service method " + serviceName + "." + methodName);
            }
          }
        } finally {
          if (!auditInternal) {
            auditFlag.set(Boolean.FALSE);
          }
        }
      }
    }
  }
  public Object audit(MethodInvocation mi) throws Throwable {
    if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue())) {
      if (auditModel instanceof AuditEntry
          && ((AuditEntry) auditModel).getEnabled() == TrueFalseUnset.TRUE) {
        boolean auditInternal =
            (auditModel.getAuditInternalServiceMethods(mi) == TrueFalseUnset.TRUE);
        try {
          Method method = mi.getMethod();
          String methodName = method.getName();
          String serviceName = publicServiceIdentifier.getPublicServiceName(mi);

          if (!auditInternal) {
            auditFlag.set(Boolean.TRUE);
          } else {
            if (logger.isDebugEnabled()) {
              logger.debug(
                  "Auditing internal service use for  - " + serviceName + "." + methodName);
            }
          }

          if (method.isAnnotationPresent(Auditable.class)) {

            if (serviceName != null) {
              if (logger.isDebugEnabled()) {
                logger.debug("Auditing - " + serviceName + "." + methodName);
              }
              return auditImpl(mi, true);
            } else {
              if (logger.isDebugEnabled()) {
                logger.debug("UnknownService." + methodName);
              }
              return auditImpl(mi, true);
            }

          } else if (method.isAnnotationPresent(NotAuditable.class)) {
            if (logger.isDebugEnabled()) {
              logger.debug("Not Audited. " + serviceName + "." + methodName);
            }
            return mi.proceed();
          } else {
            if (logger.isDebugEnabled()) {
              logger.debug("Unannotated service method " + serviceName + "." + methodName);
            }
            if (method.getDeclaringClass().isInterface()
                && method.getDeclaringClass().isAnnotationPresent(PublicService.class)) {
              throw new RuntimeException(
                  "Unannotated service method " + serviceName + "." + methodName);
            } else {
              return mi.proceed();
            }
          }
        } finally {
          if (!auditInternal) {
            auditFlag.set(Boolean.FALSE);
          }
        }
      } else {
        return mi.proceed();
      }
    } else {
      return mi.proceed();
    }
  }