/*
* ====================
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of the Common Development
* and Distribution License("CDDL") (the "License"). You may not use this file
* except in compliance with the License.
*
* You can obtain a copy of the License at
* http://opensource.org/licenses/cddl1.php
* See the License for the specific language governing permissions and limitations
* under the License.
*
* When distributing the Covered Code, include this CDDL Header Notice in each file
* and include the License file at http://opensource.org/licenses/cddl1.php.
* If applicable, add the following below this CDDL Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
* Portions Copyrighted 2014 ForgeRock AS.
*/
package org.identityconnectors.framework.impl.api;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.identityconnectors.common.logging.Log;
import org.identityconnectors.framework.api.operations.APIOperation;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
/**
* Proxy responsible for logging operations from the API.
*/
public class LoggingProxy implements InvocationHandler {
private static final Log.Level LOG_LEVEL = Log.Level.OK;
private static final Log LOG = Log.getLog(LoggingProxy.class);
private final Object target;
private final Class<? extends APIOperation> op;
public LoggingProxy(Class<? extends APIOperation> api, Object target) {
op = api;
this.target = target;
}
/**
* {@inheritDoc}
*/
public Object invoke(final Object proxy, final Method method, final Object[] args)
throws Throwable {
// do not log equals, hashCode, toString
if (method.getDeclaringClass() == Object.class) {
return method.invoke(target, args);
}
final String methodName = method.getName();
if (isLoggable()) {
StringBuilder bld = new StringBuilder();
bld.append("Enter: ").append(method.getName()).append('(');
for (int i = 0; args != null && i < args.length; i++) {
if (i != 0) {
bld.append(", ");
}
bld.append(args[i]);
}
bld.append(')');
final String msg = bld.toString();
LOG.log(op, methodName, LOG_LEVEL, msg, null);
}
// invoke the method
try {
Object ret = method.invoke(target, args);
if (isLoggable()) {
LOG.log(op, methodName, LOG_LEVEL, "Return: " + ret, null);
}
return ret;
} catch (InvocationTargetException e) {
Throwable root = e.getCause();
try {
LOG.log(op, methodName, LOG_LEVEL, "Exception: ", root);
} catch (Throwable t) {
// Ignore. Don't let a failed log prevent this from completing.
}
if (root instanceof RuntimeException) {
throw (RuntimeException) root;
} else if (root instanceof Exception) {
throw (Exception) root;
} else if (root instanceof Error) {
throw (Error) root;
} else {
throw ConnectorException.wrap(root);
}
}
}
public static boolean isLoggable() {
return LOG.isLoggable(LOG_LEVEL);
}
}