Repository: commons-csv
Updated Branches:
  refs/heads/CSV-216-with [created] c66ea98c0


CSV-216 add mutator functions

if the record is already mutable, they will return
the current object, otherwise a copy will be made
using private CSVMutableRecord subclass.

The method mutable() and immutable() can be used to ensure
either semantics.


Project: http://git-wip-us.apache.org/repos/asf/commons-csv/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-csv/commit/bb949adb
Tree: http://git-wip-us.apache.org/repos/asf/commons-csv/tree/bb949adb
Diff: http://git-wip-us.apache.org/repos/asf/commons-csv/diff/bb949adb

Branch: refs/heads/CSV-216-with
Commit: bb949adbcb519356aa0cf6c4f62ee0e3643b84ee
Parents: c290f13
Author: Stian Soiland-Reyes <st...@apache.org>
Authored: Fri Feb 9 16:07:45 2018 +0000
Committer: Stian Soiland-Reyes <st...@apache.org>
Committed: Fri Feb 9 16:08:32 2018 +0000

----------------------------------------------------------------------
 .../apache/commons/csv/CSVMutableRecord.java    |  38 +++++--
 .../java/org/apache/commons/csv/CSVRecord.java  | 104 ++++++++++++++++++-
 2 files changed, 132 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-csv/blob/bb949adb/src/main/java/org/apache/commons/csv/CSVMutableRecord.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/csv/CSVMutableRecord.java 
b/src/main/java/org/apache/commons/csv/CSVMutableRecord.java
index b529cfb..a2105c8 100644
--- a/src/main/java/org/apache/commons/csv/CSVMutableRecord.java
+++ b/src/main/java/org/apache/commons/csv/CSVMutableRecord.java
@@ -19,7 +19,19 @@ package org.apache.commons.csv;
 
 import java.util.Map;
 
