001/*
002 * SPDX-FileCopyrightText: none
003 * SPDX-License-Identifier: CC0-1.0
004 */
005
006package gov.nist.secauto.metaschema.databind.model;
007
008import gov.nist.secauto.metaschema.core.model.IBoundObject;
009import gov.nist.secauto.metaschema.core.model.IFeatureDefinitionInstanceInlined;
010import gov.nist.secauto.metaschema.core.model.IFlagInstance;
011import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
012import gov.nist.secauto.metaschema.core.util.ObjectUtils;
013import gov.nist.secauto.metaschema.databind.io.BindingException;
014import gov.nist.secauto.metaschema.databind.model.impl.InstanceFlagInline;
015import gov.nist.secauto.metaschema.databind.model.info.IFeatureScalarItemValueHandler;
016import gov.nist.secauto.metaschema.databind.model.info.IItemReadHandler;
017import gov.nist.secauto.metaschema.databind.model.info.IItemWriteHandler;
018
019import java.io.IOException;
020import java.lang.reflect.Field;
021
022import edu.umd.cs.findbugs.annotations.NonNull;
023
024/**
025 * Represents a flag instance bound to Java data.
026 */
027public interface IBoundInstanceFlag
028    extends IFlagInstance, IBoundDefinitionFlag,
029    IFeatureScalarItemValueHandler,
030    IBoundInstance<Object>,
031    IFeatureDefinitionInstanceInlined<IBoundDefinitionFlag, IBoundInstanceFlag> {
032
033  /**
034   * Create a new bound flag instance.
035   *
036   * @param field
037   *          the Java field the instance is bound to
038   * @param containingDefinition
039   *          the definition containing the instance
040   * @return the new instance
041   */
042  @NonNull
043  static IBoundInstanceFlag newInstance(
044      @NonNull Field field,
045      @NonNull IBoundDefinitionModel<IBoundObject> containingDefinition) {
046    return new InstanceFlagInline(field, containingDefinition);
047  }
048
049  /**
050   * Determines if this flag's value is used as the property name for the JSON
051   * object that holds the remaining data based on this flag's containing
052   * definition.
053   *
054   * @return {@code true} if this flag is used as a JSON key, or {@code false}
055   *         otherwise
056   */
057  boolean isJsonKey();
058
059  /**
060   * Determines if this flag is used as a JSON "value key". A "value key" is a
061   * flag who's value is used as the property name for the containing objects
062   * value.
063   *
064   * @return {@code true} if the flag is used as a JSON "value key", or
065   *         {@code false} otherwise
066   */
067  boolean isJsonValueKey();
068
069  // Flag Instance Features
070  // ======================
071
072  @Override
073  @NonNull
074  IBoundDefinitionModel<IBoundObject> getContainingDefinition();
075
076  @Override
077  @NonNull
078  default IBoundDefinitionModel<IBoundObject> getParentContainer() {
079    return getContainingDefinition();
080  }
081
082  /**
083   * {@inheritDoc}
084   * <p>
085   * For an inline instance, this instance is the definition.
086   */
087  @Override
088  @NonNull
089  IBoundDefinitionFlag getDefinition();
090
091  @Override
092  @NonNull
093  default IBoundInstanceFlag getInlineInstance() {
094    // always inline
095    return this;
096  }
097
098  @Override
099  default void deepCopy(@NonNull IBoundObject fromInstance, @NonNull IBoundObject toInstance) throws BindingException {
100    Object value = getValue(fromInstance);
101    if (value != null) {
102      setValue(toInstance, deepCopyItem(value, toInstance));
103    }
104  }
105
106  @Override
107  @NonNull
108  default Object readItem(IBoundObject parent, @NonNull IItemReadHandler handler) throws IOException {
109    return handler.readItemFlag(ObjectUtils.requireNonNull(parent, "parent"), this);
110  }
111
112  @Override
113  default void writeItem(Object item, IItemWriteHandler handler) throws IOException {
114    handler.writeItemFlag(item, this);
115  }
116
117  @Override
118  default boolean canHandleXmlQName(@NonNull IEnhancedQName qname) {
119    return qname.equals(getQName());
120  }
121}