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