• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2008, SnakeYAML
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package org.yaml.snakeyaml.nodes;
15 
16 import java.util.List;
17 import org.yaml.snakeyaml.comments.CommentLine;
18 import org.yaml.snakeyaml.error.Mark;
19 
20 /**
21  * Base class for all nodes.
22  * <p>
23  * The nodes form the node-graph described in the <a href="http://yaml.org/spec/1.1/">YAML
24  * Specification</a>.
25  * </p>
26  * <p>
27  * While loading, the node graph is usually created by the
28  * {@link org.yaml.snakeyaml.composer.Composer}, and later transformed into application specific
29  * Java classes by the classes from the {@link org.yaml.snakeyaml.constructor} package.
30  * </p>
31  */
32 public abstract class Node {
33 
34   private Tag tag;
35   private final Mark startMark;
36   protected Mark endMark;
37   private Class<? extends Object> type;
38   private boolean twoStepsConstruction;
39   private String anchor;
40   private List<CommentLine> inLineComments;
41   private List<CommentLine> blockComments;
42   // End Comments are only on the last node in a document
43   private List<CommentLine> endComments;
44 
45   /**
46    * true when the tag is assigned by the resolver
47    */
48   protected boolean resolved;
49   protected Boolean useClassConstructor;
50 
Node(Tag tag, Mark startMark, Mark endMark)51   public Node(Tag tag, Mark startMark, Mark endMark) {
52     setTag(tag);
53     this.startMark = startMark;
54     this.endMark = endMark;
55     this.type = Object.class;
56     this.twoStepsConstruction = false;
57     this.resolved = true;
58     this.useClassConstructor = null;
59     this.inLineComments = null;
60     this.blockComments = null;
61     this.endComments = null;
62   }
63 
64   /**
65    * Tag of this node.
66    * <p>
67    * Every node has a tag assigned. The tag is either local or global.
68    *
69    * @return Tag of this node.
70    */
getTag()71   public Tag getTag() {
72     return this.tag;
73   }
74 
getEndMark()75   public Mark getEndMark() {
76     return endMark;
77   }
78 
79   /**
80    * For error reporting.
81    *
82    * @see "class variable 'id' in PyYAML"
83    * @return scalar, sequence, mapping
84    */
getNodeId()85   public abstract NodeId getNodeId();
86 
getStartMark()87   public Mark getStartMark() {
88     return startMark;
89   }
90 
setTag(Tag tag)91   public void setTag(Tag tag) {
92     if (tag == null) {
93       throw new NullPointerException("tag in a Node is required.");
94     }
95     this.tag = tag;
96   }
97 
98   /**
99    * Node is only equal to itself
100    */
101   @Override
equals(Object obj)102   public final boolean equals(Object obj) {
103     return super.equals(obj);
104   }
105 
getType()106   public Class<? extends Object> getType() {
107     return type;
108   }
109 
setType(Class<? extends Object> type)110   public void setType(Class<? extends Object> type) {
111     if (!type.isAssignableFrom(this.type)) {
112       this.type = type;
113     }
114   }
115 
setTwoStepsConstruction(boolean twoStepsConstruction)116   public void setTwoStepsConstruction(boolean twoStepsConstruction) {
117     this.twoStepsConstruction = twoStepsConstruction;
118   }
119 
120   /**
121    * Indicates if this node must be constructed in two steps.
122    * <p>
123    * Two-step construction is required whenever a node is a child (direct or indirect) of it self.
124    * That is, if a recursive structure is build using anchors and aliases.
125    * </p>
126    * <p>
127    * Set by {@link org.yaml.snakeyaml.composer.Composer}, used during the construction process.
128    * </p>
129    * <p>
130    * Only relevant during loading.
131    * </p>
132    *
133    * @return <code>true</code> if the node is self referenced.
134    */
isTwoStepsConstruction()135   public boolean isTwoStepsConstruction() {
136     return twoStepsConstruction;
137   }
138 
139   @Override
hashCode()140   public final int hashCode() {
141     return super.hashCode();
142   }
143 
useClassConstructor()144   public boolean useClassConstructor() {
145     if (useClassConstructor == null) {
146       // the tag is compatible with the runtime class
147       // the tag will be ignored
148       if (!tag.isSecondary() && resolved && !Object.class.equals(type) && !tag.equals(Tag.NULL)) {
149         return true;
150       } else {
151         return tag.isCompatible(getType());
152       }
153     }
154     return useClassConstructor.booleanValue();
155   }
156 
setUseClassConstructor(Boolean useClassConstructor)157   public void setUseClassConstructor(Boolean useClassConstructor) {
158     this.useClassConstructor = useClassConstructor;
159   }
160 
161   /**
162    * Indicates if the tag was added by {@link org.yaml.snakeyaml.resolver.Resolver}.
163    *
164    * @return true if the tag of this node was resolved
165    *
166    * @deprecated Since v1.22. Absent in immediately prior versions, but present previously. Restored
167    *             deprecated for backwards compatibility.
168    */
169   @Deprecated
isResolved()170   public boolean isResolved() {
171     return resolved;
172   }
173 
getAnchor()174   public String getAnchor() {
175     return anchor;
176   }
177 
setAnchor(String anchor)178   public void setAnchor(String anchor) {
179     this.anchor = anchor;
180   }
181 
182   /**
183    * The ordered list of in-line comments. The first of which appears at the end of the line
184    * respresent by this node. The rest are in the following lines, indented per the Spec to indicate
185    * they are continuation of the inline comment.
186    *
187    * @return the comment line list.
188    */
getInLineComments()189   public List<CommentLine> getInLineComments() {
190     return inLineComments;
191   }
192 
setInLineComments(List<CommentLine> inLineComments)193   public void setInLineComments(List<CommentLine> inLineComments) {
194     this.inLineComments = inLineComments;
195   }
196 
197   /**
198    * The ordered list of blank lines and block comments (full line) that appear before this node.
199    *
200    * @return the comment line list.
201    */
getBlockComments()202   public List<CommentLine> getBlockComments() {
203     return blockComments;
204   }
205 
setBlockComments(List<CommentLine> blockComments)206   public void setBlockComments(List<CommentLine> blockComments) {
207     this.blockComments = blockComments;
208   }
209 
210   /**
211    * The ordered list of blank lines and block comments (full line) that appear AFTER this node.
212    * <p>
213    * NOTE: these comment should occur only in the last node in a document, when walking the node
214    * tree "in order"
215    *
216    * @return the comment line list.
217    */
getEndComments()218   public List<CommentLine> getEndComments() {
219     return endComments;
220   }
221 
setEndComments(List<CommentLine> endComments)222   public void setEndComments(List<CommentLine> endComments) {
223     this.endComments = endComments;
224   }
225 }
226