AbstractModelDefinitionJsonSchema.java
/*
* SPDX-FileCopyrightText: none
* SPDX-License-Identifier: CC0-1.0
*/
package gov.nist.secauto.metaschema.schemagen.json.impl;
import gov.nist.secauto.metaschema.core.model.IDefinition;
import gov.nist.secauto.metaschema.core.model.IFlagInstance;
import gov.nist.secauto.metaschema.core.model.IModelDefinition;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.schemagen.IGenerationState;
import gov.nist.secauto.metaschema.schemagen.json.IDefinitionJsonSchema;
import gov.nist.secauto.metaschema.schemagen.json.IJsonGenerationState;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
public abstract class AbstractModelDefinitionJsonSchema<D extends IModelDefinition>
extends AbstractDefinitionJsonSchema<D> {
@Nullable
private final String jsonKeyFlagName;
@Nullable
private final String discriminatorProperty;
@Nullable
private final String discriminatorValue;
@NonNull
private final List<FlagInstanceJsonProperty> flagProperties;
@NonNull
private final IKey key;
@SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Use of final fields")
protected AbstractModelDefinitionJsonSchema(
@NonNull D definition,
@Nullable String jsonKeyFlagName,
@Nullable String discriminatorProperty,
@Nullable String discriminatorValue) {
super(definition);
this.jsonKeyFlagName = jsonKeyFlagName;
this.discriminatorProperty = discriminatorProperty;
this.discriminatorValue = discriminatorValue;
this.key = IKey.of(definition, jsonKeyFlagName, discriminatorProperty, discriminatorValue);
Stream<? extends IFlagInstance> flagStream = definition.getFlagInstances().stream();
// determine the flag instances to generate
if (jsonKeyFlagName != null) {
IFlagInstance jsonKeyFlag = definition.getFlagInstanceByName(
definition.getContainingModule().toFlagQName(jsonKeyFlagName));
if (jsonKeyFlag == null) {
throw new IllegalArgumentException(
String.format("The referenced json-key flag-name '%s' does not exist on definition '%s'.",
jsonKeyFlagName,
definition.getName()));
}
flagStream = flagStream.filter(instance -> !jsonKeyFlag.equals(instance));
}
this.flagProperties = ObjectUtils.notNull(flagStream
.map(instance -> new FlagInstanceJsonProperty(ObjectUtils.requireNonNull(instance)))
.collect(Collectors.toUnmodifiableList()));
}
@Override
public IKey getKey() {
return key;
}
protected String getJsonKeyFlagName() {
return jsonKeyFlagName;
}
protected String getDiscriminatorProperty() {
return discriminatorProperty;
}
protected String getDiscriminatorValue() {
return discriminatorValue;
}
@Override
protected String generateDefinitionName(IJsonGenerationState state) {
IModelDefinition definition = getDefinition();
StringBuilder builder = new StringBuilder();
if (jsonKeyFlagName != null) {
builder
.append(IGenerationState.toCamelCase(jsonKeyFlagName))
.append("JsonKey");
}
if (discriminatorProperty != null || discriminatorValue != null) {
builder
.append(IGenerationState.toCamelCase(ObjectUtils.requireNonNull(discriminatorProperty)))
.append(IGenerationState.toCamelCase(ObjectUtils.requireNonNull(discriminatorValue)))
.append("Choice");
}
return state.getTypeNameForDefinition(
definition,
builder.toString());
}
protected List<FlagInstanceJsonProperty> getFlagProperties() {
return flagProperties;
}
@Override
public void gatherDefinitions(
@NonNull Map<IKey, IDefinitionJsonSchema<?>> gatheredDefinitions,
@NonNull IJsonGenerationState state) {
super.gatherDefinitions(gatheredDefinitions, state);
for (FlagInstanceJsonProperty property : getFlagProperties()) {
property.gatherDefinitions(gatheredDefinitions, state);
}
}
public static class ComplexKey implements IKey {
@NonNull
private final IDefinition definition;
@Nullable
private final String jsonKeyFlagName;
@Nullable
private final String discriminatorProperty;
@Nullable
private final String discriminatorValue;
public ComplexKey(
@NonNull IDefinition definition,
@Nullable String jsonKeyFlagName,
@Nullable String discriminatorProperty,
@Nullable String discriminatorValue) {
this.definition = definition;
this.jsonKeyFlagName = jsonKeyFlagName;
this.discriminatorProperty = discriminatorProperty;
this.discriminatorValue = discriminatorValue;
}
@Override
@NonNull
public IDefinition getDefinition() {
return definition;
}
@Override
@Nullable
public String getJsonKeyFlagName() {
return jsonKeyFlagName;
}
@Override
public String getDiscriminatorProperty() {
return discriminatorProperty;
}
@Override
public String getDiscriminatorValue() {
return discriminatorValue;
}
@Override
public int hashCode() {
return Objects.hash(definition, jsonKeyFlagName, discriminatorProperty, discriminatorValue);
}
@SuppressWarnings("PMD.OnlyOneReturn")
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof IKey)) {
return false;
}
IKey other = (IKey) obj;
return Objects.equals(definition, other.getDefinition())
&& Objects.equals(jsonKeyFlagName, other.getJsonKeyFlagName())
&& Objects.equals(discriminatorProperty, other.getDiscriminatorProperty())
&& Objects.equals(discriminatorValue, other.getDiscriminatorValue());
}
}
}