METAMODEL-247: Fixed
authorkaspersorensen <i.am.kasper.sorensen@gmail.com>
Thu, 28 Apr 2016 23:39:41 +0000 (16:39 -0700)
committerkaspersorensen <i.am.kasper.sorensen@gmail.com>
Thu, 28 Apr 2016 23:39:41 +0000 (16:39 -0700)
Closes #97

CHANGES.md
core/src/main/java/org/apache/metamodel/schema/naming/ColumnNamingStrategies.java
core/src/main/java/org/apache/metamodel/schema/naming/CustomColumnNamingStrategy.java [new file with mode: 0644]
fixedwidth/pom.xml
fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthColumnSpec.java [new file with mode: 0644]
fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java [new file with mode: 0644]
fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java [new file with mode: 0644]
fixedwidth/src/test/resources/metadata_spec1/data.txt [new file with mode: 0644]
fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt [new file with mode: 0644]
fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt [new file with mode: 0644]

index 4356071..dd03195 100644 (file)
-### Apache MetaModel 4.5.3 (work in progress)
-
- * [METAMODEL-235] - Fixed a bug related to handling of null or missing values in ElasticSearch using REST client.
- * [METAMODEL-225] - Fixed support for nested objects and arrays in ElasticSearch using REST client.
- * [METAMODEL-244] - Added ColumnNamingStrategies concept which allows custom column naming and column name overriding.
- * [METAMODEL-242] - Fixed issue when de-serializing old enum-instances of FunctionType.
-
-### Apache MetaModel 4.5.2
-
- * [METAMODEL-236] - Made OperatorType and FunctionType Serializable to ensure that serialization of Query is possible.
-
-### Apache MetaModel 4.5.1
-
- * [METAMODEL-227] - Fix for respecting CSV escape character also when no quote character is set.
- * [METAMODEL-183] - MongoDB module split into three: common, Mongo2 and Mongo3 to allow use of either old or new MongoDB API.
- * [METAMODEL-231] - Fixed a bug causing the Neo4j to represent the same table multiple times within a schema.
- * [METAMODEL-228] - Fixed a bug causing Number.class to not be converted to ColumnType.NUMBER.
-
-### Apache MetaModel 4.5.0
-
- * [METAMODEL-212] - New module for ElasticSearch via REST client.
- * [METAMODEL-99] - New module for Neo4j connectivity with MetaModel.
- * [METAMODEL-207] - Ensured the serializability of the SingleLineCsvRow class.
- * [METAMODEL-211] - Fixed a bug related to lookup by primary key (_id) on MongoDB.
- * [METAMODEL-216] - Added new aggregate functions: FIRST, LAST and RANDOM.
- * [METAMODEL-195] - Added new function MAP_VALUE which allows extracting a nested value from within a key/value map field.
- * [METAMODEL-15] - Query parser support for table names with space. Delimitters can be double quote or square brackets. 
- * [METAMODEL-215] - Improved the capability of NumberComparator to support Integer, Long, Double, BigInteger and other built-in Number classes.
- * [METAMODEL-218] - Fixed conversion of STRING and NUMBER types to database-specific types in JDBC module.
- * [METAMODEL-205] - Added validation of Excel sheet name before attempting to create table (sheet).
- * [METAMODEL-219] - Made HdfsResource capable of incorporating Hadoop configuration files core-site.xml and hdfs-site.xml
- * [METAMODEL-220] - Made HdfsResource capable of working with other URI schemes than 'hdfs'.
-
-### Apache MetaModel 4.4.1
-
- * [METAMODEL-198] - Fixed support for JDBC TIMESTAMP precision to match the underlying database's precision.
- * [METAMODEL-200] - Added optional "APPROXIMATE" keyword to query syntax for aggregate functions.
- * [METAMODEL-144] - Automated binary packaging of the MetaModel project.
- * [METAMODEL-197] - ElasticSearch schema update/change after CREATE TABLE statements.
- * [METAMODEL-199] - Fixed a bug in query parser when parsing two consecutive WHERE items with parentheses around them.
- * [METAMODEL-203] - Upgraded MongoDB dependency version and API to the 3.x line.
-
-### Apache MetaModel 4.4.0
-
- * [METAMODEL-192] - Added support for Scalar functions. We have a basic set of datatype conversion functions as well as support for UDF via implementing the ScalarFunction interface.
- * [METAMODEL-194] - Added support for setting the "Max rows" flag of a query to 0. This will always return an empty dataset.
- * [METAMODEL-173] - Improved CSV writing to non-file destinations. Added .write() and .append() methods to Resource interface.
- * [METAMODEL-170] - Dropped support for Java 6.
- * [METAMODEL-176] - Trimmed the transient dependencies of the JDBC module.
- * [METAMODEL-178] - Added AggregateFunction and ScalarFunction interfaces. Changed FunctionType enum to be super-interface of those. Compatibility is retained but a recompile of code using FunctionType is needed.
- * [METAMODEL-188] - Changed OperatorType enum to be an interface. Compatibility is retained but a recompile of code is needed.
- * [METAMODEL-179] - Ensured that HdfsResource is not closing a shared HDFS file system reference.
- * [METAMODEL-171] - Made integration tests for Cassandra module function properly in all environments.
- * [METAMODEL-177] - Fixed a bug pertaining to the serializability of HdfsResource.
- * [METAMODEL-172] - ElasticSearch Date types should be converted properly.
- * [METAMODEL-184] - ElasticSearch querying with "IS NULL" and "IS NOT NULL" now uses MissingFilter and ExistsFilter.
- * [METAMODEL-190] - Improved decimal number support in Excel module.
- * [METAMODEL-187] - Improved memory consumption of Excel module by passing random-access-file handles to POI when possible.
- * [METAMODEL-191] - Resolved a number of dependency conflicts/overlaps when combining multiple MetaModel modules.
- * [METAMODEL-157] - Fixed an issue in DELETE FROM statements with WHERE clauses requiring client-side data type conversion on JDBC databases.
- * [METAMODEL-182] - Improved HdfsResource and FileResource directory-based implementations by adding also getSize() and getLastModified() directory-based implementations.
-
-### Apache MetaModel 4.3.6
-
- * [METAMODEL-161] - Upgraded HBase client API to version 1.1.1
- * [METAMODEL-160] - Added support for Apache Hive via the JDBC module of MetaModel.
- * [METAMODEL-162] - Made HdfsResource Serializable and added property getters
- * [METAMODEL-163] - Made FileResource and HdfsResource work with folders containing file chunks instead of only single files
- * [METAMODEL-104] - Added 'hadoop' and 'hbase' modules to dependencies of 'MetaModel-full'.
- * [METAMODEL-164] - Fixed a bug in data type parsing of ElasticSearch mapping document.
-
-### Apache MetaModel 4.3.5
-
- * [METAMODEL-148] - Added a 'hadoop' module with a HdfsResource class to allow CSV, Excel and Fixed-width file access on HDFS.
- * [METAMODEL-152] - Fixed an issue of not clearing schema cache when refreshSchemas() is invoked.
- * [METAMODEL-149] - Added support for COUNTER data type in Cassandra.
- * [METAMODEL-151] - Added support for DOUBLE data type mapping in PostgreSQL
- * [METAMODEL-154] - Use embedded Cassandra server for integration tests.
-
-### Apache MetaModel 4.3.4
-
- * [METAMODEL-136] - Added LIKE operator native support (using conversion to regex) for MongoDB.
- * [METAMODEL-138] - Allow empty characters before AS keyword in query parsing.
- * [METAMODEL-141] - Improved mapping of ColumnType to SQL data types for Oracle, SQL Server, MySQL, DB2 and PostgreSQL
- * [METAMODEL-142] - Ensured that JDBC schema refreshes in an UpdateScript is using same Connection/Transaction as rest of operations
- * [METAMODEL-133] - Improved query parser support for multiple JOINs in same query.
- * [METAMODEL-140] - Fixed support for ElasticSearch mappings with additional property attributes.
-
-### Apache MetaModel 4.3.3
-
- * [METAMODEL-123] - Added compatibility with ElasticSearch version 1.4.x
- * [METAMODEL-93] - Added compatibility with Apache HBase version 1.0.0
- * [METAMODEL-124] - Invoked ElasticSearch cross-version incompatible methods via reflection
- * [METAMODEL-125] - Added support for comma-separated select items in Query.select(String) method argument.
- * [METAMODEL-128] - Fixed bug in DataSet ordering when aggregation functions are applied to non-JDBC modules.
- * [METAMODEL-131] - Added support for composite primary keys in JDBC CREATE TABLE statements.
-
-### Apache MetaModel 4.3.2
-
- * [METAMODEL-78] - Fixed a bug that caused SELECT DISTINCT to sometimes return duplicates records on certain DataContext implementations.
- * [METAMODEL-106] - Improved handling of invalid or non-existing index names passed to ElasticSearchDataContext
- * [METAMODEL-79] - Added update execution support on ElasticSearch module. Increased capability of pushing down WHERE items to ElasticSearch searches.
- * [METAMODEL-115] - Improved query parsing to allow lower-case function names, operators etc.
-
-### Apache MetaModel 4.3.1
-
- * [METAMODEL-100] - Fixed bug when having multiple columns of same name. Added column no. comparison when calling Column.equals(...).
-
-### Apache MetaModel 4.3.0-incubating
-
- * [METAMODEL-77] - New module 'elasticsearch' for connecting and modeling ElasticSearch indexes through MetaModel.
- * [METAMODEL-18] - New module 'cassandra' for connecting and modelling Apache Cassandra databases through MetaModel.
- * [METAMODEL-83] - Added new operator types: GREATER_THAN_OR_EQUAL ('>=') and LESS_THAN_OR_EQUAL ('<=').
- * [METAMODEL-92] - For JSON, MongoDB and CouchDB: Made it possible to specify column names referring nested fields such as "name.first" or "addresses[0].city".
- * [METAMODEL-76] - Query parser improved to handle filters without spaces inbetween operator and operands.
- * [METAMODEL-95] - Fixed a critical bug in the Salesforce.com module which caused all number values to be interpreted as '1'.
- * [METAMODEL-74] - Fixed a bug related to skipping blank values when applying an aggregate function (SUM, AVG etc.)
- * [METAMODEL-85] - Fixed a bug that caused NULL values to be evaluated with equal-sign in JDBC update and delete statements instead of 'IS NULL'.
-### Apache MetaModel 4.2.0-incubating
-
- * [METAMODEL-38] - New module 'json' for handling json files (containing JSON arrays of documents or line-delimited JSON documents)
- * [METAMODEL-54] - ColumnType converted from enum to interface to allow for further specialization in modules.
- * [METAMODEL-57] - Changed the column type VARCHAR into STRING for the modules: CSV, Fixedwidth, Excel and XML.
- * [METAMODEL-56] - Made separate column types for converted JDBC LOBs - "CLOB as String" and "BLOB as bytes".
- * [METAMODEL-46] - Improved row-lookup by primary key (ID) in CouchDB
- * [METAMODEL-58] - Fixed a bug related to using CreateTable class and primary keys not getting created.
- * [METAMODEL-3]  - Improved writing of Byte-Order-Mark (BOM) for various encoding spelling variants.
- * [METAMODEL-70] - Made the build compatible with both JDK versions 6 and 7.
- * [METAMODEL-59] - Fixed a bug related to handling of date/time literals in MS SQL Server queries.
- * [METAMODEL-60] - Fixed a bug related to DISTINCT and TOP keywords in MS SQL Server queries.
- * [METAMODEL-45] - Improved and standardized way of handling integration test connection information towards external databases.
- * [METAMODEL-62] - Fixed a bug related to fault-tolerant handling of malformed CSV lines when reading CSVs in single-line mode
- * [METAMODEL-68] - Made it possible to create a CSV table without a header line in the file, if the user configures it.
- * [METAMODEL-67] - Upgraded Jackson (JSON library) dependency from org.codehaus namespace to the newer com.fasterxml namespace.
- * [METAMODEL-69] - Fixed issue with deserialization of ColumnType into the new interface instead of the old enum.
-
-### Apache MetaModel 4.1.0-incubating
-
- * [METAMODEL-13] - Added support for Apache HBase via the new module "MetaModel-hbase"
- * [METAMODEL-41] - Added a parser for SimpleTableDef objects (SimpleTableDefParser). It parses statements similar to CREATE TABLE statements, although without the "CREATE TABLE" prefix. For example: foo (bar INTEGER, baz VARCHAR)
- * [METAMODEL-11] - New module "MetaModel-spring" which adds a convenient FactoryBean to produce various types of DataContext objects based on externalizable parameters, for Spring framework users.
- * [METAMODEL-32] - Fixed thread-safety issue in Excel module when tables (sheets) metadata is updated.
- * [METAMODEL-47] - Fixed issue in Excel of loading schema if query is fired based on metadata from a previous DataContext instance.
- * [METAMODEL-35] - Improved query rewriting for DB2 when paged queries contain ORDER BY clause.
- * [METAMODEL-44] - Added an optional method for QueryPostprocessDataContext implementations to do a row-lookup by primary key value.
- * [METAMODEL-43] - Made CSV datastores skip empty lines in file instead of treating them of rows with null values.
- * [METAMODEL-39] - Added pooling of active/used Connections and PreparedStatements in JDBC compiled queries.
- * [METAMODEL-34] - Updated LICENSE file to not include bundled dependencies' licenses.
- * [METAMODEL-33] - Ensured that Apache Rat plugin for Maven is properly activated.
- * [METAMODEL-37] - Removed old site sources from project.
-
-### Apache MetaModel 4.0.0-incubating
-
- * [METAMODEL-9] - SalesforceDataSet is throwing exception for insert sql of record having date/time.
- * [METAMODEL-4] - Use folder name as schema name for file based DataContexts
- * [METAMODEL-5] - Faster CsvDataContext implementation for single-line values
- * [METAMODEL-26] - Provide endpoint URL with SalesforceDataContext
- * Upgraded Apache POI dependency to v. 3.9
- * Improved fluent Query builder API by adding string parameter based methods for joining tables
- * Added a utility ObjectInputStream for deserializing legacy MetaModel objects
- * Performance improvement to CSV reading when values are only single line based
- * Setting up the project on apache infrastructure
- * [METAMODEL-10] - Exclude Jackcess dependency (Access module) from MetaModel
- * Renaming the package hierarchy from org.eobjects.metamodel to org.apache.metamodel
- * [METAMODEL-29] - Fixed issue in CreateTable builder class, causing it to only support a single column definition
- * [METAMODEL-30] - Fixed issue with count(*) queries on CSV resources that does not provide a byte stream length 
+### Apache MetaModel 4.5.3 (work in progress)\r
+\r
+ * [METAMODEL-235] - Fixed a bug related to handling of null or missing values in ElasticSearch using REST client.\r
+ * [METAMODEL-225] - Fixed support for nested objects and arrays in ElasticSearch using REST client.\r
+ * [METAMODEL-244] - Added ColumnNamingStrategies concept which allows custom column naming and column name overriding.\r
+ * [METAMODEL-242] - Fixed issue when de-serializing old enum-instances of FunctionType.\r
+ * [METAMODEL-247] - Added FixedWidthConfigurationReader for reading fixed width file metadata from external files.\r
+\r
+### Apache MetaModel 4.5.2\r
+\r
+ * [METAMODEL-236] - Made OperatorType and FunctionType Serializable to ensure that serialization of Query is possible.\r
+\r
+### Apache MetaModel 4.5.1\r
+\r
+ * [METAMODEL-227] - Fix for respecting CSV escape character also when no quote character is set.\r
+ * [METAMODEL-183] - MongoDB module split into three: common, Mongo2 and Mongo3 to allow use of either old or new MongoDB API.\r
+ * [METAMODEL-231] - Fixed a bug causing the Neo4j to represent the same table multiple times within a schema.\r
+ * [METAMODEL-228] - Fixed a bug causing Number.class to not be converted to ColumnType.NUMBER.\r
+\r
+### Apache MetaModel 4.5.0\r
+\r
+ * [METAMODEL-212] - New module for ElasticSearch via REST client.\r
+ * [METAMODEL-99] - New module for Neo4j connectivity with MetaModel.\r
+ * [METAMODEL-207] - Ensured the serializability of the SingleLineCsvRow class.\r
+ * [METAMODEL-211] - Fixed a bug related to lookup by primary key (_id) on MongoDB.\r
+ * [METAMODEL-216] - Added new aggregate functions: FIRST, LAST and RANDOM.\r
+ * [METAMODEL-195] - Added new function MAP_VALUE which allows extracting a nested value from within a key/value map field.\r
+ * [METAMODEL-15] - Query parser support for table names with space. Delimitters can be double quote or square brackets. \r
+ * [METAMODEL-215] - Improved the capability of NumberComparator to support Integer, Long, Double, BigInteger and other built-in Number classes.\r
+ * [METAMODEL-218] - Fixed conversion of STRING and NUMBER types to database-specific types in JDBC module.\r
+ * [METAMODEL-205] - Added validation of Excel sheet name before attempting to create table (sheet).\r
+ * [METAMODEL-219] - Made HdfsResource capable of incorporating Hadoop configuration files core-site.xml and hdfs-site.xml\r
+ * [METAMODEL-220] - Made HdfsResource capable of working with other URI schemes than 'hdfs'.\r
+\r
+### Apache MetaModel 4.4.1\r
+\r
+ * [METAMODEL-198] - Fixed support for JDBC TIMESTAMP precision to match the underlying database's precision.\r
+ * [METAMODEL-200] - Added optional "APPROXIMATE" keyword to query syntax for aggregate functions.\r
+ * [METAMODEL-144] - Automated binary packaging of the MetaModel project.\r
+ * [METAMODEL-197] - ElasticSearch schema update/change after CREATE TABLE statements.\r
+ * [METAMODEL-199] - Fixed a bug in query parser when parsing two consecutive WHERE items with parentheses around them.\r
+ * [METAMODEL-203] - Upgraded MongoDB dependency version and API to the 3.x line.\r
+\r
+### Apache MetaModel 4.4.0\r
+\r
+ * [METAMODEL-192] - Added support for Scalar functions. We have a basic set of datatype conversion functions as well as support for UDF via implementing the ScalarFunction interface.\r
+ * [METAMODEL-194] - Added support for setting the "Max rows" flag of a query to 0. This will always return an empty dataset.\r
+ * [METAMODEL-173] - Improved CSV writing to non-file destinations. Added .write() and .append() methods to Resource interface.\r
+ * [METAMODEL-170] - Dropped support for Java 6.\r
+ * [METAMODEL-176] - Trimmed the transient dependencies of the JDBC module.\r
+ * [METAMODEL-178] - Added AggregateFunction and ScalarFunction interfaces. Changed FunctionType enum to be super-interface of those. Compatibility is retained but a recompile of code using FunctionType is needed.\r
+ * [METAMODEL-188] - Changed OperatorType enum to be an interface. Compatibility is retained but a recompile of code is needed.\r
+ * [METAMODEL-179] - Ensured that HdfsResource is not closing a shared HDFS file system reference.\r
+ * [METAMODEL-171] - Made integration tests for Cassandra module function properly in all environments.\r
+ * [METAMODEL-177] - Fixed a bug pertaining to the serializability of HdfsResource.\r
+ * [METAMODEL-172] - ElasticSearch Date types should be converted properly.\r
+ * [METAMODEL-184] - ElasticSearch querying with "IS NULL" and "IS NOT NULL" now uses MissingFilter and ExistsFilter.\r
+ * [METAMODEL-190] - Improved decimal number support in Excel module.\r
+ * [METAMODEL-187] - Improved memory consumption of Excel module by passing random-access-file handles to POI when possible.\r
+ * [METAMODEL-191] - Resolved a number of dependency conflicts/overlaps when combining multiple MetaModel modules.\r
+ * [METAMODEL-157] - Fixed an issue in DELETE FROM statements with WHERE clauses requiring client-side data type conversion on JDBC databases.\r
+ * [METAMODEL-182] - Improved HdfsResource and FileResource directory-based implementations by adding also getSize() and getLastModified() directory-based implementations.\r
+\r
+### Apache MetaModel 4.3.6\r
+\r
+ * [METAMODEL-161] - Upgraded HBase client API to version 1.1.1\r
+ * [METAMODEL-160] - Added support for Apache Hive via the JDBC module of MetaModel.\r
+ * [METAMODEL-162] - Made HdfsResource Serializable and added property getters\r
+ * [METAMODEL-163] - Made FileResource and HdfsResource work with folders containing file chunks instead of only single files\r
+ * [METAMODEL-104] - Added 'hadoop' and 'hbase' modules to dependencies of 'MetaModel-full'.\r
+ * [METAMODEL-164] - Fixed a bug in data type parsing of ElasticSearch mapping document.\r
+\r
+### Apache MetaModel 4.3.5\r
+\r
+ * [METAMODEL-148] - Added a 'hadoop' module with a HdfsResource class to allow CSV, Excel and Fixed-width file access on HDFS.\r
+ * [METAMODEL-152] - Fixed an issue of not clearing schema cache when refreshSchemas() is invoked.\r
+ * [METAMODEL-149] - Added support for COUNTER data type in Cassandra.\r
+ * [METAMODEL-151] - Added support for DOUBLE data type mapping in PostgreSQL\r
+ * [METAMODEL-154] - Use embedded Cassandra server for integration tests.\r
+\r
+### Apache MetaModel 4.3.4\r
+\r
+ * [METAMODEL-136] - Added LIKE operator native support (using conversion to regex) for MongoDB.\r
+ * [METAMODEL-138] - Allow empty characters before AS keyword in query parsing.\r
+ * [METAMODEL-141] - Improved mapping of ColumnType to SQL data types for Oracle, SQL Server, MySQL, DB2 and PostgreSQL\r
+ * [METAMODEL-142] - Ensured that JDBC schema refreshes in an UpdateScript is using same Connection/Transaction as rest of operations\r
+ * [METAMODEL-133] - Improved query parser support for multiple JOINs in same query.\r
+ * [METAMODEL-140] - Fixed support for ElasticSearch mappings with additional property attributes.\r
+\r
+### Apache MetaModel 4.3.3\r
+\r
+ * [METAMODEL-123] - Added compatibility with ElasticSearch version 1.4.x\r
+ * [METAMODEL-93] - Added compatibility with Apache HBase version 1.0.0\r
+ * [METAMODEL-124] - Invoked ElasticSearch cross-version incompatible methods via reflection\r
+ * [METAMODEL-125] - Added support for comma-separated select items in Query.select(String) method argument.\r
+ * [METAMODEL-128] - Fixed bug in DataSet ordering when aggregation functions are applied to non-JDBC modules.\r
+ * [METAMODEL-131] - Added support for composite primary keys in JDBC CREATE TABLE statements.\r
+\r
+### Apache MetaModel 4.3.2\r
+\r
+ * [METAMODEL-78] - Fixed a bug that caused SELECT DISTINCT to sometimes return duplicates records on certain DataContext implementations.\r
+ * [METAMODEL-106] - Improved handling of invalid or non-existing index names passed to ElasticSearchDataContext\r
+ * [METAMODEL-79] - Added update execution support on ElasticSearch module. Increased capability of pushing down WHERE items to ElasticSearch searches.\r
+ * [METAMODEL-115] - Improved query parsing to allow lower-case function names, operators etc.\r
+\r
+### Apache MetaModel 4.3.1\r
+\r
+ * [METAMODEL-100] - Fixed bug when having multiple columns of same name. Added column no. comparison when calling Column.equals(...).\r
+\r
+### Apache MetaModel 4.3.0-incubating\r
+\r
+ * [METAMODEL-77] - New module 'elasticsearch' for connecting and modeling ElasticSearch indexes through MetaModel.\r
+ * [METAMODEL-18] - New module 'cassandra' for connecting and modelling Apache Cassandra databases through MetaModel.\r
+ * [METAMODEL-83] - Added new operator types: GREATER_THAN_OR_EQUAL ('>=') and LESS_THAN_OR_EQUAL ('<=').\r
+ * [METAMODEL-92] - For JSON, MongoDB and CouchDB: Made it possible to specify column names referring nested fields such as "name.first" or "addresses[0].city".\r
+ * [METAMODEL-76] - Query parser improved to handle filters without spaces inbetween operator and operands.\r
+ * [METAMODEL-95] - Fixed a critical bug in the Salesforce.com module which caused all number values to be interpreted as '1'.\r
+ * [METAMODEL-74] - Fixed a bug related to skipping blank values when applying an aggregate function (SUM, AVG etc.)\r
+ * [METAMODEL-85] - Fixed a bug that caused NULL values to be evaluated with equal-sign in JDBC update and delete statements instead of 'IS NULL'.\r
\r
+### Apache MetaModel 4.2.0-incubating\r
+\r
+ * [METAMODEL-38] - New module 'json' for handling json files (containing JSON arrays of documents or line-delimited JSON documents)\r
+ * [METAMODEL-54] - ColumnType converted from enum to interface to allow for further specialization in modules.\r
+ * [METAMODEL-57] - Changed the column type VARCHAR into STRING for the modules: CSV, Fixedwidth, Excel and XML.\r
+ * [METAMODEL-56] - Made separate column types for converted JDBC LOBs - "CLOB as String" and "BLOB as bytes".\r
+ * [METAMODEL-46] - Improved row-lookup by primary key (ID) in CouchDB\r
+ * [METAMODEL-58] - Fixed a bug related to using CreateTable class and primary keys not getting created.\r
+ * [METAMODEL-3]  - Improved writing of Byte-Order-Mark (BOM) for various encoding spelling variants.\r
+ * [METAMODEL-70] - Made the build compatible with both JDK versions 6 and 7.\r
+ * [METAMODEL-59] - Fixed a bug related to handling of date/time literals in MS SQL Server queries.\r
+ * [METAMODEL-60] - Fixed a bug related to DISTINCT and TOP keywords in MS SQL Server queries.\r
+ * [METAMODEL-45] - Improved and standardized way of handling integration test connection information towards external databases.\r
+ * [METAMODEL-62] - Fixed a bug related to fault-tolerant handling of malformed CSV lines when reading CSVs in single-line mode\r
+ * [METAMODEL-68] - Made it possible to create a CSV table without a header line in the file, if the user configures it.\r
+ * [METAMODEL-67] - Upgraded Jackson (JSON library) dependency from org.codehaus namespace to the newer com.fasterxml namespace.\r
+ * [METAMODEL-69] - Fixed issue with deserialization of ColumnType into the new interface instead of the old enum.\r
+\r
+### Apache MetaModel 4.1.0-incubating\r
+\r
+ * [METAMODEL-13] - Added support for Apache HBase via the new module "MetaModel-hbase"\r
+ * [METAMODEL-41] - Added a parser for SimpleTableDef objects (SimpleTableDefParser). It parses statements similar to CREATE TABLE statements, although without the "CREATE TABLE" prefix. For example: foo (bar INTEGER, baz VARCHAR)\r
+ * [METAMODEL-11] - New module "MetaModel-spring" which adds a convenient FactoryBean to produce various types of DataContext objects based on externalizable parameters, for Spring framework users.\r
+ * [METAMODEL-32] - Fixed thread-safety issue in Excel module when tables (sheets) metadata is updated.\r
+ * [METAMODEL-47] - Fixed issue in Excel of loading schema if query is fired based on metadata from a previous DataContext instance.\r
+ * [METAMODEL-35] - Improved query rewriting for DB2 when paged queries contain ORDER BY clause.\r
+ * [METAMODEL-44] - Added an optional method for QueryPostprocessDataContext implementations to do a row-lookup by primary key value.\r
+ * [METAMODEL-43] - Made CSV datastores skip empty lines in file instead of treating them of rows with null values.\r
+ * [METAMODEL-39] - Added pooling of active/used Connections and PreparedStatements in JDBC compiled queries.\r
+ * [METAMODEL-34] - Updated LICENSE file to not include bundled dependencies' licenses.\r
+ * [METAMODEL-33] - Ensured that Apache Rat plugin for Maven is properly activated.\r
+ * [METAMODEL-37] - Removed old site sources from project.\r
+\r
+### Apache MetaModel 4.0.0-incubating\r
+\r
+ * [METAMODEL-9] - SalesforceDataSet is throwing exception for insert sql of record having date/time.\r
+ * [METAMODEL-4] - Use folder name as schema name for file based DataContexts\r
+ * [METAMODEL-5] - Faster CsvDataContext implementation for single-line values\r
+ * [METAMODEL-26] - Provide endpoint URL with SalesforceDataContext\r
+ * Upgraded Apache POI dependency to v. 3.9\r
+ * Improved fluent Query builder API by adding string parameter based methods for joining tables\r
+ * Added a utility ObjectInputStream for deserializing legacy MetaModel objects\r
+ * Performance improvement to CSV reading when values are only single line based\r
+ * Setting up the project on apache infrastructure\r
+ * [METAMODEL-10] - Exclude Jackcess dependency (Access module) from MetaModel\r
+ * Renaming the package hierarchy from org.eobjects.metamodel to org.apache.metamodel\r
+ * [METAMODEL-29] - Fixed issue in CreateTable builder class, causing it to only support a single column definition\r
+ * [METAMODEL-30] - Fixed issue with count(*) queries on CSV resources that does not provide a byte stream length \r
index de78338..0696376 100644 (file)
@@ -18,6 +18,8 @@
  */\r
 package org.apache.metamodel.schema.naming;\r
 \r
