use of jp.ossc.nimbus.core.ServiceName 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