protected void _handleFirstLine() throws IOException { _handleFirstLine = false; if (_schema.usesHeader()) { int count = _schema.size(); if (count == 0) { _reportMappingError( "Schema specified that header line is to be written; but contains no column names"); } for (CsvSchema.Column column : _schema) { _writer.writeColumnName(column.getName()); } _writer.endRow(); } }
@Override public final void writeStartArray() throws IOException { _verifyValueWrite("start an array"); /* Ok to create root-level array to contain Objects/Arrays, but * can not nest arrays in objects */ if (_writeContext.inObject()) { if (!_skipValue) { // First: column may have its own separator int sep; if (_nextColumnByName >= 0) { CsvSchema.Column col = _schema.column(_nextColumnByName); sep = col.isArray() ? col.getArrayElementSeparator() : -1; } else { sep = -1; } if (sep <= 0) { if (!_schema.hasArrayElementSeparator()) { _reportMappingError( "CSV generator does not support Array values for properties without setting 'arrayElementSeparator' in schema"); } sep = _schema.getArrayElementSeparator(); } _arraySeparator = sep; if (_arrayContents == null) { _arrayContents = new StringBuilder(); } else { _arrayContents.setLength(0); } _arrayElements = 0; } } else if (_arraySeparator >= 0) { // also: no nested arrays, yet _reportMappingError("CSV generator does not support nested Array values"); } _writeContext = _writeContext.createChildArrayContext(); // and that's about it, really }
private final void _writeFieldName(String name) throws IOException { // just find the matching index -- must have schema for that if (_schema == null) { // not a low-level error, so: _reportMappingError("Unrecognized column '" + name + "', can not resolve without CsvSchema"); } // note: we are likely to get next column name, so pass it as hint CsvSchema.Column col = _schema.column(name, _nextColumnByName + 1); if (col == null) { if (isEnabled(JsonGenerator.Feature.IGNORE_UNKNOWN)) { _skipValue = true; _nextColumnByName = -1; return; } // not a low-level error, so: _reportMappingError( "Unrecognized column '" + name + "': known columns: " + _schema.getColumnDesc()); } _skipValue = false; // and all we do is just note index to use for following value write _nextColumnByName = col.getIndex(); }
@Override public void writeOmittedField(String fieldName) throws IOException { // basically combination of "writeFieldName()" and "writeNull()" if (_writeContext.writeFieldName(fieldName) == JsonWriteContext.STATUS_EXPECT_VALUE) { _reportError("Can not skip a field, expecting a value"); } // Hmmh. Should we require a match? Actually, let's use logic: if field found, // assumption is we must add a placeholder; if not, we can merely ignore CsvSchema.Column col = _schema.column(fieldName); if (col == null) { // assumed to have been removed from schema too } else { // and all we do is just note index to use for following value write _nextColumnByName = col.getIndex(); // We can basically copy what 'writeNull()' does... _verifyValueWrite("skip positional value due to filtering"); _writer.write(_columnIndex(), ""); } }
@Override public void writeNull() throws IOException { _verifyValueWrite("write null value"); if (!_skipValue) { if (_arraySeparator >= 0) { _addToArray(_schema.getNullValueOrEmpty()); } else if (!_writeContext.inObject()) { // as per [#69] // note: 'root' not enough, for case of wrap-as array, or serialize List // or, to write 'empty Object' (for common case), would // write single null, then finish row, like so: /* _writer.writeNull(_columnIndex()); finishRow(); */ } else { _writer.writeNull(_columnIndex()); } } }
static { EMPTY_SCHEMA = CsvSchema.emptySchema(); }