1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.item.atomic;
7   
8   import java.util.stream.Stream;
9   
10  import dev.metaschema.core.datatype.IDataTypeAdapter;
11  import dev.metaschema.core.metapath.function.InvalidValueForCastFunctionException;
12  import dev.metaschema.core.metapath.item.ICollectionValue;
13  import dev.metaschema.core.metapath.item.IItemVisitor;
14  import dev.metaschema.core.metapath.item.function.IMapItem;
15  import dev.metaschema.core.metapath.item.function.IMapKey;
16  import dev.metaschema.core.metapath.type.IAtomicOrUnionType;
17  import dev.metaschema.core.metapath.type.IItemType;
18  import dev.metaschema.core.util.ObjectUtils;
19  import edu.umd.cs.findbugs.annotations.NonNull;
20  import edu.umd.cs.findbugs.annotations.Nullable;
21  
22  /**
23   * The interface shared by all atomic items, representing indivisible data
24   * values that serve as the fundamental building blocks for complex data
25   * structures in the Metaschema framework.
26   */
27  public interface IAnyAtomicItem extends IAtomicValuedItem {
28    /**
29     * Get the type information for this item.
30     *
31     * @return the type information
32     */
33    @NonNull
34    static IAtomicOrUnionType<?> type() {
35      return IItemType.anyAtomic();
36    }
37  
38    @Override
39    @NonNull
40    default IAnyAtomicItem toAtomicItem() {
41      return this;
42    }
43  
44    /**
45     * Get the "wrapped" value represented by this item.
46     *
47     * @return the value
48     */
49    @Override
50    @NonNull
51    Object getValue();
52  
53    /**
54     * Converts this atomic item to a string item representation.
55     *
56     * @return a new {@link IStringItem} containing the string representation of
57     *         this item
58     * @see #asString()
59     */
60    @NonNull
61    default IStringItem asStringItem() {
62      return IStringItem.valueOf(asString());
63    }
64  
65    /**
66     * Get the item's string value.
67     *
68     * @return the string value value of the item
69     */
70    @NonNull
71    String asString();
72  
73    @Override
74    default Stream<IAnyAtomicItem> atomize() {
75      return ObjectUtils.notNull(Stream.of(this));
76    }
77  
78    /**
79     * Get the atomic item value as a map key for use with an {@link IMapItem}.
80     *
81     * @return the map key
82     */
83    @NonNull
84    IMapKey asMapKey();
85  
86    /**
87     * Get the item's type adapter.
88     *
89     * @return the type adapter for the item
90     */
91    @NonNull
92    IDataTypeAdapter<?> getJavaTypeAdapter();
93  
94    /**
95     * Cast the provided type to this item type.
96     * <p>
97     * This method simply returns the provided item, since it is already the same
98     * type.
99     *
100    * @param item
101    *          the item to cast
102    * @return the provided item
103    */
104   static IAnyAtomicItem cast(@NonNull IAnyAtomicItem item) {
105     return item;
106   }
107 
108   /**
109    * Cast the provided {@code item} to be the same type as this item.
110    *
111    * @param item
112    *          the item to cast
113    * @return an atomic item of this type
114    * @throws InvalidValueForCastFunctionException
115    *           if the provided item type cannot be cast to this item type
116    */
117   @NonNull
118   IAnyAtomicItem castAsType(@NonNull IAnyAtomicItem item);
119 
120   /**
121    * Determine if this and the other value are deeply equal, without relying on
122    * the dynamic context.
123    * <p>
124    * This is used by {@link IMapKey#isSameKey(IMapKey)} to determine key
125    * equivalence.
126    * <p>
127    * Item equality is defined by the
128    * <a href="https://www.w3.org/TR/xpath-functions-31/#func-deep-equal">XPath 3.1
129    * fn:deep-equal</a> specification.
130    *
131    * @param other
132    *          the other value to compare to this value to
133    * @return the {@code true} if the two values are equal, or {@code false}
134    *         otherwise
135    */
136   boolean deepEquals(@Nullable ICollectionValue other);
137 
138   @Override
139   default void accept(IItemVisitor visitor) {
140     visitor.visit(this);
141   }
142 }