1 /*
2 * SPDX-FileCopyrightText: none
3 * SPDX-License-Identifier: CC0-1.0
4 */
5
6 package dev.metaschema.core.metapath.format;
7
8 import java.util.stream.Collectors;
9
10 import dev.metaschema.core.metapath.item.node.IAssemblyInstanceGroupedNodeItem;
11 import dev.metaschema.core.metapath.item.node.IAssemblyNodeItem;
12 import dev.metaschema.core.metapath.item.node.IDocumentNodeItem;
13 import dev.metaschema.core.metapath.item.node.IFieldNodeItem;
14 import dev.metaschema.core.metapath.item.node.IFlagNodeItem;
15 import dev.metaschema.core.metapath.item.node.IModuleNodeItem;
16 import dev.metaschema.core.metapath.item.node.IRootAssemblyNodeItem;
17 import edu.umd.cs.findbugs.annotations.NonNull;
18
19 /**
20 * This interface provides an implementation contract for all path formatters.
21 * When {@link #format(IPathSegment)} is called on a formatter implementation,
22 * the formatter will render the path segments based on the implemented path
23 * syntax. This allows a collection of path segments to be rendered in different
24 * forms by swapping out the formatter used.
25 *
26 * A path formatter is expected to be stateless and thus thread safe.
27 */
28 public interface IPathFormatter {
29 /**
30 * A path formatter that produces Metapath-based paths.
31 */
32 @NonNull
33 IPathFormatter METAPATH_PATH_FORMATER = new MetapathFormatter();
34
35 /**
36 * A path formatter that produces XPath 3.1 paths with EQName-qualified names.
37 * <p>
38 * This formatter generates namespace-qualified paths using the EQName format
39 * (e.g., {@code Q{http://example.com}element[1]}), suitable for use with XML
40 * tooling that requires namespace qualification.
41 *
42 * @see XPathFormatter
43 */
44 @NonNull
45 IPathFormatter XPATH_PATH_FORMATTER = new XPathFormatter();
46
47 /**
48 * A path formatter that produces RFC 6901 JSON Pointer paths.
49 * <p>
50 * This formatter generates JSON Pointer paths suitable for use with JSON
51 * tooling and JSON-based error reporting. Uses JSON property names, 0-based
52 * array indices, and proper RFC 6901 escaping.
53 *
54 * @see JsonPointerFormatter
55 * @see <a href="https://www.rfc-editor.org/rfc/rfc6901">RFC 6901 - JSON
56 * Pointer</a>
57 */
58 @NonNull
59 IPathFormatter JSON_POINTER_PATH_FORMATTER = new JsonPointerFormatter();
60
61 /**
62 * Format the path represented by the provided path segment. The provided
63 * segment is expected to be the last node in this path. A call to
64 * {@link IPathSegment#getPathStream()} or {@link IPathSegment#getPath()} can be
65 * used to walk the path tree in descending order.
66 *
67 * @param segment
68 * The last segment in a sequence of path segments
69 * @return a formatted path
70 * @see IPathSegment#getPathStream()
71 * @see IPathSegment#getPath()
72 */
73 @SuppressWarnings("null")
74 @NonNull
75 default String format(@NonNull IPathSegment segment) {
76 return segment.getPathStream().map(pathSegment -> {
77 return pathSegment.format(this);
78 }).collect(Collectors.joining("/"));
79 }
80
81 /**
82 * This visitor callback is used to format an individual flag path segment.
83 *
84 * @param flag
85 * the node to format
86 * @return the formatted text for the segment
87 */
88 @NonNull
89 String formatFlag(@NonNull IFlagNodeItem flag);
90
91 /**
92 * This visitor callback is used to format an individual field path segment.
93 *
94 * @param field
95 * the node to format
96 * @return the formatted text for the segment
97 */
98 @NonNull
99 String formatField(@NonNull IFieldNodeItem field);
100
101 /**
102 * This visitor callback is used to format an individual assembly path segment.
103 *
104 * @param assembly
105 * the node to format
106 * @return the formatted text for the segment
107 */
108 @NonNull
109 String formatAssembly(@NonNull IAssemblyNodeItem assembly);
110
111 /**
112 * This visitor callback is used to format an individual grouped assembly path
113 * segment.
114 *
115 * @param assembly
116 * the node to format
117 * @return the formatted text for the segment
118 */
119 @NonNull
120 String formatAssembly(@NonNull IAssemblyInstanceGroupedNodeItem assembly);
121
122 /**
123 * This visitor callback is used to format a root assembly path segment.
124 *
125 * @param root
126 * the node to format
127 * @return the formatted text for the segment
128 */
129 @NonNull
130 String formatRootAssembly(@NonNull IRootAssemblyNodeItem root);
131
132 /**
133 * This visitor callback is used to format an individual document path segment.
134 *
135 * @param document
136 * the node to format
137 * @return the formatted text for the segment
138 */
139 @NonNull
140 String formatDocument(@NonNull IDocumentNodeItem document);
141
142 /**
143 * This visitor callback is used to format an individual metaschema path
144 * segment.
145 *
146 * @param metaschema
147 * the node to format
148 * @return the formatted text for the segment
149 */
150 @NonNull
151 String formatMetaschema(@NonNull IModuleNodeItem metaschema);
152 }