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 * CSV data format 035 */ 036@Metadata(label = "dataformat,transformation,csv", title = "CSV") 037@XmlRootElement(name = "csv") 038@XmlAccessorType(XmlAccessType.FIELD) 039public class CsvDataFormat extends DataFormatDefinition { 040 // Format options 041 @XmlAttribute 042 private String formatRef; 043 @XmlAttribute 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 // Unmarshall options 082 @XmlAttribute 083 private Boolean lazyLoad; 084 @XmlAttribute 085 private Boolean useMaps; 086 @XmlAttribute 087 private String recordConverterRef; 088 089 public CsvDataFormat() { 090 super("csv"); 091 } 092 093 public CsvDataFormat(String delimiter) { 094 this(); 095 setDelimiter(delimiter); 096 } 097 098 public CsvDataFormat(boolean lazyLoad) { 099 this(); 100 setLazyLoad(lazyLoad); 101 } 102 103 @Override 104 protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) { 105 // Format options 106 if (ObjectHelper.isNotEmpty(formatRef)) { 107 Object format = CamelContextHelper.mandatoryLookup(camelContext, formatRef); 108 setProperty(camelContext, dataFormat, "format", format); 109 } else if (ObjectHelper.isNotEmpty(formatName)) { 110 setProperty(camelContext, dataFormat, "formatName", formatName); 111 } 112 if (commentMarkerDisabled != null) { 113 setProperty(camelContext, dataFormat, "commentMarkerDisabled", commentMarkerDisabled); 114 } 115 if (commentMarker != null) { 116 setProperty(camelContext, dataFormat, "commentMarker", singleChar(commentMarker, "commentMarker")); 117 } 118 if (delimiter != null) { 119 setProperty(camelContext, dataFormat, "delimiter", singleChar(delimiter, "delimiter")); 120 } 121 if (escapeDisabled != null) { 122 setProperty(camelContext, dataFormat, "escapeDisabled", escapeDisabled); 123 } 124 if (escape != null) { 125 setProperty(camelContext, dataFormat, "escape", singleChar(escape, "escape")); 126 } 127 if (headerDisabled != null) { 128 setProperty(camelContext, dataFormat, "headerDisabled", headerDisabled); 129 } 130 if (header != null && !header.isEmpty()) { 131 setProperty(camelContext, dataFormat, "header", header.toArray(new String[header.size()])); 132 } 133 if (allowMissingColumnNames != null) { 134 setProperty(camelContext, dataFormat, "allowMissingColumnNames", allowMissingColumnNames); 135 } 136 if (ignoreEmptyLines != null) { 137 setProperty(camelContext, dataFormat, "ignoreEmptyLines", ignoreEmptyLines); 138 } 139 if (ignoreSurroundingSpaces != null) { 140 setProperty(camelContext, dataFormat, "ignoreSurroundingSpaces", ignoreSurroundingSpaces); 141 } 142 if (nullStringDisabled != null) { 143 setProperty(camelContext, dataFormat, "nullStringDisabled", nullStringDisabled); 144 } 145 if (nullString != null) { 146 setProperty(camelContext, dataFormat, "nullString", nullString); 147 } 148 if (quoteDisabled != null) { 149 setProperty(camelContext, dataFormat, "quoteDisabled", quoteDisabled); 150 } 151 if (quote != null) { 152 setProperty(camelContext, dataFormat, "quote", singleChar(quote, "quote")); 153 } 154 if (recordSeparatorDisabled != null) { 155 setProperty(camelContext, dataFormat, "recordSeparatorDisabled", recordSeparatorDisabled); 156 } 157 if (recordSeparator != null) { 158 setProperty(camelContext, dataFormat, "recordSeparator", recordSeparator); 159 } 160 if (skipHeaderRecord != null) { 161 setProperty(camelContext, dataFormat, "skipHeaderRecord", skipHeaderRecord); 162 } 163 if (quoteMode != null) { 164 setProperty(camelContext, dataFormat, "quoteMode", quoteMode); 165 } 166 167 // Unmarshall options 168 if (lazyLoad != null) { 169 setProperty(camelContext, dataFormat, "lazyLoad", lazyLoad); 170 } 171 if (useMaps != null) { 172 setProperty(camelContext, dataFormat, "useMaps", useMaps); 173 } 174 if (ObjectHelper.isNotEmpty(recordConverterRef)) { 175 Object recordConverter = CamelContextHelper.mandatoryLookup(camelContext, recordConverterRef); 176 setProperty(camelContext, dataFormat, "recordConverter", recordConverter); 177 } 178 } 179 180 private static Character singleChar(String value, String attributeName) { 181 if (value.length() != 1) { 182 throw new IllegalArgumentException(String.format("The '%s' attribute must be exactly one character long.", attributeName)); 183 } 184 return value.charAt(0); 185 } 186 187 public String getFormatRef() { 188 return formatRef; 189 } 190 191 /** 192 * The reference format to use, it will be updated with the other format options, the default value is CSVFormat.DEFAULT 193 */ 194 public void setFormatRef(String formatRef) { 195 this.formatRef = formatRef; 196 } 197 198 public String getFormatName() { 199 return formatName; 200 } 201 202 /** 203 * The name of the format to use, the default value is CSVFormat.DEFAULT 204 */ 205 public void setFormatName(String formatName) { 206 this.formatName = formatName; 207 } 208 209 public Boolean getCommentMarkerDisabled() { 210 return commentMarkerDisabled; 211 } 212 213 /** 214 * Disables the comment marker of the reference format. 215 */ 216 public void setCommentMarkerDisabled(Boolean commentMarkerDisabled) { 217 this.commentMarkerDisabled = commentMarkerDisabled; 218 } 219 220 public String getCommentMarker() { 221 return commentMarker; 222 } 223 224 /** 225 * Sets the comment marker of the reference format. 226 */ 227 public void setCommentMarker(String commentMarker) { 228 this.commentMarker = commentMarker; 229 } 230 231 public String getDelimiter() { 232 return delimiter; 233 } 234 235 /** 236 * Sets the delimiter to use. 237 * <p/> 238 * The default value is , (comma) 239 */ 240 public void setDelimiter(String delimiter) { 241 this.delimiter = delimiter; 242 } 243 244 public Boolean getEscapeDisabled() { 245 return escapeDisabled; 246 } 247 248 /** 249 * Use for disabling using escape character 250 */ 251 public void setEscapeDisabled(Boolean escapeDisabled) { 252 this.escapeDisabled = escapeDisabled; 253 } 254 255 public String getEscape() { 256 return escape; 257 } 258 259 /** 260 * Sets the escape character to use 261 */ 262 public void setEscape(String escape) { 263 this.escape = escape; 264 } 265 266 /** 267 * Use for disabling headers 268 */ 269 public Boolean getHeaderDisabled() { 270 return headerDisabled; 271 } 272 273 public void setHeaderDisabled(Boolean headerDisabled) { 274 this.headerDisabled = headerDisabled; 275 } 276 277 public List<String> getHeader() { 278 return header; 279 } 280 281 /** 282 * To configure the CSV headers 283 */ 284 public void setHeader(List<String> header) { 285 this.header = header; 286 } 287 288 public Boolean getAllowMissingColumnNames() { 289 return allowMissingColumnNames; 290 } 291 292 /** 293 * Whether to allow missing column names. 294 */ 295 public void setAllowMissingColumnNames(Boolean allowMissingColumnNames) { 296 this.allowMissingColumnNames = allowMissingColumnNames; 297 } 298 299 public Boolean getIgnoreEmptyLines() { 300 return ignoreEmptyLines; 301 } 302 303 /** 304 * Whether to ignore empty lines. 305 */ 306 public void setIgnoreEmptyLines(Boolean ignoreEmptyLines) { 307 this.ignoreEmptyLines = ignoreEmptyLines; 308 } 309 310 public Boolean getIgnoreSurroundingSpaces() { 311 return ignoreSurroundingSpaces; 312 } 313 314 /** 315 * Whether to ignore surrounding spaces 316 */ 317 public void setIgnoreSurroundingSpaces(Boolean ignoreSurroundingSpaces) { 318 this.ignoreSurroundingSpaces = ignoreSurroundingSpaces; 319 } 320 321 public Boolean getNullStringDisabled() { 322 return nullStringDisabled; 323 } 324 325 /** 326 * Used to disable null strings 327 */ 328 public void setNullStringDisabled(Boolean nullStringDisabled) { 329 this.nullStringDisabled = nullStringDisabled; 330 } 331 332 public String getNullString() { 333 return nullString; 334 } 335 336 /** 337 * Sets the null string 338 */ 339 public void setNullString(String nullString) { 340 this.nullString = nullString; 341 } 342 343 public Boolean getQuoteDisabled() { 344 return quoteDisabled; 345 } 346 347 /** 348 * Used to disable quotes 349 */ 350 public void setQuoteDisabled(Boolean quoteDisabled) { 351 this.quoteDisabled = quoteDisabled; 352 } 353 354 public String getQuote() { 355 return quote; 356 } 357 358 /** 359 * Sets the quote which by default is " 360 */ 361 public void setQuote(String quote) { 362 this.quote = quote; 363 } 364 365 public String getRecordSeparatorDisabled() { 366 return recordSeparatorDisabled; 367 } 368 369 /** 370 * Used for disabling record separator 371 */ 372 public void setRecordSeparatorDisabled(String recordSeparatorDisabled) { 373 this.recordSeparatorDisabled = recordSeparatorDisabled; 374 } 375 376 public String getRecordSeparator() { 377 return recordSeparator; 378 } 379 380 /** 381 * Sets the record separator (aka new line) which by default is \r\n (CRLF) 382 */ 383 public void setRecordSeparator(String recordSeparator) { 384 this.recordSeparator = recordSeparator; 385 } 386 387 public Boolean getSkipHeaderRecord() { 388 return skipHeaderRecord; 389 } 390 391 /** 392 * Whether to skip the header record in the output 393 */ 394 public void setSkipHeaderRecord(Boolean skipHeaderRecord) { 395 this.skipHeaderRecord = skipHeaderRecord; 396 } 397 398 public String getQuoteMode() { 399 return quoteMode; 400 } 401 402 /** 403 * Sets the quote mode 404 */ 405 public void setQuoteMode(String quoteMode) { 406 this.quoteMode = quoteMode; 407 } 408 409 public Boolean getLazyLoad() { 410 return lazyLoad; 411 } 412 413 /** 414 * Whether the unmarshalling should produce an iterator that reads the lines on the fly or if all the lines must be read at one. 415 */ 416 public void setLazyLoad(Boolean lazyLoad) { 417 this.lazyLoad = lazyLoad; 418 } 419 420 public Boolean getUseMaps() { 421 return useMaps; 422 } 423 424 /** 425 * Whether the unmarshalling should produce maps for the lines values instead of lists. It requires to have header (either defined or collected). 426 */ 427 public void setUseMaps(Boolean useMaps) { 428 this.useMaps = useMaps; 429 } 430 431 public String getRecordConverterRef() { 432 return recordConverterRef; 433 } 434 435 /** 436 * Refers to a custom <tt>CsvRecordConverter</tt> to lookup from the registry to use. 437 */ 438 public void setRecordConverterRef(String recordConverterRef) { 439 this.recordConverterRef = recordConverterRef; 440 } 441 442}