You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metamodel.apache.org by ka...@apache.org on 2014/07/20 08:03:28 UTC
[2/5] git commit: METAMODEL-69: Applied patch from review board.
METAMODEL-69: Applied patch from review board.
Project: http://git-wip-us.apache.org/repos/asf/incubator-metamodel/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-metamodel/commit/cad631d6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-metamodel/tree/cad631d6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-metamodel/diff/cad631d6
Branch: refs/heads/master
Commit: cad631d6b8b8fd0a57409356c756e4f448b8851f
Parents: 9d60bce
Author: Kasper Sørensen <i....@gmail.com>
Authored: Sat Jul 19 21:27:37 2014 +0200
Committer: Kasper Sørensen <i....@gmail.com>
Committed: Sat Jul 19 21:27:37 2014 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../org/apache/metamodel/schema/JdbcTypes.java | 2 +-
.../LegacyDeserializationObjectInputStream.java | 218 ++++++++++++++++++-
.../apache/metamodel/data/DefaultRowTest.java | 15 +-
...acyDeserializationObjectInputStreamTest.java | 83 +++++++
5 files changed, 313 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/cad631d6/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 3c4e0fa..57b7b4f 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -14,6 +14,7 @@ Apache MetaModel 4.2.0-incubating
* [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
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/cad631d6/core/src/main/java/org/apache/metamodel/schema/JdbcTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/schema/JdbcTypes.java b/core/src/main/java/org/apache/metamodel/schema/JdbcTypes.java
index 2ab39ab..a76b9c6 100644
--- a/core/src/main/java/org/apache/metamodel/schema/JdbcTypes.java
+++ b/core/src/main/java/org/apache/metamodel/schema/JdbcTypes.java
@@ -24,7 +24,7 @@ package org.apache.metamodel.schema;
* additional types (confirmed by JavaTypesTest). It is being used to convert
* JDBC types to ColumnType enumerations.
*/
-final class JdbcTypes {
+public final class JdbcTypes {
// Prevent instantiation
private JdbcTypes() {
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/cad631d6/core/src/main/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStream.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStream.java b/core/src/main/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStream.java
index c5ab2e5..3e492b8 100644
--- a/core/src/main/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStream.java
+++ b/core/src/main/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStream.java
@@ -18,10 +18,30 @@
*/
package org.apache.metamodel.util;
+import static org.apache.metamodel.schema.SuperColumnType.BINARY_TYPE;
+import static org.apache.metamodel.schema.SuperColumnType.BOOLEAN_TYPE;
+import static org.apache.metamodel.schema.SuperColumnType.LITERAL_TYPE;
+import static org.apache.metamodel.schema.SuperColumnType.NUMBER_TYPE;
+import static org.apache.metamodel.schema.SuperColumnType.OTHER_TYPE;
+import static org.apache.metamodel.schema.SuperColumnType.TIME_TYPE;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
+import java.lang.reflect.Field;
+import java.math.BigInteger;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Types;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.metamodel.schema.ColumnType;
+import org.apache.metamodel.schema.JdbcTypes;
+import org.apache.metamodel.schema.SuperColumnType;
/**
* A specialized {@link ObjectInputStream} for MetaModel which can be used or
@@ -31,17 +51,211 @@ import java.io.ObjectStreamClass;
*/
public class LegacyDeserializationObjectInputStream extends ObjectInputStream {
+ /**
+ * Implementation of the new {@link ColumnType} interface which still
+ * adheres to the constant/enum values of the old ColumnType definition.
+ * While deserializing old ColumnType objects, we will convert them to this
+ * enum.
+ */
+ protected static enum LegacyColumnType implements ColumnType {
+
+ /**
+ * Literal
+ */
+ CHAR(LITERAL_TYPE), VARCHAR(LITERAL_TYPE), LONGVARCHAR(LITERAL_TYPE), CLOB(LITERAL_TYPE), NCHAR(LITERAL_TYPE), NVARCHAR(
+ LITERAL_TYPE), LONGNVARCHAR(LITERAL_TYPE), NCLOB(LITERAL_TYPE),
+
+ /**
+ * Numbers
+ */
+ TINYINT(NUMBER_TYPE), SMALLINT(NUMBER_TYPE), INTEGER(NUMBER_TYPE), BIGINT(NUMBER_TYPE), FLOAT(NUMBER_TYPE), REAL(
+ NUMBER_TYPE), DOUBLE(NUMBER_TYPE), NUMERIC(NUMBER_TYPE), DECIMAL(NUMBER_TYPE),
+
+ /**
+ * Time based
+ */
+ DATE(TIME_TYPE), TIME(TIME_TYPE), TIMESTAMP(TIME_TYPE),
+
+ /**
+ * Booleans
+ */
+ BIT(BOOLEAN_TYPE), BOOLEAN(BOOLEAN_TYPE),
+
+ /**
+ * Binary types
+ */
+ BINARY(BINARY_TYPE), VARBINARY(BINARY_TYPE), LONGVARBINARY(BINARY_TYPE), BLOB(BINARY_TYPE),
+
+ /**
+ * Other types (as defined in {@link Types}).
+ */
+ NULL(OTHER_TYPE), OTHER(OTHER_TYPE), JAVA_OBJECT(OTHER_TYPE), DISTINCT(OTHER_TYPE), STRUCT(OTHER_TYPE), ARRAY(
+ OTHER_TYPE), REF(OTHER_TYPE), DATALINK(OTHER_TYPE), ROWID(OTHER_TYPE), SQLXML(OTHER_TYPE),
+
+ /**
+ * Additional types (added by MetaModel for non-JDBC datastores)
+ */
+ LIST(OTHER_TYPE), MAP(OTHER_TYPE);
+
+ private final SuperColumnType _superType;
+
+ private LegacyColumnType(SuperColumnType superType) {
+ if (superType == null) {
+ throw new IllegalArgumentException("SuperColumnType cannot be null");
+ }
+ _superType = superType;
+ }
+
+ @Override
+ public String getName() {
+ return name();
+ }
+
+ @Override
+ public Comparator<Object> getComparator() {
+ if (isTimeBased()) {
+ return TimeComparator.getComparator();
+ }
+ if (isNumber()) {
+ return NumberComparator.getComparator();
+ }
+ if (isLiteral()) {
+ return ToStringComparator.getComparator();
+ }
+ return ObjectComparator.getComparator();
+ }
+
+ @Override
+ public boolean isBoolean() {
+ return _superType == BOOLEAN_TYPE;
+ }
+
+ @Override
+ public boolean isBinary() {
+ return _superType == BINARY_TYPE;
+ }
+
+ @Override
+ public boolean isNumber() {
+ return _superType == NUMBER_TYPE;
+ }
+
+ @Override
+ public boolean isTimeBased() {
+ return _superType == TIME_TYPE;
+ }
+
+ @Override
+ public boolean isLiteral() {
+ return _superType == LITERAL_TYPE;
+ }
+
+ @Override
+ public boolean isLargeObject() {
+ switch (this) {
+ case BLOB:
+ case CLOB:
+ case NCLOB:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public Class<?> getJavaEquivalentClass() {
+ switch (this) {
+ case TINYINT:
+ case SMALLINT:
+ return Short.class;
+ case INTEGER:
+ return Integer.class;
+ case BIGINT:
+ return BigInteger.class;
+ case DECIMAL:
+ case NUMERIC:
+ case FLOAT:
+ case REAL:
+ case DOUBLE:
+ return Double.class;
+ case DATE:
+ case TIME:
+ case TIMESTAMP:
+ return Date.class;
+ case BLOB:
+ return Blob.class;
+ case CLOB:
+ case NCLOB:
+ return Clob.class;
+ case MAP:
+ return Map.class;
+ case LIST:
+ return List.class;
+ default:
+ // All other types have fitting java equivalent classes in the
+ // super
+ // type
+ return _superType.getJavaEquivalentClass();
+ }
+ }
+
+ @Override
+ public SuperColumnType getSuperType() {
+ return _superType;
+ }
+
+ @Override
+ public int getJdbcType() throws IllegalStateException {
+ final String name = this.toString();
+ try {
+ // We assume that the JdbcTypes class only consists of constant
+ // integer types, so we make no assertions here
+ final Field[] fields = JdbcTypes.class.getFields();
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ String fieldName = field.getName();
+ if (fieldName.equals(name)) {
+ int value = (Integer) field.getInt(null);
+ return value;
+ }
+ }
+ throw new IllegalStateException("No JdbcType found with field name: " + name);
+ } catch (Exception e) {
+ throw new IllegalStateException("Could not access fields in JdbcTypes", e);
+ }
+ }
+ }
+
+ private static final String OLD_CLASS_NAME_COLUMN_TYPE = "org.eobjects.metamodel.schema.ColumnType";
+
public LegacyDeserializationObjectInputStream(InputStream in) throws IOException, SecurityException {
super(in);
}
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
- String className = desc.getName();
+ final String className = desc.getName();
if (className.startsWith("org.eobjects.metamodel") || className.startsWith("[Lorg.eobjects.metamodel")) {
- String newClassName = className.replace("org.eobjects", "org.apache");
+ final String newClassName;
+ if (OLD_CLASS_NAME_COLUMN_TYPE.equals(className)) {
+ // since ColumnType was changed from enum to interface, there's
+ // some special treatment here.
+ newClassName = LegacyColumnType.class.getName();
+ } else {
+ newClassName = className.replace("org.eobjects", "org.apache");
+ }
return Class.forName(newClassName);
}
return super.resolveClass(desc);
}
+
+ @Override
+ protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
+ final ObjectStreamClass objectStreamClass = super.readClassDescriptor();
+ if (OLD_CLASS_NAME_COLUMN_TYPE.equals(objectStreamClass.getName())) {
+ final ObjectStreamClass result = ObjectStreamClass.lookup(LegacyColumnType.class);
+ return result;
+ }
+ return objectStreamClass;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/cad631d6/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java b/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
index a3a45f6..40f0551 100644
--- a/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
+++ b/core/src/test/java/org/apache/metamodel/data/DefaultRowTest.java
@@ -26,6 +26,8 @@ import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import org.apache.metamodel.query.SelectItem;
+import org.apache.metamodel.schema.Column;
+import org.apache.metamodel.schema.ColumnType;
import org.apache.metamodel.schema.MutableColumn;
import org.apache.metamodel.util.FileHelper;
import org.apache.metamodel.util.LegacyDeserializationObjectInputStream;
@@ -37,18 +39,18 @@ public class DefaultRowTest extends TestCase {
private SelectItem[] items = new SelectItem[] { new SelectItem(new MutableColumn("foo")),
new SelectItem(new MutableColumn("bar")) };
private Object[] values = new Object[] { "foo", "bar" };
-
+
public void testSerializeAndDeserialize() throws Exception {
DefaultRow row = new DefaultRow(new SimpleDataSetHeader(items), values);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(row);
oos.close();
-
+
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object deserialized = ois.readObject();
-
+
assertEquals("Row[values=[foo, bar]]", deserialized.toString());
assertEquals(row, deserialized);
}
@@ -78,6 +80,13 @@ public class DefaultRowTest extends TestCase {
assertEquals(Style.NO_STYLE, row.getStyle(0));
assertEquals(Style.NO_STYLE, row.getStyle(1));
+
+ Column column = selectItems[0].getColumn();
+ assertNotNull(column);
+
+ // the columns used to create the object did not have column types assigned.
+ ColumnType type = column.getType();
+ assertNull(type);
}
public void testGetValueOfColumn() throws Exception {
http://git-wip-us.apache.org/repos/asf/incubator-metamodel/blob/cad631d6/core/src/test/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStreamTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStreamTest.java b/core/src/test/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStreamTest.java
new file mode 100644
index 0000000..e202ad7
--- /dev/null
+++ b/core/src/test/java/org/apache/metamodel/util/LegacyDeserializationObjectInputStreamTest.java
@@ -0,0 +1,83 @@
+/**
+ * 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.util;
+
+import java.io.FileInputStream;
+
+import org.apache.metamodel.query.Query;
+import org.apache.metamodel.schema.Column;
+import org.apache.metamodel.schema.Table;
+
+import junit.framework.TestCase;
+
+public class LegacyDeserializationObjectInputStreamTest extends TestCase {
+
+ /**
+ * Method initially used (with org.eobjects codebase) to generate the test
+ * input file:
+ *
+ * <pre>
+ * public void testCreateOldSchema() throws Exception {
+ * MutableSchema schema = new MutableSchema("myschema");
+ * MutableTable table = new MutableTable("mytable", TableType.TABLE, schema);
+ * schema.addTable(table);
+ *
+ * table.addColumn(new MutableColumn("mycol1", ColumnType.INTEGER, table, 0, 16, "int", false, "my remark 1", false,
+ * "\""));
+ * table.addColumn(new MutableColumn("mycol1", ColumnType.VARCHAR, table, 1, 255, "text", true, "my remark 2", true,
+ * null));
+ *
+ * Query q = new Query();
+ * q.from(table);
+ * q.select(table.getColumn(0));
+ * q.where(table.getColumn(1), OperatorType.EQUALS_TO, "foo");
+ *
+ * FileOutputStream out = new FileOutputStream("src/test/resources/metamodel-3.4-query-and-schema.ser");
+ * new ObjectOutputStream(out).writeObject(q);
+ * out.close();
+ * }
+ * </pre>
+ */
+ public void testDeserializeOldQueryAndSchema() throws Exception {
+ final Object obj;
+ {
+ final FileInputStream in = new FileInputStream("src/test/resources/metamodel-3.4-query-and-schema.ser");
+ try {
+ final LegacyDeserializationObjectInputStream ois = new LegacyDeserializationObjectInputStream(in);
+ obj = ois.readObject();
+ ois.close();
+ } finally {
+ in.close();
+ }
+ }
+
+ assertTrue(obj instanceof Query);
+
+ final Query q = (Query) obj;
+ final Table table = q.getFromClause().getItem(0).getTable();
+ final Column[] columns = table.getColumns();
+
+ assertEquals("Table[name=mytable,type=TABLE,remarks=null]", table.toString());
+ assertEquals("Column[name=mycol1,columnNumber=0,type=INTEGER,nullable=false,nativeType=int,columnSize=16]", columns[0].toString());
+ assertEquals("Column[name=mycol1,columnNumber=1,type=VARCHAR,nullable=true,nativeType=text,columnSize=255]", columns[1].toString());
+
+ assertEquals("SELECT mytable.\"mycol1\" FROM myschema.mytable WHERE mytable.mycol1 = 'foo'", q.toSql());
+ }
+
+}