blob: a4c707a910a27c30749d8438237e251007365899 [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.model.typedef;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import org.apache.atlas.model.PList;
import org.apache.atlas.model.SearchFilter.SortType;
import org.apache.atlas.model.TypeCategory;
import org.apache.commons.collections.CollectionUtils;
import org.apache.hadoop.util.StringUtils;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
/**
* class that captures details of a struct-type.
*/
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
private static final long serialVersionUID = 1L;
// do not update this list contents directly - the list might be in the middle of iteration in another thread
// to update list contents: 1) make a copy 2) update the copy 3) assign the copy to this member
private List<AtlasAttributeDef> attributeDefs;
public AtlasStructDef() {
this(null, null, null, null, null);
}
public AtlasStructDef(String name) {
this(name, null, null, null, null);
}
public AtlasStructDef(String name, String description) {
this(name, description, null, null, null);
}
public AtlasStructDef(String name, String description, String typeVersion) {
this(name, description, typeVersion, null, null);
}
public AtlasStructDef(String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs) {
this(name, description, typeVersion, attributeDefs, null);
}
public AtlasStructDef(String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs, Map<String, String> options) {
this(TypeCategory.STRUCT, name, description, typeVersion, attributeDefs, options);
}
protected AtlasStructDef(TypeCategory category, String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs, Map<String, String> options) {
super(category, name, description, typeVersion, options);
setAttributeDefs(attributeDefs);
}
public AtlasStructDef(AtlasStructDef other) {
super(other);
setAttributeDefs(other != null ? other.getAttributeDefs() : null);
}
public List<AtlasAttributeDef> getAttributeDefs() {
return attributeDefs;
}
public void setAttributeDefs(List<AtlasAttributeDef> attributeDefs) {
if (this.attributeDefs != null && this.attributeDefs == attributeDefs) {
return;
}
if (CollectionUtils.isEmpty(attributeDefs)) {
this.attributeDefs = new ArrayList<>();
} else {
// if multiple attributes with same name are present, keep only the last entry
List<AtlasAttributeDef> tmpList = new ArrayList<>(attributeDefs.size());
Set<String> attribNames = new HashSet<>();
ListIterator<AtlasAttributeDef> iter = attributeDefs.listIterator(attributeDefs.size());
while (iter.hasPrevious()) {
AtlasAttributeDef attributeDef = iter.previous();
String attribName = attributeDef != null ? attributeDef.getName() : null;
if (attribName != null) {
attribName = attribName.toLowerCase();
if (!attribNames.contains(attribName)) {
tmpList.add(new AtlasAttributeDef(attributeDef));
attribNames.add(attribName);
}
}
}
Collections.reverse(tmpList);
this.attributeDefs = tmpList;
}
}
public AtlasAttributeDef getAttribute(String attrName) {
return findAttribute(this.attributeDefs, attrName);
}
public void addAttribute(AtlasAttributeDef attributeDef) {
if (attributeDef == null) {
return;
}
List<AtlasAttributeDef> a = this.attributeDefs;
List<AtlasAttributeDef> tmpList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(a)) {
// copy existing attributes, except ones having same name as the attribute being added
for (AtlasAttributeDef existingAttrDef : a) {
if (!StringUtils.equalsIgnoreCase(existingAttrDef.getName(), attributeDef.getName())) {
tmpList.add(existingAttrDef);
}
}
}
tmpList.add(new AtlasAttributeDef(attributeDef));
this.attributeDefs = tmpList;
}
public void removeAttribute(String attrName) {
List<AtlasAttributeDef> a = this.attributeDefs;
if (hasAttribute(a, attrName)) {
List<AtlasAttributeDef> tmpList = new ArrayList<>();
// copy existing attributes, except ones having same name as the attribute being removed
for (AtlasAttributeDef existingAttrDef : a) {
if (!StringUtils.equalsIgnoreCase(existingAttrDef.getName(), attrName)) {
tmpList.add(existingAttrDef);
}
}
this.attributeDefs = tmpList;
}
}
public boolean hasAttribute(String attrName) {
return getAttribute(attrName) != null;
}
private static boolean hasAttribute(List<AtlasAttributeDef> attributeDefs, String attrName) {
return findAttribute(attributeDefs, attrName) != null;
}
public static AtlasAttributeDef findAttribute(Collection<AtlasAttributeDef> attributeDefs, String attrName) {
AtlasAttributeDef ret = null;
if (CollectionUtils.isNotEmpty(attributeDefs)) {
for (AtlasAttributeDef attributeDef : attributeDefs) {
if (StringUtils.equalsIgnoreCase(attributeDef.getName(), attrName)) {
ret = attributeDef;
break;
}
}
}
return ret;
}
@Override
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("AtlasStructDef{");
super.toString(sb);
sb.append(", attributeDefs=[");
if (CollectionUtils.isNotEmpty(attributeDefs)) {
int i = 0;
for (AtlasAttributeDef attributeDef : attributeDefs) {
attributeDef.toString(sb);
if (i > 0) {
sb.append(", ");
}
i++;
}
}
sb.append("]");
sb.append('}');
return sb;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
AtlasStructDef that = (AtlasStructDef) o;
return Objects.equals(attributeDefs, that.attributeDefs);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), attributeDefs);
}
@Override
public String toString() {
return toString(new StringBuilder()).toString();
}
/**
* class that captures details of a struct-attribute.
*/
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class AtlasAttributeDef implements Serializable {
private static final long serialVersionUID = 1L;
/**
* single-valued attribute or multi-valued attribute.
*/
public enum Cardinality { SINGLE, LIST, SET }
public static final int COUNT_NOT_SET = -1;
private String name;
private String typeName;
private boolean isOptional;
private Cardinality cardinality;
private int valuesMinCount;
private int valuesMaxCount;
private boolean isUnique;
private boolean isIndexable;
private String defaultValue;
private String description;
private List<AtlasConstraintDef> constraints;
public AtlasAttributeDef() { this(null, null); }
public AtlasAttributeDef(String name, String typeName) {
this(name, typeName, false, Cardinality.SINGLE, COUNT_NOT_SET, COUNT_NOT_SET, false, false, null);
}
public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality,
int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, List<AtlasConstraintDef> constraints) {
this(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, null, constraints, null);
}
public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality,
int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, String defaultValue,
List<AtlasConstraintDef> constraints, String description) {
setName(name);
setTypeName(typeName);
setIsOptional(isOptional);
setCardinality(cardinality);
setValuesMinCount(valuesMinCount);
setValuesMaxCount(valuesMaxCount);
setIsUnique(isUnique);
setIsIndexable(isIndexable);
setDefaultValue(defaultValue);
setConstraints(constraints);
setDescription(description);
}
public AtlasAttributeDef(AtlasAttributeDef other) {
if (other != null) {
setName(other.getName());
setTypeName(other.getTypeName());
setIsOptional(other.getIsOptional());
setCardinality(other.getCardinality());
setValuesMinCount(other.getValuesMinCount());
setValuesMaxCount(other.getValuesMaxCount());
setIsUnique(other.getIsUnique());
setIsIndexable(other.getIsIndexable());
setDefaultValue(other.getDefaultValue());
setConstraints(other.getConstraints());
setDescription((other.getDescription()));
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public boolean getIsOptional() {
return isOptional;
}
public void setIsOptional(boolean optional) { isOptional = optional; }
public void setCardinality(Cardinality cardinality) {
this.cardinality = cardinality;
}
public Cardinality getCardinality() {
return cardinality;
}
public int getValuesMinCount() {
return valuesMinCount;
}
public void setValuesMinCount(int valuesMinCount) {
this.valuesMinCount = valuesMinCount;
}
public int getValuesMaxCount() {
return valuesMaxCount;
}
public void setValuesMaxCount(int valuesMaxCount) {
this.valuesMaxCount = valuesMaxCount;
}
public boolean getIsUnique() {
return isUnique;
}
public void setIsUnique(boolean unique) {
isUnique = unique;
}
public boolean getIsIndexable() {
return isIndexable;
}
public String getDefaultValue(){
return defaultValue;
}
public void setDefaultValue(String defaultValue){
this.defaultValue = defaultValue;
}
public void setIsIndexable(boolean idexable) {
isIndexable = idexable;
}
public List<AtlasConstraintDef> getConstraints() { return constraints; }
public void setConstraints(List<AtlasConstraintDef> constraints) {
if (this.constraints != null && this.constraints == constraints) {
return;
}
if (CollectionUtils.isEmpty(constraints)) {
this.constraints = null;
} else {
this.constraints = new ArrayList<>(constraints);
}
}
public void addConstraint(AtlasConstraintDef constraintDef) {
List<AtlasConstraintDef> cDefs = constraints;
if (cDefs == null) {
cDefs = new ArrayList<>();
this.constraints = cDefs;
}
cDefs.add(constraintDef);
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("AtlasAttributeDef{");
sb.append("name='").append(name).append('\'');
sb.append(", typeName='").append(typeName).append('\'');
sb.append(", description='").append(description).append('\'');
sb.append(", getIsOptional=").append(isOptional);
sb.append(", cardinality=").append(cardinality);
sb.append(", valuesMinCount=").append(valuesMinCount);
sb.append(", valuesMaxCount=").append(valuesMaxCount);
sb.append(", isUnique=").append(isUnique);
sb.append(", isIndexable=").append(isIndexable);
sb.append(", defaultValue=").append(defaultValue);
sb.append(", constraints=[");
if (CollectionUtils.isNotEmpty(constraints)) {
int i = 0;
for (AtlasConstraintDef constraintDef : constraints) {
constraintDef.toString(sb);
if (i > 0) {
sb.append(", ");
}
i++;
}
}
sb.append("]");
sb.append('}');
return sb;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AtlasAttributeDef that = (AtlasAttributeDef) o;
return isOptional == that.isOptional &&
valuesMinCount == that.valuesMinCount &&
valuesMaxCount == that.valuesMaxCount &&
isUnique == that.isUnique &&
isIndexable == that.isIndexable &&
Objects.equals(name, that.name) &&
Objects.equals(typeName, that.typeName) &&
cardinality == that.cardinality &&
Objects.equals(defaultValue, that.defaultValue) &&
Objects.equals(description, that.description) &&
Objects.equals(constraints, that.constraints);
}
@Override
public int hashCode() {
return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, defaultValue, constraints, description);
}
@Override
public String toString() {
return toString(new StringBuilder()).toString();
}
}
/**
* class that captures details of a constraint.
*/
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
public static class AtlasConstraintDef implements Serializable {
private static final long serialVersionUID = 1L;
public static final String CONSTRAINT_TYPE_OWNED_REF = "ownedRef";
public static final String CONSTRAINT_TYPE_INVERSE_REF = "inverseRef";
public static final String CONSTRAINT_PARAM_ATTRIBUTE = "attribute";
private String type; // foreignKey/mappedFromRef/valueInRange
private Map<String, Object> params; // onDelete=cascade/refAttribute=attr2/min=0,max=23
public AtlasConstraintDef() { }
public AtlasConstraintDef(String type) {
this(type, null);
}
public AtlasConstraintDef(String type, Map<String, Object> params) {
this.type = type;
if (params != null) {
this.params = new HashMap<>(params);
}
}
public AtlasConstraintDef(AtlasConstraintDef that) {
if (that != null) {
this.type = that.type;
if (that.params != null) {
this.params = new HashMap<>(that.params);
}
}
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Map<String, Object> getParams() {
return params;
}
public void setParams(Map<String, Object> params) {
this.params = params;
}
@JsonIgnore
public boolean isConstraintType(String name) {
return StringUtils.equalsIgnoreCase(name, this.type);
}
@JsonIgnore
public Object getParam(String name) {
Map<String, Object> params = this.params;
return params != null ? params.get(name) : null;
}
public StringBuilder toString(StringBuilder sb) {
if (sb == null) {
sb = new StringBuilder();
}
sb.append("AtlasConstraintDef{");
sb.append("type='").append(type).append('\'');
sb.append(", params='").append(params).append('\'');
sb.append('}');
return sb;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AtlasConstraintDef that = (AtlasConstraintDef) o;
return Objects.equals(type, that.type) &&
Objects.equals(params, that.params);
}
@Override
public int hashCode() {
return Objects.hash(type, params);
}
@Override
public String toString() { return toString(new StringBuilder()).toString(); }
}
/**
* REST serialization friendly list.
*/
@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown=true)
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlSeeAlso(AtlasStructDef.class)
public static class AtlasStructDefs extends PList<AtlasStructDef> {
private static final long serialVersionUID = 1L;
public AtlasStructDefs() {
super();
}
public AtlasStructDefs(List<AtlasStructDef> list) {
super(list);
}
public AtlasStructDefs(List list, long startIndex, int pageSize, long totalCount,
SortType sortType, String sortBy) {
super(list, startIndex, pageSize, totalCount, sortType, sortBy);
}
}
}