blob: 385a9ae9ba83dcde2077220bf752f92ec00522ff [file] [log] [blame]
/**
* 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.type;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.TypeCategory;
import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
/**
* class that implements behaviour of a map-type.
*/
public class AtlasMapType extends AtlasType {
private static final Logger LOG = LoggerFactory.getLogger(AtlasEntityType.class);
private final String keyTypeName;
private final String valueTypeName;
private AtlasType keyType;
private AtlasType valueType;
public AtlasMapType(String keyTypeName, String valueTypeName) {
super(AtlasBaseTypeDef.getMapTypeName(keyTypeName, valueTypeName), TypeCategory.MAP);
this.keyTypeName = keyTypeName;
this.valueTypeName = valueTypeName;
}
public AtlasMapType(AtlasType keyType, AtlasType valueType) {
super(AtlasBaseTypeDef.getMapTypeName(keyType.getTypeName(), valueType.getTypeName()), TypeCategory.MAP);
this.keyTypeName = keyType.getTypeName();
this.valueTypeName = valueType.getTypeName();
this.keyType = keyType;
this.valueType = valueType;
}
public AtlasMapType(String keyTypeName, String valueTypeName, AtlasTypeRegistry typeRegistry)
throws AtlasBaseException {
super(AtlasBaseTypeDef.getMapTypeName(keyTypeName, valueTypeName), TypeCategory.MAP);
this.keyTypeName = keyTypeName;
this.valueTypeName = valueTypeName;
resolveReferences(typeRegistry);
}
public String getKeyTypeName() {
return keyTypeName;
}
public String getValueTypeName() {
return valueTypeName;
}
public AtlasType getKeyType() {
return keyType;
}
public AtlasType getValueType() {
return valueType;
}
public void setKeyType(AtlasType keyType) {
this.keyType = keyType;
}
@Override
public void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
this.keyType = typeRegistry.getType(keyTypeName);
this.valueType = typeRegistry.getType(valueTypeName);
}
@Override
public Map<Object, Object> createDefaultValue() {
Map<Object, Object> ret = new HashMap<>();
Object key = keyType.createDefaultValue();
if ( key != null) {
ret.put(key, valueType.createDefaultValue());
}
return ret;
}
@Override
public boolean isValidValue(Object obj) {
if (obj != null) {
if (obj instanceof Map) {
Map<Object, Objects> map = (Map<Object, Objects>) obj;
for (Map.Entry e : map.entrySet()) {
if (!keyType.isValidValue(e.getKey()) || !valueType.isValidValue(e.getValue())) {
return false; // invalid key/value
}
}
} else {
return false; // invalid type
}
}
return true;
}
@Override
public boolean isValidValueForUpdate(Object obj) {
if (obj != null) {
if (obj instanceof Map) {
Map<Object, Objects> map = (Map<Object, Objects>) obj;
for (Map.Entry e : map.entrySet()) {
if (!keyType.isValidValueForUpdate(e.getKey()) || !valueType.isValidValueForUpdate(e.getValue())) {
return false; // invalid key/value
}
}
} else {
return false; // invalid type
}
}
return true;
}
@Override
public Map<Object, Object> getNormalizedValue(Object obj) {
if (obj == null) {
return null;
}
if (obj instanceof Map) {
Map<Object, Object> ret = new HashMap<>();
Map<Object, Objects> map = (Map<Object, Objects>) obj;
for (Map.Entry e : map.entrySet()) {
Object normalizedKey = keyType.getNormalizedValue(e.getKey());
if (normalizedKey != null) {
Object value = e.getValue();
if (value != null) {
Object normalizedValue = valueType.getNormalizedValue(e.getValue());
if (normalizedValue != null) {
ret.put(normalizedKey, normalizedValue);
} else {
return null; // invalid value
}
} else {
ret.put(normalizedKey, value);
}
} else {
return null; // invalid key
}
}
return ret;
}
return null;
}
@Override
public Map<Object, Object> getNormalizedValueForUpdate(Object obj) {
if (obj == null) {
return null;
}
if (obj instanceof Map) {
Map<Object, Object> ret = new HashMap<>();
Map<Object, Objects> map = (Map<Object, Objects>) obj;
for (Map.Entry e : map.entrySet()) {
Object normalizedKey = keyType.getNormalizedValueForUpdate(e.getKey());
if (normalizedKey != null) {
Object value = e.getValue();
if (value != null) {
Object normalizedValue = valueType.getNormalizedValueForUpdate(e.getValue());
if (normalizedValue != null) {
ret.put(normalizedKey, normalizedValue);
} else {
return null; // invalid value
}
} else {
ret.put(normalizedKey, value);
}
} else {
return null; // invalid key
}
}
return ret;
}
return null;
}
@Override
public boolean validateValue(Object obj, String objName, List<String> messages) {
boolean ret = true;
if (obj != null) {
if (obj instanceof Map) {
Map<Object, Objects> map = (Map<Object, Objects>) obj;
for (Map.Entry e : map.entrySet()) {
Object key = e.getKey();
if (!keyType.isValidValue(key)) {
ret = false;
messages.add(objName + "." + key + ": invalid key for type " + getTypeName());
} else {
Object value = e.getValue();
ret = valueType.validateValue(value, objName + "." + key, messages) && ret;
}
}
} else {
ret = false;
messages.add(objName + "=" + obj + ": invalid value for type " + getTypeName());
}
}
return ret;
}
@Override
public boolean validateValueForUpdate(Object obj, String objName, List<String> messages) {
boolean ret = true;
if (obj != null) {
if (obj instanceof Map) {
Map<Object, Objects> map = (Map<Object, Objects>) obj;
for (Map.Entry e : map.entrySet()) {
Object key = e.getKey();
if (!keyType.isValidValueForUpdate(key)) {
ret = false;
messages.add(objName + "." + key + ": invalid key for type " + getTypeName());
} else {
Object value = e.getValue();
ret = valueType.validateValueForUpdate(value, objName + "." + key, messages) && ret;
}
}
} else {
ret = false;
messages.add(objName + "=" + obj + ": invalid value for type " + getTypeName());
}
}
return ret;
}
@Override
public AtlasType getTypeForAttribute() {
AtlasType keyAttributeType = keyType.getTypeForAttribute();
AtlasType valueAttributeType = valueType.getTypeForAttribute();
if (keyAttributeType == keyType && valueAttributeType == valueType) {
return this;
} else {
AtlasType attributeType = new AtlasMapType(keyAttributeType, valueAttributeType);
if (LOG.isDebugEnabled()) {
LOG.debug("getTypeForAttribute(): {} ==> {}", getTypeName(), attributeType.getTypeName());
}
return attributeType;
}
}
}