+import java.util.List;\r
+\r
 /**\r
  * Constructors and common utilities for {@link ColumnNamingStrategy} objects.\r
  */\r
@@ -32,4 +34,12 @@ public class ColumnNamingStrategies {
     public static ColumnNamingStrategy defaultStrategy() {\r
         return DEFAULT_STRATEGY;\r
     }\r
+\r
+    public static ColumnNamingStrategy customNames(List<String> columnNames) {\r
+        return new CustomColumnNamingStrategy(columnNames);\r
+    }\r
+\r
+    public static ColumnNamingStrategy customNames(String ... columnNames) {\r
+        return new CustomColumnNamingStrategy(columnNames);\r
+    }\r
 }\r
diff --git a/core/src/main/java/org/apache/metamodel/schema/naming/CustomColumnNamingStrategy.java b/core/src/main/java/org/apache/metamodel/schema/naming/CustomColumnNamingStrategy.java
new file mode 100644 (file)
index 0000000..e6cc706
--- /dev/null
@@ -0,0 +1,62 @@
+/**\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.naming;\r
+\r
+import java.util.Arrays;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+/**\r
+ * A {@link ColumnNamingStrategy} that allows the user to supply his own list of\r
+ * custom column names.\r
+ */\r
+public class CustomColumnNamingStrategy implements ColumnNamingStrategy {\r
+\r
+    private static final long serialVersionUID = 1L;\r
+\r
+    private final List<String> columnNames;\r
+\r
+    public CustomColumnNamingStrategy(List<String> columnNames) {\r
+        this.columnNames = columnNames;\r
+    }\r
+\r
+    public CustomColumnNamingStrategy(String... columnNames) {\r
+        this(Arrays.asList(columnNames));\r
+    }\r
+\r
+    @Override\r
+    public ColumnNamingSession startColumnNamingSession() {\r
+        final Iterator<String> iterator = columnNames.iterator();\r
+        return new ColumnNamingSession() {\r
+\r
+            @Override\r
+            public String getNextColumnName(ColumnNamingContext ctx) {\r
+                if (iterator.hasNext()) {\r
+                    return iterator.next();\r
+                }\r
+                return null;\r
+            }\r
+\r
+            @Override\r
+            public void close() {\r
+            }\r
+        };\r
+    }\r
+\r
+}\r
index e667a10..43e4021 100644 (file)
@@ -1,46 +1,52 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<!--
-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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-       <parent>
-               <artifactId>MetaModel</artifactId>
-               <groupId>org.apache.metamodel</groupId>
-               <version>4.5.3-SNAPSHOT</version>
-       </parent>
-       <modelVersion>4.0.0</modelVersion>
-       <artifactId>MetaModel-fixedwidth</artifactId>
-       <name>MetaModel module for fixed width value files</name>
-       <dependencies>
-               <dependency>
-                       <groupId>org.apache.metamodel</groupId>
-                       <artifactId>MetaModel-core</artifactId>
-                       <version>${project.version}</version>
-               </dependency>
-               <dependency>
-                       <groupId>org.slf4j</groupId>
-                       <artifactId>slf4j-nop</artifactId>
-                       <scope>test</scope>
-               </dependency>
-               <dependency>
-                       <groupId>junit</groupId>
-                       <artifactId>junit</artifactId>
-                       <scope>test</scope>
-               </dependency>
-       </dependencies>
-</project>
+<?xml version="1.0" encoding="UTF-8" ?>\r
+<!--\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
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">\r
+       <parent>\r
+               <artifactId>MetaModel</artifactId>\r
+               <groupId>org.apache.metamodel</groupId>\r
+               <version>4.5.3-SNAPSHOT</version>\r
+       </parent>\r
+       <modelVersion>4.0.0</modelVersion>\r
+       <artifactId>MetaModel-fixedwidth</artifactId>\r
+       <name>MetaModel module for fixed width value files</name>\r
+       <dependencies>\r
+               <dependency>\r
+                       <groupId>org.apache.metamodel</groupId>\r
+                       <artifactId>MetaModel-core</artifactId>\r
+                       <version>${project.version}</version>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.apache.metamodel</groupId>\r
+                       <artifactId>MetaModel-csv</artifactId>\r
+                       <version>${project.version}</version>\r
+                       <optional>true</optional>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>org.slf4j</groupId>\r
+                       <artifactId>slf4j-nop</artifactId>\r
+                       <scope>test</scope>\r
+               </dependency>\r
+               <dependency>\r
+                       <groupId>junit</groupId>\r
+                       <artifactId>junit</artifactId>\r
+                       <scope>test</scope>\r
+               </dependency>\r
+       </dependencies>\r
+</project>\r
diff --git a/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthColumnSpec.java b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthColumnSpec.java
new file mode 100644 (file)
index 0000000..65ec219
--- /dev/null
@@ -0,0 +1,45 @@
+/**\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.fixedwidth;\r
+\r
+import org.apache.metamodel.util.HasName;\r
+\r
+/**\r
+ * Represents the specification of a single column for a\r
+ * {@link FixedWidthDataContext}.\r
+ */\r
+public final class FixedWidthColumnSpec implements HasName {\r
+\r
+    private final String name;\r
+    private final int width;\r
+\r
+    public FixedWidthColumnSpec(String name, int width) {\r
+        this.name = name;\r
+        this.width = width;\r
+    }\r
+\r
+    @Override\r
+    public String getName() {\r
+        return name;\r
+    }\r
+\r
+    public int getWidth() {\r
+        return width;\r
+    }\r
+}\r
index 6e9f0f1..2b2cae5 100644 (file)
-/**
- * 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.fixedwidth;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.metamodel.data.DataSet;
-import org.apache.metamodel.schema.naming.ColumnNamingStrategies;
-import org.apache.metamodel.schema.naming.ColumnNamingStrategy;
-import org.apache.metamodel.util.BaseObject;
-import org.apache.metamodel.util.FileHelper;
-
-/**
- * Configuration of metadata about a fixed width values datacontext.
- */
-public final class FixedWidthConfiguration extends BaseObject implements
-               Serializable {
-
-       private static final long serialVersionUID = 1L;
-
-       public static final int NO_COLUMN_NAME_LINE = 0;
-       public static final int DEFAULT_COLUMN_NAME_LINE = 1;
-
-       private final String encoding;
-       private final int fixedValueWidth;
-       private final int[] valueWidths;
-       private final int columnNameLineNumber;
-       private final boolean failOnInconsistentLineWidth;
-       private final ColumnNamingStrategy columnNamingStrategy;
-
-       public FixedWidthConfiguration(int fixedValueWidth) {
-               this(DEFAULT_COLUMN_NAME_LINE, FileHelper.DEFAULT_ENCODING,
-                               fixedValueWidth);
-       }
-
-       public FixedWidthConfiguration(int[] valueWidth) {
-               this(DEFAULT_COLUMN_NAME_LINE, FileHelper.DEFAULT_ENCODING, valueWidth,
-                               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[] 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.
-        * 
-        * @return an int representing the line number of the column headers/names.
-        */
-       public int getColumnNameLineNumber() {
-               return columnNameLineNumber;
-       }
-       
-       /**
-        * Gets a {@link ColumnNamingStrategy} to use if needed.
-        * @return
-        */
-       public ColumnNamingStrategy getColumnNamingStrategy() {
-           if (columnNamingStrategy == null) {
-               return ColumnNamingStrategies.defaultStrategy();
-           }
-        return columnNamingStrategy;
-    }
-
-       /**
-        * Gets the file encoding to use for reading the file.
-        * 
-        * @return the text encoding to use for reading the file.
-        */
-       public String getEncoding() {
-               return encoding;
-       }
-
-       /**
-        * Gets the width of each value within the fixed width value file.
-        * 
-        * @return the fixed width to use when parsing the file.
-        */
-       public int getFixedValueWidth() {
-               return fixedValueWidth;
-       }
-
-       public int[] getValueWidths() {
-               return valueWidths;
-       }
-
-       /**
-        * Determines if the {@link DataSet#next()} should throw an exception in
-        * case of inconsistent line width in the fixed width value file.
-        * 
-        * @return a boolean indicating whether or not to fail on inconsistent line
-        *         widths.
-        */
-       public boolean isFailOnInconsistentLineWidth() {
-               return failOnInconsistentLineWidth;
-       }
-
-       @Override
-       protected void decorateIdentity(List<Object> identifiers) {
-               identifiers.add(columnNameLineNumber);
-               identifiers.add(encoding);
-               identifiers.add(fixedValueWidth);
-               identifiers.add(valueWidths);
-               identifiers.add(failOnInconsistentLineWidth);
-       }
-
-       @Override
-       public String toString() {
-               return "FixedWidthConfiguration[encoding=" + encoding
-                               + ", fixedValueWidth=" + fixedValueWidth + ", valueWidths="
-                               + Arrays.toString(valueWidths) + ", columnNameLineNumber="
-                               + columnNameLineNumber + ", failOnInconsistentLineWidth="
-                               + failOnInconsistentLineWidth + "]";
-       }
-
-       public boolean isConstantValueWidth() {
-               return fixedValueWidth != -1;
-       }
-
-       public int getValueWidth(int columnIndex) {
-               if (isConstantValueWidth()) {
-                       return fixedValueWidth;
-               }
-               return valueWidths[columnIndex];
-       }
-}
+/**\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.fixedwidth;\r
+\r
+import java.io.Serializable;\r
+import java.util.Arrays;\r
+import java.util.List;\r
+\r
+import org.apache.metamodel.data.DataSet;\r
+import org.apache.metamodel.schema.naming.ColumnNamingStrategies;\r
+import org.apache.metamodel.schema.naming.ColumnNamingStrategy;\r
+import org.apache.metamodel.util.BaseObject;\r
+import org.apache.metamodel.util.CollectionUtils;\r
+import org.apache.metamodel.util.FileHelper;\r
+import org.apache.metamodel.util.HasNameMapper;\r
+\r
+/**\r
+ * Configuration of metadata about a fixed width values datacontext.\r
+ */\r
+public final class FixedWidthConfiguration extends BaseObject implements\r
+               Serializable {\r
+\r
+       private static final long serialVersionUID = 1L;\r
+\r
+       public static final int NO_COLUMN_NAME_LINE = 0;\r
+       public static final int DEFAULT_COLUMN_NAME_LINE = 1;\r
+\r
+       private final String encoding;\r
+       private final int fixedValueWidth;\r
+       private final int[] valueWidths;\r
+       private final int columnNameLineNumber;\r
+       private final boolean failOnInconsistentLineWidth;\r
+       private final ColumnNamingStrategy columnNamingStrategy;\r
+\r
+       public FixedWidthConfiguration(int fixedValueWidth) {\r
+               this(DEFAULT_COLUMN_NAME_LINE, FileHelper.DEFAULT_ENCODING,\r
+                               fixedValueWidth);\r
+       }\r
+\r
+       public FixedWidthConfiguration(int[] valueWidth) {\r
+               this(DEFAULT_COLUMN_NAME_LINE, FileHelper.DEFAULT_ENCODING, valueWidth,\r
+                               false);\r
+       }\r
+\r
+    public FixedWidthConfiguration(int columnNameLineNumber, String encoding, int fixedValueWidth) {\r
+        this(columnNameLineNumber, encoding, fixedValueWidth, false);\r
+    }\r
+\r
+    public FixedWidthConfiguration(int columnNameLineNumber, String encoding, int fixedValueWidth,\r
+            boolean failOnInconsistentLineWidth) {\r
+        this.encoding = encoding;\r
+        this.fixedValueWidth = fixedValueWidth;\r
+        this.columnNameLineNumber = columnNameLineNumber;\r
+        this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;\r
+        this.columnNamingStrategy = null;\r
+        this.valueWidths = new int[0];\r
+    }\r
+\r
+    public FixedWidthConfiguration(int columnNameLineNumber, String encoding,\r
+            int[] valueWidths, boolean failOnInconsistentLineWidth) {\r
+        this(columnNameLineNumber, null, encoding, valueWidths, failOnInconsistentLineWidth);\r
+    }\r
+    \r
+    public FixedWidthConfiguration(int columnNameLineNumber, ColumnNamingStrategy columnNamingStrategy, String encoding,\r
+            int[] valueWidths, boolean failOnInconsistentLineWidth) {\r
+        this.encoding = encoding;\r
+        this.fixedValueWidth = -1;\r
+        this.columnNameLineNumber = columnNameLineNumber;\r
+        this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;\r
+        this.columnNamingStrategy = columnNamingStrategy;\r
+        this.valueWidths = valueWidths;\r
+    }\r
+    \r
+    public FixedWidthConfiguration(String encoding, List<FixedWidthColumnSpec> columnSpecs) {\r
+        this(encoding, columnSpecs, false);\r
+    }\r
+\r
+    public FixedWidthConfiguration(String encoding, List<FixedWidthColumnSpec> columnSpecs,\r
+            boolean failOnInconsistentLineWidth) {\r
+        this.encoding = encoding;\r
+        this.fixedValueWidth = -1;\r
+        this.columnNameLineNumber = NO_COLUMN_NAME_LINE;\r
+        this.columnNamingStrategy = ColumnNamingStrategies.customNames(CollectionUtils.map(columnSpecs,\r
+                new HasNameMapper()));\r
+        this.valueWidths = new int[columnSpecs.size()];\r
+        for (int i = 0; i < valueWidths.length; i++) {\r
+            valueWidths[i] = columnSpecs.get(i).getWidth();\r
+        }\r
+        this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;\r
+    }\r
+\r
+    /**\r
+        * The line number (1 based) from which to get the names of the columns.\r
+        * \r
+        * @return an int representing the line number of the column headers/names.\r
+        */\r
+       public int getColumnNameLineNumber() {\r
+               return columnNameLineNumber;\r
+       }\r
+       \r
+       /**\r
+        * Gets a {@link ColumnNamingStrategy} to use if needed.\r
+        * @return\r
+        */\r
+       public ColumnNamingStrategy getColumnNamingStrategy() {\r
+           if (columnNamingStrategy == null) {\r
+               return ColumnNamingStrategies.defaultStrategy();\r
+           }\r
+        return columnNamingStrategy;\r
+    }\r
+\r
+       /**\r
+        * Gets the file encoding to use for reading the file.\r
+        * \r
+        * @return the text encoding to use for reading the file.\r
+        */\r
+       public String getEncoding() {\r
+               return encoding;\r
+       }\r
+\r
+       /**\r
+        * Gets the width of each value within the fixed width value file.\r
+        * \r
+        * @return the fixed width to use when parsing the file.\r
+        */\r
+       public int getFixedValueWidth() {\r
+               return fixedValueWidth;\r
+       }\r
+\r
+       public int[] getValueWidths() {\r
+               return valueWidths;\r
+       }\r
+\r
+       /**\r
+        * Determines if the {@link DataSet#next()} should throw an exception in\r
+        * case of inconsistent line width in the fixed width value file.\r
+        * \r
+        * @return a boolean indicating whether or not to fail on inconsistent line\r
+        *         widths.\r
+        */\r
+       public boolean isFailOnInconsistentLineWidth() {\r
+               return failOnInconsistentLineWidth;\r
+       }\r
+\r
+       @Override\r
+       protected void decorateIdentity(List<Object> identifiers) {\r
+               identifiers.add(columnNameLineNumber);\r
+               identifiers.add(encoding);\r
+               identifiers.add(fixedValueWidth);\r
+               identifiers.add(valueWidths);\r
+               identifiers.add(failOnInconsistentLineWidth);\r
+       }\r
+\r
+       @Override\r
+       public String toString() {\r
+               return "FixedWidthConfiguration[encoding=" + encoding\r
+                               + ", fixedValueWidth=" + fixedValueWidth + ", valueWidths="\r
+                               + Arrays.toString(valueWidths) + ", columnNameLineNumber="\r
+                               + columnNameLineNumber + ", failOnInconsistentLineWidth="\r
+                               + failOnInconsistentLineWidth + "]";\r
+       }\r
+\r
+       public boolean isConstantValueWidth() {\r
+               return fixedValueWidth != -1;\r
+       }\r
+\r
+       public int getValueWidth(int columnIndex) {\r
+               if (isConstantValueWidth()) {\r
+                       return fixedValueWidth;\r
+               }\r
+               return valueWidths[columnIndex];\r
+       }\r
+}\r
diff --git a/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java
new file mode 100644 (file)
index 0000000..9154e5e
--- /dev/null
@@ -0,0 +1,180 @@
+/**\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.fixedwidth;\r
+\r
+import java.io.BufferedReader;\r
+import java.io.InputStream;\r
+import java.io.InputStreamReader;\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.LinkedHashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.apache.metamodel.csv.CsvConfiguration;\r
+import org.apache.metamodel.csv.CsvDataContext;\r
+import org.apache.metamodel.data.DataSet;\r
+import org.apache.metamodel.schema.Table;\r
+import org.apache.metamodel.util.Action;\r
+import org.apache.metamodel.util.Resource;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ * Object capable of reading fixed width metadata from external sources and\r
+ * thereby producing an appropriate {@link FixedWidthConfiguration} to use with\r
+ * a {@link FixedWidthDataContext}.\r
+ */\r
+public class FixedWidthConfigurationReader {\r
+\r
+    private static final Logger logger = LoggerFactory.getLogger(FixedWidthConfigurationReader.class);\r
+\r
+    // example: @1 COL1 $char1.\r
+    private final Pattern PATTERN_SAS_INPUT_LINE = Pattern.compile("\\@(\\d+) (.+) .*?(\\d+)\\.");\r
+\r
+    // example: COL1 "Record type"\r
+    private final Pattern PATTERN_SAS_LABEL_LINE = Pattern.compile("(.+) \\\"(.+)\\\"");\r
+\r
+    /**\r
+     * Reads a {@link FixedWidthConfiguration} based on a SAS 'format file',\r
+     * <a href=\r
+     * "http://support.sas.com/documentation/cdl/en/etlug/67323/HTML/default/viewer.htm#p0h03yig7fp1qan1arghp3lwjqi6.htm">\r
+     * described here</a>.\r
+     * \r
+     * @param encoding\r
+     * @param resource\r
+     *            the format file resource\r
+     * @param failOnInconsistentLineWidth\r
+     * @return a {@link FixedWidthConfiguration} object to use\r
+     */\r
+    public FixedWidthConfiguration readFromSasFormatFile(String encoding, Resource resource,\r
+            boolean failOnInconsistentLineWidth) {\r
+        final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>();\r
+\r
+        final CsvDataContext dataContext = new CsvDataContext(resource, new CsvConfiguration());\r
+        final Table table = dataContext.getDefaultSchema().getTable(0);\r
+        try (final DataSet dataSet = dataContext.query().from(table).select("Name", "BeginPosition", "EndPosition")\r
+                .execute()) {\r
+            while (dataSet.next()) {\r
+                final String name = (String) dataSet.getRow().getValue(0);\r
+                final int beginPosition = Integer.parseInt((String) dataSet.getRow().getValue(1));\r
+                final int endPosition = Integer.parseInt((String) dataSet.getRow().getValue(2));\r
+                final int width = 1 + endPosition - beginPosition;\r
+                columnSpecs.add(new FixedWidthColumnSpec(name, width));\r
+            }\r
+        }\r
+\r
+        return new FixedWidthConfiguration(encoding, columnSpecs, failOnInconsistentLineWidth);\r
+    }\r
+\r
+    /**\r
+     * Reads a {@link FixedWidthConfiguration} based on a SAS INPUT declaration.\r
+     * The reader method also optionally will look for a LABEL defintion for\r
+     * column naming.\r
+     * \r
+     * @param encoding\r
+     * @param resource\r
+     *            the format file resource\r
+     * @param failOnInconsistentLineWidth\r
+     * @return a {@link FixedWidthConfiguration} object to use\r
+     */\r
+    public FixedWidthConfiguration readFromSasInputDefinition(String encoding, Resource resource,\r
+            boolean failOnInconsistentLineWidth) {\r
+\r
+        final Map<String, Integer> inputWidthDeclarations = new LinkedHashMap<>();\r
+        final Map<String, String> labelDeclarations = new HashMap<>();\r
+\r
+        resource.read(new Action<InputStream>() {\r
+\r
+            private boolean inInputSection = false;\r
+            private boolean inLabelSection = false;\r
+\r
+            @Override\r
+            public void run(InputStream in) throws Exception {\r
+                try (final BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {\r
+                    for (String line = reader.readLine(); line != null; line = reader.readLine()) {\r
+                        processLine(line);\r
+                    }\r
+                }\r
+            }\r
+\r
+            private void processLine(String line) {\r
+                line = line.trim();\r
+                if (line.isEmpty()) {\r
+                    return;\r
+                }\r
+                if (";".equals(line)) {\r
+                    inInputSection = false;\r
+                    inLabelSection = false;\r
+                    return;\r
+                } else if ("INPUT".equals(line)) {\r
+                    inInputSection = true;\r
+                    return;\r
+                } else if ("LABEL".equals(line)) {\r
+                    inLabelSection = true;\r
+                    return;\r
+                }\r
+\r
+                if (inInputSection) {\r
+                    final Matcher matcher = PATTERN_SAS_INPUT_LINE.matcher(line);\r
+                    if (matcher.matches()) {\r
+                        final String positionSpec = matcher.group(1);\r
+                        final String nameSpec = matcher.group(2);\r
+                        final int width = Integer.parseInt(matcher.group(3));\r
+                        logger.debug("Parsed INPUT line \"{}\": position={}, name={}, width={}", line, positionSpec,\r
+                                nameSpec, width);\r
+                        inputWidthDeclarations.put(nameSpec, width);\r
+                    } else {\r
+                        logger.debug("Failed to parse/recognize INPUT line \"{}\"", line);\r
+                    }\r
+                } else if (inLabelSection) {\r
+                    final Matcher matcher = PATTERN_SAS_LABEL_LINE.matcher(line);\r
+                    if (matcher.matches()) {\r
+                        final String nameSpec = matcher.group(1);\r
+                        final String labelSpec = matcher.group(2);\r
+                        logger.debug("Parsed LABEL line \"{}\": name={}, label={}", line, nameSpec, labelSpec);\r
+                        labelDeclarations.put(nameSpec, labelSpec);\r
+                    } else {\r
+                        logger.debug("Failed to parse/recognize LABEL line \"{}\"", line);\r
+                    }\r
+                }\r
+\r
+                if (line.endsWith(";")) {\r
+                    inInputSection = false;\r
+                    inLabelSection = false;\r
+                }\r
+            }\r
+        });\r
+\r
+        final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>();\r
+        for (Entry<String, Integer> entry : inputWidthDeclarations.entrySet()) {\r
+            final String columnKey = entry.getKey();\r
+            final Integer columnWidth = entry.getValue();\r
+            final String columnLabel = labelDeclarations.get(columnKey);\r
+            final String columnName = columnLabel == null ? columnKey : columnLabel;\r
+            columnSpecs.add(new FixedWidthColumnSpec(columnName, columnWidth));\r
+        }\r
+\r
+        return new FixedWidthConfiguration(encoding, columnSpecs, failOnInconsistentLineWidth);\r
+    }\r
+\r
+}\r
diff --git a/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java b/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java
new file mode 100644 (file)
index 0000000..eb57233
--- /dev/null
@@ -0,0 +1,89 @@
+/**\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.fixedwidth;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+import java.util.Arrays;\r
+\r
+import org.apache.metamodel.DataContext;\r
+import org.apache.metamodel.data.DataSet;\r
+import org.apache.metamodel.schema.Table;\r
+import org.apache.metamodel.util.FileResource;\r
+import org.apache.metamodel.util.Resource;\r
+import org.junit.Test;\r
+\r
+public class FixedWidthConfigurationReaderTest {\r
+\r
+    private final FileResource dataResource = new FileResource("src/test/resources/metadata_spec1/data.txt");\r
+\r
+    @Test\r
+    public void testReadConfigurationFromSasFormatFile() throws Exception {\r
+        final FixedWidthConfigurationReader reader = new FixedWidthConfigurationReader();\r
+        final Resource resource = new FileResource("src/test/resources/metadata_spec1/sas-formatfile-metadata.txt");\r
+        assertTrue(resource.isExists());\r
+\r
+        final FixedWidthConfiguration configuration = reader.readFromSasFormatFile("UTF8", resource, false);\r
+        assertEquals("[1, 20, 2]", Arrays.toString(configuration.getValueWidths()));\r
+\r
+        final FixedWidthDataContext dataContext = new FixedWidthDataContext(dataResource, configuration);\r
+\r
+        performAssertionsOnSpec1(dataContext);\r
+    }\r
+    \r
+    @Test\r
+    public void testReadConfigurationFromSasInputMetadata() throws Exception {\r
+        final FixedWidthConfigurationReader reader = new FixedWidthConfigurationReader();\r
+        final Resource resource = new FileResource("src/test/resources/metadata_spec1/sas-input-metadata.txt");\r
+        assertTrue(resource.isExists());\r
+\r
+        final FixedWidthConfiguration configuration = reader.readFromSasInputDefinition("UTF8", resource, false);\r
+        assertEquals("[1, 20, 2]", Arrays.toString(configuration.getValueWidths()));\r
+\r
+        final FixedWidthDataContext dataContext = new FixedWidthDataContext(dataResource, configuration);\r
+\r
+        performAssertionsOnSpec1(dataContext);\r
+    }\r
+\r
+    /**\r
+     * Shared assertions section once the 'metadata_spec1' {@link DataContext}\r
+     * has been loaded.\r
+     * \r
+     * @param dataContext\r
+     */\r
+    private void performAssertionsOnSpec1(FixedWidthDataContext dataContext) {\r
+        final Table table = dataContext.getDefaultSchema().getTable(0);\r
+        final String[] columnNames = table.getColumnNames();\r
+        assertEquals("[Record type, Description, Initials]", Arrays.toString(columnNames));\r
+\r
+        try (final DataSet dataSet = dataContext.query().from(table).selectAll().execute()) {\r
+            assertTrue(dataSet.next());\r
+            assertEquals("Row[values=[P, Kasper Sorensen, KS]]", dataSet.getRow().toString());\r
+            assertTrue(dataSet.next());\r
+            assertEquals("Row[values=[C, Human Inference, HI]]", dataSet.getRow().toString());\r
+            assertTrue(dataSet.next());\r
+            assertEquals("Row[values=[P, Ankit Kumar, AK]]", dataSet.getRow().toString());\r
+            assertTrue(dataSet.next());\r
+            assertEquals("Row[values=[C, Stratio, S]]", dataSet.getRow().toString());\r
+            assertTrue(dataSet.next());\r
+            assertEquals("Row[values=[U, Unknown, ]]", dataSet.getRow().toString());\r
+            assertFalse(dataSet.next());\r
+        }\r
+    }\r
+}\r
diff --git a/fixedwidth/src/test/resources/metadata_spec1/data.txt b/fixedwidth/src/test/resources/metadata_spec1/data.txt
new file mode 100644 (file)
index 0000000..785a539
--- /dev/null
@@ -0,0 +1,5 @@
+PKasper Sorensen     KS\r
+CHuman Inference     HI\r
+PAnkit Kumar         AK\r
+CStratio             S \r
+UUnknown               \r
diff --git a/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt b/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt
new file mode 100644 (file)
index 0000000..9bbe411
--- /dev/null
@@ -0,0 +1,4 @@
+Name,SASColumnType,BeginPosition,EndPosition,ReadFlag,Desc,SASFormat,SASInformat\r
+Record type,C,1,1,y,Record Type,$char.,$char.\r
+Description,C,2,21,y,Description of record,$char.,$char.\r
+Initials,C,22,23,y,Initials of record,,\r
diff --git a/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt b/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt
new file mode 100644 (file)
index 0000000..f12e418
--- /dev/null
@@ -0,0 +1,19 @@
+INPUT\r
+\r
+   @1 COL1 $char1.\r
+\r
+   @2 COL2 $char20.\r
+\r
+   @22 COL3 $char2.\r
+   \r
+;\r
+\r
+LABEL\r
+\r
+   COL1 "Record type"\r
+\r
+   COL2 "Description"\r
+\r
+   COL3 "Initials"\r
+\r
+;\r