Commit 4c1f4c8f by Harish Butani

refactor: introduce concepts for ConstructableType, HierarchicalType, IInstance,…

refactor: introduce concepts for ConstructableType, HierarchicalType, IInstance, ITypedInstance etc.
parent 7a33946d
/**
* 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.metadata;
/**
* Represents a Struct or Trait or Object.
*/
public interface IInstance {
String getTypeName();
Object get(String attrName) throws MetadataException;
void set(String attrName, Object val) throws MetadataException;
}
/**
* 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.metadata;
import com.google.common.collect.ImmutableList;
import org.apache.metadata.storage.Id;
/**
* Represents and instance of a ClassType. These have identity.
* Transient instances will have a UNASSIGNED identity.
*/
public interface IReferencableInstance extends IStruct {
ImmutableList<String> getTraits();
Id getId();
IStruct getTrait(String typeName);
}
......@@ -18,9 +18,9 @@
package org.apache.metadata;
public interface IStruct {
/**
* A marker interface for StructType and TraitType instances.
*/
public interface IStruct extends IInstance {
String getTypeName();
Object get(String attrName) throws MetadataException;
void set(String attrName, Object val) throws MetadataException;
}
/**
* 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.metadata;
import org.apache.metadata.types.FieldMapping;
/**
* An instance whose structure is associated with a IDataType.
* This is obtained by a call to 'createInstance' or the result of a Query.
* A ITypedInstance can only contain information on attributes of the associated Type.
* Instance can still be invalid because of missing required fields or incorrect multiplicity.
* But user can only get/set on a known field of the associated type. Type values have to match
* the IDataType of the associated attribute.
*/
public interface ITypedInstance extends IInstance {
FieldMapping fieldMapping();
}
/**
* 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.metadata;
public interface ITypedReferencableInstance extends ITypedInstance, IReferencableInstance {
}
/**
* 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.metadata;
public interface ITypedStruct extends IStruct, ITypedInstance {
}
......@@ -24,14 +24,16 @@ public class Id {
public final int id;
public final String className;
public final int version;
public Id(int id, String className) {
public Id(int id, int version, String className) {
this.id = id;
this.className = className;
this.version = version;
}
public Id(String className) {
this(UNASSIGNED, className);
this(UNASSIGNED, 0, className);
}
public boolean isUnassigned() {
......
......@@ -20,6 +20,7 @@ package org.apache.metadata.storage;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.metadata.IStruct;
import org.apache.metadata.ITypedStruct;
import org.apache.metadata.MetadataException;
import org.apache.metadata.types.AttributeInfo;
import org.apache.metadata.types.FieldMapping;
......@@ -30,7 +31,7 @@ import java.math.BigInteger;
import java.util.Date;
import java.util.Map;
public class StructInstance implements IStruct {
public class StructInstance implements ITypedStruct {
public final String dataTypeName;
public final FieldMapping fieldMapping;
public final boolean nullFlags[];
......@@ -84,6 +85,11 @@ public class StructInstance implements IStruct {
}
@Override
public FieldMapping fieldMapping() {
return fieldMapping;
}
@Override
public Object get(String attrName) throws MetadataException {
return fieldMapping.get(this, attrName);
}
......
package org.apache.metadata.types;
import org.apache.metadata.ITypedInstance;
public interface IConstructableType<U, T extends ITypedInstance> extends IDataType<U> {
T createInstance();
FieldMapping fieldMapping();
}
......@@ -20,6 +20,7 @@ package org.apache.metadata.types;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.metadata.IStruct;
import org.apache.metadata.ITypedStruct;
import org.apache.metadata.MetadataException;
import org.apache.metadata.Struct;
import org.apache.metadata.storage.StructInstance;
......@@ -28,12 +29,14 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
public class StructType extends AbstractDataType<IStruct> {
public class StructType extends AbstractDataType<IStruct>
implements IConstructableType<IStruct, ITypedStruct> {
public final ITypeBrowser typeSystem;
public final String name;
public final FieldMapping fieldMapping;
public final int numFields;
private final TypedStructHandler handler;
/**
* Used when creating a StructType, to support recursive Structs.
......@@ -43,6 +46,7 @@ public class StructType extends AbstractDataType<IStruct> {
this.name = name;
this.fieldMapping = null;
this.numFields = numFields;
this.handler = null;
}
protected StructType(ITypeBrowser typeSystem, String name,
......@@ -52,6 +56,11 @@ public class StructType extends AbstractDataType<IStruct> {
this.fieldMapping = constructFieldMapping(superTypes,
fields);
this.numFields = this.fieldMapping.fields.size();
this.handler = new TypedStructHandler(this);
}
public FieldMapping fieldMapping() {
return fieldMapping;
}
@Override
......@@ -156,77 +165,21 @@ public class StructType extends AbstractDataType<IStruct> {
@Override
public StructInstance convert(Object val, Multiplicity m) throws MetadataException {
if ( val != null ) {
if ( val instanceof Struct ) {
Struct s = (Struct) val;
if ( s.typeName != name ) {
throw new ValueConversionException(this, val);
}
StructInstance ts = createInstance();
for(Map.Entry<String,AttributeInfo> e : fieldMapping.fields.entrySet() ) {
String attrKey = e.getKey();
AttributeInfo i = e.getValue();
Object aVal = s.get(attrKey);
try {
ts.set(attrKey, aVal);
} catch(ValueConversionException ve) {
throw new ValueConversionException(this, val, ve);
}
}
return ts;
} else if ( val instanceof StructInstance && ((StructInstance)val).getTypeName() == getName() ) {
return (StructInstance) val;
} else {
throw new ValueConversionException(this, val);
}
}
if (!m.nullAllowed() ) {
throw new ValueConversionException.NullConversionException(m);
}
return null;
public DataTypes.TypeCategory getTypeCategory() {
return DataTypes.TypeCategory.STRUCT;
}
@Override
public DataTypes.TypeCategory getTypeCategory() {
return DataTypes.TypeCategory.STRUCT;
public ITypedStruct convert(Object val, Multiplicity m) throws MetadataException {
return handler.convert(val, m);
}
public StructInstance createInstance() {
return new StructInstance(getName(),
fieldMapping,
new boolean[fieldMapping.fields.size()],
fieldMapping.numBools == 0 ? null : new boolean[fieldMapping.numBools],
fieldMapping.numBytes == 0 ? null : new byte[fieldMapping.numBytes],
fieldMapping.numShorts == 0 ? null : new short[fieldMapping.numShorts],
fieldMapping.numInts == 0 ? null : new int[fieldMapping.numInts],
fieldMapping.numLongs == 0 ? null : new long[fieldMapping.numLongs],
fieldMapping.numFloats == 0 ? null : new float[fieldMapping.numFloats],
fieldMapping.numDoubles == 0 ? null : new double[fieldMapping.numDoubles],
fieldMapping.numBigDecimals == 0 ? null : new BigDecimal[fieldMapping.numBigDecimals],
fieldMapping.numBigInts == 0 ? null : new BigInteger[fieldMapping.numBigInts],
fieldMapping.numDates == 0 ? null : new Date[fieldMapping.numDates],
fieldMapping.numStrings == 0 ? null : new String[fieldMapping.numStrings],
fieldMapping.numArrays == 0 ? null : new ImmutableList[fieldMapping.numArrays],
fieldMapping.numMaps == 0 ? null : new ImmutableMap[fieldMapping.numMaps],
fieldMapping.numStructs == 0 ? null : new StructInstance[fieldMapping.numStructs]);
public ITypedStruct createInstance() {
return handler.createInstance();
}
@Override
public void output(IStruct s, Appendable buf, String prefix) throws MetadataException {
TypeUtils.outputVal("{", buf, prefix);
if ( s == null ) {
TypeUtils.outputVal("<null>\n", buf, "");
return;
}
TypeUtils.outputVal("\n", buf, "");
String fieldPrefix = prefix + "\t";
for(AttributeInfo i : fieldMapping.fields.values()) {
Object aVal = s.get(i.name);
TypeUtils.outputVal(i.name + " : ", buf, fieldPrefix);
i.dataType().output(aVal, buf, "");
TypeUtils.outputVal("\n", buf, "");
}
TypeUtils.outputVal("\n}\n", buf, "");
handler.output(s, buf, prefix);
}
}
/**
* 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.metadata.types;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.apache.metadata.IStruct;
import org.apache.metadata.ITypedStruct;
import org.apache.metadata.MetadataException;
import org.apache.metadata.Struct;
import org.apache.metadata.storage.StructInstance;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.Map;
public class TypedStructHandler {
private final IConstructableType<IStruct, ITypedStruct> structType;
private final FieldMapping fieldMapping;
public TypedStructHandler(IConstructableType<IStruct, ITypedStruct> structType) {
this.structType = structType;
fieldMapping = structType.fieldMapping();
}
public ITypedStruct convert(Object val, Multiplicity m) throws MetadataException {
if ( val != null ) {
if ( val instanceof Struct) {
Struct s = (Struct) val;
if ( s.typeName != structType.getName() ) {
throw new ValueConversionException(structType, val);
}
ITypedStruct ts = createInstance();
for(Map.Entry<String,AttributeInfo> e : fieldMapping.fields.entrySet() ) {
String attrKey = e.getKey();
AttributeInfo i = e.getValue();
Object aVal = s.get(attrKey);
try {
ts.set(attrKey, aVal);
} catch(ValueConversionException ve) {
throw new ValueConversionException(structType, val, ve);
}
}
return ts;
} else if ( val instanceof StructInstance && ((StructInstance)val).getTypeName() == structType.getName() ) {
return (StructInstance) val;
} else {
throw new ValueConversionException(structType, val);
}
}
if (!m.nullAllowed() ) {
throw new ValueConversionException.NullConversionException(m);
}
return null;
}
public DataTypes.TypeCategory getTypeCategory() {
return DataTypes.TypeCategory.STRUCT;
}
public ITypedStruct createInstance() {
return new StructInstance(structType.getName(),
fieldMapping,
new boolean[fieldMapping.fields.size()],
fieldMapping.numBools == 0 ? null : new boolean[fieldMapping.numBools],
fieldMapping.numBytes == 0 ? null : new byte[fieldMapping.numBytes],
fieldMapping.numShorts == 0 ? null : new short[fieldMapping.numShorts],
fieldMapping.numInts == 0 ? null : new int[fieldMapping.numInts],
fieldMapping.numLongs == 0 ? null : new long[fieldMapping.numLongs],
fieldMapping.numFloats == 0 ? null : new float[fieldMapping.numFloats],
fieldMapping.numDoubles == 0 ? null : new double[fieldMapping.numDoubles],
fieldMapping.numBigDecimals == 0 ? null : new BigDecimal[fieldMapping.numBigDecimals],
fieldMapping.numBigInts == 0 ? null : new BigInteger[fieldMapping.numBigInts],
fieldMapping.numDates == 0 ? null : new Date[fieldMapping.numDates],
fieldMapping.numStrings == 0 ? null : new String[fieldMapping.numStrings],
fieldMapping.numArrays == 0 ? null : new ImmutableList[fieldMapping.numArrays],
fieldMapping.numMaps == 0 ? null : new ImmutableMap[fieldMapping.numMaps],
fieldMapping.numStructs == 0 ? null : new StructInstance[fieldMapping.numStructs]);
}
public void output(IStruct s, Appendable buf, String prefix) throws MetadataException {
TypeUtils.outputVal("{", buf, prefix);
if ( s == null ) {
TypeUtils.outputVal("<null>\n", buf, "");
return;
}
TypeUtils.outputVal("\n", buf, "");
String fieldPrefix = prefix + "\t";
for(AttributeInfo i : fieldMapping.fields.values()) {
Object aVal = s.get(i.name);
TypeUtils.outputVal(i.name + " : ", buf, fieldPrefix);
i.dataType().output(aVal, buf, "");
TypeUtils.outputVal("\n", buf, "");
}
TypeUtils.outputVal("\n}\n", buf, "");
}
}
......@@ -18,12 +18,12 @@
package org.apache.metadata.dsl
import org.apache.metadata.MetadataService
import org.apache.metadata.{ITypedStruct, MetadataService}
import org.apache.metadata.storage.StructInstance
import org.apache.metadata.types.TypeSystem
import scala.language.dynamics
class DynamicTypedStruct(val ts : StructInstance) extends Dynamic {
class DynamicTypedStruct(val ts : ITypedStruct) extends Dynamic {
def selectDynamic(name: String) = ts.get(name)
def updateDynamic(name: String)(value: Any) {
var value1 = value
......
......@@ -82,7 +82,7 @@ package object dsl {
def createInstance(typeName : String) = {
new DynamicTypedStruct(
ts.getDataType(typeName).asInstanceOf[StructType].createInstance())
ts.getDataType(typeName).asInstanceOf[IConstructableType[IStruct, ITypedStruct]].createInstance())
}
implicit def dynTypedStructToTypedStruct(s : DynamicTypedStruct) = s.ts
......
......@@ -19,7 +19,7 @@
package org.apache.metadata.json
import org.apache.metadata.types.DataTypes.{MapType, TypeCategory, ArrayType}
import org.apache.metadata.{MetadataException, MetadataService}
import org.apache.metadata.{ITypedStruct, IStruct, MetadataException, MetadataService}
import org.apache.metadata.types._
import org.json4s.JsonAST.JInt
import org.json4s._
......@@ -27,7 +27,6 @@ import org.json4s.native.Serialization.{read, write => swrite}
import org.json4s.reflect.{ScalaType, Reflector}
import java.util.regex.Pattern
import java.util.Date
import org.apache.metadata.storage.StructInstance
import collection.JavaConversions._
import scala.collection.JavaConverters._
......@@ -45,7 +44,7 @@ class BigIntegerSerializer extends CustomSerializer[java.math.BigInteger](format
}
))
class TypedStructSerializer extends Serializer[StructInstance] {
class TypedStructSerializer extends Serializer[ITypedStruct] {
def extractList(lT : ArrayType, value : JArray)(implicit format: Formats) : Any = {
val dT = lT.getElemType
......@@ -69,15 +68,15 @@ class TypedStructSerializer extends Serializer[StructInstance] {
case value : JObject if dT.getTypeCategory eq TypeCategory.MAP =>
extractMap(dT.asInstanceOf[MapType], value.asInstanceOf[JObject])
case value : JObject =>
Extraction.extract[StructInstance](value)
Extraction.extract[ITypedStruct](value)
}
def deserialize(implicit format: Formats) = {
case (TypeInfo(clazz, ptype), json) if classOf[StructInstance].isAssignableFrom(clazz) => json match {
case (TypeInfo(clazz, ptype), json) if classOf[ITypedStruct].isAssignableFrom(clazz) => json match {
case JObject(fs) =>
val(typ, fields) = fs.partition(f => f._1 == Serialization.STRUCT_TYPE_FIELD_NAME)
val typName = typ(0)._2.asInstanceOf[JString].s
val sT = MetadataService.getCurrentTypeSystem().getDataType(typName).asInstanceOf[StructType]
val sT = MetadataService.getCurrentTypeSystem().getDataType(typName).asInstanceOf[IConstructableType[IStruct, ITypedStruct]]
val s = sT.createInstance()
fields.foreach { f =>
val fName = f._1
......@@ -85,7 +84,8 @@ class TypedStructSerializer extends Serializer[StructInstance] {
if ( fInfo != null ) {
//println(fName)
var v = f._2
if ( fInfo.dataType().isInstanceOf[StructType] ) {
if ( fInfo.dataType().getTypeCategory == TypeCategory.TRAIT ||
fInfo.dataType().getTypeCategory == TypeCategory.STRUCT) {
v = v match {
case JObject(sFields) =>
JObject(JField(Serialization.STRUCT_TYPE_FIELD_NAME, JString(fInfo.dataType.getName)) :: sFields)
......@@ -109,7 +109,7 @@ class TypedStructSerializer extends Serializer[StructInstance] {
//implicit def javaBigInteger2bigInt(x: java.math.BigInteger): BigInt = new BigInt(x)
def serialize(implicit format: Formats) = {
case e: StructInstance =>
case e: ITypedStruct =>
val fields = e.fieldMapping.fields.map {
case (fName, info) => {
var v = e.get(fName)
......@@ -119,7 +119,7 @@ class TypedStructSerializer extends Serializer[StructInstance] {
JField(fName, Extraction.decompose(v))
}
}.toList.map(_.asInstanceOf[JField])
JObject(JField(Serialization.STRUCT_TYPE_FIELD_NAME, JString(e.dataTypeName)) :: fields)
JObject(JField(Serialization.STRUCT_TYPE_FIELD_NAME, JString(e.getTypeName)) :: fields)
}
}
......
......@@ -38,7 +38,7 @@ public class StructTest extends BaseTest {
@Test
public void test1() throws MetadataException {
Struct s = createStruct(ms);
StructInstance ts = structType.convert(s, Multiplicity.REQUIRED);
ITypedStruct ts = structType.convert(s, Multiplicity.REQUIRED);
System.out.println(ts);
}
......@@ -49,7 +49,7 @@ public class StructTest extends BaseTest {
Struct s2 = new Struct(recursiveStructType.getName());
s2.set("a", 1);
s2.set("s", s1);
StructInstance ts = recursiveStructType.convert(s2, Multiplicity.REQUIRED);
ITypedStruct ts = recursiveStructType.convert(s2, Multiplicity.REQUIRED);
System.out.println(ts);
}
......
......@@ -64,7 +64,7 @@ public class TraitTest extends BaseTest {
s1.set("A.C.D.d", 3);
StructInstance ts = DType.convert(s1, Multiplicity.REQUIRED);
ITypedStruct ts = DType.convert(s1, Multiplicity.REQUIRED);
System.out.println(ts);
/*
......
......@@ -19,11 +19,10 @@
package org.apache.metadata.json
import com.google.common.collect.ImmutableList
import org.apache.metadata.Struct
import org.apache.metadata.{ITypedStruct, Struct, BaseTest}
import org.apache.metadata.storage.StructInstance
import org.apache.metadata.storage.StructInstance
import org.apache.metadata.types._
import org.apache.metadata.{Struct, BaseTest}
import org.json4s.NoTypeHints
import org.junit.Before
import org.junit.Test
......@@ -46,7 +45,7 @@ class SerializationTest extends BaseTest {
@Test def test1 {
val s: Struct = BaseTest.createStruct(ms)
val ts: StructInstance = structType.convert(s, Multiplicity.REQUIRED)
val ts: ITypedStruct = structType.convert(s, Multiplicity.REQUIRED)
println("Typed Struct :")
println(ts)
......@@ -65,7 +64,7 @@ class SerializationTest extends BaseTest {
@Test def test2 {
val s: Struct = BaseTest.createStruct(ms)
val ts: StructInstance = structType.convert(s, Multiplicity.REQUIRED)
val ts: ITypedStruct = structType.convert(s, Multiplicity.REQUIRED)
implicit val formats = org.json4s.native.Serialization.formats(NoTypeHints) + new TypedStructSerializer +
new BigDecimalSerializer + new BigIntegerSerializer
......@@ -108,7 +107,7 @@ class SerializationTest extends BaseTest {
s1.set("A.C.D.d", 3)
val s: Struct = BaseTest.createStruct(ms)
val ts: StructInstance = DType.convert(s1, Multiplicity.REQUIRED)
val ts: ITypedStruct = DType.convert(s1, Multiplicity.REQUIRED)
implicit val formats = org.json4s.native.Serialization.formats(NoTypeHints) + new TypedStructSerializer +
new BigDecimalSerializer + new BigIntegerSerializer
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment