Esempio n. 1
0
  /**
   * Read the contents of a roster XML file into this object.
   *
   * <p>Note that this does not clear any existing entries.
   *
   * @param name filename of roster file
   */
  void readFile(String name) throws org.jdom2.JDOMException, java.io.IOException {
    // roster exists?
    if (!(new File(name)).exists()) {
      log.debug(
          "no roster file found; this is normal if you haven't put decoders in your roster yet");
      return;
    }

    // find root
    Element root = rootFromName(name);
    if (root == null) {
      log.error("Roster file exists, but could not be read; roster not available");
      return;
    }
    // if (log.isDebugEnabled()) XmlFile.dumpElement(root);

    // decode type, invoke proper processing routine if a decoder file
    if (root.getChild("roster") != null) { // NOI18N
      List<Element> l = root.getChild("roster").getChildren("locomotive"); // NOI18N
      if (log.isDebugEnabled()) {
        log.debug("readFile sees " + l.size() + " children");
      }
      l.stream()
          .forEach(
              (e) -> {
                addEntry(new RosterEntry(e));
              });

      // Scan the object to check the Comment and Decoder Comment fields for
      // any <?p?> processor directives and change them to back \n characters
      for (int i = 0; i < numEntries(); i++) {
        // Get a RosterEntry object for this index
        RosterEntry r = _list.get(i);

        // Extract the Comment field and create a new string for output
        String tempComment = r.getComment();
        String xmlComment = "";

        // transfer tempComment to xmlComment one character at a time, except
        // when <?p?> is found.  In that case, insert a \n and skip over those
        // characters in tempComment.
        for (int k = 0; k < tempComment.length(); k++) {
          if (tempComment.startsWith("<?p?>", k)) { // NOI18N
            xmlComment = xmlComment + "\n"; // NOI18N
            k = k + 4;
          } else {
            xmlComment = xmlComment + tempComment.substring(k, k + 1);
          }
        }
        r.setComment(xmlComment);

        // Now do the same thing for the decoderComment field
        String tempDecoderComment = r.getDecoderComment();
        String xmlDecoderComment = "";

        for (int k = 0; k < tempDecoderComment.length(); k++) {
          if (tempDecoderComment.startsWith("<?p?>", k)) { // NOI18N
            xmlDecoderComment = xmlDecoderComment + "\n"; // NOI18N
            k = k + 4;
          } else {
            xmlDecoderComment = xmlDecoderComment + tempDecoderComment.substring(k, k + 1);
          }
        }

        r.setDecoderComment(xmlDecoderComment);
      }
    } else {
      log.error("Unrecognized roster file contents in file: " + name);
    }
    if (root.getChild("rosterGroup") != null) { // NOI18N
      List<Element> groups = root.getChild("rosterGroup").getChildren("group"); // NOI18N
      groups
          .stream()
          .forEach(
              (group) -> {
                addRosterGroup(group.getText());
              });
    }
  }
Esempio n. 2
0
  /**
   * Write the entire roster to a file object. This does not do backup; that has to be done
   * separately. See writeRosterFile() for a public function that finds the default location, does a
   * backup and then calls this.
   *
   * @param file an op
   */
  void writeFile(File file) throws java.io.IOException {
    // create root element
    Element root = new Element("roster-config"); // NOI18N
    root.setAttribute(
        "noNamespaceSchemaLocation", // NOI18N
        "http://jmri.org/xml/schema/roster" + schemaVersion + ".xsd", // NOI18N
        org.jdom2.Namespace.getNamespace(
            "xsi", // NOI18N
            "http://www.w3.org/2001/XMLSchema-instance")); // NOI18N
    Document doc = newDocument(root);

    // add XSLT processing instruction
    // <?xml-stylesheet type="text/xsl" href="XSLT/roster.xsl"?>
    java.util.Map<String, String> m = new java.util.HashMap<>();
    m.put("type", "text/xsl"); // NOI18N
    m.put("href", xsltLocation + "roster2array.xsl"); // NOI18N
    ProcessingInstruction p = new ProcessingInstruction("xml-stylesheet", m); // NOI18N
    doc.addContent(0, p);

    String newLocoString = SymbolicProgBundle.getMessage("LabelNewDecoder");

    // Check the Comment and Decoder Comment fields for line breaks and
    // convert them to a processor directive for storage in XML
    // Note: this is also done in the LocoFile.java class to do
    // the same thing in the indidvidual locomotive roster files
    // Note: these changes have to be undone after writing the file
    // since the memory version of the roster is being changed to the
    // file version for writing
    for (int i = 0; i < numEntries(); i++) {

      // Extract the RosterEntry at this index and inspect the Comment and
      // Decoder Comment fields to change any \n characters to <?p?> processor
      // directives so they can be stored in the xml file and converted
      // back when the file is read.
      RosterEntry r = _list.get(i);
      if (!r.getId().equals(newLocoString)) {
        String tempComment = r.getComment();
        String xmlComment = "";

        // transfer tempComment to xmlComment one character at a time, except
        // when \n is found.  In that case, insert <?p?>
        for (int k = 0; k < tempComment.length(); k++) {
          if (tempComment.startsWith("\n", k)) { // NOI18N
            xmlComment = xmlComment + "<?p?>"; // NOI18N
          } else {
            xmlComment = xmlComment + tempComment.substring(k, k + 1);
          }
        }
        r.setComment(xmlComment);

        // Now do the same thing for the decoderComment field
        String tempDecoderComment = r.getDecoderComment();
        String xmlDecoderComment = "";

        for (int k = 0; k < tempDecoderComment.length(); k++) {
          if (tempDecoderComment.startsWith("\n", k)) { // NOI18N
            xmlDecoderComment = xmlDecoderComment + "<?p?>"; // NOI18N
          } else {
            xmlDecoderComment = xmlDecoderComment + tempDecoderComment.substring(k, k + 1);
          }
        }
        r.setDecoderComment(xmlDecoderComment);
      } else {
        log.debug("skip unsaved roster entry with default name " + r.getId());
      }
    }
    // All Comments and Decoder Comment line feeds have been changed to processor directives

    // add top-level elements
    Element values = new Element("roster"); // NOI18N
    root.addContent(values);
    // add entries
    for (int i = 0; i < numEntries(); i++) {
      if (!_list.get(i).getId().equals(newLocoString)) {
        values.addContent(_list.get(i).store());
      } else {
        log.debug("skip unsaved roster entry with default name " + _list.get(i).getId());
      }
    }

    if (!this.rosterGroups.isEmpty()) {
      Element rosterGroup = new Element("rosterGroup"); // NOI18N
      rosterGroups
          .keySet()
          .stream()
          .forEach(
              (name) -> {
                Element group = new Element("group"); // NOI18N
                if (!name.equals(Roster.ALLENTRIES)) {
                  group.addContent(name);
                  rosterGroup.addContent(group);
                }
              });
      root.addContent(rosterGroup);
    }

    writeXML(file, doc);

    // Now that the roster has been rewritten in file form we need to
    // restore the RosterEntry object to its normal \n state for the
    // Comment and Decoder comment fields, otherwise it can cause problems in
    // other parts of the program (e.g. in copying a roster)
    for (int i = 0; i < numEntries(); i++) {
      RosterEntry r = _list.get(i);
      if (!r.getId().equals(newLocoString)) {
        String xmlComment = r.getComment();
        String tempComment = "";

        for (int k = 0; k < xmlComment.length(); k++) {
          if (xmlComment.startsWith("<?p?>", k)) { // NOI18N
            tempComment = tempComment + "\n"; // NOI18N
            k = k + 4;
          } else {
            tempComment = tempComment + xmlComment.substring(k, k + 1);
          }
        }
        r.setComment(tempComment);

        String xmlDecoderComment = r.getDecoderComment();
        String tempDecoderComment = ""; // NOI18N

        for (int k = 0; k < xmlDecoderComment.length(); k++) {
          if (xmlDecoderComment.startsWith("<?p?>", k)) { // NOI18N
            tempDecoderComment = tempDecoderComment + "\n"; // NOI18N
            k = k + 4;
          } else {
            tempDecoderComment = tempDecoderComment + xmlDecoderComment.substring(k, k + 1);
          }
        }
        r.setDecoderComment(tempDecoderComment);
      } else {
        log.debug("skip unsaved roster entry with default name " + r.getId());
      }
    }

    // done - roster now stored, so can't be dirty
    setDirty(false);
    firePropertyChange(SAVED, false, true);
  }