-public final class CSVMutableRecord extends CSVRecord {
+/**
+ * A mutable version of CSVRecord
+ * <p>
+ * As mutation is generally done within the parent {@link CSVRecord}, this 
+ * package-private class just includes more efficient versions of 
+ * mutator functions, bypassing the need to make copies 
+ * (except in {@link #immutable()}).
+ * <p>
+ * To enable generating CSVMutableRecord by default, set 
+ * {@link CSVFormat#withMutableRecords(boolean)} to <code>true</code>.
+ *
+ */
+final class CSVMutableRecord extends CSVRecord {
 
     private static final long serialVersionUID = 1L;
 
@@ -29,13 +41,25 @@ public final class CSVMutableRecord extends CSVRecord {
     }
 
     @Override
-    public void put(int index, String value) {
-        super.put(index, value);
+    public CSVMutableRecord withValue(int index, String value) {
+       super.put(index, value);
+       return this;
     }
-
+    
     @Override
-    public void put(String name, String value) {
-        super.put(name, value);
+    public CSVMutableRecord withValue(String name, String value) {
+       super.put(name, value);
+       return this;
+    }
+    
+    @Override
+    public CSVRecord withComment(String comment) {
+       this.comment = comment;
+       return this;
+    }    
+    
+    @Override
+    boolean isMutable() {
+       return true;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/commons-csv/blob/bb949adb/src/main/java/org/apache/commons/csv/CSVRecord.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/csv/CSVRecord.java 
b/src/main/java/org/apache/commons/csv/CSVRecord.java
index 35812ae..8b08353 100644
--- a/src/main/java/org/apache/commons/csv/CSVRecord.java
+++ b/src/main/java/org/apache/commons/csv/CSVRecord.java
@@ -36,8 +36,11 @@ public class CSVRecord implements Serializable, 
Iterable<String> {
 
     private final long characterPosition;
 
-    /** The accumulated comments (if any) */
-    private final String comment;
+    /** The accumulated comments (if any)
+     *
+     * package-private so it can be mutated by {@link CSVMutableRecord}
+     */
+    String comment;
 
     /** The column name to index mapping. */
     private final Map<String, Integer> mapping;
@@ -182,6 +185,28 @@ public class CSVRecord implements Serializable, 
Iterable<String> {
     }
 
     /**
+     * Return an immutable CSVRecord.
+     * <p>
+     * Immutable records have fixed values and are thus thread-safe. 
+     * <p>
+     * If this record is already immutable, it will be returned directly, 
+     * otherwise a copy of its current values will be made. 
+     * <p>
+     * Use {@link #mutable()} or {@link #withValue(int, String)} to get a 
mutable CSVRecord. 
+     * 
+     * @return Am immutable CSVRecord
+     */    
+    public CSVRecord immutable() {
+       if (isMutable()) {
+               // Subclass is probably CSVMutableRecord, freeze values
+               String[] frozenValue = Arrays.copyOf(values, values.length);
+               return new CSVRecord(frozenValue, mapping, comment, 
recordNumber, characterPosition);
+       } else {
+               return this;                    
+       }
+    }    
+    
+    /**
      * Checks whether a given column is mapped, i.e. its name has been defined 
to the parser.
      *
      * @param name
@@ -191,7 +216,11 @@ public class CSVRecord implements Serializable, 
Iterable<String> {
     public boolean isMapped(final String name) {
         return mapping != null && mapping.containsKey(name);
     }
-
+    
+    boolean isMutable() { 
+       return false;
+    }
+    
     /**
      * Checks whether a given columns is mapped and has a value.
      *
@@ -212,6 +241,28 @@ public class CSVRecord implements Serializable, 
Iterable<String> {
     public Iterator<String> iterator() {
         return toList().iterator();
     }
+    
+    /**
+     * Return a mutable CSVRecord.
+     * <p>
+     * Mutable records have more efficient implementations of 
+     * {@link #withValue(int, String)} and {@link #withValue(String, String)}
+     * for when multiple modifications are to be done on the same record.
+     * <p>
+     * If this record is already mutable, it will be returned directly, 
otherwise
+     * a copy of its values will be made for the new mutable record. 
+     * <p>
+     * Use {@link #immutable()} to freeze a mutable CSVRecord. 
+     * 
+     * @return A mutable CSVRecord
+     */
+    public CSVRecord mutable() {
+       if (isMutable()) {
+               return this;
+       }
+               String[] newValues = Arrays.copyOf(values, values.length);
+       return new CSVMutableRecord(newValues, mapping, comment, recordNumber, 
characterPosition);
+       }    
 
     void put(final int index, String value) {
         values[index] = value;
@@ -286,5 +337,52 @@ public class CSVRecord implements Serializable, 
Iterable<String> {
     String[] values() {
         return values;
     }
+    
+    /**
+     * Return a CSVRecord with the given column value set.
+     * 
+     * @param name
+     *            the name of the column to set.
+     * @param value
+     *                           The new value to set
+     * @throws IllegalStateException
+     *             if no header mapping was provided
+     * @throws IllegalArgumentException
+     *             if {@code name} is not mapped or if the record is 
inconsistent
+     * @return A mutated CSVRecord
+     */
+    public CSVRecord withValue(String name, String value) {            
+       CSVRecord r = mutable();
+       r.put(name,  value);
+       return r;
+    }
+
+    /**
+     * Return a CSVRecord with the given column value set.
+     * 
+     * @param index
+     *            the column to be retrieved.
+     * @param value
+     *                           The new value to set
+     * @return A mutated CSVRecord
+     */    
+    public CSVRecord withValue(int index, String value) {
+       CSVRecord r = mutable();
+       r.put(index,  value);
+       return r;
+    }
+    
+    /**
+     * Return a CSVRecord with the given comment set.
+     * 
+     * @param comment
+     *                         the comment to set, or <code>null</code> for no 
comment.
+     * @return A mutated CSVRecord
+     */
+    public CSVRecord withComment(String comment) {
+       CSVRecord r = mutable();
+       r.comment = comment;
+       return r;
+    }
 
 }

Reply via email to