use of jp.ossc.nimbus.beans.MethodEditor in project nimbus by nimbus-org.
the class TraceLoggingInterceptorService method invoke.
/**
* ログを出力して、次のインターセプタを呼び出す。<p>
* サービスが開始されていない場合は、次のインターセプタを呼び出す。<br>
*
* @param context 呼び出しのコンテキスト情報
* @param chain 次のインターセプタを呼び出すためのチェーン
* @return 呼び出し結果の戻り値
* @exception Throwable 呼び出し先で例外が発生した場合、またはこのインターセプタで任意の例外が発生した場合。但し、本来呼び出される処理がthrowしないRuntimeException以外の例外をthrowしても、呼び出し元には伝播されない。
*/
public Object invoke(InvocationContext context, InterceptorChain chain) throws Throwable {
if (getState() != STARTED || !isEnabled()) {
return chain.invokeNext(context);
}
final long start = System.currentTimeMillis();
StringBuilder buf = null;
StringBuilder targetBuf = null;
StringBuilder methodBuf = null;
StringBuilder parameterBuf = null;
String sequenceId = null;
if (sequence != null) {
sequenceId = sequence.increment();
if (buf == null) {
buf = new StringBuilder();
}
buf.append(sequenceId);
}
if (isOutputTarget || isOutputTargetOnResponse) {
targetBuf = new StringBuilder();
Object target = context.getTargetObject();
if (outputTargetProperties != null && outputTargetProperties.length != 0) {
targetBuf.append('[');
for (int i = 0; i < outputTargetProperties.length; i++) {
Object prop = null;
try {
prop = propertyAccess.get(target, outputTargetProperties[i]);
} catch (IllegalArgumentException e) {
} catch (NoSuchPropertyException e) {
} catch (InvocationTargetException e) {
}
printObject(targetBuf, prop);
if (i != outputTargetProperties.length - 1) {
targetBuf.append(',');
}
}
targetBuf.append(']');
} else {
printObject(targetBuf, target);
}
if (isOutputTarget) {
if (buf == null) {
buf = new StringBuilder();
} else {
buf.append(',');
}
buf.append(targetBuf);
}
}
if (context instanceof MethodInvocationContext) {
MethodInvocationContext methodContext = (MethodInvocationContext) context;
if (isOutputMethod || isOutputMethodOnResponse) {
methodBuf = new StringBuilder();
Method method = methodContext.getTargetMethod();
if (method != null) {
MethodEditor editor = new MethodEditor();
editor.setValue(method);
methodBuf.append(editor.getAsText());
} else {
methodBuf.append("null");
}
if (isOutputMethod) {
if (buf == null) {
buf = new StringBuilder();
} else {
buf.append(',');
}
buf.append(methodBuf);
}
}
if (isOutputParameter || isOutputParameterOnResponse) {
parameterBuf = new StringBuilder();
Object[] params = methodContext.getParameters();
if (params != null) {
parameterBuf.append('[');
if (outputParameterProperties != null && outputParameterProperties.length != 0) {
for (int i = 0; i < outputParameterProperties.length; i++) {
Object prop = null;
try {
prop = propertyAccess.get(params, outputParameterProperties[i]);
} catch (IllegalArgumentException e) {
} catch (NoSuchPropertyException e) {
} catch (InvocationTargetException e) {
}
printObject(parameterBuf, prop);
if (i != outputParameterProperties.length - 1) {
parameterBuf.append(',');
}
}
} else {
printObject(parameterBuf, params);
}
parameterBuf.append(']');
} else {
parameterBuf.append("null");
}
if (isOutputParameter) {
if (buf == null) {
buf = new StringBuilder();
} else {
buf.append(',');
}
buf.append(parameterBuf);
}
}
}
if (isOutputRequestLog && getLogger().isWrite(requestMessageId)) {
if (isOutputCallStackTrace) {
getLogger().write(requestMessageId, buf == null ? "" : buf.toString(), new Exception("Call stack"));
} else {
getLogger().write(requestMessageId, buf == null ? "" : buf.toString());
}
}
if (buf != null) {
buf.setLength(0);
}
Throwable throwable = null;
Object ret = null;
try {
ret = chain.invokeNext(context);
return ret;
} catch (Throwable th) {
throwable = th;
throw th;
} finally {
final long end = System.currentTimeMillis();
if (isOutputResponseLog && getLogger().isWrite(responseMessageId)) {
if (buf == null) {
buf = new StringBuilder();
}
if (sequenceId != null) {
buf.append(sequenceId);
}
if (isOutputTargetOnResponse) {
if (buf.length() != 0) {
buf.append(',');
}
buf.append(targetBuf);
}
if (isOutputMethodOnResponse) {
if (buf.length() != 0) {
buf.append(',');
}
buf.append(methodBuf);
}
if (isOutputParameterOnResponse) {
if (buf.length() != 0) {
buf.append(',');
}
buf.append(parameterBuf);
}
if (throwable == null) {
if (isOutputReturn) {
if (buf.length() != 0) {
buf.append(',');
}
if (outputReturnProperties != null && outputReturnProperties.length != 0) {
buf.append('[');
for (int i = 0; i < outputReturnProperties.length; i++) {
Object prop = null;
try {
prop = propertyAccess.get(ret, outputReturnProperties[i]);
} catch (IllegalArgumentException e) {
} catch (NoSuchPropertyException e) {
} catch (InvocationTargetException e) {
}
printObject(buf, prop);
if (i != outputReturnProperties.length - 1) {
buf.append(',');
}
}
buf.append(']');
} else {
printObject(buf, ret);
}
}
}
if (isOutputPerformance) {
if (buf.length() != 0) {
buf.append(',');
}
buf.append(end - start);
}
if (throwable != null && isOutputThrowable) {
getLogger().write(responseMessageId, buf.toString(), throwable);
} else {
getLogger().write(responseMessageId, buf.toString());
}
}
}
}
use of jp.ossc.nimbus.beans.MethodEditor in project nimbus by nimbus-org.
the class ServiceCallActionService method execute.
/**
* ローカルのサービスを呼び出して、戻り値を返す。<p>
* リソースのフォーマットは、以下。<br>
* <pre>
* serviceName
* methodSigniture
* argumentType
* argument
* </pre>
* serviceNameは、呼び出す対象のサービス名を指定する。サービス名のフォーマットは、{@link ServiceNameEditor}の仕様に準じる。<br>
* methodSignitureは、呼び出すメソッドのシグニチャを指定する。シグニチャのフォーマットは、{@link MethodEditor}の仕様に準じる。<br>
* argumentTypeは、呼び出すメソッドの引数の指定方法で、"id"、"value"、"chain"、"interpreter"のいずれかを指定する。<br>
* argumentは、argumentTypeによって、記述方法が異なる。<br>
* <ul>
* <li>argumentTypeが"id"の場合<br>TestActionの戻り値を引数として使用するもので、同一テストケース中に、このTestActionより前に、引数オブジェクトを戻すテストアクションが存在する場合は、そのアクションIDを指定する。また、同一シナリオ中に、このTestActionより前に、引数オブジェクトを戻すテストアクションが存在する場合は、テストケースIDとアクションIDをカンマ区切りで指定する。</li>
* <li>argumentTypeが"value"の場合<br>引数を文字列で指定する。引数が複数存在する場合は、改行する。引数がnullである事を指定する場合は、"null"と指定する。</li>
* <li>argumentTypeが"chain"の場合<br>{@link ChainTestAction$TestActionProcess TestActionProcess}として呼び出され、前アクションから引数を受け取る事を意味する。この場合argumentの行は指定する必要がない。</li>
* <li>argumentTypeが"interpreter"の場合<br>引数を生成するスクリプト文字列を記述する。スクリプト文字列は、{@link Interpreter#evaluate(String,java.util.Map)}で評価され、その戻り値が引数として使用される。スクリプト内では、変数"context"で、TestContextが参照できる。スクリプトの終了は、空行。</li>
* </ul>
* 引数が複数ある場合は、argumentType、argumentを繰り返す。<br>
*
* @param context コンテキスト
* @param actionId アクションID
* @param preResult 1つ前のアクションの戻り値
* @param resource リソース
* @return サービスを呼び出した戻り値
*/
public Object execute(TestContext context, String actionId, Object preResult, Reader resource) throws Exception {
BufferedReader br = new BufferedReader(resource);
ServiceName targetServiceName = null;
Method method = null;
Object[] arguments = null;
try {
final String serviceNameStr = br.readLine();
if (serviceNameStr == null || serviceNameStr.length() == 0) {
throw new Exception("Unexpected EOF on serviceName");
}
final ServiceNameEditor serviceNameEditor = new ServiceNameEditor();
serviceNameEditor.setAsText(serviceNameStr);
targetServiceName = (ServiceName) serviceNameEditor.getValue();
final String methodSigniture = br.readLine();
if (methodSigniture == null || methodSigniture.length() == 0) {
throw new Exception("Unexpected EOF on methodSigniture");
}
final MethodEditor methodEditor = new MethodEditor();
methodEditor.setAsText(methodSigniture);
method = (Method) methodEditor.getValue();
final Class[] paramTypes = method.getParameterTypes();
if (paramTypes.length != 0) {
arguments = paramTypes == null || paramTypes.length == 0 ? null : new Object[paramTypes.length];
String argumentType = null;
int index = 0;
while ((argumentType = br.readLine()) != null) {
if (argumentType.length() == 0) {
continue;
}
if (index >= paramTypes.length) {
throw new Exception("Unmatch argument length. signitureParamLength=" + paramTypes.length + ", argumentLength>" + index);
}
if ("chain".equals(argumentType)) {
arguments[index] = preResult;
} else if ("id".equals(argumentType)) {
String line = br.readLine();
if (line == null) {
throw new Exception("Unexpected EOF on argument");
}
if (line != null && line.length() != 0) {
if (line.indexOf(",") == -1) {
arguments[index] = context.getTestActionResult(line);
} else {
String[] ids = line.split(",");
if (ids.length != 2) {
throw new Exception("Illegal argument id format. id=" + line);
}
arguments[index] = context.getTestActionResult(ids[0], ids[1]);
}
}
} else if ("value".equals(argumentType)) {
String line = br.readLine();
if (line == null) {
throw new Exception("Unexpected EOF on argument");
}
PropertyEditor editor = NimbusPropertyEditorManager.findEditor(paramTypes[index]);
if (editor == null) {
throw new Exception("PropertyEditor not found. type=" + paramTypes[index]);
}
try {
editor.setAsText(line);
arguments[index] = editor.getValue();
} catch (Exception e) {
throw new Exception("PropertyEditor can not edit. editor=" + editor + ", value=" + line, e);
}
} else if ("interpreter".equals(argumentType)) {
if (interpreter == null) {
throw new UnsupportedOperationException("Interpreter is null.");
}
String script = null;
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
String line = br.readLine();
if (line == null) {
throw new Exception("Unexpected EOF on argument");
}
try {
do {
pw.println(line);
} while ((line = br.readLine()) != null && line.length() != 0);
pw.flush();
script = sw.toString();
} finally {
pw.close();
}
if (paramTypes != null) {
final Map params = new HashMap();
params.put("context", context);
arguments[index] = interpreter.evaluate(script, params);
}
} else {
throw new Exception("Unknown argumentType : " + argumentType);
}
index++;
}
}
} finally {
br.close();
br = null;
}
if (invoker == null) {
return method.invoke(ServiceManagerFactory.getServiceObject(targetServiceName), arguments);
} else {
try {
return invoker.invoke(new DefaultMethodInvocationContext(targetServiceName, method, arguments));
} catch (Throwable th) {
if (th instanceof Exception) {
throw (Exception) th;
} else {
throw (Error) th;
}
}
}
}
Aggregations