METAMODEL-247: Fixed

Closes #97

Project: http://git-wip-us.apache.org/repos/asf/metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/metamodel/commit/47c6d56c
Tree: http://git-wip-us.apache.org/repos/asf/metamodel/tree/47c6d56c
Diff: http://git-wip-us.apache.org/repos/asf/metamodel/diff/47c6d56c

Branch: refs/heads/5.x
Commit: 47c6d56cc7dbc3e6772b94d3816b94252622cbef
Parents: 025d07f
Author: kaspersorensen <[email protected]>
Authored: Thu Apr 28 16:39:41 2016 -0700
Committer: kaspersorensen <[email protected]>
Committed: Thu Apr 28 16:39:41 2016 -0700

----------------------------------------------------------------------
 CHANGES.md                                      | 335 ++++++++---------
 .../schema/naming/ColumnNamingStrategies.java   |  10 +
 .../naming/CustomColumnNamingStrategy.java      |  62 ++++
 fixedwidth/pom.xml                              |  98 ++---
 .../fixedwidth/FixedWidthColumnSpec.java        |  45 +++
 .../fixedwidth/FixedWidthConfiguration.java     | 358 ++++++++++---------
 .../FixedWidthConfigurationReader.java          | 180 ++++++++++
 .../FixedWidthConfigurationReaderTest.java      |  89 +++++
 .../src/test/resources/metadata_spec1/data.txt  |   5 +
 .../metadata_spec1/sas-formatfile-metadata.txt  |   4 +
 .../metadata_spec1/sas-input-metadata.txt       |  19 +
 11 files changed, 823 insertions(+), 382 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/CHANGES.md
