/**
  * create new instance of src object, connecting all inputs from src object Note if input is a
  * SubstModel, it is duplicated as well.
  *
  * @param src object to be copied
  * @param i index used to extend ID with.
  * @return copy of src object
  */
 private Object duplicate(BEASTInterface src, int i) {
   if (src == null) {
     return null;
   }
   BEASTInterface copy;
   try {
     copy = src.getClass().newInstance();
     copy.setID(src.getID() + "_" + i);
   } catch (InstantiationException | IllegalAccessException e) {
     e.printStackTrace();
     throw new RuntimeException(
         "Programmer error: every object in the model should have a default constructor that is publicly accessible: "
             + src.getClass().getName());
   }
   for (Input<?> input : src.listInputs()) {
     if (input.get() != null) {
       if (input.get() instanceof List) {
         // handle lists
         // ((List)copy.getInput(input.getName())).clear();
         for (Object o : (List<?>) input.get()) {
           if (o instanceof BEASTInterface) {
             // make sure it is not already in the list
             copy.setInputValue(input.getName(), o);
           }
         }
       } else if (input.get() instanceof SubstitutionModel) {
         // duplicate subst models
         BEASTInterface substModel = (BEASTInterface) duplicate((BEASTInterface) input.get(), i);
         copy.setInputValue(input.getName(), substModel);
       } else {
         // it is some other value
         copy.setInputValue(input.getName(), input.get());
       }
     }
   }
   copy.initAndValidate();
   return copy;
 }
Example #2
0
  /**
   * produce elements for a beast object with name name, putting results in buf. It tries to create
   * XML conforming to the XML transformation rules (see XMLParser) that is moderately readable.
   */
  @SuppressWarnings("rawtypes")
  void beastObjectToXML(
      BEASTInterface beastObject, StringBuffer buf, String name, boolean isTopLevel)
      throws Exception {
    // determine element name, default is input, otherswise find one of the defaults
    String elementName = "input";
    for (String key : element2ClassMap.keySet()) {
      String className = element2ClassMap.get(key);
      Class _class = Class.forName(className);
      if (_class.equals(beastObject.getClass())) {
        elementName = key;
      }
    }

    //        if (beastObject instanceof Alignment) {
    //            elementName = XMLParser.DATA_ELEMENT;
    //        }
    //        if (beastObject instanceof Sequence) {
    //            elementName = XMLParser.SEQUENCE_ELEMENT;
    //        }
    //        if (beastObject instanceof State) {
    //            elementName = XMLParser.STATE_ELEMENT;
    //        }
    //        if (beastObject instanceof Distribution) {
    //            elementName = XMLParser.DISTRIBUTION_ELEMENT;
    //        }
    //        if (beastObject instanceof Logger) {
    //            elementName = XMLParser.LOG_ELEMENT;
    //        }
    //        if (beastObject instanceof Operator) {
    //            elementName = XMLParser.OPERATOR_ELEMENT;
    //        }
    //        if (beastObject instanceof RealParameter) {
    //            elementName = XMLParser.REAL_PARAMETER_ELEMENT;
    //        }
    //        if (beastObject instanceof Tree) {
    //            elementName = XMLParser.TREE_ELEMENT;
    //        }

    if (isTopLevel) {
      elementName = XMLParser.RUN_ELEMENT;
    }
    for (int i = 0; i < indent; i++) {
      buf.append("    ");
    }
    indent++;

    // open element
    buf.append("<").append(elementName);

    boolean skipInputs = false;
    if (isDone.stream().anyMatch(x -> x == beastObject)) {
      // XML is already produced, we can idref it
      buf.append(" idref='" + normalise(beastObject.getID()) + "'");
      skipInputs = true;
    } else {
      // see whether a reasonable id can be generated
      if (beastObject.getID() != null && !beastObject.getID().equals("")) {
        String id = beastObject.getID();
        // ensure ID is unique
        if (IDs.contains(id)) {
          int k = 1;
          while (IDs.contains(id + k)) {
            k++;
          }
          id = id + k;
        }
        buf.append(" id='" + normalise(id) + "'");
        IDs.add(id);
      }
      isDone.add(beastObject);
    }
    String className = beastObject.getClass().getName();
    if (skipInputs == false
        && (!element2ClassMap.containsKey(elementName)
            || !element2ClassMap.get(elementName).equals(className))) {
      // only add spec element if it cannot be deduced otherwise (i.e., by idref or default mapping
      buf.append(" spec='" + className + "'");
    }
    if (name != null && !name.equals(elementName)) {
      // only add name element if it differs from element = default name
      buf.append(" name='" + name + "'");
    }

    if (!skipInputs) {
      // process inputs of this beast object
      // first, collect values as attributes
      List<Input<?>> inputs = beastObject.listInputs();
      for (Input<?> input : inputs) {
        Object value = input.get();
        inputToXML(input, value, beastObject, buf, true);
      }
      // next, collect values as input elements
      StringBuffer buf2 = new StringBuffer();
      for (Input input : inputs) {
        Object value = input.get();
        inputToXML(input, value, beastObject, buf2, false);
      }
      if (buf2.length() == 0) {
        // if nothing was added by the inputs, close element
        indent--;
        buf.append("/>\n");
      } else {
        // add contribution of inputs
        if (buf2.indexOf("<") >= 0) {
          buf.append(">\n");
          buf.append(buf2);
          indent--;
          for (int i = 0; i < indent; i++) {
            buf.append("    ");
          }
        } else {
          buf.append(">");
          buf.append(buf2.toString().trim());
          indent--;
        }
        // add closing element
        buf.append("</" + elementName + ">\n");
      }
    } else {
      // close element
      indent--;
      buf.append("/>\n");
    }
    if (indent < 2) {
      buf.append("\n");
    }
  } // pluginToXML
