METAMODEL-244: Implemented naming strategy support in csv module
authorKasper Sørensen <i.am.kasper.sorensen@gmail.com>
Sun, 24 Apr 2016 20:48:28 +0000 (13:48 -0700)
committerKasper Sørensen <i.am.kasper.sorensen@gmail.com>
Sun, 24 Apr 2016 20:48:28 +0000 (13:48 -0700)
core/src/main/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategy.java
core/src/test/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategyTest.java [new file with mode: 0644]
csv/src/main/java/org/apache/metamodel/csv/CsvConfiguration.java
csv/src/main/java/org/apache/metamodel/csv/CsvTable.java
fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java

index 9aef863..2cc9fb7 100644 (file)
@@ -24,6 +24,8 @@ package org.apache.metamodel.schema.builder;
  */\r
 public class DefaultColumnNamingStrategy extends DelegatingIntrinsicSwitchColumnNamingStrategy {\r
 \r
+    private static final long serialVersionUID = 1L;\r
+\r
     public DefaultColumnNamingStrategy() {\r
         super(new UniqueColumnNamingStrategy(), new AlphabeticColumnNamingStrategy());\r
     }\r
diff --git a/core/src/test/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategyTest.java b/core/src/test/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategyTest.java
new file mode 100644 (file)
index 0000000..b903065
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * 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.metamodel.schema.builder;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class DefaultColumnNamingStrategyTest {
+
+    private final DefaultColumnNamingStrategy namingStrategy = new DefaultColumnNamingStrategy();
+
+    @Test
+    public void testDuplicateColumnNames() throws Exception {
+        try (final ColumnNamingSession session = namingStrategy.startColumnNamingSession()) {
+            assertEquals("foo", session.getNextColumnName(new ColumnNamingContextImpl(null, "foo", 0)));
+            assertEquals("bar", session.getNextColumnName(new ColumnNamingContextImpl(null, "bar", 1)));
+            assertEquals("foo2", session.getNextColumnName(new ColumnNamingContextImpl(null, "foo", 2)));
+        }
+    }
+
+    @Test
+    public void testNoIntrinsicColumnNames() throws Exception {
+        try (final ColumnNamingSession session = namingStrategy.startColumnNamingSession()) {
+            assertEquals("A", session.getNextColumnName(new ColumnNamingContextImpl(null, "", 0)));
+            assertEquals("B", session.getNextColumnName(new ColumnNamingContextImpl(null, null, 1)));
+            assertEquals("C", session.getNextColumnName(new ColumnNamingContextImpl(null, "", 2)));
+        }
+    }
+}
index d45709c..4d1874c 100644 (file)
@@ -21,6 +21,8 @@ package org.apache.metamodel.csv;
 import java.io.Serializable;
 import java.util.List;
 
+import org.apache.metamodel.schema.builder.ColumnNamingStrategy;
+import org.apache.metamodel.schema.builder.DefaultColumnNamingStrategy;
 import org.apache.metamodel.util.BaseObject;
 import org.apache.metamodel.util.FileHelper;
 
@@ -50,6 +52,7 @@ public final class CsvConfiguration extends BaseObject implements Serializable {
     private final char escapeChar;
     private final boolean failOnInconsistentRowLength;
     private final boolean multilineValues;
+    private final ColumnNamingStrategy columnNamingStrategy;
 
     public CsvConfiguration() {
         this(DEFAULT_COLUMN_NAME_LINE);
@@ -74,9 +77,16 @@ public final class CsvConfiguration extends BaseObject implements Serializable {
             char escapeChar, boolean failOnInconsistentRowLength) {
         this(columnNameLineNumber, encoding, separatorChar, quoteChar, escapeChar, failOnInconsistentRowLength, true);
     }
-
+    
     public CsvConfiguration(int columnNameLineNumber, String encoding, char separatorChar, char quoteChar,
             char escapeChar, boolean failOnInconsistentRowLength, boolean multilineValues) {
+        this(columnNameLineNumber, null, encoding, separatorChar, quoteChar, escapeChar, failOnInconsistentRowLength,
+                multilineValues);
+    }
+
+    public CsvConfiguration(int columnNameLineNumber, ColumnNamingStrategy columnNamingStrategy, String encoding,
+            char separatorChar, char quoteChar, char escapeChar, boolean failOnInconsistentRowLength,
+            boolean multilineValues) {
         this.columnNameLineNumber = columnNameLineNumber;
         this.encoding = encoding;
         this.separatorChar = separatorChar;
@@ -84,6 +94,18 @@ public final class CsvConfiguration extends BaseObject implements Serializable {
         this.escapeChar = escapeChar;
         this.failOnInconsistentRowLength = failOnInconsistentRowLength;
         this.multilineValues = multilineValues;
+        this.columnNamingStrategy = null;
+    }
+    
+    /**
+     * Gets a {@link ColumnNamingStrategy} to use if needed.
+     * @return
+     */
+    public ColumnNamingStrategy getColumnNamingStrategy() {
+        if (columnNamingStrategy == null) {
+            return new DefaultColumnNamingStrategy();
+        }
+        return columnNamingStrategy;
     }
 
     /**
index b5ae485..e2a665d 100644 (file)
@@ -27,7 +27,9 @@ import org.apache.metamodel.schema.MutableColumn;
 import org.apache.metamodel.schema.Relationship;
 import org.apache.metamodel.schema.Schema;
 import org.apache.metamodel.schema.TableType;
-import org.apache.metamodel.util.AlphabeticSequence;
+import org.apache.metamodel.schema.builder.ColumnNamingContextImpl;
+import org.apache.metamodel.schema.builder.ColumnNamingSession;
+import org.apache.metamodel.schema.builder.ColumnNamingStrategy;
 import org.apache.metamodel.util.FileHelper;
 
 import au.com.bytecode.opencsv.CSVReader;
@@ -109,23 +111,23 @@ final class CsvTable extends AbstractTable {
         if (columnNames == null) {
             return new Column[0];
         }
-
+        
         final CsvConfiguration configuration = _schema.getDataContext().getConfiguration();
         final int columnNameLineNumber = configuration.getColumnNameLineNumber();
         final boolean nullable = !configuration.isFailOnInconsistentRowLength();
+        final ColumnNamingStrategy columnNamingStrategy = configuration.getColumnNamingStrategy();
 
         final Column[] columns = new Column[columnNames.length];
-        final AlphabeticSequence sequence = new AlphabeticSequence();
-        for (int i = 0; i < columnNames.length; i++) {
-            final String columnName;
-            if (columnNameLineNumber == CsvConfiguration.NO_COLUMN_NAME_LINE) {
-                columnName = sequence.next();
-            } else {
-                columnName = columnNames[i];
+        try (final ColumnNamingSession namingSession = columnNamingStrategy.startColumnNamingSession()) {
+            for (int i = 0; i < columnNames.length; i++) {
+                final String intrinsicColumnName = columnNameLineNumber == CsvConfiguration.NO_COLUMN_NAME_LINE ? null
+                        : columnNames[i];
+                final String columnName = namingSession.getNextColumnName(new ColumnNamingContextImpl(this,
+                        intrinsicColumnName, i));
+                final Column column = new MutableColumn(columnName, ColumnType.STRING, this, i, null, null, nullable,
+                        null, false, null);
+                columns[i] = column;
             }
-            Column column = new MutableColumn(columnName, ColumnType.STRING, this, i, null, null, nullable, null,
-                    false, null);
-            columns[i] = column;
         }
         return columns;
     }
index 6538f5c..9c0dd46 100644 (file)
@@ -56,30 +56,34 @@ public final class FixedWidthConfiguration extends BaseObject implements
                                false);
        }
 
-       public FixedWidthConfiguration(int columnNameLineNumber, String encoding,
-                       int fixedValueWidth) {
-               this(columnNameLineNumber, encoding, fixedValueWidth, false);
-       }
+    public FixedWidthConfiguration(int columnNameLineNumber, String encoding, int fixedValueWidth) {
+        this(columnNameLineNumber, encoding, fixedValueWidth, false);
+    }
 
-       public FixedWidthConfiguration(int columnNameLineNumber, String encoding,
-                       int fixedValueWidth, boolean failOnInconsistentLineWidth) {
-               this.encoding = encoding;
-               this.fixedValueWidth = fixedValueWidth;
-               this.columnNameLineNumber = columnNameLineNumber;
-               this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;
-               this.columnNamingStrategy = null;
-               this.valueWidths = new int[0];
-       }
+    public FixedWidthConfiguration(int columnNameLineNumber, String encoding, int fixedValueWidth,
+            boolean failOnInconsistentLineWidth) {
+        this.encoding = encoding;
+        this.fixedValueWidth = fixedValueWidth;
+        this.columnNameLineNumber = columnNameLineNumber;
+        this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;
+        this.columnNamingStrategy = null;
+        this.valueWidths = new int[0];
+    }
 
-       public FixedWidthConfiguration(int columnNameLineNumber, String encoding,
-                       int[] valueWidths, boolean failOnInconsistentLineWidth) {
-               this.encoding = encoding;
-               this.fixedValueWidth = -1;
-               this.columnNameLineNumber = columnNameLineNumber;
-               this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;
-               this.columnNamingStrategy = null;
-               this.valueWidths = valueWidths;
-       }
+    public FixedWidthConfiguration(int columnNameLineNumber, String encoding,
+            int[] valueWidths, boolean failOnInconsistentLineWidth) {
+        this(columnNameLineNumber, null, encoding, valueWidths, failOnInconsistentLineWidth);
+    }
+    
+    public FixedWidthConfiguration(int columnNameLineNumber, ColumnNamingStrategy columnNamingStrategy, String encoding,
+            int[] valueWidths, boolean failOnInconsistentLineWidth) {
+        this.encoding = encoding;
+        this.fixedValueWidth = -1;
+        this.columnNameLineNumber = columnNameLineNumber;
+        this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;
+        this.columnNamingStrategy = columnNamingStrategy;
+        this.valueWidths = valueWidths;
+    }
 
        /**
         * The line number (1 based) from which to get the names of the columns.