2222 *
2323 * @author Aaron Hansen
2424 */
25- public class DSInfo implements ApiObject , GroupListener {
25+ public class DSInfo < T extends DSIObject > implements ApiObject , GroupListener {
2626
2727 ///////////////////////////////////////////////////////////////////////////
2828 // Constants
@@ -44,7 +44,7 @@ public class DSInfo implements ApiObject, GroupListener {
4444 DSMap metadata ;
4545 String name ;
4646 DSInfo next ;
47- DSIObject object ;
47+ T object ;
4848 DSNode parent ;
4949 DSInfo prev ;
5050
@@ -55,7 +55,7 @@ public class DSInfo implements ApiObject, GroupListener {
5555 DSInfo () {
5656 }
5757
58- public DSInfo (String name , DSIObject object ) {
58+ protected DSInfo (String name , T object ) {
5959 this .name = name ;
6060 setObject (object );
6161 }
@@ -64,22 +64,6 @@ public DSInfo(String name, DSIObject object) {
6464 // Public Methods
6565 ///////////////////////////////////////////////////////////////////////////
6666
67- public DSInfo copy () {
68- DSInfo ret = new DSInfo ();
69- ret .copyState (this );
70- if (isDefaultOnCopy ()) {
71- DSIObject val = getDefaultObject ();
72- if (val != null ) {
73- ret .setObject (val .copy ());
74- return ret ;
75- }
76- }
77- if (object != null ) {
78- ret .setObject (object .copy ());
79- }
80- return ret ;
81- }
82-
8367 public void decodeState (DSElement state ) {
8468 flags = state .toInt ();
8569 }
@@ -159,7 +143,7 @@ public boolean equivalent(Object arg) {
159143 /**
160144 * Returns the target object.
161145 */
162- public DSIObject get () {
146+ public T get () {
163147 return object ;
164148 }
165149
@@ -201,13 +185,6 @@ public Iterator<String> getChildren() {
201185 return bucket .iterator ();
202186 }
203187
204- /**
205- * If this is a proxy , this will return the original default instance.
206- */
207- public DSIObject getDefaultObject () {
208- return get ();
209- }
210-
211188 /**
212189 * A convenience that casts the object. Will call DSIValue.toElement on values.
213190 */
@@ -248,15 +225,6 @@ public DSNode getNode() {
248225 return (DSNode ) get ();
249226 }
250227
251- /**
252- * User get() instead.
253- *
254- * @deprecated 18-11-14
255- */
256- public DSIObject getObject () {
257- return object ;
258- }
259-
260228 public DSNode getParent () {
261229 return parent ;
262230 }
@@ -288,7 +256,7 @@ public boolean hasNext() {
288256 /**
289257 * True if the value of the info is an instance of the given class.
290258 */
291- public boolean is (Class clazz ) {
259+ public boolean is (Class <?> clazz ) {
292260 if (object == null ) {
293261 return false ;
294262 }
@@ -328,7 +296,8 @@ public boolean isFrozen() {
328296 }
329297
330298 /**
331- * True if the info cannot be removed or renamed. Use for non-default nodes.
299+ * True if the info cannot be removed or renamed.
300+ * Intended for non-default children, default children are implicitly locked.
332301 */
333302 public boolean isLocked () {
334303 return getFlag (LOCKED );
@@ -348,7 +317,10 @@ public boolean isNull() {
348317 if (object == null ) {
349318 return true ;
350319 }
351- return object .isNull ();
320+ if (isValue ()) {
321+ return getValue ().isNull ();
322+ }
323+ return false ;
352324 }
353325
354326 /**
@@ -388,73 +360,73 @@ public void modified(DSGroup map) {
388360 }
389361
390362 /**
391- * The next info in the parent node.
363+ * The next info in the parent node, or null .
392364 */
393365 public DSInfo next () {
394366 return next ;
395367 }
396368
397369 /**
398- * The next DSInfo in the parent whose object is of the given type.
370+ * The next DSInfo in the parent whose object is of the given type, or null .
399371 */
400- public DSInfo next (Class is ) {
372+ public DSInfo next (Class <?> is ) {
401373 DSInfo cur = next ;
402374 while (cur != null ) {
403375 if (cur .is (is )) {
404376 return cur ;
405377 }
406378 cur = cur .next ();
407379 }
408- return cur ;
380+ return null ;
409381 }
410382
411383 /**
412384 * The next DSInfo in the parent that is an action, or null.
413385 */
414- public DSInfo nextAction () {
386+ public DSInfo < DSAction > nextAction () {
415387 DSInfo cur = next ;
416388 while (cur != null ) {
417389 if (cur .isAction ()) {
418390 return cur ;
419391 }
420392 cur = cur .next ();
421393 }
422- return cur ;
394+ return null ;
423395 }
424396
425397 /**
426398 * The next DSInfo in the parent that is a node, or null.
427399 */
428- public DSInfo nextNode () {
400+ public DSInfo < DSNode > nextNode () {
429401 DSInfo cur = next ;
430402 while (cur != null ) {
431403 if (cur .isNode ()) {
432404 return cur ;
433405 }
434406 cur = cur .next ();
435407 }
436- return cur ;
408+ return null ;
437409 }
438410
439411 /**
440412 * The next DSInfo in the parent that is a value, or null.
441413 */
442- public DSInfo nextValue () {
414+ public DSInfo < DSIValue > nextValue () {
443415 DSInfo cur = next ;
444416 while (cur != null ) {
445417 if (cur .isValue ()) {
446418 return cur ;
447419 }
448420 cur = cur .next ();
449421 }
450- return cur ;
422+ return null ;
451423 }
452424
453425 /**
454426 * False by default, set to true if you don't want the child to require admin level
455427 * permissions.
456428 */
457- public DSInfo setAdmin (boolean admin ) {
429+ public DSInfo < T > setAdmin (boolean admin ) {
458430 setFlag (ADMIN , admin );
459431 return this ;
460432 }
@@ -463,21 +435,21 @@ public DSInfo setAdmin(boolean admin) {
463435 * False by default, set to true to reset the target to it's default when the encapsulated node
464436 * is copied.
465437 */
466- public DSInfo setDefaultOnCopy (boolean defaultOnCopy ) {
438+ public DSInfo < T > setDefaultOnCopy (boolean defaultOnCopy ) {
467439 setFlag (DEFAULT_ON_COPY , defaultOnCopy );
468440 return this ;
469441 }
470442
471443 /**
472444 * False by default, set to true if the info cannot be removed or renamed.
473- * Use for non-default nodes .
445+ * Intended for non-default children, default children are implicitly locked .
474446 */
475- public DSInfo setLocked (boolean locked ) {
447+ public DSInfo < T > setLocked (boolean locked ) {
476448 setFlag (LOCKED , locked );
477449 return this ;
478450 }
479451
480- public DSInfo setMetadata (DSMap map ) {
452+ public DSInfo < T > setMetadata (DSMap map ) {
481453 map .setParent (this );
482454 metadata = map ;
483455 return this ;
@@ -486,23 +458,23 @@ public DSInfo setMetadata(DSMap map) {
486458 /**
487459 * False by default, set to true if you don't want the child to be sent to clients.
488460 */
489- public DSInfo setPrivate (boolean hidden ) {
461+ public DSInfo < T > setPrivate (boolean hidden ) {
490462 setFlag (PRIVATE , hidden );
491463 return this ;
492464 }
493465
494466 /**
495467 * False by default, set to true if you don't want the child to be written by clients.
496468 */
497- public DSInfo setReadOnly (boolean readOnly ) {
469+ public DSInfo < T > setReadOnly (boolean readOnly ) {
498470 setFlag (READONLY , readOnly );
499471 return this ;
500472 }
501473
502474 /**
503475 * False by default, set to true if you don't want the child persisted.
504476 */
505- public DSInfo setTransient (boolean trans ) {
477+ public DSInfo < T > setTransient (boolean trans ) {
506478 setFlag (TRANSIENT , trans );
507479 return this ;
508480 }
@@ -518,32 +490,47 @@ public String toString() {
518490 // Package Methods
519491 ///////////////////////////////////////////////////////////////////////////
520492
521- /**
522- * This is only called by DSNode.copy. Therefore, this will already
523- * be populated with the default value.
524- */
525- void copy (DSInfo info ) {
493+ DSInfo <T > copy () {
494+ DSInfo <T > ret = new DSInfo <>();
495+ ret .copyState (this );
496+ if (isDefaultOnCopy ()) {
497+ DSIObject val = getDefaultObject ();
498+ if (val != null ) {
499+ ret .setObject ((T ) val .copy ());
500+ return ret ;
501+ }
502+ }
503+ if (object != null ) {
504+ ret .setObject ((T ) object .copy ());
505+ }
506+ return ret ;
507+ }
508+
509+ void copy (DSInfo <T > info ) {
526510 copyState (info );
527511 if (isDefaultOnCopy ()) {
528512 return ;
529513 }
530514 if (info .object != null ) {
531- setObject (info .object .copy ());
515+ setObject (( T ) info .object .copy ());
532516 }
533517 }
534518
535- /**
536- * This is only called by DSNode.copy. Therefore, this will already
537- * be populated with the default value.
538- */
539- void copyState (DSInfo info ) {
519+ void copyState (DSInfo <T > info ) {
540520 flags = info .flags ;
541521 name = info .name ;
542522 if (info .metadata != null ) {
543523 metadata = info .metadata .copy ();
544524 }
545525 }
546526
527+ /**
528+ * If this is a proxy , this will return the original default instance.
529+ */
530+ T getDefaultObject () {
531+ return get ();
532+ }
533+
547534 boolean getFlag (int position ) {
548535 return DSUtil .getBit (flags , position );
549536 }
@@ -566,28 +553,32 @@ boolean isProxy() {
566553 return false ;
567554 }
568555
569- DSInfo setFlag (int position , boolean on ) {
556+ DSInfo <T > newProxy () {
557+ return new DSInfoProxy <>(this );
558+ }
559+
560+ DSInfo <T > setFlag (int position , boolean on ) {
570561 //modified?
571562 flags = DSUtil .setBit (flags , position , on );
572563 return this ;
573564 }
574565
575- DSInfo setName (String arg ) {
566+ DSInfo < T > setName (String arg ) {
576567 this .name = arg ;
577568 return this ;
578569 }
579570
580- DSInfo setObject (DSIObject arg ) {
571+ DSInfo < T > setObject (T arg ) {
581572 this .object = arg ;
582573 return this ;
583574 }
584575
585- DSInfo setParent (DSNode arg ) {
576+ DSInfo < T > setParent (DSNode arg ) {
586577 this .parent = arg ;
587578 return this ;
588579 }
589580
590- DSInfo setDeclared (boolean arg ) {
581+ DSInfo < T > setDeclared (boolean arg ) {
591582 setFlag (DECLARED , arg );
592583 return this ;
593584 }
0 commit comments