/* * JaamSim Discrete Event Simulation * Copyright (C) 2016 JaamSim Software 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.StringProviders; import com.jaamsim.basicsim.Entity; import com.jaamsim.basicsim.ErrorException; import com.jaamsim.basicsim.ObjectType; import com.jaamsim.input.ExpError; import com.jaamsim.input.ExpEvaluator; import com.jaamsim.input.ExpParser; import com.jaamsim.input.ExpResType; import com.jaamsim.input.ExpResult; import com.jaamsim.input.ExpValResult; import com.jaamsim.input.InputErrorException; import com.jaamsim.input.ExpParser.Expression; import com.jaamsim.units.Unit; import com.jaamsim.units.UserSpecifiedUnit; public class StringProvExpression implements StringProvider { private final Expression exp; private final Entity thisEnt; private final Class<? extends Unit> unitType; private final ExpEvaluator.EntityParseContext parseContext; public StringProvExpression(String expString, Entity ent, Class<? extends Unit> ut) throws ExpError { thisEnt = ent; unitType = ut; parseContext = ExpEvaluator.getParseContext(thisEnt, expString); exp = ExpParser.parseExpression(parseContext, expString); if (exp.validationResult.state == ExpValResult.State.VALID && exp.validationResult.type == ExpResType.NUMBER) { // Check that a unit type has been specified if (unitType == UserSpecifiedUnit.class) { throw new InputErrorException("Unit type has not been specified"); } // We know the returned unit type with certainty, so we can check it against what we expect Class<? extends Unit> expUnitType = exp.validationResult.unitType; if (expUnitType != unitType) { throw new InputErrorException("Invalid unit returned by an expression: '%s'%n" + "Received: %s, expected: %s", exp, ObjectType.getObjectTypeForClass(expUnitType), ObjectType.getObjectTypeForClass(unitType)); } } } @Override public String getNextString(double simTime, String fmt, double siFactor) { String ret = ""; try { ExpResult result = ExpEvaluator.evaluateExpression(exp, simTime); switch (result.type) { case STRING: ret = String.format(fmt, result.stringVal); break; case ENTITY: ret = String.format(fmt, result.entVal.getName()); break; case NUMBER: if (result.unitType != unitType) { thisEnt.error("Invalid unit returned by an expression: '%s'%n" + "Received: %s, expected: %s", exp, ObjectType.getObjectTypeForClass(result.unitType), ObjectType.getObjectTypeForClass(unitType)); } ret = String.format(fmt, result.value/siFactor); break; default: assert(false); ret = "???"; break; } } catch(ExpError e) { throw new ErrorException(thisEnt, e); } return ret; } @Override public String toString() { return parseContext.getUpdatedSource(); } }