AbstractConstraintBuilder.java
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/
package gov.nist.secauto.metaschema.core.model.constraint;
import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.core.model.IAttributable;
import gov.nist.secauto.metaschema.core.model.ISource;
import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.Level;
import gov.nist.secauto.metaschema.core.util.CollectionUtil;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
/**
* Provides builder methods for the core data elements of an
* {@link IConstraint}.
* <p>
* The base class of all constraint builders.
*
* @param <T>
* the Java type of the implementing builder
* @param <R>
* the Java type of the resulting built object
*/
public abstract class AbstractConstraintBuilder<
T extends AbstractConstraintBuilder<T, R>,
R extends IConstraint> {
private String id;
private String formalName;
private MarkupLine description;
private ISource source;
@NonNull
private Level level = IConstraint.DEFAULT_LEVEL;
@NonNull
private String target = IConstraint.DEFAULT_TARGET_METAPATH;
@NonNull
private Map<IAttributable.Key, Set<String>> properties = new LinkedHashMap<>(); // NOPMD not thread safe
private MarkupMultiline remarks;
/**
* Get the builder.
* <p>
* Implementations of this method must return {@code this}.
*
* @return the builder instance
*/
@NonNull
protected abstract T getThis();
/**
* Set an identifier for the constraint.
*
* @param id
* the identifier to set
* @return this builder
*/
@NonNull
public T identifier(@NonNull String id) {
this.id = id;
return getThis();
}
/**
* Set a formal name for the constraint.
*
* @param name
* the formal name to set
* @return this builder
*/
@NonNull
public T formalName(@NonNull String name) {
this.formalName = name;
return getThis();
}
/**
* Set a description for the constraint.
*
* @param description
* the description to set
* @return this builder
*/
@NonNull
public T description(@NonNull MarkupLine description) {
this.description = description;
return getThis();
}
/**
* Set the source the constraint was parsed from.
*
* @param source
* the source to set
* @return this builder
*/
@NonNull
public T source(@NonNull ISource source) {
this.source = source;
return getThis();
}
/**
* Set the severity level for when the constraint is violated.
*
* @param level
* the level to set
* @return this builder
*/
@NonNull
public T level(@NonNull Level level) {
this.level = level;
return getThis();
}
/**
* Set the Metapath expression used to get the target(s) of the constraint.
*
* @param target
* a Metapath expression, which will be evaluated relative to the
* definition it is declared on
* @return this builder
*/
@NonNull
public T target(@NonNull String target) {
this.target = target;
return getThis();
}
/**
* Set the collection of properties associated with the constraint.
*
* @param properties
* the properties to set
* @return this builder
*/
@NonNull
public T properties(@NonNull Map<IAttributable.Key, Set<String>> properties) {
this.properties = properties;
return getThis();
}
/**
* Set the values of the property with the provided {@code name} to the provided
* {@code value}.
*
* @param key
* the property's name
* @param value
* the value to set
* @return this builder
*/
@NonNull
public T property(@NonNull IAttributable.Key key, @NonNull String value) {
return property(key, CollectionUtil.singleton(value));
}
/**
* Set the values of the property with the provided {@code name} to the provided
* {@code values}.
*
* @param key
* the property's name
* @param values
* the values to set
* @return this builder
*/
@NonNull
public T property(@NonNull IAttributable.Key key, @NonNull Set<String> values) {
properties.put(key, new LinkedHashSet<>(values));
return getThis();
}
/**
* Set the provided {@code remarks}.
*
* @param remarks
* the remarks to set
* @return this builder
*/
@NonNull
public T remarks(@NonNull MarkupMultiline remarks) {
this.remarks = remarks;
return getThis();
}
/**
* Validate the values provided to the builder.
*
* @throws NullPointerException
* if a required value is {@code null}
* @throws IllegalStateException
* in other cases where the combination of values is inappropriate
*/
protected void validate() {
ObjectUtils.requireNonNull(getSource());
}
/**
* Get a new instance of the built object.
*
* @return the built instance
*/
@NonNull
protected abstract R newInstance();
/**
* Generate the built instance after validating the provided data.
*
* @return the built instance
*/
@NonNull
public R build() {
validate();
return newInstance();
}
/**
* Get the constraint identifier provided to the builder.
*
* @return the identifier or {@code null} if no identifier has been set
*/
@Nullable
protected String getId() {
return id;
}
/**
* Get the constraint formal name provided to the builder.
*
* @return the formal name or {@code null} if no formal name has been set
*/
@Nullable
protected String getFormalName() {
return formalName;
}
/**
* Get the constraint description provided to the builder.
*
* @return the description or {@code null} if no description has been set
*/
@Nullable
protected MarkupLine getDescription() {
return description;
}
/**
* Get the constraint source provided to the builder.
*
* @return the source or {@code null} if no source has been set
*/
@Nullable
protected ISource getSource() {
return source;
}
/**
* Get the constraint severity level provided to the builder.
*
* @return the severity level
*/
@NonNull
protected Level getLevel() {
return level;
}
/**
* Get the Metapath expression, provided to the builder, used to get the
* target(s) of the constraint.
*
* @return the target Metapath expression
*/
@NonNull
protected String getTarget() {
return target;
}
/**
* Get the constraint properties provided to the builder.
*
* @return the properties or an empty Map if no properties are set
*/
@NonNull
protected Map<IAttributable.Key, Set<String>> getProperties() {
return properties;
}
/**
* Get the remarks provided to the builder.
*
* @return the remarks
*/
@Nullable
protected MarkupMultiline getRemarks() {
return remarks;
}
}