test_class.declarator: EMPTY_HEADER = "Timestamp,Event,Event Description,Event Severity"
test_class.modifier: private static final
test_class.original_string: private static final String EMPTY_HEADER = "Timestamp,Event,Event Description,Event Severity";
test_class.type: String
test_class.var_name: EMPTY_HEADER
test_class.declarator: converter
test_class.modifier: private
test_class.original_string: private CsvConverter converter;
test_class.type: CsvConverter
test_class.var_name: converter
test_class.declarator: recording
test_class.modifier: private
test_class.original_string: private Recording recording;
test_class.type: Recording
test_class.var_name: recording
test_class.file: app/src/test/java/edu/wpi/first/shuffleboard/app/sources/recording/CsvConverterTest.java
test_class.identifier: CsvConverterTest
test_case.body: @Test
    public void testMultipleMarkersInSameWindow() {
      // First two markers are in the same time window
      // The second marker should be skipped, but the first and third should still be present
      recording.addMarker(new Marker("First", "", MarkerImportance.LOW, 0L));
      recording.addMarker(new Marker("Second", "", MarkerImportance.CRITICAL, 0L));
      recording.addMarker(new Marker("Third", "", MarkerImportance.NORMAL, 255));
  
      String csv = converter.convertToCsv(recording);
      var lines = csv.lines().collect(Collectors.toList());
  
      assertAll(
          () -> assertEquals(EMPTY_HEADER, lines.get(0), "First line should be the header"),
          () -> assertEquals("0,First,,LOW", lines.get(1), "Second line should be the first marker"),
          () -> assertEquals("255,Third,,NORMAL", lines.get(2), "Third line should be the third marker")
      );
    }
test_case.class_method_signature: CsvConverterTest.testMultipleMarkersInSameWindow()
test_case.full_signature: @Test public void testMultipleMarkersInSameWindow()
test_case.identifier: testMultipleMarkersInSameWindow
test_case.invocations: addMarker addMarker addMarker convertToCsv collect lines toList assertAll assertEquals get assertEquals get assertEquals get
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testMultipleMarkersInSameWindow()
focal_class.declarator: Instance = new CsvConverter(Preferences.userNodeForPackage(CsvConverter.class))
focal_class.modifier: public static final
focal_class.original_string: public static final CsvConverter Instance = new CsvConverter(Preferences.userNodeForPackage(CsvConverter.class));
focal_class.type: CsvConverter
focal_class.var_name: Instance
focal_class.declarator: log = Logger.getLogger(CsvConverter.class.getName())
focal_class.modifier: private static final
focal_class.original_string: private static final Logger log = Logger.getLogger(CsvConverter.class.getName());
focal_class.type: Logger
focal_class.var_name: log
focal_class.declarator: invariantViolatedMessageFormat =
        "Invariant violated: multiple event markers for same timestamp (found: %s at entry %d of %d), for timestamp %d"
focal_class.modifier: private static final
focal_class.original_string: private static final String invariantViolatedMessageFormat =
        "Invariant violated: multiple event markers for same timestamp (found: %s at entry %d of %d), for timestamp %d";