Example #3
0
  /**
   * Produce JSON fragment for a beast object with given name, putting results in buf. It tries to
   * create JSON conforming to the JSON transformation rules (see JSONParser) that is moderately
   * readable.
   */
  void beastObjectToJSON(
      BEASTInterface beastObject,
      Class<?> defaultType,
      StringBuffer buf,
      String name,
      boolean isTopLevel)
      throws Exception {
    // determine element name, default is input, otherwise find one of the defaults

    String indent = "";
    for (int i = 0; i < indentCount; i++) {
      indent += "\t";
      // buf.append("    ");
    }
    indentCount++;

    // open element
    boolean needsComma = false;
    if (name != null) {
      // buf.append((indentCount == 1 ? "" : indent.substring(1)) + " \"" + name + "\": {");
      buf.append((indentCount == 1 ? "" : indent.substring(1)) + " " + name + ": {");
    } else {
      buf.append(indent + "{");
    }

    boolean skipInputs = false;
    if (isDone.contains(beastObject)) {
      // JSON is already produced, we can idref it
      buf.append((needsComma == true) ? ",\n" + indent + " " : "");
      buf.append("idref: \"" + beastObject.getID() + "\" ");
      needsComma = true;
      skipInputs = true;
    } else {
      // see whether a reasonable id can be generated
      if (beastObject.getID() != null && !beastObject.getID().equals("")) {
        String id = beastObject.getID();
        // ensure ID is unique
        if (IDs.contains(id)) {
          int k = 1;
          while (IDs.contains(id + k)) {
            k++;
          }
          id = id + k;
        }
        buf.append((needsComma == true) ? ",\n" + indent + " " : "");
        buf.append("id: \"" + normalise(null, id) + "\"");
        needsComma = true;
        IDs.add(id);
      }
      isDone.add(beastObject);
    }
    String className = beastObject.getClass().getName();
    if (skipInputs == false) {
      // only add spec element if it cannot be deduced otherwise (i.e., by idref)
      if (defaultType != null && !defaultType.getName().equals(className)) {
        buf.append((needsComma == true) ? ",\n" + indent + " " : "");
        // buf.append("\"spec\": \"" + className + "\"");
        buf.append("spec: \"" + className + "\"");
        needsComma = true;
      }
    }

    if (!skipInputs) {
      // process inputs of this beastObject
      // first, collect values as attributes
      List<Input<?>> inputs = beastObject.listInputs();
      // List<InputType> inputs = XMLParserUtils.listInputs(beastObject.getClass(), beastObject);
      for (Input<?> input : inputs) {
        StringBuffer buf2 = new StringBuffer();
        Object value = input.get();
        inputToJSON(input, value, beastObject, buf2, true, indent);
        if (buf2.length() > 0) {
          buf.append((needsComma == true) ? "," : "");
          buf.append(buf2);
          needsComma = true;
        }
      }
      // next, collect values as input elements
      StringBuffer buf2 = new StringBuffer();
      for (Input<?> input : inputs) {
        StringBuffer buf3 = new StringBuffer();
        Object value = input.get();
        inputToJSON(input, value, beastObject, buf3, false, indent);
        if (buf3.length() > 0) {
          buf2.append((needsComma == true) ? ",\n" : "\n");
          buf2.append(buf3);
          needsComma = true;
        }
      }
      if (buf2.length() != 0) {
        buf.append(buf2);
      }
      indentCount--;
      if (needsComma) {
        buf.append("\n" + indent);
      }
      needsComma = true;
    } else {
      // close element
      indentCount--;
      buf.append("");
      needsComma = true;
    }
    // if (m_nIndent < 2) {
    // collapse newlines if there are no sub-objects
    String str = buf.toString();
    if (str.indexOf('}') < 0 && str.length() < 1024) {
      str = str.replaceAll("\\s+", " ");
      buf.delete(0, buf.length());
      buf.append(indent);
      buf.append(str);
    }

    buf.append("}");
    // }
  } // beastObjectToJSON