1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.format;
7   
8   import dev.metaschema.core.metapath.item.node.IAssemblyInstanceGroupedNodeItem;
9   import dev.metaschema.core.metapath.item.node.IAssemblyNodeItem;
10  import dev.metaschema.core.metapath.item.node.IDocumentNodeItem;
11  import dev.metaschema.core.metapath.item.node.IFieldNodeItem;
12  import dev.metaschema.core.metapath.item.node.IFlagNodeItem;
13  import dev.metaschema.core.metapath.item.node.IModelNodeItem;
14  import dev.metaschema.core.metapath.item.node.IModuleNodeItem;
15  import dev.metaschema.core.metapath.item.node.INodeItem;
16  import dev.metaschema.core.metapath.item.node.IRootAssemblyNodeItem;
17  import dev.metaschema.core.util.ObjectUtils;
18  import edu.umd.cs.findbugs.annotations.NonNull;
19  
20  /**
21   * An {@link IPathFormatter} that produces a Metapath expression for the path to
22   * a given {@link INodeItem}.
23   */
24  public class MetapathFormatter implements IPathFormatter {
25  
26    @Override
27    @NonNull
28    public String formatMetaschema(IModuleNodeItem metaschema) {
29      // this will result in a slash being generated using the join in the format
30      // method
31      return "";
32    }
33  
34    @Override
35    public String formatDocument(IDocumentNodeItem document) {
36      // this will result in a slash being generated using the join in the format
37      // method
38      return "";
39    }
40  
41    @Override
42    public String formatRootAssembly(IRootAssemblyNodeItem root) {
43      return ObjectUtils.notNull(root.getQName().getLocalName());
44    }
45  
46    @Override
47    public String formatAssembly(IAssemblyNodeItem assembly) {
48      // TODO: does it make sense to use this for an intermediate that has no parent?
49      return formatModelPathSegment(assembly);
50    }
51  
52    @Override
53    public String formatAssembly(IAssemblyInstanceGroupedNodeItem assembly) {
54      // TODO: does it make sense to use this for an intermediate that has no parent?
55      return formatModelPathSegment(assembly);
56    }
57  
58    @Override
59    public String formatField(IFieldNodeItem field) {
60      return formatModelPathSegment(field);
61    }
62  
63    @Override
64    public String formatFlag(IFlagNodeItem flag) {
65      return "@" + flag.getQName();
66    }
67  
68    @SuppressWarnings("null")
69    @NonNull
70    private static String formatModelPathSegment(@NonNull IModelNodeItem<?, ?> item) {
71      StringBuilder builder = new StringBuilder(item.getQName().getLocalName())
72          .append('[')
73          .append(item.getPosition())
74          .append(']');
75      return builder.toString();
76    }
77  }