METAMODEL-244: Refactored fixedwidth module a bit and added strategies
authorkaspersorensen <i.am.kasper.sorensen@gmail.com>
Fri, 22 Apr 2016 22:50:06 +0000 (15:50 -0700)
committerkaspersorensen <i.am.kasper.sorensen@gmail.com>
Fri, 22 Apr 2016 22:50:06 +0000 (15:50 -0700)
core/src/main/java/org/apache/metamodel/schema/builder/AlphabeticColumnNamingStrategy.java
core/src/main/java/org/apache/metamodel/schema/builder/ColumnNamingStrategy.java
core/src/main/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategy.java [new file with mode: 0644]
core/src/main/java/org/apache/metamodel/schema/builder/DelegatingIntrinsicSwitchColumnNamingStrategy.java [new file with mode: 0644]
core/src/main/java/org/apache/metamodel/schema/builder/UniqueColumnNamingStrategy.java [new file with mode: 0644]
fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthDataContext.java

index 284e851..83679a3 100644 (file)
@@ -21,16 +21,12 @@ package org.apache.metamodel.schema.builder;
 import org.apache.metamodel.util.AlphabeticSequence;\r
 \r
 public class AlphabeticColumnNamingStrategy implements ColumnNamingStrategy {\r
+    \r
+    private final AlphabeticSequence seq = new AlphabeticSequence();\r
 \r
     @Override\r
-    public String getColumnName(ColumnNamingContext ctx) {\r
-        final int columnIndex = ctx.getColumnIndex();\r
-        final AlphabeticSequence seq = new AlphabeticSequence("A");\r
-        // naive way to get to the right value is to iterate - to be optimized\r
-        for (int i = 0; i < columnIndex; i++) {\r
-            seq.next();\r
-        }\r
-        return seq.current();\r
+    public String getNextColumnName(ColumnNamingContext ctx) {\r
+        return seq.next();\r
     }\r
 \r
 }\r
index 626daaf..4923c58 100644 (file)
@@ -33,5 +33,5 @@ public interface ColumnNamingStrategy {
      *            column index, intrinsic name etc. if available.\r
      * @return the name to provide to the column.\r
      */\r
-    public String getColumnName(ColumnNamingContext ctx);\r
+    public String getNextColumnName(ColumnNamingContext ctx);\r
 }\r
diff --git a/core/src/main/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategy.java b/core/src/main/java/org/apache/metamodel/schema/builder/DefaultColumnNamingStrategy.java
new file mode 100644 (file)
index 0000000..9aef863
--- /dev/null
@@ -0,0 +1,31 @@
+/**\r
+ * Licensed to the Apache Software Foundation (ASF) under one\r
+ * or more contributor license agreements.  See the NOTICE file\r
+ * distributed with this work for additional information\r
+ * regarding copyright ownership.  The ASF licenses this file\r
+ * to you under the Apache License, Version 2.0 (the\r
+ * "License"); you may not use this file except in compliance\r
+ * with the License.  You may obtain a copy of the License at\r
+ *\r
+ *   http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing,\r
+ * software distributed under the License is distributed on an\r
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
+ * KIND, either express or implied.  See the License for the\r
+ * specific language governing permissions and limitations\r
+ * under the License.\r
+ */\r
+package org.apache.metamodel.schema.builder;\r
+\r
+/**\r
+ * The default (in most cases) {@link ColumnNamingStrategy} to use when no other\r
+ * strategy is specified.\r
+ */\r
+public class DefaultColumnNamingStrategy extends DelegatingIntrinsicSwitchColumnNamingStrategy {\r
+\r
+    public DefaultColumnNamingStrategy() {\r
+        super(new UniqueColumnNamingStrategy(), new AlphabeticColumnNamingStrategy());\r
+    }\r
+\r
+}\r
diff --git a/core/src/main/java/org/apache/metamodel/schema/builder/DelegatingIntrinsicSwitchColumnNamingStrategy.java b/core/src/main/java/org/apache/metamodel/schema/builder/DelegatingIntrinsicSwitchColumnNamingStrategy.java
new file mode 100644 (file)
index 0000000..99cdaf5
--- /dev/null
@@ -0,0 +1,46 @@
+/**\r
+ * Licensed to the Apache Software Foundation (ASF) under one\r
+ * or more contributor license agreements.  See the NOTICE file\r
+ * distributed with this work for additional information\r
+ * regarding copyright ownership.  The ASF licenses this file\r
+ * to you under the Apache License, Version 2.0 (the\r
+ * "License"); you may not use this file except in compliance\r
+ * with the License.  You may obtain a copy of the License at\r
+ *\r
+ *   http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing,\r
+ * software distributed under the License is distributed on an\r
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
+ * KIND, either express or implied.  See the License for the\r
+ * specific language governing permissions and limitations\r
+ * under the License.\r
+ */\r
+package org.apache.metamodel.schema.builder;\r
+\r
+/**\r
+ * A {@link ColumnNamingStrategy} that switches between two other\r
+ * {@link ColumnNamingStrategy} delegates depending on the availability of a\r
+ * intrinsic column name.\r
+ */\r
+public class DelegatingIntrinsicSwitchColumnNamingStrategy implements ColumnNamingStrategy {\r
+\r
+    private final ColumnNamingStrategy intrinsicStrategy;\r
+    private final ColumnNamingStrategy nonIntrinsicStrategy;\r
+\r
+    public DelegatingIntrinsicSwitchColumnNamingStrategy(ColumnNamingStrategy intrinsicStrategy,\r
+            ColumnNamingStrategy nonIntrinsicStrategy) {\r
+        this.intrinsicStrategy = intrinsicStrategy;\r
+        this.nonIntrinsicStrategy = nonIntrinsicStrategy;\r
+    }\r
+\r
+    @Override\r
+    public String getNextColumnName(ColumnNamingContext ctx) {\r
+        final String intrinsicColumnName = ctx.getIntrinsicColumnName();\r
+        if (intrinsicColumnName == null || intrinsicColumnName.isEmpty()) {\r
+            return nonIntrinsicStrategy.getNextColumnName(ctx);\r
+        }\r
+        return intrinsicStrategy.getNextColumnName(ctx);\r
+    }\r
+\r
+}\r
diff --git a/core/src/main/java/org/apache/metamodel/schema/builder/UniqueColumnNamingStrategy.java b/core/src/main/java/org/apache/metamodel/schema/builder/UniqueColumnNamingStrategy.java
new file mode 100644 (file)
index 0000000..9371059
--- /dev/null
@@ -0,0 +1,50 @@
+/**\r
+ * Licensed to the Apache Software Foundation (ASF) under one\r
+ * or more contributor license agreements.  See the NOTICE file\r
+ * distributed with this work for additional information\r
+ * regarding copyright ownership.  The ASF licenses this file\r
+ * to you under the Apache License, Version 2.0 (the\r
+ * "License"); you may not use this file except in compliance\r
+ * with the License.  You may obtain a copy of the License at\r
+ *\r
+ *   http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing,\r
+ * software distributed under the License is distributed on an\r
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r
+ * KIND, either express or implied.  See the License for the\r
+ * specific language governing permissions and limitations\r
+ * under the License.\r
+ */\r
+package org.apache.metamodel.schema.builder;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+/**\r
+ * A {@link ColumnNamingStrategy} that uses the intrinsic column names, but\r
+ * ensures that all column names are unique. When duplicate names are\r
+ * encountered a number will be appended yielding column names like "name",\r
+ * "name1", "name2" etc.\r
+ */\r
+public class UniqueColumnNamingStrategy implements ColumnNamingStrategy {\r
+\r
+    private final Set<String> names = new HashSet<>();\r
+\r
+    @Override\r
+    public String getNextColumnName(ColumnNamingContext ctx) {\r
+        final String intrinsicName = ctx.getIntrinsicColumnName();\r
+        boolean unique = names.add(intrinsicName);\r
+        if (unique) {\r
+            return intrinsicName;\r
+        }\r
+\r
+        String newName = null;\r
+        for (int i = 2; !unique; i++) {\r
+            newName = intrinsicName + i;\r
+            unique = names.add(newName);\r
+        }\r
+        return newName;\r
+    }\r
+\r
+}\r
index 3b90b32..6538f5c 100644 (file)
@@ -23,8 +23,8 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.metamodel.data.DataSet;
-import org.apache.metamodel.schema.builder.AlphabeticColumnNamingStrategy;
 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;
 
@@ -96,7 +96,7 @@ public final class FixedWidthConfiguration extends BaseObject implements
         */
        public ColumnNamingStrategy getColumnNamingStrategy() {
            if (columnNamingStrategy == null) {
-               return new AlphabeticColumnNamingStrategy();
+               return new DefaultColumnNamingStrategy();
            }
         return columnNamingStrategy;
     }
index fcc31ed..0a326cc 100644 (file)
@@ -122,19 +122,22 @@ public class FixedWidthDataContext extends QueryPostprocessDataContext {
         final FixedWidthReader reader = createReader();
         final String[] columnNames;
         try {
-            if (_configuration.getColumnNameLineNumber() != FixedWidthConfiguration.NO_COLUMN_NAME_LINE) {
+            final boolean hasColumnHeader = _configuration
+                    .getColumnNameLineNumber() != FixedWidthConfiguration.NO_COLUMN_NAME_LINE;
+            if (hasColumnHeader) {
                 for (int i = 1; i < _configuration.getColumnNameLineNumber(); i++) {
                     reader.readLine();
                 }
                 columnNames = reader.readLine();
             } else {
-                final ColumnNamingStrategy columnNamingStrategy = _configuration.getColumnNamingStrategy();
                 columnNames = reader.readLine();
-                if (columnNames != null) {
-                    for (int i = 0; i < columnNames.length; i++) {
-                        columnNames[i] = columnNamingStrategy.getColumnName(new ColumnNamingContextImpl(table, null,
-                                i));
-                    }
+            }
+            final ColumnNamingStrategy columnNamingStrategy = _configuration.getColumnNamingStrategy();
+            if (columnNames != null) {
+                for (int i = 0; i < columnNames.length; i++) {
+                    final String intrinsicColumnName = hasColumnHeader ? columnNames[i] : null;
+                    columnNames[i] = columnNamingStrategy.getNextColumnName(new ColumnNamingContextImpl(table,
+                            intrinsicColumnName, i));
                 }
             }
         } finally {