@@ -157,6 +157,7 @@ public final class CSVFormat implements Serializable {
157157 private final String recordSeparator ; // for outputs
158158 private final String nullString ; // the string to be used for null values
159159 private final String [] header ; // array of header column names
160+ private final String [] headerComments ; // array of header comment lines
160161 private final boolean skipHeaderRecord ;
161162
162163 /**
@@ -173,7 +174,7 @@ public final class CSVFormat implements Serializable {
173174 * </ul>
174175 */
175176 public static final CSVFormat DEFAULT = new CSVFormat (COMMA , DOUBLE_QUOTE_CHAR , null , null , null ,
176- false , true , CRLF , null , null , false , false );
177+ false , true , CRLF , null , null , null , false , false );
177178
178179 /**
179180 * Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
@@ -307,7 +308,7 @@ private static boolean isLineBreak(final Character c) {
307308 * @see #TDF
308309 */
309310 public static CSVFormat newFormat (final char delimiter ) {
310- return new CSVFormat (delimiter , null , null , null , null , false , false , null , null , null , false , false );
311+ return new CSVFormat (delimiter , null , null , null , null , false , false , null , null , null , null , false , false );
311312 }
312313
313314 /**
@@ -331,6 +332,7 @@ public static CSVFormat newFormat(final char delimiter) {
331332 * the line separator to use for output
332333 * @param nullString
333334 * the line separator to use for output
335+ * @param toHeaderComments TODO
334336 * @param header
335337 * the header
336338 * @param skipHeaderRecord TODO
@@ -341,8 +343,8 @@ private CSVFormat(final char delimiter, final Character quoteChar,
341343 final QuoteMode quoteMode , final Character commentStart ,
342344 final Character escape , final boolean ignoreSurroundingSpaces ,
343345 final boolean ignoreEmptyLines , final String recordSeparator ,
344- final String nullString , final String [] header , final boolean skipHeaderRecord ,
345- final boolean allowMissingColumnNames ) {
346+ final String nullString , final Object [] headerComments , final String [] header ,
347+ final boolean skipHeaderRecord , final boolean allowMissingColumnNames ) {
346348 if (isLineBreak (delimiter )) {
347349 throw new IllegalArgumentException ("The delimiter cannot be a line break" );
348350 }
@@ -356,6 +358,7 @@ private CSVFormat(final char delimiter, final Character quoteChar,
356358 this .ignoreEmptyLines = ignoreEmptyLines ;
357359 this .recordSeparator = recordSeparator ;
358360 this .nullString = nullString ;
361+ this .headerComments = toStringArray (headerComments );
359362 if (header == null ) {
360363 this .header = null ;
361364 } else {
@@ -372,6 +375,18 @@ private CSVFormat(final char delimiter, final Character quoteChar,
372375 validate ();
373376 }
374377
378+ private String [] toStringArray (Object [] values ) {
379+ if (values == null ) {
380+ return null ;
381+ }
382+ String [] strings = new String [values .length ];
383+ for (int i = 0 ; i < values .length ; i ++) {
384+ Object value = values [i ];
385+ strings [i ] = value == null ? null : value .toString ();
386+ }
387+ return strings ;
388+ }
389+
375390 @ Override
376391 public boolean equals (final Object obj ) {
377392 if (this == obj ) {
@@ -495,6 +510,15 @@ public String[] getHeader() {
495510 return header != null ? header .clone () : null ;
496511 }
497512
513+ /**
514+ * Returns a copy of the header comment array.
515+ *
516+ * @return a copy of the header comment array; {@code null} if disabled.
517+ */
518+ public String [] getHeaderComments () {
519+ return headerComments != null ? headerComments .clone () : null ;
520+ }
521+
498522 /**
499523 * Specifies whether missing column names are allowed when parsing the header line.
500524 *
@@ -701,6 +725,10 @@ public String toString() {
701725 sb .append (" SurroundingSpaces:ignored" );
702726 }
703727 sb .append (" SkipHeaderRecord:" ).append (skipHeaderRecord );
728+ if (headerComments != null ) {
729+ sb .append (' ' );
730+ sb .append ("HeaderComments:" ).append (Arrays .toString (headerComments ));
731+ }
704732 if (header != null ) {
705733 sb .append (' ' );
706734 sb .append ("Header:" ).append (Arrays .toString (header ));
@@ -775,8 +803,8 @@ public CSVFormat withCommentMarker(final Character commentMarker) {
775803 throw new IllegalArgumentException ("The comment start marker character cannot be a line break" );
776804 }
777805 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
778- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
779- allowMissingColumnNames );
806+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
807+ skipHeaderRecord , allowMissingColumnNames );
780808 }
781809
782810 /**
@@ -793,8 +821,8 @@ public CSVFormat withDelimiter(final char delimiter) {
793821 throw new IllegalArgumentException ("The delimiter cannot be a line break" );
794822 }
795823 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
796- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
797- allowMissingColumnNames );
824+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
825+ skipHeaderRecord , allowMissingColumnNames );
798826 }
799827
800828 /**
@@ -824,8 +852,8 @@ public CSVFormat withEscape(final Character escape) {
824852 throw new IllegalArgumentException ("The escape character cannot be a line break" );
825853 }
826854 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escape ,
827- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
828- allowMissingColumnNames );
855+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
856+ skipHeaderRecord , allowMissingColumnNames );
829857 }
830858
831859 /**
@@ -847,8 +875,27 @@ public CSVFormat withEscape(final Character escape) {
847875 */
848876 public CSVFormat withHeader (final String ... header ) {
849877 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
850- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
851- allowMissingColumnNames );
878+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
879+ skipHeaderRecord , allowMissingColumnNames );
880+ }
881+
882+ /**
883+ * Sets the header comments of the format. The comments will be printed first, before the headers.
884+ *
885+ * <pre>
886+ * CSVFormat format = aformat.withHeaderComments("Generated by Apache Commons CSV 1.1.", new Date());</pre>
887+ *
888+ * @param header
889+ * the header, {@code null} if disabled, empty if parsed automatically, user specified otherwise.
890+ *
891+ * @return A new CSVFormat that is equal to this but with the specified header
892+ * @see #withSkipHeaderRecord(boolean)
893+ * @since 1.1
894+ */
895+ public CSVFormat withHeaderComments (final Object ... headerComments ) {
896+ return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
897+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , headerComments , header ,
898+ skipHeaderRecord , allowMissingColumnNames );
852899 }
853900
854901 /**
@@ -872,8 +919,8 @@ public CSVFormat withAllowMissingColumnNames() {
872919 */
873920 public CSVFormat withAllowMissingColumnNames (final boolean allowMissingColumnNames ) {
874921 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
875- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
876- allowMissingColumnNames );
922+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
923+ skipHeaderRecord , allowMissingColumnNames );
877924 }
878925
879926 /**
@@ -897,8 +944,8 @@ public CSVFormat withIgnoreEmptyLines() {
897944 */
898945 public CSVFormat withIgnoreEmptyLines (final boolean ignoreEmptyLines ) {
899946 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
900- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
901- allowMissingColumnNames );
947+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
948+ skipHeaderRecord , allowMissingColumnNames );
902949 }
903950
904951 /**
@@ -922,8 +969,8 @@ public CSVFormat withIgnoreSurroundingSpaces() {
922969 */
923970 public CSVFormat withIgnoreSurroundingSpaces (final boolean ignoreSurroundingSpaces ) {
924971 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
925- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
926- allowMissingColumnNames );
972+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
973+ skipHeaderRecord , allowMissingColumnNames );
927974 }
928975
929976 /**
@@ -943,8 +990,8 @@ public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpac
943990 */
944991 public CSVFormat withNullString (final String nullString ) {
945992 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
946- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
947- allowMissingColumnNames );
993+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
994+ skipHeaderRecord , allowMissingColumnNames );
948995 }
949996
950997 /**
@@ -974,8 +1021,8 @@ public CSVFormat withQuote(final Character quoteChar) {
9741021 throw new IllegalArgumentException ("The quoteChar cannot be a line break" );
9751022 }
9761023 return new CSVFormat (delimiter , quoteChar , quoteMode , commentMarker , escapeCharacter ,
977- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
978- allowMissingColumnNames );
1024+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
1025+ skipHeaderRecord , allowMissingColumnNames );
9791026 }
9801027
9811028 /**
@@ -988,8 +1035,8 @@ public CSVFormat withQuote(final Character quoteChar) {
9881035 */
9891036 public CSVFormat withQuoteMode (final QuoteMode quoteModePolicy ) {
9901037 return new CSVFormat (delimiter , quoteCharacter , quoteModePolicy , commentMarker , escapeCharacter ,
991- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
992- allowMissingColumnNames );
1038+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
1039+ skipHeaderRecord , allowMissingColumnNames );
9931040 }
9941041
9951042 /**
@@ -1022,8 +1069,8 @@ public CSVFormat withRecordSeparator(final char recordSeparator) {
10221069 */
10231070 public CSVFormat withRecordSeparator (final String recordSeparator ) {
10241071 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
1025- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
1026- allowMissingColumnNames );
1072+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
1073+ skipHeaderRecord , allowMissingColumnNames );
10271074 }
10281075
10291076 /**
@@ -1052,7 +1099,7 @@ public CSVFormat withSkipHeaderRecord() {
10521099 */
10531100 public CSVFormat withSkipHeaderRecord (final boolean skipHeaderRecord ) {
10541101 return new CSVFormat (delimiter , quoteCharacter , quoteMode , commentMarker , escapeCharacter ,
1055- ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , header , skipHeaderRecord ,
1056- allowMissingColumnNames );
1102+ ignoreSurroundingSpaces , ignoreEmptyLines , recordSeparator , nullString , null , header ,
1103+ skipHeaderRecord , allowMissingColumnNames );
10571104 }
10581105}
0 commit comments