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
