1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef SNGXML_DOM_NODE_INCLUDED
  7 #define SNGXML_DOM_NODE_INCLUDED
  8 #include <sngxml/dom/DomApi.hpp>
  9 #include <soulng/util/CodeFormatter.hpp>
 10 #include <string>
 11 #include <memory>
 12 #include <vector>
 13 
 14 namespace sngxml { namespace dom {
 15 
 16 using namespace soulng::util;
 17 
 18 enum class NodeType
 19 {
 20     attributeNodedocumentFragmentNodedocumentNodeelementNodeentityNodeentityReferenceNodenotationNodeprocessingInstructionNodetextNodecdataSectionNodecommentNode
 21 };
 22 
 23 class Node;
 24 class ParentNode;
 25 class Document;
 26 class NodeList;
 27 class Element;
 28 class Text;
 29 class EntityReference;
 30 class CDataSection;
 31 class Comment;
 32 class ProcessingInstruction;
 33 
 34 class Visitor 
 35 {
 36 public:
 37     virtual void BeginVisit(Document* document) {}
 38     virtual void EndVisit(Document* document) {}
 39     virtual void BeginVisit(Element* element) {}
 40     virtual void EndVisit(Element* element) {}
 41     virtual void Visit(Text* text) {}
 42     virtual void Visit(CDataSection* cdataSection) {}
 43     virtual void Visit(Comment* comment) {}
 44     virtual void Visit(EntityReference* entityReference) {}
 45     virtual void Visit(ProcessingInstruction* processingInstruction) {}
 46 };
 47 
 48 class NodeOp 
 49 {
 50 public:
 51     virtual ~NodeOp();
 52     virtual void Apply(Node* node);
 53 };
 54 
 55 enum class Axis
 56 {
 57     childdescendantparentancestorfollowingSiblingprecedingSiblingfollowingprecedingattributensselfdescendantOrSelfancestorOrSelf
 58 };
 59 
 60 std::u32string AxisName(Axis axis);
 61 
 62 class Node 
 63 {
 64 public:
 65     Node(NodeType nodeType_const std::u32string& name_);
 66     virtual ~Node();
 67     Node(const Node&) = delete;
 68     Node& operator=(const Node&) = delete;
 69     Node(Node&&) = delete;
 70     Node& operator=(Node&&) = delete;
 71     virtual std::unique_ptr<Node> CloneNode(bool deep) = 0;
 72     NodeType GetNodeType() const { return nodeType; }
 73     const std::u32string& Name() const { return name; }
 74     const std::u32string& NamespaceUri() const { return namespaceUri; }
 75     std::u32string Prefix() const;
 76     void SetPrefix(const std::u32string& prefix);
 77     std::u32string LocalName() const;
 78     virtual bool HasChildNodes() const { return false; }
 79     virtual bool HasAttributes() const { return false; }
 80     virtual void Write(CodeFormatter& formatter) = 0;
 81     virtual bool ValueContainsNewLine() const { return false; }
 82     virtual void Accept(Visitor& visitor) {}
 83     void Walk(NodeOp& nodeOpAxis axis);
 84     virtual void WalkChildren(NodeOp& nodeOp);
 85     virtual void WalkDescendant(NodeOp& nodeOp);
 86     virtual void WalkDescendantOrSelf(NodeOp& nodeOp);
 87     void WalkParent(NodeOp& nodeOp);
 88     virtual void WalkFollowing(NodeOp& nodeOp);
 89     virtual void WalkPreceding(NodeOp& nodeOp);
 90     virtual void WalkPrecedingOrSelf(NodeOp& nodeOp);
 91     void WalkAncestor(NodeOp& nodeOp);
 92     void WalkAncestorOrSelf(NodeOp& nodeOp);
 93     void WalkFollowingSibling(NodeOp& nodeOp);
 94     void WalkPrecedingSibling(NodeOp& nodeOp);
 95     virtual void WalkAttribute(NodeOp& nodeOp);
 96     Node* PreviousSibling() const { return previousSibling; }
 97     Node* NextSibling() const { return nextSibling; }
 98     ParentNode* Parent() const { return parent; }
 99     Document* OwnerDocument() const { return ownerDocument; }
100     void InternalLinkBefore(Node* newNode);
101     void InternalLinkAfter(Node* newNode);
102     void InternalUnlink();
103     void InternalSetParent(ParentNode* parent_) { parent = parent_; }
104     void InternalSetOwnerDocument(Document* ownerDocument_) { ownerDocument = ownerDocument_; }
105     void InternalSetNamespaceUri(const std::u32string& namespaceUri_);
106 private:
107     NodeType nodeType;
108     std::u32string name;
109     std::u32string namespaceUri;
110     ParentNode* parent;
111     Node* previousSibling;
112     Node* nextSibling;
113     Document* ownerDocument;
114 };
115 
116 class ParentNode public Node
117 {
118 public:
119     ParentNode(NodeType nodeType_const std::u32string& name_);
120     ~ParentNode() override;
121     ParentNode(const Node&) = delete;
122     ParentNode& operator=(const Node&) = delete;
123     ParentNode(ParentNode&&) = delete;
124     ParentNode& operator=(ParentNode&&) = delete;
125     bool HasChildNodes() const override { return firstChild != nullptr; }
126     NodeList ChildNodes() const;
127     void Write(CodeFormatter& formatter) override;
128     void CloneChildrenTo(ParentNode* clone) const;
129     Node* FirstChild() const { return firstChild; }
130     Node* LastChild() const { return lastChild; }
131     virtual Node* InsertBefore(std::std::unique_ptr<Node>&&newChildNode*refChild);
132     virtual std::unique_ptr<Node> ReplaceChild(std::std::unique_ptr<Node>&&newChildNode*oldChild);
133     virtual std::unique_ptr<Node> RemoveChild(Node* oldChild);
134     virtual Node* AppendChild(std::std::unique_ptr<Node>&&newChild);
135     void Accept(Visitor& visitor) override;
136     void WalkChildren(NodeOp& nodeOp) override;
137     void WalkDescendant(NodeOp& nodeOp) override;
138     void WalkDescendantOrSelf(NodeOp& nodeOp) override;
139     void WalkPreceding(NodeOp& nodeOp) override;
140     void WalkPrecedingOrSelf(NodeOp& nodeOp) override;
141 private:
142     Node* firstChild;
143     Node* lastChild;
144 };
145 
146 class NodeList 
147 {
148 public:
149     Node* Item(int index) const { return nodes[index]; }
150     Node* operator[](int index) const { return nodes[index]; }
151     int Length() const { return nodes.size(); }
152     void InternalAddNode(Node* node);
153 private:
154     std::vector<Node*> nodes;
155 };
156 
157 } } // namespace sngxml::dom
158 
159 #endif // SNGXML_DOM_NODE_INCLUDED