001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.model.dataformat; 018 019import java.util.List; 020import javax.xml.bind.annotation.XmlAccessType; 021import javax.xml.bind.annotation.XmlAccessorType; 022import javax.xml.bind.annotation.XmlAttribute; 023import javax.xml.bind.annotation.XmlElement; 024import javax.xml.bind.annotation.XmlRootElement; 025 026import org.apache.camel.CamelContext; 027import org.apache.camel.model.DataFormatDefinition; 028import org.apache.camel.spi.DataFormat; 029import org.apache.camel.spi.Metadata; 030import org.apache.camel.util.CamelContextHelper; 031import org.apache.camel.util.ObjectHelper; 032 033/** 034 * The CSV data format is used for handling CSV payloads. 035 */ 036@Metadata(firstVersion = "1.3.0", label = "dataformat,transformation,csv", title = "CSV") 037@XmlRootElement(name = "csv") 038@XmlAccessorType(XmlAccessType.FIELD) 039public class CsvDataFormat extends DataFormatDefinition { 040 // Format options 041 @XmlAttribute @Metadata(label = "advanced") 042 private String formatRef; 043 @XmlAttribute @Metadata(enums = "DEFAULT,EXCEL,INFORMIX_UNLOAD,INFORMIX_UNLOAD_CSV,MYSQL,RFC4180") 044 private String formatName; 045 @XmlAttribute 046 private Boolean commentMarkerDisabled; 047 @XmlAttribute 048 private String commentMarker; 049 @XmlAttribute 050 private String delimiter; 051 @XmlAttribute 052 private Boolean escapeDisabled; 053 @XmlAttribute 054 private String escape; 055 @XmlAttribute 056 private Boolean headerDisabled; 057 @XmlElement 058 private List<String> header; 059 @XmlAttribute 060 private Boolean allowMissingColumnNames; 061 @XmlAttribute 062 private Boolean ignoreEmptyLines; 063 @XmlAttribute 064 private Boolean ignoreSurroundingSpaces; 065 @XmlAttribute 066 private Boolean nullStringDisabled; 067 @XmlAttribute 068 private String nullString; 069 @XmlAttribute 070 private Boolean quoteDisabled; 071 @XmlAttribute 072 private String quote; 073 @XmlAttribute 074 private String recordSeparatorDisabled; 075 @XmlAttribute 076 private String recordSeparator; 077 @XmlAttribute 078 private Boolean skipHeaderRecord; 079 @XmlAttribute 080 private String quoteMode; 081 @XmlAttribute 082 private Boolean ignoreHeaderCase; 083 @XmlAttribute 084 private Boolean trim; 085 @XmlAttribute 086 private Boolean trailingDelimiter; 087 088 // Unmarshall options 089 @XmlAttribute 090 private Boolean lazyLoad; 091 @XmlAttribute 092 private Boolean useMaps; 093 @XmlAttribute 094 private String recordConverterRef; 095 096 public CsvDataFormat() { 097 super("csv"); 098 } 099 100 public CsvDataFormat(String delimiter) { 101 this(); 102 setDelimiter(delimiter); 103 } 104 105 public CsvDataFormat(boolean lazyLoad) { 106 this(); 107 setLazyLoad(lazyLoad); 108 } 109 110 @Override 111 protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) { 112 // Format options 113 if (ObjectHelper.isNotEmpty(formatRef)) { 114 Object format = CamelContextHelper.mandatoryLookup(camelContext, formatRef); 115 setProperty(camelContext, dataFormat, "format", format); 116 } else if (ObjectHelper.isNotEmpty(formatName)) { 117 setProperty(camelContext, dataFormat, "formatName", formatName); 118 } 119 if (commentMarkerDisabled != null) { 120 setProperty(camelContext, dataFormat, "commentMarkerDisabled", commentMarkerDisabled); 121 } 122 if (commentMarker != null) { 123 setProperty(camelContext, dataFormat, "commentMarker", singleChar(commentMarker, "commentMarker")); 124 } 125 if (delimiter != null) { 126 setProperty(camelContext, dataFormat, "delimiter", singleChar(delimiter, "delimiter")); 127 } 128 if (escapeDisabled != null) { 129 setProperty(camelContext, dataFormat, "escapeDisabled", escapeDisabled); 130 } 131 if (escape != null) { 132 setProperty(camelContext, dataFormat, "escape", singleChar(escape, "escape")); 133 } 134 if (headerDisabled != null) { 135 setProperty(camelContext, dataFormat, "headerDisabled", headerDisabled); 136 } 137 if (header != null && !header.isEmpty()) { 138 setProperty(camelContext, dataFormat, "header", header.toArray(new String[header.size()])); 139 } 140 if (allowMissingColumnNames != null) { 141 setProperty(camelContext, dataFormat, "allowMissingColumnNames", allowMissingColumnNames); 142 } 143 if (ignoreEmptyLines != null) { 144 setProperty(camelContext, dataFormat, "ignoreEmptyLines", ignoreEmptyLines); 145 } 146 if (ignoreSurroundingSpaces != null) { 147 setProperty(camelContext, dataFormat, "ignoreSurroundingSpaces", ignoreSurroundingSpaces); 148 } 149 if (nullStringDisabled != null) { 150 setProperty(camelContext, dataFormat, "nullStringDisabled", nullStringDisabled); 151 } 152 if (nullString != null) { 153 setProperty(camelContext, dataFormat, "nullString", nullString); 154 } 155 if (quoteDisabled != null) { 156 setProperty(camelContext, dataFormat, "quoteDisabled", quoteDisabled); 157 } 158 if (quote != null) { 159 setProperty(camelContext, dataFormat, "quote", singleChar(quote, "quote")); 160 } 161 if (recordSeparatorDisabled != null) { 162 setProperty(camelContext, dataFormat, "recordSeparatorDisabled", recordSeparatorDisabled); 163 } 164 if (recordSeparator != null) { 165 setProperty(camelContext, dataFormat, "recordSeparator", recordSeparator); 166 } 167 if (skipHeaderRecord != null) { 168 setProperty(camelContext, dataFormat, "skipHeaderRecord", skipHeaderRecord); 169 } 170 if (quoteMode != null) { 171 setProperty(camelContext, dataFormat, "quoteMode", quoteMode); 172 } 173 if (trim != null) { 174 setProperty(camelContext, dataFormat, "trim", trim); 175 } 176 if (ignoreHeaderCase != null) { 177 setProperty(camelContext, dataFormat, "ignoreHeaderCase", ignoreHeaderCase); 178 } 179 if (trailingDelimiter != null) { 180 setProperty(camelContext, dataFormat, "trailingDelimiter", trailingDelimiter); 181 } 182 183 // Unmarshall options 184 if (lazyLoad != null) { 185 setProperty(camelContext, dataFormat, "lazyLoad", lazyLoad); 186 } 187 if (useMaps != null) { 188 setProperty(camelContext, dataFormat, "useMaps", useMaps); 189 } 190 if (ObjectHelper.isNotEmpty(recordConverterRef)) { 191 Object recordConverter = CamelContextHelper.mandatoryLookup(camelContext, recordConverterRef); 192 setProperty(camelContext, dataFormat, "recordConverter", recordConverter); 193 } 194 } 195 196 private static Character singleChar(String value, String attributeName) { 197 if (value.length() != 1) { 198 throw new IllegalArgumentException(String.format("The '%s' attribute must be exactly one character long.", attributeName)); 199 } 200 return value.charAt(0); 201 } 202 203 public String getFormatRef() { 204 return formatRef; 205 } 206 207 /** 208 * The reference format to use, it will be updated with the other format options, the default value is CSVFormat.DEFAULT 209 */ 210 public void setFormatRef(String formatRef) { 211 this.formatRef = formatRef; 212 } 213 214 public String getFormatName() { 215 return formatName; 216 } 217 218 /** 219 * The name of the format to use, the default value is CSVFormat.DEFAULT 220 */ 221 public void setFormatName(String formatName) { 222 this.formatName = formatName; 223 } 224 225 public Boolean getCommentMarkerDisabled() { 226 return commentMarkerDisabled; 227 } 228 229 /** 230 * Disables the comment marker of the reference format. 231 */ 232 public void setCommentMarkerDisabled(Boolean commentMarkerDisabled) { 233 this.commentMarkerDisabled = commentMarkerDisabled; 234 } 235 236 public String getCommentMarker() { 237 return commentMarker; 238 } 239 240 /** 241 * Sets the comment marker of the reference format. 242 */ 243 public void setCommentMarker(String commentMarker) { 244 this.commentMarker = commentMarker; 245 } 246 247 public String getDelimiter() { 248 return delimiter; 249 } 250 251 /** 252 * Sets the delimiter to use. 253 * <p/> 254 * The default value is , (comma) 255 */ 256 public void setDelimiter(String delimiter) { 257 this.delimiter = delimiter; 258 } 259 260 public Boolean getEscapeDisabled() { 261 return escapeDisabled; 262 } 263 264 /** 265 * Use for disabling using escape character 266 */ 267 public void setEscapeDisabled(Boolean escapeDisabled) { 268 this.escapeDisabled = escapeDisabled; 269 } 270 271 public String getEscape() { 272 return escape; 273 } 274 275 /** 276 * Sets the escape character to use 277 */ 278 public void setEscape(String escape) { 279 this.escape = escape; 280 } 281 282 /** 283 * Use for disabling headers 284 */ 285 public Boolean getHeaderDisabled() { 286 return headerDisabled; 287 } 288 289 public void setHeaderDisabled(Boolean headerDisabled) { 290 this.headerDisabled = headerDisabled; 291 } 292 293 public List<String> getHeader() { 294 return header; 295 } 296 297 /** 298 * To configure the CSV headers 299 */ 300 public void setHeader(List<String> header) { 301 this.header = header; 302 } 303 304 public Boolean getAllowMissingColumnNames() { 305 return allowMissingColumnNames; 306 } 307 308 /** 309 * Whether to allow missing column names. 310 */ 311 public void setAllowMissingColumnNames(Boolean allowMissingColumnNames) { 312 this.allowMissingColumnNames = allowMissingColumnNames; 313 } 314 315 public Boolean getIgnoreEmptyLines() { 316 return ignoreEmptyLines; 317 } 318 319 /** 320 * Whether to ignore empty lines. 321 */ 322 public void setIgnoreEmptyLines(Boolean ignoreEmptyLines) { 323 this.ignoreEmptyLines = ignoreEmptyLines; 324 } 325 326 public Boolean getIgnoreSurroundingSpaces() { 327 return ignoreSurroundingSpaces; 328 } 329 330 /** 331 * Whether to ignore surrounding spaces 332 */ 333 public void setIgnoreSurroundingSpaces(Boolean ignoreSurroundingSpaces) { 334 this.ignoreSurroundingSpaces = ignoreSurroundingSpaces; 335 } 336 337 public Boolean getNullStringDisabled() { 338 return nullStringDisabled; 339 } 340 341 /** 342 * Used to disable null strings 343 */ 344 public void setNullStringDisabled(Boolean nullStringDisabled) { 345 this.nullStringDisabled = nullStringDisabled; 346 } 347 348 public String getNullString() { 349 return nullString; 350 } 351 352 /** 353 * Sets the null string 354 */ 355 public void setNullString(String nullString) { 356 this.nullString = nullString; 357 } 358 359 public Boolean getQuoteDisabled() { 360 return quoteDisabled; 361 } 362 363 /** 364 * Used to disable quotes 365 */ 366 public void setQuoteDisabled(Boolean quoteDisabled) { 367 this.quoteDisabled = quoteDisabled; 368 } 369 370 public String getQuote() { 371 return quote; 372 } 373 374 /** 375 * Sets the quote which by default is " 376 */ 377 public void setQuote(String quote) { 378 this.quote = quote; 379 } 380 381 public String getRecordSeparatorDisabled() { 382 return recordSeparatorDisabled; 383 } 384 385 /** 386 * Used for disabling record separator 387 */ 388 public void setRecordSeparatorDisabled(String recordSeparatorDisabled) { 389 this.recordSeparatorDisabled = recordSeparatorDisabled; 390 } 391 392 public String getRecordSeparator() { 393 return recordSeparator; 394 } 395 396 /** 397 * Sets the record separator (aka new line) which by default is new line characters (CRLF) 398 */ 399 public void setRecordSeparator(String recordSeparator) { 400 this.recordSeparator = recordSeparator; 401 } 402 403 public Boolean getSkipHeaderRecord() { 404 return skipHeaderRecord; 405 } 406 407 /** 408 * Whether to skip the header record in the output 409 */ 410 public void setSkipHeaderRecord(Boolean skipHeaderRecord) { 411 this.skipHeaderRecord = skipHeaderRecord; 412 } 413 414 public String getQuoteMode() { 415 return quoteMode; 416 } 417 418 /** 419 * Sets the quote mode 420 */ 421 public void setQuoteMode(String quoteMode) { 422 this.quoteMode = quoteMode; 423 } 424 425 public Boolean getLazyLoad() { 426 return lazyLoad; 427 } 428 429 /** 430 * Whether the unmarshalling should produce an iterator that reads the lines on the fly or if all the lines must be read at one. 431 */ 432 public void setLazyLoad(Boolean lazyLoad) { 433 this.lazyLoad = lazyLoad; 434 } 435 436 public Boolean getUseMaps() { 437 return useMaps; 438 } 439 440 /** 441 * Whether the unmarshalling should produce maps for the lines values instead of lists. It requires to have header (either defined or collected). 442 */ 443 public void setUseMaps(Boolean useMaps) { 444 this.useMaps = useMaps; 445 } 446 447 public String getRecordConverterRef() { 448 return recordConverterRef; 449 } 450 451 /** 452 * Refers to a custom <tt>CsvRecordConverter</tt> to lookup from the registry to use. 453 */ 454 public void setRecordConverterRef(String recordConverterRef) { 455 this.recordConverterRef = recordConverterRef; 456 } 457 458 /** 459 * Sets whether or not to trim leading and trailing blanks. 460 */ 461 public void setTrim(Boolean trim) { 462 this.trim = trim; 463 } 464 465 public Boolean getTrim() { 466 return trim; 467 } 468 469 /** 470 * Sets whether or not to ignore case when accessing header names. 471 */ 472 public void setIgnoreHeaderCase(Boolean ignoreHeaderCase) { 473 this.ignoreHeaderCase = ignoreHeaderCase; 474 } 475 476 public Boolean getIgnoreHeaderCase() { 477 return ignoreHeaderCase; 478 } 479 480 /** 481 * Sets whether or not to add a trailing delimiter. 482 */ 483 public void setTrailingDelimiter(Boolean trailingDelimiter) { 484 this.trailingDelimiter = trailingDelimiter; 485 } 486 487 public Boolean getTrailingDelimiter() { 488 return trailingDelimiter; 489 } 490 491}