blob: 41d86e8ee1efb7ef0a99d6185ec4c6a0c699e61f [file] [log] [blame]
sonu gupta1bb37b82016-11-11 16:51:18 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
sonu gupta1bb37b82016-11-11 16:51:18 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yms.app.ydt;
18
sonu gupta1bb37b82016-11-11 16:51:18 +053019import org.onosproject.yangutils.datamodel.YangSchemaNode;
20import org.onosproject.yangutils.datamodel.YangSchemaNodeContextInfo;
21import org.onosproject.yangutils.datamodel.YangSchemaNodeIdentifier;
22import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
23import org.onosproject.yms.app.ydt.exceptions.YdtException;
24import org.onosproject.yms.ydt.YdtContext;
25import org.onosproject.yms.ydt.YdtContextOperationType;
26import org.onosproject.yms.ydt.YdtExtendedInfoType;
27import org.onosproject.yms.ydt.YdtType;
28
29import java.util.ArrayList;
30import java.util.HashMap;
31import java.util.HashSet;
32import java.util.List;
33import java.util.Map;
34import java.util.Set;
35
36import static org.onosproject.yms.app.ydt.YdtConstants.errorMsg;
37
38/**
39 * Represents implementation of interfaces to build and obtain YANG data tree
40 * which is data (sub)instance representation, abstract of protocol.
41 */
42public abstract class YdtNode<T> implements YdtExtendedContext, Cloneable {
43
sonu guptaeff184b2016-11-24 12:43:49 +053044 // YDT formatted error string
45 private static final String FMT_NON_LIST_STR =
sonu gupta1bb37b82016-11-11 16:51:18 +053046 "List of key cannot be created for leaf and leaf-list %s node.";
47 private static final String FMT_VAL_N =
48 "Value cannot be set in non leaf %s node.";
49 private static final String FMT_VAL_NS =
50 "ValueSet cannot be set in non leaf-list %s node.";
51 private static final String FMT_VAL_IN =
52 "Value cannot be invoke from non leaf %s node.";
53 private static final String FMT_VAL_INS =
54 "ValueSet cannot be invoke from non leaf-list %s node";
sonu gupta1bb37b82016-11-11 16:51:18 +053055
sonu guptaeff184b2016-11-24 12:43:49 +053056 // YDT error string
sonu gupta1bb37b82016-11-11 16:51:18 +053057 private static final String E_EXIST = "Node is already part of a tree";
58 private static final String E_ATOMIC =
59 "Child to be added is not atomic, it already has a child";
60 private static final String E_SIB =
61 "Child to be added is not atomic, it already has a next sibling";
62 private static final String E_PRE =
63 "Child to be added is not atomic, it already has a previous " +
64 "sibling";
65 private static final String E_SUPPORT = "Requested node type not supported";
66
67 /*
68 * Parent reference.
69 */
70 private YdtNode parent;
71
72 /*
73 * First child reference.
74 */
75 private YdtNode child;
76
77 /*
78 * Next sibling reference.
79 */
80 private YdtNode nextSibling;
81
82 /*
83 * Previous sibling reference.
84 */
85 private YdtNode previousSibling;
86
87 /*
88 * Last child reference.
89 */
90 private YdtNode lastChild;
91
92 /*
93 * Type of node.
94 */
sonu guptaeff184b2016-11-24 12:43:49 +053095 private final YdtType ydtType;
sonu gupta1bb37b82016-11-11 16:51:18 +053096
97 /*
98 * Flag to keep the track of context switch,
99 * if set then traverse back to parent in YDT app tree else no need.
100 */
101 private boolean isContextSwitch;
102
103 /*
104 * YDT extended information.
105 */
106 private T ydtExtendedInfo;
107
108 /*
109 * YDT extended information type.
110 */
111 private YdtExtendedInfoType ydtExtendedInfoType;
112
113 /*
sonu guptaeff184b2016-11-24 12:43:49 +0530114 * Ydt map to keep the track of node added under current parent node.
sonu gupta1bb37b82016-11-11 16:51:18 +0530115 */
sonu guptaeff184b2016-11-24 12:43:49 +0530116 final Map<YangSchemaNodeIdentifier, YdtNode<T>> ydtNodeMap =
117 new HashMap<>();
118
119 /*
120 * Ydt map to keep the track of multi instance node added under current
121 * parent node.
122 */
123 private final Map<YangSchemaNodeIdentifier,
124 List<YdtNode<YdtMultiInstanceNode>>> ydtMultiInsMap =
sonu gupta1bb37b82016-11-11 16:51:18 +0530125 new HashMap<>();
126
127 /*
128 * Reference for data-model schema node.
129 */
130 private YangSchemaNode yangSchemaNode;
131
132 /*
133 * Reference for ydt node operation type.
134 */
135 private YdtContextOperationType ydtContextOperationType;
136
137 /*
sonu gupta1bb37b82016-11-11 16:51:18 +0530138 * Ydt map to keep the track of application information object
139 * with respective type.
140 */
141 private final Map<AppType, Object> ydtAppInfoMap = new HashMap<>();
142
143 private YdtContext clonedNode;
144
145 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530146 * Creates a specific type of node.
147 *
148 * @param type of YDT node
149 * @param node schema node
150 */
151 YdtNode(YdtType type, YangSchemaNode node) {
152 ydtType = type;
153 yangSchemaNode = node;
154 }
155
156 /**
157 * Creates a specific type of node.
158 *
159 * @param type of YDT node
160 */
161 YdtNode(YdtType type) {
162 ydtType = type;
163 }
164
165 /**
sonu gupta1bb37b82016-11-11 16:51:18 +0530166 * Returns the cloned ydt node.
167 *
168 * @return clonedNode cloned ydt node
169 */
170 public YdtContext getClonedNode() {
171 return clonedNode;
172 }
173
174 /**
175 * Sets the cloned node.
176 *
177 * @param clonedNode cloned ydt node
178 */
179 public void setClonedNode(YdtContext clonedNode) {
180 this.clonedNode = clonedNode;
181 }
182
183 @Override
184 public String getName() {
sonu guptaeff184b2016-11-24 12:43:49 +0530185 return yangSchemaNode.getName();
sonu gupta1bb37b82016-11-11 16:51:18 +0530186 }
187
188 @Override
189 public String getNamespace() {
sonu guptaeff184b2016-11-24 12:43:49 +0530190 return yangSchemaNode.getNameSpace().getModuleNamespace();
191 }
192
193 @Override
194 public String getModuleNameAsNameSpace() {
195 return yangSchemaNode.getNameSpace().getModuleName();
sonu gupta1bb37b82016-11-11 16:51:18 +0530196 }
197
198 @Override
199 public <T> T getYdtContextExtendedInfo() {
200 return (T) ydtExtendedInfo;
201 }
202
203 @Override
204 public YdtExtendedInfoType getYdtExtendedInfoType() {
205 return ydtExtendedInfoType;
206 }
207
208 @Override
209 public YdtType getYdtType() {
210 return ydtType;
211 }
212
213 @Override
214 public YdtNode getParent() {
215 return parent;
216 }
217
218 @Override
219 public YdtNode getFirstChild() {
220 return child;
221 }
222
223 @Override
224 public YdtNode getNextSibling() {
225 return nextSibling;
226 }
227
228 public YangSchemaNode getYangSchemaNode() {
229 return yangSchemaNode;
230 }
231
232 @Override
233 public YdtNode getLastChild() {
234 return lastChild;
235 }
236
237 @Override
238 public Object getAppInfo(AppType appType) {
239 return ydtAppInfoMap.get(appType);
240 }
241
242 @Override
243 public void addAppInfo(AppType appType, Object object) {
244 ydtAppInfoMap.put(appType, object);
245 }
246
sonu guptaeff184b2016-11-24 12:43:49 +0530247 /**
248 * Returns child schema node context information. It is used by YMS to
249 * obtain the child schema corresponding to data node identifier.
250 *
251 * @param id represents a identifier of YANG data tree node
252 * @return YANG data node context information
253 * @throws YdtException when user requested node schema doesn't exist
254 */
sonu gupta1bb37b82016-11-11 16:51:18 +0530255 public YangSchemaNodeContextInfo getSchemaNodeContextInfo(
sonu guptaeff184b2016-11-24 12:43:49 +0530256 YangSchemaNodeIdentifier id) throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530257 try {
258 return getYangSchemaNode().getChildSchema(id);
259 } catch (DataModelException e) {
sonu guptaeff184b2016-11-24 12:43:49 +0530260 throw new YdtException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530261 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530262 }
263
264 /**
265 * Adds the given value to the non single instance leaf node.
266 * <p>
267 * This default implementation throws an exception stating that
268 * the value cannot be added. Subclasses may override this method
269 * to provide the correct behavior for their specific implementation.
270 *
271 * @param value value in a single instance node
Bharat saraswal1f371982016-11-23 15:32:57 +0530272 * @throws YdtException when fails to add value for non single instance
273 * leaf node
sonu gupta1bb37b82016-11-11 16:51:18 +0530274 */
sonu guptaeff184b2016-11-24 12:43:49 +0530275 public void addValue(String value) throws YdtException {
276 throw new YdtException(errorMsg(FMT_VAL_N, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530277 }
278
279 /**
280 * Creates the list of key element's of multi instance node.
sonu guptaeff184b2016-11-24 12:43:49 +0530281 * This will not be applicable on leaf and leaf-list node.
282 *
283 * @throws YdtException when user requested multi instance node is missing
284 * any of the key element in request or requested
285 * node is of type other then multi instance node
sonu gupta1bb37b82016-11-11 16:51:18 +0530286 */
sonu guptaeff184b2016-11-24 12:43:49 +0530287 public void createKeyNodeList() throws YdtException {
288 throw new YdtException(errorMsg(FMT_NON_LIST_STR, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530289 }
290
291 /**
292 * Adds the given value to the non single instance leaf node.
293 * <p>
294 * This default implementation throws an exception stating that
295 * the value cannot be added. Subclasses may override this method
296 * to provide the correct behavior for their specific implementation.
297 * This will be applicable in case of call from SBI so no need
298 * to validate the value.
299 *
sonu guptaeff184b2016-11-24 12:43:49 +0530300 * @param value value in a single instance leaf node
301 * @param isKeyLeaf true, for key leaf; false non key leaf
Bharat saraswal1f371982016-11-23 15:32:57 +0530302 * @throws YdtException when fails to add value for non single instance
303 * leaf node
sonu gupta1bb37b82016-11-11 16:51:18 +0530304 */
sonu guptaeff184b2016-11-24 12:43:49 +0530305 public void addValueWithoutValidation(String value, boolean isKeyLeaf)
306 throws YdtException {
307 throw new YdtException(errorMsg(FMT_VAL_N, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530308 }
309
310 /**
311 * Adds the given valueSet to the non multi instance leaf node.
312 * <p>
313 * This default implementation throws an exception stating that
314 * the value cannot be added. Subclasses may override this method
315 * to provide the correct behavior for their specific implementation.
316 *
317 * @param valueSet valueSet in a multi instance leaf node
Bharat saraswal1f371982016-11-23 15:32:57 +0530318 * @throws YdtException when fails to add value set for non multi instance
319 * leaf node
sonu gupta1bb37b82016-11-11 16:51:18 +0530320 */
sonu guptaeff184b2016-11-24 12:43:49 +0530321 public void addValueSet(Set<String> valueSet) throws YdtException {
322 throw new YdtException(errorMsg(FMT_VAL_NS, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530323 }
324
325 /**
326 * Adds the given valueSet to the non multi instance leaf node.
327 * <p>
328 * This default implementation throws an exception stating that
329 * the value cannot be added. Subclasses may override this method
330 * to provide the correct behavior for their specific implementation.
331 * This will be applicable in case of call from SBI so no need
332 * to validate the value.
333 *
334 * @param valueSet valueSet in a multi instance leaf node
Bharat saraswal1f371982016-11-23 15:32:57 +0530335 * @throws YdtException when fails to add value set for non multi instance
336 * leaf node
sonu gupta1bb37b82016-11-11 16:51:18 +0530337 */
sonu guptaeff184b2016-11-24 12:43:49 +0530338 public void addValueSetWithoutValidation(Set<String> valueSet)
339 throws YdtException {
340 throw new YdtException(errorMsg(FMT_VAL_NS, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530341 }
342
343 /**
344 * Validates requested node allowed to have duplicate entry or not.
345 * <p>
346 * This default implementation throws an exception stating that
347 * the duplicate entry found. Subclasses may override this method
348 * to provide the correct behavior for their specific implementation.
Bharat saraswal1f371982016-11-23 15:32:57 +0530349 *
350 * @throws YdtException when fails to process valid duplicate entry in YDT
sonu gupta1bb37b82016-11-11 16:51:18 +0530351 */
sonu guptaeff184b2016-11-24 12:43:49 +0530352 void validDuplicateEntryProcessing() throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530353 }
354
355 /**
356 * Returns already existing YdtNode in Ydt tree with same nodeIdentifier.
357 *
358 * @param id represents a identifier of YANG data tree node
359 * @return YDT node
sonu guptaeff184b2016-11-24 12:43:49 +0530360 * @throws YdtException when user requested node already part of YDT tree.
sonu gupta1bb37b82016-11-11 16:51:18 +0530361 */
sonu guptaeff184b2016-11-24 12:43:49 +0530362 public YdtNode getCollidingChild(YangSchemaNodeIdentifier id)
363 throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530364
365 // Find the key in YDT map for getting the colliding node.
sonu guptaeff184b2016-11-24 12:43:49 +0530366 YdtNode collidingChild = ydtNodeMap.get(id);
sonu gupta1bb37b82016-11-11 16:51:18 +0530367
368 /*
369 * If colliding child exist then process colliding node in respective
370 * YDT node type.
371 */
372 if (collidingChild != null) {
sonu guptaeff184b2016-11-24 12:43:49 +0530373 collidingChild.validDuplicateEntryProcessing();
374 return collidingChild;
sonu gupta1bb37b82016-11-11 16:51:18 +0530375 }
376
377 return null;
378 }
379
380 /**
sonu gupta1bb37b82016-11-11 16:51:18 +0530381 * Sets the parent of node.
382 *
383 * @param parent node
384 */
385 public void setParent(YdtNode parent) {
386 this.parent = parent;
387 }
388
389 /**
390 * Sets the first instance of a child node.
391 *
392 * @param child is only child to be set
393 */
394 public void setChild(YdtNode child) {
395 this.child = child;
396 }
397
398 /**
399 * Sets the next sibling of node.
400 *
401 * @param sibling YANG node
402 */
403 public void setNextSibling(YdtNode sibling) {
404 nextSibling = sibling;
405 }
406
407 /**
408 * Returns the previous sibling of a node.
409 *
410 * @return previous sibling of a node
411 */
412 public YdtNode getPreviousSibling() {
413 return previousSibling;
414 }
415
416 /**
417 * Sets the previous sibling.
418 *
419 * @param previousSibling points to predecessor sibling
420 */
421 public void setPreviousSibling(YdtNode previousSibling) {
422 this.previousSibling = previousSibling;
423 }
424
425 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530426 public String getValue() throws YdtException {
427 throw new YdtException(errorMsg(FMT_VAL_IN, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530428 }
429
430 @Override
sonu guptaeff184b2016-11-24 12:43:49 +0530431 public Set<String> getValueSet() throws YdtException {
432 throw new YdtException(errorMsg(FMT_VAL_INS, getName()));
sonu gupta1bb37b82016-11-11 16:51:18 +0530433 }
434
435 /**
436 * Sets the data-model node reference for of a given node.
437 *
438 * @param yangSchemaNode YANG data node
439 */
440 public void setYangSchemaNode(YangSchemaNode yangSchemaNode) {
441 this.yangSchemaNode = yangSchemaNode;
442 }
443
444 /**
445 * Sets the last instance of a child node.
446 *
447 * @param child is last child to be set
448 */
449 public void setLastChild(YdtNode child) {
450 lastChild = child;
451 }
452
sonu gupta1bb37b82016-11-11 16:51:18 +0530453
454 /**
455 * Adds a child node.
456 * The children sibling list will be sorted based on node
457 * type. This will add single child or sub-tree based on isAtomic flag.
458 *
459 * @param newChild refers to a new child to be added
460 * @param isAtomic boolean flag to maintain atomicity of the current node
461 * @throws YdtException in case of violation of any YDT rule
462 */
463 public void addChild(YdtContext newChild, boolean isAtomic)
464 throws YdtException {
465
466 if (!(newChild instanceof YdtNode)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530467 throw new YdtException(errorMsg(E_SUPPORT));
sonu gupta1bb37b82016-11-11 16:51:18 +0530468 }
469
470 YdtNode node = (YdtNode) newChild;
471
472 if (node.getParent() == null) {
473 node.setParent(this);
474 } else if (!node.getParent().equals(this)) {
sonu guptaeff184b2016-11-24 12:43:49 +0530475 throw new YdtException(E_EXIST);
sonu gupta1bb37b82016-11-11 16:51:18 +0530476 }
477
478 if (node.getFirstChild() != null && isAtomic) {
sonu guptaeff184b2016-11-24 12:43:49 +0530479 throw new YdtException(E_ATOMIC);
sonu gupta1bb37b82016-11-11 16:51:18 +0530480 }
481
482 if (node.getNextSibling() != null) {
sonu guptaeff184b2016-11-24 12:43:49 +0530483 throw new YdtException(E_SIB);
sonu gupta1bb37b82016-11-11 16:51:18 +0530484 }
485
486 if (node.getPreviousSibling() != null) {
sonu guptaeff184b2016-11-24 12:43:49 +0530487 throw new YdtException(E_PRE);
sonu gupta1bb37b82016-11-11 16:51:18 +0530488 }
489
490 // If new node needs to be added as first child.
491 if (getFirstChild() == null) {
492 setChild(node);
493 setLastChild(node);
494 return;
495 }
496
497 // If new node needs to be added as last child.
498 YdtNode curNode = getLastChild();
499 curNode.setNextSibling(node);
500 node.setPreviousSibling(curNode);
501 setLastChild(node);
502 }
503
504 @Override
505 public YdtContextOperationType getYdtContextOperationType() {
506 return ydtContextOperationType;
507 }
508
509 /**
510 * Sets type of yang data tree node operation.
511 *
512 * @param opType type of yang data tree node operation
513 */
514 public void setYdtContextOperationType(YdtContextOperationType opType) {
515 ydtContextOperationType = opType;
516 }
517
518 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530519 * Updates ydt maps of current context parent node.
520 *
521 * @param node ydt node for which map need to be updated
522 */
523 void updateYdtMap(YdtNode node) {
524
525 YangSchemaNodeIdentifier id = node.getYangSchemaNode()
526 .getYangSchemaNodeIdentifier();
527 /*
528 * If node to be added is of type multi instance node(list) then multi
529 * instance node to be updated
530 */
531 if (node.getYdtType() == YdtType.MULTI_INSTANCE_NODE) {
532 updateMultiInsMap(id, node);
533 }
534
535 /*
536 * If entry for multi instance node is already there with same id then
537 * existing entry will be overwritten by the new entry.
538 */
539 ydtNodeMap.put(id, node);
540 }
541
542 /**
543 * Updates ydt multi instance map of current context parent node.
sonu gupta1bb37b82016-11-11 16:51:18 +0530544 *
545 * @param id object node identifier
546 * @param node ydt node for which map need to be updated
547 */
sonu guptaeff184b2016-11-24 12:43:49 +0530548 private void updateMultiInsMap(YangSchemaNodeIdentifier id, YdtNode node) {
549
550 List<YdtNode<YdtMultiInstanceNode>> list = ydtMultiInsMap.get(id);
sonu gupta1bb37b82016-11-11 16:51:18 +0530551 if (list == null) {
552 list = new ArrayList<>();
sonu guptaeff184b2016-11-24 12:43:49 +0530553 ydtMultiInsMap.put(id, list);
sonu gupta1bb37b82016-11-11 16:51:18 +0530554 }
555 list.add(node);
556 }
557
558 /**
559 * Returns the flag for node if context switch.
560 *
561 * @return isContextSwitch flag of a node
562 */
563 public boolean getAppContextSwitch() {
564 return isContextSwitch;
565 }
566
567 /**
568 * Sets the flag to keep the track of context switch.
569 * If it is set then when YDT get traverToParent then
570 * traverse back to parent in YDT application tree.
571 */
572 public void setAppContextSwitch() {
573 isContextSwitch = true;
574 }
575
576 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530577 * Validates all multi Instance nodes inside current context.
Bharat saraswal1f371982016-11-23 15:32:57 +0530578 *
579 * @throws YdtException when fails to validate multi instance node
sonu gupta1bb37b82016-11-11 16:51:18 +0530580 */
sonu guptaeff184b2016-11-24 12:43:49 +0530581 public void validateMultiInstanceNode() throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530582
583 // Set for checking whether input string is unique or not.
584 Set<String> keyStringSet = new HashSet<>();
585
sonu guptaeff184b2016-11-24 12:43:49 +0530586 if (ydtMultiInsMap.size() != 0) {
587 /*
588 * Iterating over values in map and find multi instance node list
589 * only.
590 */
591 for (List<YdtNode<YdtMultiInstanceNode>> ydtNodeList :
592 ydtMultiInsMap.values()) {
593 try {
594 ydtNodeList.get(0).validateInstances(keyStringSet,
595 ydtNodeList);
596 } catch (YdtException e) {
597 throw new YdtException(e.getLocalizedMessage());
sonu gupta1bb37b82016-11-11 16:51:18 +0530598 }
599 }
600 }
601 }
602
603 /**
sonu guptaeff184b2016-11-24 12:43:49 +0530604 * Validates the given list of instances by verifying the allowed
605 * instance count and key element uniqueness.
606 * <p>
607 * This default implementation do nothing if requested node is of type
608 * other then multiInstanceNode. Subclasses may override this method
609 * to provide the correct behavior for their specific implementation.
sonu gupta1bb37b82016-11-11 16:51:18 +0530610 *
sonu guptaeff184b2016-11-24 12:43:49 +0530611 * @param keyStringSet set to validate the key element uniqueness
612 * @param ydtNodeList list of instance's of same list
Bharat saraswal1f371982016-11-23 15:32:57 +0530613 * @throws YdtException when user requested multi instance node instance's
614 * count doesn't fit into the allowed instance's limit
615 * or doesn't have unique key's
sonu gupta1bb37b82016-11-11 16:51:18 +0530616 */
sonu guptaeff184b2016-11-24 12:43:49 +0530617 void validateInstances(Set<String> keyStringSet,
618 List<YdtNode<YdtMultiInstanceNode>>
619 ydtNodeList) throws YdtException {
sonu gupta1bb37b82016-11-11 16:51:18 +0530620
sonu gupta1bb37b82016-11-11 16:51:18 +0530621 }
622
623 /**
624 * Clones the current node contents and create a new node.
625 *
626 * @return cloned node
627 * @throws CloneNotSupportedException clone is not supported
628 * by the referred node
629 */
630 public YdtNode clone() throws CloneNotSupportedException {
631 YdtNode clonedNode = (YdtNode) super.clone();
632 clonedNode.setPreviousSibling(null);
633 clonedNode.setNextSibling(null);
634 clonedNode.setParent(null);
635 clonedNode.setChild(null);
636 clonedNode.setLastChild(null);
637 return clonedNode;
638 }
sonu gupta1bb37b82016-11-11 16:51:18 +0530639}