package com.framsticks.params; import com.framsticks.params.types.*; import com.framsticks.util.lang.Numbers; import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.Arrays; /** * The class ParamBuilder helps building Param objects. * * @author Mateusz Jarus (please replace name and * surname with my personal data) * * @author Piotr Ĺšniegowski */ public class ParamBuilder { private final static Logger log = Logger.getLogger(ParamBuilder.class.getName()); private static final String ID_FIELD = "id"; private static final String NAME_FIELD = "name"; private static final String HELP_FIELD = "help"; private static final String GROUP_FIELD = "group"; private static final String TYPE_FIELD = "type"; private static final String FLAGS_FIELD = "flags"; /** The parameter getId. */ private String id; /** * The parameter internal getId. It's set by a user to use user's own getId in * code */ private String internalId; /** The number of group, that parameter belongs to. */ private Integer group = 0; /** The getFlags stored as a bit sum. */ private Integer flags = 0; /** The parameter getName. */ private String name; /** The getHelp (description) concerning parameter. */ private String help; /** The getType of parameter. */ private Class paramType; private Param param; private PrimitiveParam primitiveParam; ParamBuilder() { } /** * Build Param based on provided data. * * @return Param object * @throws Exception * when Param getType is not defined */ public Param finish() { assert param != null; param.id = id; param.name = name; param.help = help; param.group = group; param.flags = flags; param.internalId = internalId; return param; } public ParamBuilder id(String id) { this.id = id; return this; } protected ParamBuilder internalSetType(Class type, T param) { this.paramType = type; this.param = param; if (param instanceof PrimitiveParam) { primitiveParam = (PrimitiveParam) param; } return this; } public ParamBuilder type(Class type) { try { return internalSetType(type, type.newInstance()); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } return this; } public ParamBuilder type(T param) { return internalSetType(param.getClass(), param); } public ParamBuilder setInternalId(String internalId) { this.internalId = internalId; return this; } public ParamBuilder group(Integer group) { this.group = group; return this; } public ParamBuilder flags(Integer flags) { this.flags = flags; return this; } public ParamBuilder name(String name) { this.name = name; return this; } protected void parseMinMaxDefNumber(Class type, String second, String third) { if (primitiveParam == null) { log.warn("param is not a primitive param"); return; } if (second != null) { this.primitiveParam.min = Numbers.parse(second, type); if (this.primitiveParam.min == null) { log.warn("value of min attribute was invalid"); } } if (third != null) { this.primitiveParam.max = Numbers.parse(third, type); if (this.primitiveParam.max == null) { log.warn("value of min attribute was invalid"); } } } public ParamBuilder type(String type) { log.trace("parsing type: " + type); String[] typeSplitted = type.split(" "); String first = typeSplitted[0]; String second = typeSplitted.length > 1 ? typeSplitted[1] : null; String third = typeSplitted.length > 2 ? typeSplitted[2] : null; switch (first.charAt(0)) { case 'o': { type(new ObjectParam(second != null ? second : first.substring(1))); break; } case 'p': { ProcedureParam procedureParam = new ProcedureParam(); String signature = type.substring(1); try { procedureParam.parseSignature(signature); } catch (Exception e) { log.error("invalid procedure signature '" + signature + "': " + e); } type(procedureParam); break; } case 'd': { int tildeIndex = type.indexOf("~"); if (tildeIndex != -1) { type(new EnumParam(new ArrayList(Arrays.asList(type.substring(tildeIndex + 1).split("~"))))); } else { if (first.length() >= 2) { switch (first.charAt(1)) { case 'b': { type(BinaryParam.class); break; } case 'c': { type(ColorParam.class); break; } default: { log.error("unknown type: " + first); return this; } } } if ("0".equals(second) && "1".equals(third)) { type(BooleanParam.class); } if (param == null) { type(DecimalParam.class); } } if (this.param instanceof DecimalParam) { parseMinMaxDefNumber(Integer.class, second, third); } break; } case 'f': { type(FloatParam.class); parseMinMaxDefNumber(Double.class, second, third); break; } case 'x': { type(UniversalParam.class); break; } case 's': { type(StringParam.class); min(second); max(third); break; } case 'e': { type(EventParam.class); break; } case 'l': { type(third != null ? new UniqueListParam(second, third) : new ArrayListParam(second)); break; } default:{ log.error("unknown type: " + first); return this; } } return this; } public ParamBuilder help(String help) { this.help = help; return this; } /** * @return the paramType */ public Class getParamType() { return paramType; } public ParamBuilder min(T min) { if (primitiveParam != null) { this.primitiveParam.min = min; } return this; } public ParamBuilder max(T max) { if (primitiveParam != null) { this.primitiveParam.max = max; } return this; } public ParamBuilder def(T def) { if (def != null && primitiveParam != null) { this.primitiveParam.def = def; } return this; } public Class getStorageType() { assert param != null; return param.getStorageType(); } public Param build(String line) throws Exception { String[] paramEntryValues = line.split(","); if (paramEntryValues.length == 0) { log.warn("field empty or wrong format (" + line + ") - omitting"); return null; } for (int i = 0; i < paramEntryValues.length; ++i) { paramEntryValues[i] = paramEntryValues[i].trim(); } try { id(paramEntryValues[0]); group(Integer.valueOf(paramEntryValues[1])); flags(Flags.read(paramEntryValues[2])); name(paramEntryValues[3]); type(paramEntryValues[4]); help(paramEntryValues[6]); } catch (IndexOutOfBoundsException e) { /** everything is ok, parameters have just finished*/ } catch (NumberFormatException ex) { log.warn("wrong format of entry: " + line + ", omitting"); return null; } return finish(); } public void setField(String key, String value) { switch (key) { case ID_FIELD: id(value); break; case NAME_FIELD: name(value); break; case TYPE_FIELD: type(value); break; case FLAGS_FIELD: flags(Flags.read(value)); break; case HELP_FIELD: help(value); break; case GROUP_FIELD: group(Integer.valueOf(value)); break; default: log.error("unknown field for Param: " + key); break; } } public static FramsClass getFramsClass() { return new FramsClass("prop", "prop", null) .append(Param.build().id("name").name("Name").type(StringParam.class)) .append(Param.build().id("id").name("Id").type(StringParam.class)) .append(Param.build().id("type").name("Type").type(StringParam.class)) .append(Param.build().id("help").name("Help").type(StringParam.class)) .append(Param.build().id("group").name("Group").type(DecimalParam.class)) .append(Param.build().id("flags").name("Flags").type(DecimalParam.class)); } }