| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.sqoop.lib; |
| |
| /** |
| * Encapsulates a set of delimiters used to encode a record. |
| */ |
| public class DelimiterSet implements Cloneable { |
| |
| public static final char NULL_CHAR = '\000'; |
| |
| private char fieldDelim; // fields terminated by this. |
| private char recordDelim; // records terminated by this. |
| |
| // If these next two fields are '\000', then they are ignored. |
| private char enclosedBy; |
| private char escapedBy; |
| |
| // If true, then the enclosed-by character is applied to every |
| // field, not just ones containing embedded delimiters. |
| |
| private boolean encloseRequired; |
| |
| public static final String OUTPUT_FIELD_DELIM_KEY = |
| "sqoop.output.field.delim"; |
| public static final String OUTPUT_RECORD_DELIM_KEY = |
| "sqoop.output.record.delim"; |
| public static final String OUTPUT_ENCLOSED_BY_KEY = |
| "sqoop.output.enclosed.by"; |
| public static final String OUTPUT_ESCAPED_BY_KEY = |
| "sqoop.output.escaped.by"; |
| public static final String OUTPUT_ENCLOSE_REQUIRED_KEY = |
| "sqoop.output.enclose.required"; |
| |
| /** |
| * Create the input variations for export instead of overloading them. |
| */ |
| public static final String INPUT_FIELD_DELIM_KEY = |
| "sqoop.input.field.delim"; |
| public static final String INPUT_RECORD_DELIM_KEY = |
| "sqoop.input.record.delim"; |
| public static final String INPUT_ENCLOSED_BY_KEY = |
| "sqoop.input.enclosed.by"; |
| public static final String INPUT_ESCAPED_BY_KEY = |
| "sqoop.input.escaped.by"; |
| public static final String INPUT_ENCLOSE_REQUIRED_KEY = |
| "sqoop.input.enclose.required"; |
| /** |
| * Create a delimiter set with the default delimiters |
| * (comma for fields, newline for records). |
| */ |
| public DelimiterSet() { |
| this(',', '\n', NULL_CHAR, NULL_CHAR, false); |
| } |
| |
| /** |
| * Create a delimiter set with the specified delimiters. |
| * @param field the fields-terminated-by delimiter |
| * @param record the lines-terminated-by delimiter |
| * @param enclose the enclosed-by character |
| * @param escape the escaped-by character |
| * @param isEncloseRequired If true, enclosed-by is applied to all |
| * fields. If false, only applied to fields that embed delimiters. |
| */ |
| public DelimiterSet(char field, char record, char enclose, char escape, |
| boolean isEncloseRequired) { |
| this.fieldDelim = field; |
| this.recordDelim = record; |
| this.enclosedBy = enclose; |
| this.escapedBy = escape; |
| this.encloseRequired = isEncloseRequired; |
| } |
| |
| /** |
| * Identical to clone() but does not throw spurious exceptions. |
| * @return a new copy of this same set of delimiters. |
| */ |
| public DelimiterSet copy() { |
| try { |
| return (DelimiterSet) clone(); |
| } catch (CloneNotSupportedException cnse) { |
| // Should never happen for DelimiterSet. |
| return null; |
| } |
| } |
| |
| /** |
| * Sets the fields-terminated-by character. |
| */ |
| public void setFieldsTerminatedBy(char f) { |
| this.fieldDelim = f; |
| } |
| |
| /** |
| * @return the fields-terminated-by character. |
| */ |
| public char getFieldsTerminatedBy() { |
| return this.fieldDelim; |
| } |
| |
| /** |
| * Sets the end-of-record lines-terminated-by character. |
| */ |
| public void setLinesTerminatedBy(char r) { |
| this.recordDelim = r; |
| } |
| |
| /** |
| * @return the end-of-record (lines-terminated-by) character. |
| */ |
| public char getLinesTerminatedBy() { |
| return this.recordDelim; |
| } |
| |
| /** |
| * Sets the enclosed-by character. |
| * @param e the enclosed-by character, or '\000' for no enclosing character. |
| */ |
| public void setEnclosedBy(char e) { |
| this.enclosedBy = e; |
| } |
| |
| /** |
| * @return the enclosed-by character, or '\000' for none. |
| */ |
| public char getEnclosedBy() { |
| return this.enclosedBy; |
| } |
| |
| /** |
| * Sets the escaped-by character. |
| * @param e the escaped-by character, or '\000' for no escape character. |
| */ |
| public void setEscapedBy(char e) { |
| this.escapedBy = e; |
| } |
| |
| /** |
| * @return the escaped-by character, or '\000' for none. |
| */ |
| public char getEscapedBy() { |
| return this.escapedBy; |
| } |
| |
| /** |
| * Set whether the enclosed-by character must be applied to all fields, |
| * or only fields with embedded delimiters. |
| */ |
| public void setEncloseRequired(boolean required) { |
| this.encloseRequired = required; |
| } |
| |
| /** |
| * @return true if the enclosed-by character must be applied to all fields, |
| * or false if it's only used for fields with embedded delimiters. |
| */ |
| public boolean isEncloseRequired() { |
| return this.encloseRequired; |
| } |
| |
| @Override |
| /** |
| * @return a string representation of the delimiters. |
| */ |
| public String toString() { |
| return "fields=" + this.fieldDelim |
| + " records=" + this.recordDelim |
| + " escape=" + this.escapedBy |
| + " enclose=" + this.enclosedBy |
| + " required=" + this.encloseRequired; |
| } |
| |
| /** |
| * Format this set of delimiters as a call to the constructor for |
| * this object, that would generate identical delimiters. |
| * @return a String that can be embedded in generated code that |
| * provides this set of delimiters. |
| */ |
| public String formatConstructor() { |
| return "new DelimiterSet((char) " + (int) this.fieldDelim + ", " |
| + "(char) " + (int) this.recordDelim + ", " |
| + "(char) " + (int) this.enclosedBy + ", " |
| + "(char) " + (int) this.escapedBy + ", " |
| + this.encloseRequired + ")"; |
| } |
| |
| @Override |
| /** |
| * @return a hash code for this set of delimiters. |
| */ |
| public int hashCode() { |
| return (int) this.fieldDelim |
| + (((int) this.recordDelim) << 4) |
| + (((int) this.escapedBy) << 8) |
| + (((int) this.enclosedBy) << 12) |
| + (((int) this.recordDelim) << 16) |
| + (this.encloseRequired ? 0xFEFE : 0x7070); |
| } |
| |
| @Override |
| /** |
| * @return true if this delimiter set is the same as another set of |
| * delimiters. |
| */ |
| public boolean equals(Object other) { |
| if (null == other) { |
| return false; |
| } else if (!other.getClass().equals(getClass())) { |
| return false; |
| } |
| |
| DelimiterSet set = (DelimiterSet) other; |
| return this.fieldDelim == set.fieldDelim |
| && this.recordDelim == set.recordDelim |
| && this.escapedBy == set.escapedBy |
| && this.enclosedBy == set.enclosedBy |
| && this.encloseRequired == set.encloseRequired; |
| } |
| |
| @Override |
| /** |
| * @return a new copy of this same set of delimiters. |
| */ |
| public Object clone() throws CloneNotSupportedException { |
| return super.clone(); |
| } |
| } |