blob: 532710282ec7e55422663cc22dda75c3c2797a04 [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.enterprise.adaptor.sharepoint;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.xml.ws.Holder;
/**
* InvocationHandler that can wrap WebService instances and log input/output
* values. This is more helpful than manual logging because it checks the
* mode of a parameter and only prints it when appropriate. The mode of a
* parameter defines when it is sent, so this logging method accurately
* represents the exchange of information.
*/
class LoggingWSHandler implements InvocationHandler {
private static final Logger log
= Logger.getLogger(LoggingWSHandler.class.getName());
private final Object wrapped;
public LoggingWSHandler(Object wrapped) {
this.wrapped = wrapped;
}
public static <T> T create(Class<T> webServiceInterface, T wrapped) {
InvocationHandler invokeHandler = new LoggingWSHandler(wrapped);
Object oInstance = Proxy.newProxyInstance(
LoggingWSHandler.class.getClassLoader(),
new Class<?>[] {webServiceInterface}, invokeHandler);
@SuppressWarnings("unchecked")
T tInstance = (T) oInstance;
return tInstance;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
final Level logLevel = Level.FINE;
if (log.isLoggable(logLevel)) {
WebMethod webMethod = method.getAnnotation(WebMethod.class);
if (webMethod != null) {
String inArgs = formArgumentString(method, args, WebParam.Mode.IN);
log.log(logLevel, "WS Request {0}: {1}",
new Object[] {webMethod.operationName(), inArgs});
}
}
Object ret;
try {
ret = method.invoke(wrapped, args);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Misconfigured LoggingWSHandler", ex);
} catch (IllegalArgumentException ex) {
throw new RuntimeException("Misconfigured LoggingWSHandler", ex);
} catch (InvocationTargetException ex) {
throw ex.getCause();
}
if (log.isLoggable(logLevel)) {
WebMethod webMethod = method.getAnnotation(WebMethod.class);
if (webMethod != null) {
String outArgs = formArgumentString(method, args, WebParam.Mode.OUT);
log.log(logLevel, "WS Response {0}: {1}",
new Object[] {webMethod.operationName(), outArgs});
}
}
return ret;
}
private String formArgumentString(Method method, Object[] args,
WebParam.Mode mode) {
StringBuilder argsBuffer = new StringBuilder();
Annotation[][] annotates = method.getParameterAnnotations();
if (annotates.length != 0 && annotates.length != args.length) {
throw new AssertionError();
}
for (int i = 0; i < annotates.length; i++) {
for (Annotation annotate : annotates[i]) {
if (!(annotate instanceof WebParam)) {
break;
}
WebParam webParam = (WebParam) annotate;
if (webParam.mode() == mode
|| webParam.mode() == WebParam.Mode.INOUT) {
argsBuffer.append(", ").append(webParam.name()).append("=");
if (webParam.mode() == WebParam.Mode.IN) {
argsBuffer.append("" + args[i]);
} else {
Holder<?> holder = (Holder<?>) args[i];
argsBuffer.append(
holder == null ? "<null holder>" : "" + holder.value);
}
}
}
}
return argsBuffer.length() > 1 ? argsBuffer.substring(2) : "";
}
}