/* * JaamSim Discrete Event Simulation * Copyright (C) 2014 Ausenco Engineering Canada Inc. * 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.input; import java.util.ArrayList; import com.jaamsim.basicsim.Entity; import com.jaamsim.units.DimensionlessUnit; import com.jaamsim.units.Unit; /** * AttributeDefinitionListInput is an object for parsing inputs consisting of a list of * Attribute definitions using the syntax: * Entity AttributeDefinitionList { { AttibuteName1 Value1 Unit1 } { AttibuteName2 Value2 Unit2 } ... } * @author Harry King */ public class AttributeDefinitionListInput extends ListInput<ArrayList<AttributeHandle>> { private final Entity ent; public AttributeDefinitionListInput(Entity e, String key, String cat, ArrayList<AttributeHandle> def) { super(key, cat, def); ent = e; } @Override public void parse(KeywordIndex kw) throws InputErrorException { // Divide up the inputs by the inner braces ArrayList<KeywordIndex> subArgs = kw.getSubArgs(); ArrayList<AttributeHandle> temp = new ArrayList<>(subArgs.size()); // Parse the inputs within each inner brace for (int i = 0; i < subArgs.size(); i++) { KeywordIndex subArg = subArgs.get(i); Input.assertCount(subArg, 2, 3); try { // Parse the attribute name String name = subArg.getArg(0); if (OutputHandle.hasOutput(ent.getClass(), name)) { throw new InputErrorException("Attribute name is the same as existing output name: %s", name); } ExpResult expVal; Class<? extends Unit> unitType = DimensionlessUnit.class; if (subArg.numArgs() == 2) { // parse this as an expression String expString = subArg.getArg(1); ExpParser.Expression exp = ExpParser.parseExpression(ExpEvaluator.getParseContext(ent, expString), expString); expVal = ExpEvaluator.evaluateExpression(exp, 0); if (expVal.type == ExpResType.NUMBER) { unitType = expVal.unitType; } } else { // Parse the unit type double factor = 1.0; if (subArg.numArgs() == 3) { Unit unit = Input.parseUnit(subArg.getArg(2)); unitType = unit.getClass(); factor = unit.getConversionFactorToSI(); } // Parse the initial value double val; try { val = factor * Double.valueOf(subArg.getArg(1)); } catch (Exception e) { throw new InputErrorException(INP_ERR_DOUBLE, subArg.getArg(1)); } expVal = ExpResult.makeNumResult(val, unitType); } // Save the data for this attribute AttributeHandle h = (AttributeHandle) ent.getOutputHandle(name); if (h == null) h = new AttributeHandle(ent, name); h.setUnitType(unitType); h.setInitialValue(expVal); h.setValue(expVal); temp.add(h); } catch (ExpError e) { throw new InputErrorException(e); } catch (InputErrorException e) { throw new InputErrorException(INP_ERR_ELEMENT, i+1, e.getMessage()); } } // Save the data for each attribute value = temp; } @Override public void copyFrom(Input<?> in) { super.copyFrom(in); value = new ArrayList<>(); @SuppressWarnings("unchecked") ArrayList<AttributeHandle> inValue = (ArrayList<AttributeHandle>) (in.value); for (AttributeHandle h : inValue) { AttributeHandle hNew = new AttributeHandle(ent, h.getName()); hNew.setUnitType(h.getUnitType()); hNew.setInitialValue(h.getInitialValue()); hNew.setValue(h.getValue(0.0d, ExpResult.class)); value.add(hNew); } } @Override public int getListSize() { if (value == null) return 0; else return value.size(); } @Override public String getDefaultString() { if (defValue == null || defValue.isEmpty()) return ""; return this.getInputString(defValue); } private String getInputString(ArrayList<AttributeHandle> handleList) { StringBuilder tmp = new StringBuilder(); for (int i = 0; i < handleList.size(); i++) { if (i > 0) tmp.append(SEPARATOR); AttributeHandle h = handleList.get(i); tmp.append("{ "); tmp.append(h.getName()); tmp.append(SEPARATOR); double val = h.getInitialValue().value; String unitString = Unit.getSIUnit(h.getUnitType()); // Check for a preferred unit Unit unit = Unit.getPreferredUnit(h.getUnitType()); if (unit != null) { unitString = unit.toString(); val = h.getValueAsDouble(0.0d, 0.0d, unit); } tmp.append(val); // Print the unit unless it is dimensionless if (h.getUnitType() != DimensionlessUnit.class) { tmp.append(SEPARATOR); tmp.append(unitString); } tmp.append(" }"); } return tmp.toString(); } }