----------------------------------------------------------------------
diff --git a/CHANGES.md b/CHANGES.md
index 4356071..dd03195 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,167 +1,168 @@
-### 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)
+
+ * [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.
+ * [METAMODEL-247] - Added FixedWidthConfigurationReader for reading fixed 
width file metadata from external files.
+
+### 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 

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/core/src/main/java/org/apache/metamodel/schema/naming/ColumnNamingStrategies.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/metamodel/schema/naming/ColumnNamingStrategies.java
 
b/core/src/main/java/org/apache/metamodel/schema/naming/ColumnNamingStrategies.java
index de78338..0696376 100644
--- 
a/core/src/main/java/org/apache/metamodel/schema/naming/ColumnNamingStrategies.java
+++ 
b/core/src/main/java/org/apache/metamodel/schema/naming/ColumnNamingStrategies.java
@@ -18,6 +18,8 @@
  */
 package org.apache.metamodel.schema.naming;
 
+import java.util.List;
+
 /**
  * Constructors and common utilities for {@link ColumnNamingStrategy} objects.
  */
@@ -32,4 +34,12 @@ public class ColumnNamingStrategies {
     public static ColumnNamingStrategy defaultStrategy() {
         return DEFAULT_STRATEGY;
     }
+
+    public static ColumnNamingStrategy customNames(List<String> columnNames) {
+        return new CustomColumnNamingStrategy(columnNames);
+    }
+
+    public static ColumnNamingStrategy customNames(String ... columnNames) {
+        return new CustomColumnNamingStrategy(columnNames);
+    }
 }

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/core/src/main/java/org/apache/metamodel/schema/naming/CustomColumnNamingStrategy.java
----------------------------------------------------------------------
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
index 0000000..e6cc706
--- /dev/null
+++ 
b/core/src/main/java/org/apache/metamodel/schema/naming/CustomColumnNamingStrategy.java
@@ -0,0 +1,62 @@
+/**
+ * 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.naming;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * A {@link ColumnNamingStrategy} that allows the user to supply his own list 
of
+ * custom column names.
+ */
+public class CustomColumnNamingStrategy implements ColumnNamingStrategy {
+
+    private static final long serialVersionUID = 1L;
+
+    private final List<String> columnNames;
+
+    public CustomColumnNamingStrategy(List<String> columnNames) {
+        this.columnNames = columnNames;
+    }
+
+    public CustomColumnNamingStrategy(String... columnNames) {
+        this(Arrays.asList(columnNames));
+    }
+
+    @Override
+    public ColumnNamingSession startColumnNamingSession() {
+        final Iterator<String> iterator = columnNames.iterator();
+        return new ColumnNamingSession() {
+
+            @Override
+            public String getNextColumnName(ColumnNamingContext ctx) {
+                if (iterator.hasNext()) {
+                    return iterator.next();
+                }
+                return null;
+            }
+
+            @Override
+            public void close() {
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/pom.xml
----------------------------------------------------------------------
diff --git a/fixedwidth/pom.xml b/fixedwidth/pom.xml
index e667a10..43e4021 100644
--- a/fixedwidth/pom.xml
+++ b/fixedwidth/pom.xml
@@ -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" ?>
+<!--
+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.apache.metamodel</groupId>
+                       <artifactId>MetaModel-csv</artifactId>
+                       <version>${project.version}</version>
+                       <optional>true</optional>
+               </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>

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthColumnSpec.java
----------------------------------------------------------------------
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
index 0000000..65ec219
--- /dev/null
+++ 
b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthColumnSpec.java
@@ -0,0 +1,45 @@
+/**
+ * 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 org.apache.metamodel.util.HasName;
+
+/**
+ * Represents the specification of a single column for a
+ * {@link FixedWidthDataContext}.
+ */
+public final class FixedWidthColumnSpec implements HasName {
+
+    private final String name;
+    private final int width;
+
+    public FixedWidthColumnSpec(String name, int width) {
+        this.name = name;
+        this.width = width;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
----------------------------------------------------------------------
diff --git 
a/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
 
b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
index 6e9f0f1..2b2cae5 100644
--- 
a/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
+++ 
b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfiguration.java
@@ -1,169 +1,189 @@
-/**
- * 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];
-       }
-}
+/**
+ * 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.CollectionUtils;
+import org.apache.metamodel.util.FileHelper;
+import org.apache.metamodel.util.HasNameMapper;
+
+/**
+ * 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;
+    }
+    
+    public FixedWidthConfiguration(String encoding, List<FixedWidthColumnSpec> 
columnSpecs) {
+        this(encoding, columnSpecs, false);
+    }
+
+    public FixedWidthConfiguration(String encoding, List<FixedWidthColumnSpec> 
columnSpecs,
+            boolean failOnInconsistentLineWidth) {
+        this.encoding = encoding;
+        this.fixedValueWidth = -1;
+        this.columnNameLineNumber = NO_COLUMN_NAME_LINE;
+        this.columnNamingStrategy = 
ColumnNamingStrategies.customNames(CollectionUtils.map(columnSpecs,
+                new HasNameMapper()));
+        this.valueWidths = new int[columnSpecs.size()];
+        for (int i = 0; i < valueWidths.length; i++) {
+            valueWidths[i] = columnSpecs.get(i).getWidth();
+        }
+        this.failOnInconsistentLineWidth = failOnInconsistentLineWidth;
+    }
+
+    /**
+        * 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];
+       }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java
----------------------------------------------------------------------
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
index 0000000..9154e5e
--- /dev/null
+++ 
b/fixedwidth/src/main/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReader.java
@@ -0,0 +1,180 @@
+/**
+ * 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.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.metamodel.csv.CsvConfiguration;
+import org.apache.metamodel.csv.CsvDataContext;
+import org.apache.metamodel.data.DataSet;
+import org.apache.metamodel.schema.Table;
+import org.apache.metamodel.util.Action;
+import org.apache.metamodel.util.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Object capable of reading fixed width metadata from external sources and
+ * thereby producing an appropriate {@link FixedWidthConfiguration} to use with
+ * a {@link FixedWidthDataContext}.
+ */
+public class FixedWidthConfigurationReader {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(FixedWidthConfigurationReader.class);
+
+    // example: @1 COL1 $char1.
+    private final Pattern PATTERN_SAS_INPUT_LINE = Pattern.compile("\\@(\\d+) 
(.+) .*?(\\d+)\\.");
+
+    // example: COL1 "Record type"
+    private final Pattern PATTERN_SAS_LABEL_LINE = Pattern.compile("(.+) 
\\\"(.+)\\\"");
+
+    /**
+     * Reads a {@link FixedWidthConfiguration} based on a SAS 'format file',
+     * <a href=
+     * 
"http://support.sas.com/documentation/cdl/en/etlug/67323/HTML/default/viewer.htm#p0h03yig7fp1qan1arghp3lwjqi6.htm";>
+     * described here</a>.
+     * 
+     * @param encoding
+     * @param resource
+     *            the format file resource
+     * @param failOnInconsistentLineWidth
+     * @return a {@link FixedWidthConfiguration} object to use
+     */
+    public FixedWidthConfiguration readFromSasFormatFile(String encoding, 
Resource resource,
+            boolean failOnInconsistentLineWidth) {
+        final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>();
+
+        final CsvDataContext dataContext = new CsvDataContext(resource, new 
CsvConfiguration());
+        final Table table = dataContext.getDefaultSchema().getTable(0);
+        try (final DataSet dataSet = 
dataContext.query().from(table).select("Name", "BeginPosition", "EndPosition")
+                .execute()) {
+            while (dataSet.next()) {
+                final String name = (String) dataSet.getRow().getValue(0);
+                final int beginPosition = Integer.parseInt((String) 
dataSet.getRow().getValue(1));
+                final int endPosition = Integer.parseInt((String) 
dataSet.getRow().getValue(2));
+                final int width = 1 + endPosition - beginPosition;
+                columnSpecs.add(new FixedWidthColumnSpec(name, width));
+            }
+        }
+
+        return new FixedWidthConfiguration(encoding, columnSpecs, 
failOnInconsistentLineWidth);
+    }
+
+    /**
+     * Reads a {@link FixedWidthConfiguration} based on a SAS INPUT 
declaration.
+     * The reader method also optionally will look for a LABEL defintion for
+     * column naming.
+     * 
+     * @param encoding
+     * @param resource
+     *            the format file resource
+     * @param failOnInconsistentLineWidth
+     * @return a {@link FixedWidthConfiguration} object to use
+     */
+    public FixedWidthConfiguration readFromSasInputDefinition(String encoding, 
Resource resource,
+            boolean failOnInconsistentLineWidth) {
+
+        final Map<String, Integer> inputWidthDeclarations = new 
LinkedHashMap<>();
+        final Map<String, String> labelDeclarations = new HashMap<>();
+
+        resource.read(new Action<InputStream>() {
+
+            private boolean inInputSection = false;
+            private boolean inLabelSection = false;
+
+            @Override
+            public void run(InputStream in) throws Exception {
+                try (final BufferedReader reader = new BufferedReader(new 
InputStreamReader(in))) {
+                    for (String line = reader.readLine(); line != null; line = 
reader.readLine()) {
+                        processLine(line);
+                    }
+                }
+            }
+
+            private void processLine(String line) {
+                line = line.trim();
+                if (line.isEmpty()) {
+                    return;
+                }
+                if (";".equals(line)) {
+                    inInputSection = false;
+                    inLabelSection = false;
+                    return;
+                } else if ("INPUT".equals(line)) {
+                    inInputSection = true;
+                    return;
+                } else if ("LABEL".equals(line)) {
+                    inLabelSection = true;
+                    return;
+                }
+
+                if (inInputSection) {
+                    final Matcher matcher = 
PATTERN_SAS_INPUT_LINE.matcher(line);
+                    if (matcher.matches()) {
+                        final String positionSpec = matcher.group(1);
+                        final String nameSpec = matcher.group(2);
+                        final int width = Integer.parseInt(matcher.group(3));
+                        logger.debug("Parsed INPUT line \"{}\": position={}, 
name={}, width={}", line, positionSpec,
+                                nameSpec, width);
+                        inputWidthDeclarations.put(nameSpec, width);
+                    } else {
+                        logger.debug("Failed to parse/recognize INPUT line 
\"{}\"", line);
+                    }
+                } else if (inLabelSection) {
+                    final Matcher matcher = 
PATTERN_SAS_LABEL_LINE.matcher(line);
+                    if (matcher.matches()) {
+                        final String nameSpec = matcher.group(1);
+                        final String labelSpec = matcher.group(2);
+                        logger.debug("Parsed LABEL line \"{}\": name={}, 
label={}", line, nameSpec, labelSpec);
+                        labelDeclarations.put(nameSpec, labelSpec);
+                    } else {
+                        logger.debug("Failed to parse/recognize LABEL line 
\"{}\"", line);
+                    }
+                }
+
+                if (line.endsWith(";")) {
+                    inInputSection = false;
+                    inLabelSection = false;
+                }
+            }
+        });
+
+        final List<FixedWidthColumnSpec> columnSpecs = new ArrayList<>();
+        for (Entry<String, Integer> entry : inputWidthDeclarations.entrySet()) 
{
+            final String columnKey = entry.getKey();
+            final Integer columnWidth = entry.getValue();
+            final String columnLabel = labelDeclarations.get(columnKey);
+            final String columnName = columnLabel == null ? columnKey : 
columnLabel;
+            columnSpecs.add(new FixedWidthColumnSpec(columnName, columnWidth));
+        }
+
+        return new FixedWidthConfiguration(encoding, columnSpecs, 
failOnInconsistentLineWidth);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java
----------------------------------------------------------------------
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
index 0000000..eb57233
--- /dev/null
+++ 
b/fixedwidth/src/test/java/org/apache/metamodel/fixedwidth/FixedWidthConfigurationReaderTest.java
@@ -0,0 +1,89 @@
+/**
+ * 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 static org.junit.Assert.*;
+
+import java.util.Arrays;
+
+import org.apache.metamodel.DataContext;
+import org.apache.metamodel.data.DataSet;
+import org.apache.metamodel.schema.Table;
+import org.apache.metamodel.util.FileResource;
+import org.apache.metamodel.util.Resource;
+import org.junit.Test;
+
+public class FixedWidthConfigurationReaderTest {
+
+    private final FileResource dataResource = new 
FileResource("src/test/resources/metadata_spec1/data.txt");
+
+    @Test
+    public void testReadConfigurationFromSasFormatFile() throws Exception {
+        final FixedWidthConfigurationReader reader = new 
FixedWidthConfigurationReader();
+        final Resource resource = new 
FileResource("src/test/resources/metadata_spec1/sas-formatfile-metadata.txt");
+        assertTrue(resource.isExists());
+
+        final FixedWidthConfiguration configuration = 
reader.readFromSasFormatFile("UTF8", resource, false);
+        assertEquals("[1, 20, 2]", 
Arrays.toString(configuration.getValueWidths()));
+
+        final FixedWidthDataContext dataContext = new 
FixedWidthDataContext(dataResource, configuration);
+
+        performAssertionsOnSpec1(dataContext);
+    }
+    
+    @Test
+    public void testReadConfigurationFromSasInputMetadata() throws Exception {
+        final FixedWidthConfigurationReader reader = new 
FixedWidthConfigurationReader();
+        final Resource resource = new 
FileResource("src/test/resources/metadata_spec1/sas-input-metadata.txt");
+        assertTrue(resource.isExists());
+
+        final FixedWidthConfiguration configuration = 
reader.readFromSasInputDefinition("UTF8", resource, false);
+        assertEquals("[1, 20, 2]", 
Arrays.toString(configuration.getValueWidths()));
+
+        final FixedWidthDataContext dataContext = new 
FixedWidthDataContext(dataResource, configuration);
+
+        performAssertionsOnSpec1(dataContext);
+    }
+
+    /**
+     * Shared assertions section once the 'metadata_spec1' {@link DataContext}
+     * has been loaded.
+     * 
+     * @param dataContext
+     */
+    private void performAssertionsOnSpec1(FixedWidthDataContext dataContext) {
+        final Table table = dataContext.getDefaultSchema().getTable(0);
+        final String[] columnNames = table.getColumnNames();
+        assertEquals("[Record type, Description, Initials]", 
Arrays.toString(columnNames));
+
+        try (final DataSet dataSet = 
dataContext.query().from(table).selectAll().execute()) {
+            assertTrue(dataSet.next());
+            assertEquals("Row[values=[P, Kasper Sorensen, KS]]", 
dataSet.getRow().toString());
+            assertTrue(dataSet.next());
+            assertEquals("Row[values=[C, Human Inference, HI]]", 
dataSet.getRow().toString());
+            assertTrue(dataSet.next());
+            assertEquals("Row[values=[P, Ankit Kumar, AK]]", 
dataSet.getRow().toString());
+            assertTrue(dataSet.next());
+            assertEquals("Row[values=[C, Stratio, S]]", 
dataSet.getRow().toString());
+            assertTrue(dataSet.next());
+            assertEquals("Row[values=[U, Unknown, ]]", 
dataSet.getRow().toString());
+            assertFalse(dataSet.next());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/test/resources/metadata_spec1/data.txt
----------------------------------------------------------------------
diff --git a/fixedwidth/src/test/resources/metadata_spec1/data.txt 
b/fixedwidth/src/test/resources/metadata_spec1/data.txt
new file mode 100644
index 0000000..785a539
--- /dev/null
+++ b/fixedwidth/src/test/resources/metadata_spec1/data.txt
@@ -0,0 +1,5 @@
+PKasper Sorensen     KS
+CHuman Inference     HI
+PAnkit Kumar         AK
+CStratio             S 
+UUnknown               

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt
----------------------------------------------------------------------
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
index 0000000..9bbe411
--- /dev/null
+++ b/fixedwidth/src/test/resources/metadata_spec1/sas-formatfile-metadata.txt
@@ -0,0 +1,4 @@
+Name,SASColumnType,BeginPosition,EndPosition,ReadFlag,Desc,SASFormat,SASInformat
+Record type,C,1,1,y,Record Type,$char.,$char.
+Description,C,2,21,y,Description of record,$char.,$char.
+Initials,C,22,23,y,Initials of record,,

http://git-wip-us.apache.org/repos/asf/metamodel/blob/47c6d56c/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt
----------------------------------------------------------------------
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
index 0000000..f12e418
--- /dev/null
+++ b/fixedwidth/src/test/resources/metadata_spec1/sas-input-metadata.txt
@@ -0,0 +1,19 @@
+INPUT
+
+   @1 COL1 $char1.
+
+   @2 COL2 $char20.
+
+   @22 COL3 $char2.
+   
+;
+
+LABEL
+
+   COL1 "Record type"
+
+   COL2 "Description"
+
+   COL3 "Initials"
+
+;

Reply via email to