1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.core.metapath.item;
7   
8   import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter;
9   import gov.nist.secauto.metaschema.core.metapath.ICollectionValue;
10  import gov.nist.secauto.metaschema.core.metapath.ISequence;
11  import gov.nist.secauto.metaschema.core.metapath.function.InvalidTypeFunctionException;
12  import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
13  import gov.nist.secauto.metaschema.core.metapath.type.IItemType;
14  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
15  
16  import java.util.stream.Stream;
17  
18  import edu.umd.cs.findbugs.annotations.NonNull;
19  
20  /**
21   * The base interface inherited by all Metapath item implementations.
22   */
23  public interface IItem extends ICollectionValue {
24    /**
25     * Get the type information for this item.
26     *
27     * @return the type information
28     */
29    @NonNull
30    static IItemType type() {
31      return IItemType.item();
32    }
33  
34    /**
35     * Get the type information for the item.
36     *
37     * @return the item's type information
38     */
39    @NonNull
40    IItemType getType();
41  
42    /**
43     * Get the item's "wrapped" value. This "wrapped" value may be:
44     * <ul>
45     * <li>In the case of an Assembly, a Java object representing the fields and
46     * flags of the assembly.</li>
47     * <li>In the case of a Field with flags, a Java object representing the field
48     * value and flags of the field.
49     * <li>In the case of a Field without flags or a flag, a Java type managed by a
50     * {@link IDataTypeAdapter} or a primitive type provided by the Java standard
51     * library.
52     * </ul>
53     *
54     * @return the value or {@code null} if the item has no available value
55     */
56    Object getValue();
57  
58    /**
59     * Determine if the item has an associated value.
60     *
61     * @return {@code true} if the item has a non-{@code null} value or
62     *         {@code false} otherwise
63     */
64    default boolean hasValue() {
65      return getValue() != null;
66    }
67  
68    @Override
69    default ISequence<?> toSequence() {
70      return ISequence.of(this);
71    }
72  
73    /**
74     * Get the atomic value for the item. This may be the same item if the item is
75     * an instance of {@link IAnyAtomicItem}.
76     * <p>
77     * An implementation of
78     * <a href="https://www.w3.org/TR/xpath-31/#id-atomization">item
79     * atomization</a>.
80     *
81     * @return the atomic value or {@code null} if the item has no available value
82     * @throws InvalidTypeFunctionException
83     *           with code
84     *           {@link InvalidTypeFunctionException#NODE_HAS_NO_TYPED_VALUE} if the
85     *           item does not have a typed value
86     */
87    // FIXME: get rid of the possible null result and throw
88    // InvalidTypeFunctionException#NODE_HAS_NO_TYPED_VALUE
89    IAnyAtomicItem toAtomicItem();
90  
91    /**
92     * {@inheritDoc}
93     *
94     * @throws InvalidTypeFunctionException
95     *           with code
96     *           {@link InvalidTypeFunctionException#NODE_HAS_NO_TYPED_VALUE} if the
97     *           item does not have a typed value
98     */
99    @Override
100   default Stream<IAnyAtomicItem> atomize() {
101     return ObjectUtils.notNull(Stream.of(this.toAtomicItem()));
102   }
103 
104   @SuppressWarnings("null")
105   @Override
106   default Stream<? extends IItem> flatten() {
107     return Stream.of(this);
108   }
109 
110   /**
111    * A visitor callback used to visit a variety of Metapath item types.
112    *
113    * @param visitor
114    *          the visitor to call back
115    */
116   void accept(@NonNull IItemVisitor visitor);
117 
118   @Override
119   default ISequence<?> contentsAsSequence() {
120     return toSequence();
121   }
122 }