/*
* JaamSim Discrete Event Simulation
* Copyright (C) 2012 Ausenco Engineering Canada Inc.
*
* 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.jaamsim.basicsim;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.jaamsim.input.EntityInput;
import com.jaamsim.input.Input;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.StringInput;
import com.jaamsim.input.StringListInput;
public class OutputMethod extends Entity {
@Keyword(description = "The target Entity we are collecting output from",
example = "Output1 Target { Entity1 }")
private final EntityInput<Entity> target;
@Keyword(description = "The name of the method to call on the target",
example = "Output1 Method { getAmountLoaded }")
private final StringInput method;
@Keyword(description = "A list of arguments to pass to the target method, these will be interpreted" +
"Entities, then Integers and finally as literal Strings",
example = "Output1 Arguments { Entity1 5 'A String' }")
private final StringListInput arguments;
{
target = new EntityInput<>(Entity.class, "Target", "Outputs", null);
this.addInput(target);
method = new StringInput("Method", "Outputs", null);
this.addInput(method);
arguments = new StringListInput("Arguments", "Outputs", null);
this.addInput(arguments);
}
public OutputMethod() {}
public String getReportLine() {
StringBuilder str = new StringBuilder();
str.append(target.getValue().getName());
str.append(" ");
str.append(method.getValue());
if (arguments.getValue() != null) {
for (String arg : arguments.getValue()) {
str.append(" ");
str.append(arg);
}
}
this.appendOutput(str);
return str.toString();
}
private void appendOutput(StringBuilder bld) {
Entity ent = target.getValue();
if (ent == null) {
bld.append("\t#ERROR");
return;
}
int numParams = 0;
if (arguments.getValue()!= null)
numParams = arguments.getValue().size();
Object[] params = new Object[numParams];
Class<?>[] paramClass = new Class<?>[numParams];
for (int i = 0; i < numParams; i++) {
String arg = arguments.getValue().get(i);
// Treat as an Entity if possible
Entity e = Input.tryParseEntity(arg, Entity.class);
if (e != null) {
params[i] = e;
paramClass[i] = e.getClass();
continue;
}
// Otherwise, check if it is an Integer
if (Input.isInteger(arg)) {
params[i] = Integer.parseInt(arg);
paramClass[i] = Integer.class;
continue;
}
// Last resort, pass through a String directly
params[i] = arg;
paramClass[i] = String.class;
}
Method meth = null;
try {
meth = ent.getClass().getMethod(method.getValue(), paramClass);
}
catch (NoSuchMethodException e) {}
catch (SecurityException e) {}
if (meth == null) {
bld.append("\t#ERROR");
return;
}
try {
Object ret = meth.invoke(ent, params);
if (ret instanceof Double) {
double d = ((Double)ret).doubleValue();
if (Double.isNaN(d)) {
bld.append("\t#ERROR");
return;
}
else {
bld.append("\t").append(d);
return;
}
}
if (ret instanceof Integer) {
int i = ((Integer)ret).intValue();
bld.append("\t").append(i);
return;
}
bld.append("\t#ERROR");
}
catch (IllegalArgumentException e) {}
catch (IllegalAccessException e) {}
catch (InvocationTargetException e) {}
catch (ExceptionInInitializerError e) {}
}
}