1 #ifndef HTML___NODE__HPP
2 #define HTML___NODE__HPP
3 
4 /*  $Id: node.hpp 534860 2017-05-03 12:47:52Z ivanov $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author:  Lewis Geer
30  *
31  */
32 
33 /// @file node.hpp
34 /// The standard node class.
35 
36 
37 #include <corelib/ncbistd.hpp>
38 #include <corelib/ncbiobj.hpp>
39 #include <map>
40 #include <list>
41 #include <memory>
42 
43 
44 /** @addtogroup HTMLcomp
45  *
46  * @{
47  */
48 
49 
50 BEGIN_NCBI_SCOPE
51 
52 
53 class CNCBINode;
54 typedef CRef<CNCBINode> CNodeRef;
55 //#define NCBI_LIGHTWEIGHT_LIST 1
56 
57 // Base class for a graph node.
58 class NCBI_XHTML_EXPORT CNCBINode : public CObject
59 {
60 public:
61     friend class CRef<CNCBINode>;
62     typedef list<CNodeRef> TChildren;
63 #if NCBI_LIGHTWEIGHT_LIST
64     typedef TChildren TChildrenMember;
65 #else
66     typedef unique_ptr<TChildren> TChildrenMember;
67 #endif
68     struct SAttributeValue
69     {
SAttributeValueCNCBINode::SAttributeValue70         SAttributeValue(void)
71             : m_Optional(true)
72             {
73                 return;
74             }
SAttributeValueCNCBINode::SAttributeValue75         SAttributeValue(const string& value, bool optional)
76             : m_Value(value), m_Optional(optional)
77             {
78                 return;
79             }
operator =CNCBINode::SAttributeValue80         SAttributeValue& operator=(const string& value)
81             {
82                 m_Value = value;
83                 m_Optional = true;
84                 return *this;
85             }
GetValueCNCBINode::SAttributeValue86         const string& GetValue(void) const
87             {
88                 return m_Value;
89             }
operator const string&CNCBINode::SAttributeValue90         operator const string&(void) const
91             {
92                 return m_Value;
93             }
IsOptionalCNCBINode::SAttributeValue94         bool IsOptional(void) const
95             {
96                 return m_Optional;
97             }
SetOptionalCNCBINode::SAttributeValue98         void SetOptional(bool optional = true)
99             {
100                 m_Optional = optional;
101             }
102     private:
103         string m_Value;
104         bool m_Optional;
105     };
106     typedef map<string, SAttributeValue, PNocase> TAttributes;
107 
108     enum EMode {
109         eHTML      = 0,
110         ePlainText = 1,
111         eXHTML     = 2
112     };
113 
114     class TMode {
115     public:
TMode(EMode mode=eHTML)116         TMode(EMode mode = eHTML)
117             : m_Mode(mode), m_Node(0), m_Previous(0)
118             {
119                 return;
120             }
TMode(int mode)121         TMode(int mode)
122             : m_Mode(EMode(mode)), m_Node(0), m_Previous(0)
123             {
124                 return;
125             }
TMode(const TMode * mode,CNCBINode * node)126         TMode(const TMode* mode, CNCBINode* node)
127             : m_Mode(mode->m_Mode), m_Node(node), m_Previous(mode)
128             {
129                 return;
130             }
operator EMode(void) const131         operator EMode(void) const
132             {
133                 return m_Mode;
134             }
operator ==(EMode mode) const135         bool operator==(EMode mode) const
136             {
137                 return mode == m_Mode;
138             }
139 
GetNode(void) const140         CNCBINode* GetNode(void) const
141             {
142                 return m_Node;
143             }
GetPreviousContext(void) const144         const TMode* GetPreviousContext(void) const
145             {
146                 return m_Previous;
147             }
148     private:
149         // to avoid allocation in
150         EMode m_Mode;
151         CNCBINode* m_Node;
152         const TMode* m_Previous;
153     };
154 
155     // 'structors
156     CNCBINode(void);
157     CNCBINode(const string& name);
158     CNCBINode(const char* name);
159     virtual ~CNCBINode();
160 
161     // Add a Node * to the end of m_Children.
162     // Returns 'this' for chained AppendChild().
163     CNCBINode* AppendChild(CNCBINode* child);
164     CNCBINode* AppendChild(CNodeRef& ref);
165 
166     // Remove all occurencies of the child from this node's subtree
167     // (along with its subtree).
168     // Throw exception if the child is not found.
169     // Return smart pointer to the removed child node.
170     CNodeRef RemoveChild(CNCBINode* child);
171     CNodeRef RemoveChild(CNodeRef&  child);
172     void RemoveAllChildren(void);
173 
174     // All child operations (except AppendChild) are valid only if
175     // have children return true
176     bool HaveChildren(void) const;
177     TChildren& Children(void);
178     const TChildren& Children(void) const;
179     TChildren::iterator ChildBegin(void);
180     TChildren::iterator ChildEnd(void);
181     static CNCBINode* Node(TChildren::iterator i);
182     TChildren::const_iterator ChildBegin(void) const;
183     TChildren::const_iterator ChildEnd(void) const;
184     static const CNCBINode* Node(TChildren::const_iterator i);
185 
186     virtual CNcbiOstream& Print(CNcbiOstream& out, TMode mode = eHTML);
187     virtual CNcbiOstream& PrintBegin(CNcbiOstream& out, TMode mode);
188     virtual CNcbiOstream& PrintChildren(CNcbiOstream& out, TMode mode);
189     virtual CNcbiOstream& PrintEnd(CNcbiOstream& out, TMode mode);
190 
191     void    SetRepeatCount(size_t count = 0);
192     size_t  GetRepeatCount(void);
193 
194     // This method will be called once before Print().
195     virtual void CreateSubNodes(void);
196     // Call CreateSubNodes() if it's not called yet.
197     void Initialize(void);
198     // Reinitialize node, so hierarhy can be created anew.
199     // All previously set attributes remains unchanged.
200     // On the next Print() the CreateSubNodes() method
201     // will be called again.
202     void ReInitialize(void);
203 
204     // Find and replace text with a node.
205     virtual CNCBINode* MapTag(const string& tagname);
206     CNodeRef MapTagAll(const string& tagname, const TMode& mode);
207 
208     // Repeat tag node (works only inside tag node mappers)
209     void RepeatTag(bool enable = true);
210     bool NeedRepeatTag(void);
211 
212     const string& GetName(void) const;
213 
214     bool HaveAttributes(void) const;
215     TAttributes& Attributes(void);
216     const TAttributes& Attributes(void) const;
217     // Retrieve attribute.
218     bool HaveAttribute(const string& name) const;
219     const string& GetAttribute(const string& name) const;
220     bool AttributeIsOptional(const string& name) const;
221     bool AttributeIsOptional(const char* name) const;
222     void SetAttributeOptional(const string& name, bool optional = true);
223     void SetAttributeOptional(const char* name, bool optional = true);
224     const string* GetAttributeValue(const string& name) const;
225 
226     // Set attribute.
227     void SetAttribute(const string& name, const string& value);
228     void SetAttribute(const string& name);
229     void SetAttribute(const string& name, int value);
230     void SetOptionalAttribute(const string& name, const string& value);
231     void SetOptionalAttribute(const string& name, bool set);
232 
233     void SetAttribute(const char* name, const string& value);
234     void SetAttribute(const char* name);
235     void SetAttribute(const char* name, int value);
236     void SetOptionalAttribute(const char* name, const string& value);
237     void SetOptionalAttribute(const char* name, bool set);
238 
239     // Exception handling.
240 
241     /// Flags defining how to catch and process exceptions.
242     /// By default flags are unsettled.
243     /// Note that without the fCatchAll flag only CHTMLExceptions and
244     /// all derived exceptons can be traced.
245     enum EExceptionFlags {
246         fAddTrace              = 0x1, ///< Enable tag trace.
247         fCatchAll              = 0x2, ///< Catch all other exceptions and
248                                       ///< rethrow CHTMLException.
249         fDisableCheckRecursion = 0x4  ///< Disable to throw exception if
250                                       ///<  nodes tree have endless recursion.
251     };
252     typedef int TExceptionFlags;      ///< Binary OR of "EExceptionFlags"
253 
254     // Set/get global exception handling flags.
255     static void SetExceptionFlags(TExceptionFlags flags);
256     static TExceptionFlags GetExceptionFlags(void);
257 
258 protected:
259     virtual void DoAppendChild(CNCBINode* child);
260     virtual void DoSetAttribute(const string& name,
261                                 const string& value, bool optional);
262 
263     bool            m_CreateSubNodesCalled;
264     TChildrenMember m_Children;         ///< Child nodes
265     string          m_Name;             ///< Node name
266     size_t          m_RepeatCount;      ///< How many times repeat node
267 
268     // Repeat tag flag (used only inside tag node mappers hooks). See RepeatTag().
269     bool            m_RepeatTag;
270 
271     // Attributes, e.g. href="link.html"
272     unique_ptr<TAttributes> m_Attributes;
273 
274 private:
275     // To prevent copy constructor.
276     CNCBINode(const CNCBINode& node);
277     // To prevent assignment operator.
278     CNCBINode& operator=(const CNCBINode& node);
279 
280     // Return children list (create if needed).
281     TChildren& GetChildren(void);
282     // Return attributes map (create if needed).
283     TAttributes& GetAttributes(void);
284 };
285 
286 
287 // Inline functions are defined here:
288 #include <html/node.inl>
289 
290 
291 END_NCBI_SCOPE
292 
293 
294 /* @} */
295 
296 #endif  /*  HTML___NODE__HPP */
297