http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
new file mode 100755
index 0000000..6f04fb8
--- /dev/null
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/Id.java
@@ -0,0 +1,242 @@
+/**
+ * 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.atlas.typesystem.persistence;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.atlas.MetadataException;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+import org.apache.atlas.typesystem.types.FieldMapping;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+public class Id implements ITypedReferenceableInstance {
+
+    public final String id;
+    public final String className;
+    public final int version;
+
+    public Id(String id, int version, String className) {
+        this.id = id;
+        this.className = className;
+        this.version = version;
+    }
+
+    public Id(long id, int version, String className) {
+        this("" + id, version, className);
+    }
+
+    public Id(String className) {
+        this("" + (-System.nanoTime()), 0, className);
+    }
+
+    public boolean isUnassigned() {
+        try {
+            long l = Long.parseLong(id);
+            return l < 0;
+        } catch (NumberFormatException ne) {
+            return false;
+        }
+    }
+
+    public boolean isAssigned() {
+        try {
+            UUID.fromString(id);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public String toString() {
+        return String
+                .format("(type: %s, id: %s)", className, isUnassigned() ? 
"<unassigned>" : "" + id);
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public String _getId() {
+        return id;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Id id1 = (Id) o;
+
+        if (version != id1.version) return false;
+        if (!className.equals(id1.className)) return false;
+        if (!id.equals(id1.id)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = id.hashCode();
+        result = 31 * result + className.hashCode();
+        result = 31 * result + version;
+        return result;
+    }
+
+    @Override
+    public ImmutableList<String> getTraits() {
+        return null;
+    }
+
+    @Override
+    public Id getId() {
+        return this;
+    }
+
+    @Override
+    public IStruct getTrait(String typeName) {
+        return null;
+    }
+
+    @Override
+    public String getTypeName() {
+        return className;
+    }
+
+    @Override
+    public Object get(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    @Override
+    public void set(String attrName, Object val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    @Override
+    public FieldMapping fieldMapping() {
+        return null;
+    }
+
+    @Override
+    public Map<String, Object> getValuesMap() throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setNull(String attrName) throws MetadataException {
+        set(attrName, null);
+    }
+
+    public boolean getBoolean(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public byte getByte(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public short getShort(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public int getInt(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public long getLong(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public float getFloat(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public double getDouble(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public BigInteger getBigInt(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public BigDecimal getBigDecimal(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public Date getDate(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public String getString(String attrName) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setBoolean(String attrName, boolean val) throws 
MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setByte(String attrName, byte val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setShort(String attrName, short val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setInt(String attrName, int val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setLong(String attrName, long val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setFloat(String attrName, float val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setDouble(String attrName, double val) throws 
MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setBigInt(String attrName, BigInteger val) throws 
MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setBigDecimal(String attrName, BigDecimal val) throws 
MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setDate(String attrName, Date val) throws MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+
+    public void setString(String attrName, String val) throws 
MetadataException {
+        throw new MetadataException("Get/Set not supported on an Id object");
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/MapIds.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/MapIds.java 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/MapIds.java
new file mode 100755
index 0000000..8dae5a3
--- /dev/null
+++ 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/MapIds.java
@@ -0,0 +1,71 @@
+/**
+ * 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.atlas.typesystem.persistence;
+
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableMap;
+import org.apache.atlas.MetadataException;
+import org.apache.atlas.typesystem.IReferenceableInstance;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.atlas.typesystem.types.ObjectGraphWalker;
+
+import java.util.Map;
+
+public class MapIds implements ObjectGraphWalker.NodeProcessor {
+
+    final Map<Id, Id> idToNewIdMap;
+
+    public MapIds(Map<Id, Id> idToNewIdMap) {
+        this.idToNewIdMap = idToNewIdMap;
+    }
+
+    @Override
+    public void processNode(ObjectGraphWalker.Node nd) throws 
MetadataException {
+
+        IReferenceableInstance ref = null;
+        Id id = null;
+
+        if (nd.attributeName == null) {
+            ref = (IReferenceableInstance) nd.instance;
+            Id newId = idToNewIdMap.get(ref.getId());
+            if (newId != null) {
+                ((ReferenceableInstance) ref).replaceWithNewId(newId);
+            }
+        } else if (nd.aInfo.dataType().getTypeCategory() == 
DataTypes.TypeCategory.CLASS) {
+            if (nd.value != null && nd.value instanceof 
IReferenceableInstance) {
+                Id oldId = ((IReferenceableInstance) nd.value).getId();
+                Id newId = idToNewIdMap.get(oldId);
+                /*
+                 * Replace Instances with Ids, irrespective of whether they 
map to newIds or not.
+                 */
+                newId = newId == null ? oldId : newId;
+                nd.instance.set(nd.attributeName, newId);
+            }
+        } else if (nd.aInfo.dataType().getTypeCategory() == 
DataTypes.TypeCategory.ARRAY) {
+            DataTypes.ArrayType aT = (DataTypes.ArrayType) nd.aInfo.dataType();
+            Object v = aT
+                    .mapIds((ImmutableCollection) nd.value, 
nd.aInfo.multiplicity, idToNewIdMap);
+            nd.instance.set(nd.attributeName, v);
+        } else if (nd.aInfo.dataType().getTypeCategory() == 
DataTypes.TypeCategory.MAP) {
+            DataTypes.MapType mT = (DataTypes.MapType) nd.aInfo.dataType();
+            Object v = mT.mapIds((ImmutableMap) nd.value, 
nd.aInfo.multiplicity, idToNewIdMap);
+            nd.instance.set(nd.attributeName, v);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
new file mode 100755
index 0000000..1ec8e07
--- /dev/null
+++ 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/ReferenceableInstance.java
@@ -0,0 +1,103 @@
+/**
+ * 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.atlas.typesystem.persistence;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.atlas.MetadataException;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+import org.apache.atlas.typesystem.ITypedStruct;
+import org.apache.atlas.typesystem.types.FieldMapping;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+/*
+ * @todo handle names prefixed by traitName.
+ */
+public class ReferenceableInstance extends StructInstance implements 
ITypedReferenceableInstance {
+
+    private final ImmutableMap<String, ITypedStruct> traits;
+    private final ImmutableList<String> traitNames;
+    private Id id;
+
+
+    public ReferenceableInstance(Id id, String dataTypeName, FieldMapping 
fieldMapping,
+                                 boolean[] nullFlags,
+                                 boolean[] bools, byte[] bytes, short[] 
shorts, int[] ints,
+                                 long[] longs,
+                                 float[] floats, double[] doubles, 
BigDecimal[] bigDecimals,
+                                 BigInteger[] bigIntegers, Date[] dates, 
String[] strings,
+                                 ImmutableList<Object>[] arrays,
+                                 ImmutableMap<Object, Object>[] maps,
+                                 StructInstance[] structs,
+                                 ReferenceableInstance[] 
referenceableInstances,
+                                 Id[] ids,
+                                 ImmutableMap<String, ITypedStruct> traits) {
+        super(dataTypeName, fieldMapping, nullFlags, bools, bytes, shorts, 
ints, longs, floats,
+                doubles, bigDecimals,
+                bigIntegers, dates, strings, arrays, maps, structs, 
referenceableInstances, ids);
+        this.id = id;
+        this.traits = traits;
+        ImmutableList.Builder<String> b = new ImmutableList.Builder<String>();
+        for (String t : traits.keySet()) {
+            b.add(t);
+        }
+        this.traitNames = b.build();
+    }
+
+    @Override
+    public ImmutableList<String> getTraits() {
+        return traitNames;
+    }
+
+    @Override
+    public Id getId() {
+        return id;
+    }
+
+    @Override
+    public IStruct getTrait(String typeName) {
+        return traits.get(typeName);
+    }
+
+    /**
+     * @nopub
+     * @param id
+     */
+    void replaceWithNewId(Id id) {
+        this.id = id;
+    }
+
+    @Override
+    public String toString() {
+        try {
+            StringBuilder buf = new StringBuilder();
+            String prefix = "";
+
+            fieldMapping.output(this, buf, prefix);
+            return buf.toString();
+
+        } catch (MetadataException me) {
+            throw new RuntimeException(me);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/StructInstance.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/StructInstance.java
 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/StructInstance.java
new file mode 100755
index 0000000..cf89bb0
--- /dev/null
+++ 
b/typesystem/src/main/java/org/apache/atlas/typesystem/persistence/StructInstance.java
@@ -0,0 +1,757 @@
+/**
+ * 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.atlas.typesystem.persistence;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.atlas.MetadataException;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedStruct;
+import org.apache.atlas.typesystem.types.AttributeInfo;
+import org.apache.atlas.typesystem.types.ClassType;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.atlas.typesystem.types.EnumType;
+import org.apache.atlas.typesystem.types.EnumValue;
+import org.apache.atlas.typesystem.types.FieldMapping;
+import org.apache.atlas.typesystem.types.TypeSystem;
+import org.apache.atlas.typesystem.types.TypeUtils;
+import org.apache.atlas.typesystem.types.ValueConversionException;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+public class StructInstance implements ITypedStruct {
+    public final String dataTypeName;
+    public final FieldMapping fieldMapping;
+    public final boolean nullFlags[];
+    public final boolean[] bools;
+    public final byte[] bytes;
+    public final short[] shorts;
+    public final int[] ints;
+    public final long[] longs;
+    public final float[] floats;
+    public final double[] doubles;
+    public final BigDecimal[] bigDecimals;
+    public final BigInteger[] bigIntegers;
+    public final Date[] dates;
+    public final String[] strings;
+    public final ImmutableList<Object>[] arrays;
+    public final ImmutableMap<Object, Object>[] maps;
+    public final StructInstance[] structs;
+    public final ReferenceableInstance[] referenceables;
+    public final Id[] ids;
+
+    public StructInstance(String dataTypeName, FieldMapping fieldMapping,
+                          boolean[] nullFlags, boolean[] bools, byte[] bytes, 
short[] shorts,
+                          int[] ints,
+                          long[] longs, float[] floats, double[] doubles,
+                          BigDecimal[] bigDecimals, BigInteger[] bigIntegers, 
Date[] dates,
+                          String[] strings,
+                          ImmutableList<Object>[] arrays, ImmutableMap<Object, 
Object>[] maps,
+                          StructInstance[] structs, ReferenceableInstance[] 
referenceables,
+                          Id[] ids) {
+        assert dataTypeName != null;
+        this.dataTypeName = dataTypeName;
+        this.fieldMapping = fieldMapping;
+        this.nullFlags = nullFlags;
+        this.bools = bools;
+        this.bytes = bytes;
+        this.shorts = shorts;
+        this.ints = ints;
+        this.longs = longs;
+        this.floats = floats;
+        this.doubles = doubles;
+        this.bigDecimals = bigDecimals;
+        this.bigIntegers = bigIntegers;
+        this.dates = dates;
+        this.strings = strings;
+        this.arrays = arrays;
+        this.maps = maps;
+        this.structs = structs;
+        this.referenceables = referenceables;
+        this.ids = ids;
+
+        for (int i = 0; i < nullFlags.length; i++) {
+            nullFlags[i] = true;
+        }
+    }
+
+    @Override
+    public String getTypeName() {
+        return dataTypeName;
+    }
+
+    @Override
+    public FieldMapping fieldMapping() {
+        return fieldMapping;
+    }
+
+    public void set(String attrName, Object val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new ValueConversionException(getTypeName(), val, "Unknown 
field " + attrName);
+        }
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+        Object cVal = null;
+
+        if (val != null && val instanceof Id) {
+            ClassType clsType =
+                    TypeSystem.getInstance().getDataType(ClassType.class, 
i.dataType().getName());
+            clsType.validateId((Id) val);
+            cVal = val;
+        } else {
+            cVal = i.dataType().convert(val, i.multiplicity);
+        }
+        if (cVal == null) {
+            nullFlags[nullPos] = true;
+            return;
+        }
+        nullFlags[nullPos] = false;
+        if (i.dataType() == DataTypes.BOOLEAN_TYPE) {
+            bools[pos] = ((Boolean) cVal).booleanValue();
+        } else if (i.dataType() == DataTypes.BYTE_TYPE) {
+            bytes[pos] = ((Byte) cVal).byteValue();
+        } else if (i.dataType() == DataTypes.SHORT_TYPE) {
+            shorts[pos] = ((Short) cVal).shortValue();
+        } else if (i.dataType() == DataTypes.INT_TYPE) {
+            ints[pos] = ((Integer) cVal).intValue();
+        } else if (i.dataType() == DataTypes.LONG_TYPE) {
+            longs[pos] = ((Long) cVal).longValue();
+        } else if (i.dataType() == DataTypes.FLOAT_TYPE) {
+            floats[pos] = ((Float) cVal).floatValue();
+        } else if (i.dataType() == DataTypes.DOUBLE_TYPE) {
+            doubles[pos] = ((Double) cVal).doubleValue();
+        } else if (i.dataType() == DataTypes.BIGINTEGER_TYPE) {
+            bigIntegers[pos] = (BigInteger) cVal;
+        } else if (i.dataType() == DataTypes.BIGDECIMAL_TYPE) {
+            bigDecimals[pos] = (BigDecimal) cVal;
+        } else if (i.dataType() == DataTypes.DATE_TYPE) {
+            dates[pos] = (Date) cVal;
+        } else if (i.dataType() == DataTypes.STRING_TYPE) {
+            strings[pos] = (String) cVal;
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.ENUM) {
+            ints[pos] = ((EnumValue) cVal).ordinal;
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.ARRAY) {
+            arrays[pos] = (ImmutableList) cVal;
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.MAP) {
+            maps[pos] = (ImmutableMap) cVal;
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.STRUCT ||
+                i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.TRAIT) {
+            structs[pos] = (StructInstance) cVal;
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.CLASS) {
+            if (cVal instanceof Id) {
+                ids[pos] = (Id) cVal;
+            } else {
+                referenceables[pos] = (ReferenceableInstance) cVal;
+            }
+        } else {
+            throw new MetadataException(String.format("Unknown datatype %s", 
i.dataType()));
+        }
+    }
+
+    public Object get(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return null;
+        }
+
+        if (i.dataType() == DataTypes.BOOLEAN_TYPE) {
+            return bools[pos];
+        } else if (i.dataType() == DataTypes.BYTE_TYPE) {
+            return bytes[pos];
+        } else if (i.dataType() == DataTypes.SHORT_TYPE) {
+            return shorts[pos];
+        } else if (i.dataType() == DataTypes.INT_TYPE) {
+            return ints[pos];
+        } else if (i.dataType() == DataTypes.LONG_TYPE) {
+            return longs[pos];
+        } else if (i.dataType() == DataTypes.FLOAT_TYPE) {
+            return floats[pos];
+        } else if (i.dataType() == DataTypes.DOUBLE_TYPE) {
+            return doubles[pos];
+        } else if (i.dataType() == DataTypes.BIGINTEGER_TYPE) {
+            return bigIntegers[pos];
+        } else if (i.dataType() == DataTypes.BIGDECIMAL_TYPE) {
+            return bigDecimals[pos];
+        } else if (i.dataType() == DataTypes.DATE_TYPE) {
+            return dates[pos];
+        } else if (i.dataType() == DataTypes.STRING_TYPE) {
+            return strings[pos];
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.ENUM) {
+            return ((EnumType) i.dataType()).fromOrdinal(ints[pos]);
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.ARRAY) {
+            return arrays[pos];
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.MAP) {
+            return maps[pos];
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.STRUCT ||
+                i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.TRAIT) {
+            return structs[pos];
+        } else if (i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.CLASS) {
+            if (ids[pos] != null) {
+                return ids[pos];
+            } else {
+                return referenceables[pos];
+            }
+        } else {
+            throw new MetadataException(String.format("Unknown datatype %s", 
i.dataType()));
+        }
+    }
+
+    public void setNull(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+        nullFlags[nullPos] = true;
+    }
+
+    /*
+     * Use only for json serialization
+     * @nonpublic
+     */
+    @Override
+    public Map<String, Object> getValuesMap() throws MetadataException {
+
+        Map<String,Object> m = new HashMap<>();
+        for (String attr : fieldMapping.fields.keySet()) {
+            m.put(attr, get(attr));
+        }
+        return m;
+    }
+
+    public boolean getBoolean(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BOOLEAN_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.BOOLEAN_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.BOOLEAN_TYPE.nullValue();
+        }
+
+        return bools[pos];
+    }
+
+    public byte getByte(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BYTE_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.BYTE_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.BYTE_TYPE.nullValue();
+        }
+
+        return bytes[pos];
+    }
+
+    public short getShort(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.SHORT_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.SHORT_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.SHORT_TYPE.nullValue();
+        }
+
+        return shorts[pos];
+    }
+
+    public int getInt(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+
+        if (i.dataType() != DataTypes.INT_TYPE && !(i.dataType() instanceof 
EnumType)) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.INT_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.INT_TYPE.nullValue();
+        }
+
+        return ints[pos];
+    }
+
+    public long getLong(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.LONG_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.LONG_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.LONG_TYPE.nullValue();
+        }
+
+        return longs[pos];
+    }
+
+    public float getFloat(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.FLOAT_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.FLOAT_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.FLOAT_TYPE.nullValue();
+        }
+
+        return floats[pos];
+    }
+
+    public double getDouble(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.DOUBLE_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.DOUBLE_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.DOUBLE_TYPE.nullValue();
+        }
+
+        return doubles[pos];
+    }
+
+    public BigInteger getBigInt(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BIGINTEGER_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.BIGINTEGER_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.BIGINTEGER_TYPE.nullValue();
+        }
+
+        return bigIntegers[pos];
+    }
+
+    public BigDecimal getBigDecimal(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BIGDECIMAL_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.BIGDECIMAL_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.BIGDECIMAL_TYPE.nullValue();
+        }
+
+        return bigDecimals[pos];
+    }
+
+    public Date getDate(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.DATE_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.DATE_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.DATE_TYPE.nullValue();
+        }
+
+        return dates[pos];
+    }
+
+    public String getString(String attrName) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.STRING_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic get method",
+                            attrName, getTypeName(), 
DataTypes.STRING_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        if (nullFlags[nullPos]) {
+            return DataTypes.STRING_TYPE.nullValue();
+        }
+
+        return strings[pos];
+    }
+
+    public void setBoolean(String attrName, boolean val) throws 
MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BOOLEAN_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.BOOLEAN_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        bools[pos] = val;
+    }
+
+    public void setByte(String attrName, byte val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BYTE_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.BYTE_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        bytes[pos] = val;
+    }
+
+    public void setShort(String attrName, short val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.SHORT_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.SHORT_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        shorts[pos] = val;
+    }
+
+    public void setInt(String attrName, int val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.INT_TYPE && !(i.dataType() instanceof 
EnumType)) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.INT_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        ints[pos] = val;
+    }
+
+    public void setLong(String attrName, long val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.LONG_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.LONG_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        longs[pos] = val;
+    }
+
+    public void setFloat(String attrName, float val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.FLOAT_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.FLOAT_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        floats[pos] = val;
+    }
+
+    public void setDouble(String attrName, double val) throws 
MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.DOUBLE_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.DOUBLE_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = false;
+        doubles[pos] = val;
+    }
+
+    public void setBigInt(String attrName, BigInteger val) throws 
MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BIGINTEGER_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.BIGINTEGER_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = val == null;
+        bigIntegers[pos] = val;
+    }
+
+    public void setBigDecimal(String attrName, BigDecimal val) throws 
MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.BIGDECIMAL_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.BIGDECIMAL_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = val == null;
+        bigDecimals[pos] = val;
+    }
+
+    public void setDate(String attrName, Date val) throws MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.DATE_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.DATE_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = val == null;
+        dates[pos] = val;
+    }
+
+    public void setString(String attrName, String val) throws 
MetadataException {
+        AttributeInfo i = fieldMapping.fields.get(attrName);
+        if (i == null) {
+            throw new MetadataException(
+                    String.format("Unknown field %s for Struct %s", attrName, 
getTypeName()));
+        }
+
+        if (i.dataType() != DataTypes.STRING_TYPE) {
+            throw new MetadataException(
+                    String.format("Field %s for Struct %s is not a %s, call 
generic set method",
+                            attrName, getTypeName(), 
DataTypes.STRING_TYPE.getName()));
+        }
+
+        int pos = fieldMapping.fieldPos.get(attrName);
+        int nullPos = fieldMapping.fieldNullPos.get(attrName);
+
+        nullFlags[nullPos] = val == null;
+        strings[pos] = val;
+    }
+
+    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 (Map.Entry<String, AttributeInfo> e : 
fieldMapping.fields.entrySet()) {
+            String attrName = e.getKey();
+            AttributeInfo i = e.getValue();
+            Object aVal = s.get(attrName);
+            TypeUtils.outputVal(attrName + " : ", buf, fieldPrefix);
+            i.dataType().output(aVal, buf, "");
+            TypeUtils.outputVal("\n", buf, "");
+        }
+        TypeUtils.outputVal("\n}\n", buf, "");
+    }
+
+    @Override
+    public String toString() {
+        try {
+            StringBuilder buf = new StringBuilder();
+            String prefix = "";
+
+            fieldMapping.output(this, buf, prefix);
+            return buf.toString();
+
+        } catch (MetadataException me) {
+            throw new RuntimeException(me);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/types/AbstractDataType.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/types/AbstractDataType.java
 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/AbstractDataType.java
new file mode 100755
index 0000000..a3287fc
--- /dev/null
+++ 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/AbstractDataType.java
@@ -0,0 +1,37 @@
+/**
+ * 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.atlas.typesystem.types;
+
+import org.apache.atlas.MetadataException;
+
+abstract class AbstractDataType<T> implements IDataType<T> {
+
+    protected T convertNull(Multiplicity m) throws MetadataException {
+        if (!m.nullAllowed()) {
+            throw new ValueConversionException.NullConversionException(m);
+        }
+        return null;
+    }
+
+    @Override
+    public void output(T val, Appendable buf, String prefix) throws 
MetadataException {
+        TypeUtils.outputVal(val == null ? "<null>" : val.toString(), buf, 
prefix);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeDefinition.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeDefinition.java
 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeDefinition.java
new file mode 100755
index 0000000..e18305f
--- /dev/null
+++ 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeDefinition.java
@@ -0,0 +1,93 @@
+/**
+ * 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.atlas.typesystem.types;
+
+import org.apache.atlas.ParamChecker;
+
+public final class AttributeDefinition {
+
+    public final String name;
+    public final String dataTypeName;
+    public final Multiplicity multiplicity;
+    public final boolean isComposite;
+    public final boolean isUnique;
+    public final boolean isIndexable;
+
+    /**
+     * If this is a reference attribute, then the name of the attribute on the 
Class
+     * that this refers to.
+     */
+    public final String reverseAttributeName;
+
+    public AttributeDefinition(String name, String dataTypeName, Multiplicity 
multiplicity,
+                               boolean isComposite, String 
reverseAttributeName) {
+        this(name, dataTypeName, multiplicity, isComposite, false, true, 
reverseAttributeName);
+
+    }
+
+    public AttributeDefinition(String name, String dataTypeName,
+                               Multiplicity multiplicity, boolean isComposite, 
boolean isUnique,
+                               boolean isIndexable, String 
reverseAttributeName) {
+        this.name = ParamChecker.notEmpty(name, "Attribute name");
+        this.dataTypeName = ParamChecker.notEmpty(dataTypeName, "Attribute 
type");
+        this.multiplicity = multiplicity;
+        this.isComposite = isComposite;
+        this.isUnique = isUnique;
+        this.isIndexable = isIndexable;
+        this.reverseAttributeName = 
ParamChecker.notEmptyIfNotNull(reverseAttributeName, "Reverse attribute name");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AttributeDefinition that = (AttributeDefinition) o;
+
+        if (isComposite != that.isComposite) return false;
+        if (isUnique != that.isUnique) return false;
+        if (isIndexable != that.isIndexable) return false;
+        if (!dataTypeName.equals(that.dataTypeName)) return false;
+        if (!multiplicity.equals(that.multiplicity)) return false;
+        if (!name.equals(that.name)) return false;
+        if (reverseAttributeName != null
+                ? !reverseAttributeName.equals(that.reverseAttributeName)
+                : that.reverseAttributeName != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = 31 * result + dataTypeName.hashCode();
+        result = 31 * result + multiplicity.hashCode();
+        result = 31 * result + (isComposite ? 1 : 0);
+        result = 31 * result + (isUnique ? 1 : 0);
+        result = 31 * result + (isIndexable ? 1 : 0);
+        result = 31 * result + (reverseAttributeName != null ? 
reverseAttributeName.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeInfo.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeInfo.java 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeInfo.java
new file mode 100755
index 0000000..8761013
--- /dev/null
+++ 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/AttributeInfo.java
@@ -0,0 +1,94 @@
+/**
+ * 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.atlas.typesystem.types;
+
+import org.apache.atlas.MetadataException;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+
+import java.util.Map;
+
+public class AttributeInfo {
+    public final String name;
+    public final Multiplicity multiplicity;
+    public final boolean isComposite;
+    public final boolean isUnique;
+    public final boolean isIndexable;
+    /**
+     * If this is a reference attribute, then the name of the attribute on the 
Class
+     * that this refers to.
+     */
+    public final String reverseAttributeName;
+    private IDataType dataType;
+
+    AttributeInfo(TypeSystem t, AttributeDefinition def, Map<String, 
IDataType> tempTypes) throws MetadataException {
+        this.name = def.name;
+        this.dataType = (tempTypes != null && 
tempTypes.containsKey(def.dataTypeName)) ?
+                tempTypes.get(def.dataTypeName) : 
t.getDataType(IDataType.class, def.dataTypeName);
+        this.multiplicity = def.multiplicity;
+        this.isComposite = def.isComposite;
+        this.isUnique = def.isUnique;
+        this.isIndexable = def.isIndexable;
+        this.reverseAttributeName = def.reverseAttributeName;
+    }
+
+    public IDataType dataType() {
+        return dataType;
+    }
+
+    void setDataType(IDataType dT) {
+        dataType = dT;
+    }
+
+    @Override
+    public String toString() {
+        return "AttributeInfo{" +
+                "name='" + name + '\'' +
+                ", dataType=" + dataType +
+                ", multiplicity=" + multiplicity +
+                ", isComposite=" + isComposite +
+                ", isUnique=" + isUnique +
+                ", isIndexable=" + isIndexable +
+                ", reverseAttributeName='" + reverseAttributeName + '\'' +
+                '}';
+    }
+
+    public String toJson() throws JSONException {
+        JSONObject json = new JSONObject();
+        json.put("name", name);
+        json.put("multiplicity", multiplicity.toJson());
+        json.put("isComposite", isComposite);
+        json.put("isUnique", isUnique);
+        json.put("isIndexable", isIndexable);
+        json.put("dataType", dataType.getName());
+        json.put("reverseAttributeName", reverseAttributeName);
+        return json.toString();
+    }
+
+    public static AttributeDefinition fromJson(String jsonStr) throws 
JSONException {
+        JSONObject json = new JSONObject(jsonStr);
+        String reverseAttr = null;
+        if (json.has("reverseAttributeName")) {
+            reverseAttr = json.getString("reverseAttributeName");
+        }
+        return new AttributeDefinition(json.getString("name"), 
json.getString("dataType"),
+                Multiplicity.fromJson(json.getString("multiplicity")), 
json.getBoolean("isComposite"),
+                json.getBoolean("isUnique"), json.getBoolean("isIndexable"), 
reverseAttr);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/30711973/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
----------------------------------------------------------------------
diff --git 
a/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java 
b/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
new file mode 100755
index 0000000..f7b2721
--- /dev/null
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/ClassType.java
@@ -0,0 +1,231 @@
+/**
+ * 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.atlas.typesystem.types;
+
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.atlas.MetadataException;
+import org.apache.atlas.typesystem.IReferenceableInstance;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+import org.apache.atlas.typesystem.ITypedStruct;
+import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.typesystem.Struct;
+import org.apache.atlas.typesystem.persistence.Id;
+import org.apache.atlas.typesystem.persistence.ReferenceableInstance;
+import org.apache.atlas.typesystem.persistence.StructInstance;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+public class ClassType extends HierarchicalType<ClassType, 
IReferenceableInstance>
+        implements IConstructableType<IReferenceableInstance, 
ITypedReferenceableInstance> {
+
+    public static final String TRAIT_NAME_SEP = "::";
+
+    public final Map<AttributeInfo, List<String>> infoToNameMap;
+
+    /**
+     * Used when creating a ClassType, to support recursive Structs.
+     */
+    ClassType(TypeSystem typeSystem, String name, ImmutableList<String> 
superTypes, int numFields) {
+        super(typeSystem, ClassType.class, name, superTypes, numFields);
+        infoToNameMap = null;
+    }
+
+    ClassType(TypeSystem typeSystem, String name, ImmutableList<String> 
superTypes,
+              AttributeInfo... fields)
+    throws MetadataException {
+        super(typeSystem, ClassType.class, name, superTypes, fields);
+        infoToNameMap = TypeUtils.buildAttrInfoToNameMap(fieldMapping);
+    }
+
+    @Override
+    public DataTypes.TypeCategory getTypeCategory() {
+        return DataTypes.TypeCategory.CLASS;
+    }
+
+    public void validateId(Id id) throws MetadataException {
+        if (id != null) {
+            ClassType cType = typeSystem.getDataType(ClassType.class, 
id.className);
+            if (isSubType(cType.getName())) {
+                return;
+            }
+            throw new MetadataException(
+                    String.format("Id %s is not valid for class %s", id, 
getName()));
+        }
+    }
+
+    protected Id getId(Object val) throws MetadataException {
+        if (val instanceof Referenceable) {
+            return ((Referenceable) val).getId();
+        }
+        throw new MetadataException(String.format("Cannot get id from class 
%s", val.getClass()));
+    }
+
+    @Override
+    public ITypedReferenceableInstance convert(Object val, Multiplicity m)
+    throws MetadataException {
+
+        if (val != null) {
+            if (val instanceof ITypedReferenceableInstance) {
+                ITypedReferenceableInstance tr = (ITypedReferenceableInstance) 
val;
+                if (!tr.getTypeName().equals(getName())) {
+                     /*
+                     * If val is a subType instance; invoke convert on it.
+                     */
+                    ClassType valType = typeSystem.getDataType(superTypeClass, 
tr.getTypeName());
+                    if (valType.superTypePaths.containsKey(name)) {
+                        return valType.convert(val, m);
+                    }
+                    throw new ValueConversionException(this, val);
+                }
+                return tr;
+            } else if (val instanceof Struct) {
+                Struct s = (Struct) val;
+                Referenceable r = null;
+                Id id = null;
+
+                if (!s.typeName.equals(getName())) {
+                    /*
+                     * If val is a subType instance; invoke convert on it.
+                     */
+                    ClassType valType = typeSystem.getDataType(superTypeClass, 
s.typeName);
+                    if (valType.superTypePaths.containsKey(name)) {
+                        return valType.convert(s, m);
+                    }
+                    throw new ValueConversionException(this, val);
+                }
+
+                if (val instanceof Referenceable) {
+                    r = (Referenceable) val;
+                    id = r.getId();
+                }
+
+                ITypedReferenceableInstance tr = r != null ?
+                        createInstanceWithTraits(id, r, 
r.getTraits().toArray(new String[0]))
+                        : createInstance(id);
+
+                if (id != null && id.isAssigned()) {
+                    return tr;
+                }
+
+                for (Map.Entry<String, AttributeInfo> e : 
fieldMapping.fields.entrySet()) {
+                    String attrKey = e.getKey();
+                    AttributeInfo i = e.getValue();
+                    Object aVal = s.get(attrKey);
+                    if (aVal != null &&
+                            i.dataType().getTypeCategory() == 
DataTypes.TypeCategory.CLASS) {
+                        if (!i.isComposite) {
+                            aVal = ((IReferenceableInstance) aVal).getId();
+                        }
+                    }
+
+                    try {
+                        tr.set(attrKey, aVal);
+                    } catch (ValueConversionException ve) {
+                        throw new ValueConversionException(this, val, ve);
+                    }
+                }
+
+                return tr;
+            } else if (val instanceof ReferenceableInstance) {
+                validateId(((ReferenceableInstance) val).getId());
+                return (ReferenceableInstance) val;
+            } else {
+                throw new ValueConversionException(this, val);
+            }
+        }
+        if (!m.nullAllowed()) {
+            throw new ValueConversionException.NullConversionException(m);
+        }
+        return null;
+    }
+
+    @Override
+    public ITypedReferenceableInstance createInstance() throws 
MetadataException {
+        return createInstance((String[])null);
+    }
+
+    public ITypedReferenceableInstance createInstance(String... traitNames)
+    throws MetadataException {
+        return createInstance(null, traitNames);
+    }
+
+    public ITypedReferenceableInstance createInstance(Id id, String... 
traitNames)
+    throws MetadataException {
+        return createInstanceWithTraits(id, null, traitNames);
+    }
+
+    public ITypedReferenceableInstance createInstanceWithTraits(Id id, 
Referenceable r,
+                                                                String... 
traitNames)
+    throws MetadataException {
+
+        ImmutableMap.Builder<String, ITypedStruct> b
+                = new ImmutableBiMap.Builder<String, ITypedStruct>();
+        if (traitNames != null) {
+            for (String t : traitNames) {
+                TraitType tType = typeSystem.getDataType(TraitType.class, t);
+                IStruct iTraitObject = r == null ? null : r.getTrait(t);
+                ITypedStruct trait = iTraitObject == null ? 
tType.createInstance() :
+                        tType.convert(iTraitObject, Multiplicity.REQUIRED);
+                b.put(t, trait);
+            }
+        }
+
+        return new ReferenceableInstance(id == null ? new Id(getName()) : id,
+                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],
+                fieldMapping.numReferenceables == 0 ? null
+                        : new 
ReferenceableInstance[fieldMapping.numReferenceables],
+                fieldMapping.numReferenceables == 0 ? null : new 
Id[fieldMapping.numReferenceables],
+                b.build());
+    }
+
+    @Override
+    public void output(IReferenceableInstance s, Appendable buf, String prefix)
+    throws MetadataException {
+        fieldMapping.output(s, buf, prefix);
+    }
+
+    @Override
+    public List<String> getNames(AttributeInfo info) {
+        return infoToNameMap.get(info);
+    }
+}
\ No newline at end of file

Reply via email to