focal_class.type: String
focal_class.var_name: invariantViolatedMessageFormat
focal_class.declarator: includeMetadata = new SimpleBooleanProperty(false)
focal_class.modifier: private final
focal_class.original_string: private final BooleanProperty includeMetadata = new SimpleBooleanProperty(false);
focal_class.type: BooleanProperty
focal_class.var_name: includeMetadata
focal_class.declarator: fillEmpty = new SimpleBooleanProperty(false)
focal_class.modifier: private final
focal_class.original_string: private final BooleanProperty fillEmpty = new SimpleBooleanProperty(false);
focal_class.type: BooleanProperty
focal_class.var_name: fillEmpty
focal_class.declarator: windowSize = new SimpleIntegerProperty(7)
focal_class.modifier: private final
focal_class.original_string: private final IntegerProperty windowSize = new SimpleIntegerProperty(7);
focal_class.type: IntegerProperty
focal_class.var_name: windowSize
focal_class.file: app/src/main/java/edu/wpi/first/shuffleboard/app/sources/recording/CsvConverter.java
focal_class.identifier: CsvConverter
focal_class.interfaces: implements Converter
focal_class.class_method_signature: CsvConverter.CsvConverter(Preferences prefs)
focal_class.full_signature: @VisibleForTesting  CsvConverter(Preferences prefs)
focal_class.identifier: CsvConverter
focal_class.modifiers: @VisibleForTesting
focal_class.parameters: (Preferences prefs)
focal_class.signature:  CsvConverter(Preferences prefs)
focal_class.class_method_signature: CsvConverter.formatName()
focal_class.full_signature: @Override public String formatName()
focal_class.identifier: formatName
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: String
focal_class.signature: String formatName()
focal_class.class_method_signature: CsvConverter.fileExtension()
focal_class.full_signature: @Override public String fileExtension()
focal_class.identifier: fileExtension
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: String
focal_class.signature: String fileExtension()
focal_class.class_method_signature: CsvConverter.export(Recording recording, Path destination)
focal_class.full_signature: @Override public void export(Recording recording, Path destination)
focal_class.identifier: export
focal_class.modifiers: @Override public
focal_class.parameters: (Recording recording, Path destination)
focal_class.return: void
focal_class.signature: void export(Recording recording, Path destination)
focal_class.class_method_signature: CsvConverter.getSettings()
focal_class.full_signature: @Override public List<Group> getSettings()
focal_class.identifier: getSettings
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: List<Group>
focal_class.signature: List<Group> getSettings()
focal_class.class_method_signature: CsvConverter.convertToCsv(Recording recording)
focal_class.full_signature: @SuppressFBWarnings(value = "UC_USELESS_OBJECT", justification = "False positive with List.forEach") public String convertToCsv(Recording recording)
focal_class.identifier: convertToCsv
focal_class.modifiers: @SuppressFBWarnings(value = "UC_USELESS_OBJECT", justification = "False positive with List.forEach") public
focal_class.parameters: (Recording recording)
focal_class.return: String
focal_class.signature: String convertToCsv(Recording recording)
focal_class.class_method_signature: CsvConverter.fillEmptyCells(List<Object[]> rows)
focal_class.full_signature: @VisibleForTesting static void fillEmptyCells(List<Object[]> rows)
focal_class.identifier: fillEmptyCells
focal_class.modifiers: @VisibleForTesting static
focal_class.parameters: (List<Object[]> rows)
focal_class.return: void
focal_class.signature: void fillEmptyCells(List<Object[]> rows)
focal_class.class_method_signature: CsvConverter.toRow(List<String> header, int headerSize, Map.Entry<Long, List<RecordingEntry>> entry)
focal_class.full_signature: private Object[] toRow(List<String> header, int headerSize, Map.Entry<Long, List<RecordingEntry>> entry)
focal_class.identifier: toRow
focal_class.modifiers: private
focal_class.parameters: (List<String> header, int headerSize, Map.Entry<Long, List<RecordingEntry>> entry)
focal_class.return: Object[]
focal_class.signature: Object[] toRow(List<String> header, int headerSize, Map.Entry<Long, List<RecordingEntry>> entry)
focal_class.class_method_signature: CsvConverter.makeHeader(Recording recording)
focal_class.full_signature: private List<String> makeHeader(Recording recording)
focal_class.identifier: makeHeader
focal_class.modifiers: private
focal_class.parameters: (Recording recording)
focal_class.return: List<String>
focal_class.signature: List<String> makeHeader(Recording recording)
focal_method.body: @SuppressFBWarnings(value = "UC_USELESS_OBJECT", justification = "False positive with List.forEach")
    public String convertToCsv(Recording recording) {
      List<String> header = makeHeader(recording);
      int headerSize = header.size();
      CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader(header.toArray(new String[headerSize]));
  
      try (var writer = new StringWriter();
           var csvPrinter = new CSVPrinter(writer, csvFormat)) {
        var flattenedData = Converter.flatten(recording, not(Converter::isMetadata), windowSize.get());
  
        var rows = flattenedData.entrySet()
            .stream()
            .sorted(Comparator.comparingLong(Map.Entry::getKey))
            .map(e -> toRow(header, headerSize, e))
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
  
        if (fillEmpty.get()) {
          fillEmptyCells(rows);
        }
  
        for (Object[] row : rows) {
          csvPrinter.printRecord(row);
        }
  
        return writer.toString();
      } catch (IOException e) {
        throw new IllegalStateException("Could not convert recording to CSV", e);
      }
    }
focal_method.class_method_signature: CsvConverter.convertToCsv(Recording recording)
focal_method.full_signature: @SuppressFBWarnings(value = "UC_USELESS_OBJECT", justification = "False positive with List.forEach") public String convertToCsv(Recording recording)
focal_method.identifier: convertToCsv
focal_method.invocations: makeHeader size withHeader toArray flatten not get collect filter map sorted stream entrySet comparingLong toRow toList get fillEmptyCells printRecord toString
focal_method.modifiers: @SuppressFBWarnings(value = "UC_USELESS_OBJECT", justification = "False positive with List.forEach") public
focal_method.parameters: (Recording recording)
focal_method.return: String
focal_method.signature: String convertToCsv(Recording recording)