/** convert plain text string to JSON string, replacing some entities * */ private String normalise(Input<?> input, String str) { str = str.replaceAll("\\\\", "\\\\\\\\"); str = str.replaceAll("/", "\\\\/"); str = str.replaceAll("\b", "\\\\b"); str = str.replaceAll("\f", "\\\\f"); str = str.replaceAll("\t", "\\\\t"); str = str.replaceAll("\\r", "\\\\r"); str = str.replaceAll("\"", "\\\\\""); str = str.replaceAll("\n", "\\\\n"); if (input != null && !input.getType().equals(Double.class) && !input.getType().equals(Integer.class) && !input.getType().equals(Boolean.class)) { str = "\"" + str + "\""; } return str; }
/** Find the input associated with this panel based on the path Input. */ @SuppressWarnings("unchecked") public Input<?> resolveInput(BeautiDoc doc, int iPartition) { try { // if (parentPlugins != null && parentPlugins.size() > 0 && _input != null) // System.err.println("sync " + parentPlugins.get(iPartition) + "[?] = " + // _input.get()); List<BEASTInterface> plugins; if (bHasPartitionsInput.get() == Partition.none) { plugins = new ArrayList<BEASTInterface>(); plugins.add(doc.mcmc.get()); } else { plugins = doc.getPartitions(bHasPartitionsInput.get().toString()); } parentPlugins = new ArrayList<BEASTInterface>(); parentInputs = new ArrayList<Input<?>>(); parentPlugins.add(doc); parentInputs.add(doc.mcmc); type = doc.mcmc.getType(); bIsList = false; for (int i = 0; i < sPathComponents.length; i++) { List<BEASTInterface> oldPlugins = plugins; plugins = new ArrayList<BEASTInterface>(); parentPlugins = new ArrayList<BEASTInterface>(); parentInputs = new ArrayList<Input<?>>(); for (BEASTInterface plugin : oldPlugins) { Input<?> namedInput = plugin.getInput(sPathComponents[i]); type = namedInput.getType(); if (namedInput.get() instanceof List<?>) { bIsList = true; List<?> list = (List<?>) namedInput.get(); if (sConditionalAttribute[i] == null) { for (Object o : list) { BEASTInterface plugin2 = (BEASTInterface) o; plugins.add(plugin2); parentPlugins.add(plugin); parentInputs.add(namedInput); } // throw new Exception ("Don't know which element to pick from the list. List // component should come with a condition. " + m_sPathComponents[i]); } else { int nMatches = 0; for (int j = 0; j < list.size(); j++) { BEASTInterface plugin2 = (BEASTInterface) list.get(j); if (matches(plugin2, sConditionalAttribute[i], sConditionalValue[i])) { plugins.add(plugin2); parentPlugins.add(plugin); parentInputs.add(namedInput); nMatches++; break; } } if (nMatches == 0) { parentInputs.add(namedInput); parentPlugins.add(plugin); } } } else if (namedInput.get() instanceof BEASTInterface) { bIsList = false; if (sConditionalAttribute[i] == null) { plugins.add((BEASTInterface) namedInput.get()); parentPlugins.add(plugin); parentInputs.add(namedInput); } else { if (matches(plugin, sConditionalAttribute[i], sConditionalValue[i])) { // if ((m_sConditionalAttribute[i].equals("id") && // plugin.getID().equals(m_sConditionalValue[i])) || // (m_sConditionalAttribute[i].equals("type") && // plugin.getClass().getName().equals(m_sConditionalValue[i]))) { plugins.add(plugin); parentPlugins.add(plugin); parentInputs.add(namedInput); } } } else { throw new Exception("input " + sPathComponents[i] + " is not a plugin or list"); } } } if (sTypeInput.get() != null) { type = Class.forName(sTypeInput.get()); } // sanity check if (!bIsList && (bHasPartitionsInput.get() == Partition.none) && plugins.size() > 1) { System.err.println("WARNING: multiple plugins match, but hasPartitions=none"); // this makes sure that all mathing plugins are available in one go bIsList = true; // this suppresses syncing parentInputs.clear(); } inputs.clear(); startInputs.clear(); for (BEASTInterface plugin : plugins) { inputs.add(plugin); startInputs.add(plugin); } if (!bIsList) { _input = new FlexibleInput<BEASTInterface>(); } else { _input = new FlexibleInput<ArrayList<BEASTInterface>>(new ArrayList<BEASTInterface>()); } _input.setRule(Validate.REQUIRED); syncTo(iPartition); // if (parentPlugins != null && parentPlugins.size() > 0) // System.err.println("sync " + parentPlugins.get(iPartition) + "[?] = " + // _input.get()); if (bIsList) { checkForDups((List<Object>) _input.get()); } return _input; } catch (Exception e) { System.err.println( "Warning: could not find objects in path " + Arrays.toString(sPathComponents)); } return null; } // resolveInputs
/** * produce JSON for an input of a beastObject, both as attribute/value pairs for primitive inputs * (if isShort=true) and as individual elements (if isShort=false) * * @param input0: name of the input * @param beastObject: beastObject to produce this input JSON for * @param buf: gets JSON results are appended * @param isShort: flag to indicate attribute/value format (true) or element format (false) * @throws Exception */ @SuppressWarnings({"rawtypes", "unchecked"}) private void inputToJSON( Input input, Object value, BEASTInterface beastObject, StringBuffer buf, boolean isShort, String indent) throws Exception { if (value != null) { // distinguish between Map, List, BEASTObject and primitive input types if (value instanceof Map) { if (!isShort) { Map<String, ?> map = (Map<String, ?>) value; StringBuffer buf2 = new StringBuffer(); // determine label width int whiteSpaceWidth = 0; for (String key : map.keySet()) { whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length()); } boolean needsComma = false; List<String> keys = new ArrayList<>(); keys.addAll(map.keySet()); Collections.sort(keys); for (String key : keys) { if (needsComma) { buf2.append(",\n"); } buf2.append(indent + " " + key); for (int k = key.length(); k < whiteSpaceWidth; k++) { buf2.append(' '); } buf2.append(" :\"" + map.get(key) + "\""); needsComma = true; } buf.append(buf2); } return; } else if (value instanceof List) { if (!isShort) { StringBuffer buf2 = new StringBuffer(); // buf2.append(indent + " \"" + input0 + "\": [\n"); buf2.append(indent + " " + input.getName() + ": [\n"); boolean needsComma = false; int oldLen = buf2.length(); for (Object o2 : (List) value) { if (needsComma) { buf2.append(",\n"); } StringBuffer buf3 = new StringBuffer(); if (o2 instanceof BEASTInterface) { beastObjectToJSON((BEASTInterface) o2, input.getType(), buf3, null, false); } else { buf2.append(o2.toString()); } buf2.append(buf3); needsComma = oldLen < buf2.length(); } if (buf2.length() != oldLen) { buf.append(buf2); buf.append("\n" + indent + " ]"); } } return; } else if (value instanceof BEASTInterface) { if (!value.equals(input.defaultValue)) { // Parameters can use short hand notation if they are not in the state // Note this means lower and upper bounds are lost -- no problem for BEAST, but maybe for // BEAUti if (value instanceof Parameter.Base) { Parameter.Base parameter = (Parameter.Base) value; boolean isInState = false; for (Object o : parameter.getOutputs()) { if (o instanceof State) { isInState = true; break; } } if (!isInState) { if (isShort) { buf.append(" " + input.getName() + ": \"" + parameter.getValue() + "\""); } else { return; } } } if (isShort && isDone.contains(value)) { buf.append(" " + input.getName() + ": \"@" + ((BEASTInterface) value).getID() + "\""); if (!isInputsDone.containsKey(beastObject)) { isInputsDone.put(beastObject, new HashSet<>()); } isInputsDone.get(beastObject).add(input.getName()); } if (!isShort && (!isInputsDone.containsKey(beastObject) || !isInputsDone.get(beastObject).contains(input.getName()))) { beastObjectToJSON((BEASTInterface) value, input.getType(), buf, input.getName(), false); } } return; } else { // primitive type if (!value.equals(input.defaultValue)) { String valueString = value.toString(); if (isShort) { if (valueString.indexOf('\n') < 0) { buf.append(" " + input.getName() + ": " + normalise(input, value.toString()) + ""); } } else { if (valueString.indexOf('\n') >= 0) { buf.append( indent + "" + input.getName() + ": " + normalise(input, value.toString()) + ""); } } } return; } } else { // value=null, no JSON to produce return; } } // inputToJSON