1616import java .util .ArrayList ;
1717import java .util .Collections ;
1818import java .util .HashMap ;
19+ import java .util .Iterator ;
1920import java .util .List ;
2021import java .util .Set ;
2122import java .util .logging .Logger ;
@@ -42,6 +43,7 @@ private class Node {
4243
4344 private HashMap <String , Node > children ;
4445 private E element ;
46+ private boolean significant = true ;
4547
4648 public Node (E element ) {
4749 this .element = element ;
@@ -63,6 +65,10 @@ public Set<String> getKeySet() {
6365 public Node getChild (String pathelement ) {
6466 return children .get (pathelement );
6567 }
68+
69+ public void setSignificant (boolean significant ) {
70+ this .significant = significant ;
71+ }
6672 }
6773
6874 private static Logger logger = Logger .getLogger (ReportTree .class .getName ());
@@ -338,16 +344,45 @@ public static <E extends DataObject<E>> void sumInparent(
338344
339345 }
340346
347+ /**
348+ * @author <a href="https://openlowcode.com/" rel="nofollow">Open Lowcode
349+ * SAS</a>
350+ *
351+ * @param <E> data object in the report tree
352+ */
341353 public interface Enricher <E extends DataObject <E >> {
354+ /**
355+ * @param originobject
356+ */
342357 public void enrich (E originobject );
343358 }
344359
360+ /**
361+ * This interface checks if the object has any significant information to reduce
362+ * the report tree to only significant data
363+ *
364+ * @author <a href="https://openlowcode.com/" rel="nofollow">Open Lowcode
365+ * SAS</a>
366+ *
367+ * @param <E> data object in the report tree
368+ */
369+
370+ @ FunctionalInterface
371+ public interface SignificantChecker <E extends DataObject <E >> {
372+ /**
373+ * @param object
374+ * @return true if the object is significant
375+ */
376+ public boolean isSignificant (E object );
377+ }
378+
345379 private DataObjectDefinition <E > objectdefinition ;
346380 private Node rootnode ;
347381
348382 private Namesetter <E > namesetter ;
349383 private Consolidator <E >[] consolidators ;
350384 private ComplexConsolidator <E > complexconsolidator ;
385+ private SignificantChecker <E > significantchecker ;
351386 private ValueExtractor <E , String > nameextractor ;
352387 private Initiator <E > initiator ;
353388
@@ -458,6 +493,10 @@ public void addComplexConsolidator(ComplexConsolidator<E> complexconsolidator) {
458493 this .complexconsolidator = complexconsolidator ;
459494 }
460495
496+ public void addsignificantchecker (SignificantChecker <E > significantchecker ) {
497+ this .significantchecker = significantchecker ;
498+ }
499+
461500 /**
462501 * This method will add the given object as a node if it has a label. If it does
463502 * not have a label, the value will be rolled-up into the parent of the last
@@ -500,7 +539,7 @@ public void addNode(String[] parentlabels, E node) {
500539 droperror .append ("]" );
501540 for (int i = 0 ; i < parentlabelstouse .length ; i ++)
502541 if (parentlabelstouse [i ] == null ) {
503- logger .severe (" ---- Error null label for object " + node .dropToString ());
542+ logger .fine (" ---- Error null label for object " + node .dropToString ());
504543 throw new RuntimeException ("Null element " + i + " in parent labels " + droperror .toString ());
505544 }
506545 Node currentnode = rootnode ;
@@ -555,17 +594,39 @@ public NodeTree<E> generateNodeTree(DataObjectDefinition<E> objectdefinition) {
555594 rollupamount (rootnode , 0 );
556595
557596 NodeTree <E > nodetree = new NodeTree <E >(rootnode .getElement ());
558-
597+
598+ if (this .significantchecker !=null ) checksignificant (rootnode ,0 );
559599 addChildren (nodetree , rootnode , 0 );
560600 return nodetree ;
561601 }
562602
603+ /**
604+ * @param node node to check for significance
605+ * @param circuitbreaker recursive circuit breaker
606+ */
607+ private boolean checksignificant (ReportTree <E >.Node node , int circuitbreaker ) {
608+ if (circuitbreaker > 50 )
609+ throw new RuntimeException (
610+ "Recursive path error for element " + nameextractor .extract (node .getElement ()));
611+ boolean childrensignificant = false ;
612+ Iterator <String > keyiterator = node .getKeySet ().iterator ();
613+ while (keyiterator .hasNext ()) {
614+ boolean childsignificant = this .checksignificant (node .getChild (keyiterator .next ()), circuitbreaker +1 );
615+ if (childsignificant ) childrensignificant =true ;
616+ }
617+ boolean owndatasignificant = this .significantchecker .isSignificant (node .getElement ());
618+ boolean significanttotal = childrensignificant | owndatasignificant ;
619+ node .setSignificant (significanttotal );
620+ logger .fine ("Set significant for node " +nameextractor .extract (node .getElement ())+" total=" +significanttotal +", own=" +owndatasignificant +", children = " +childrensignificant );
621+ return significanttotal ;
622+ }
623+
563624 /**
564625 * Just before the node generation, the roll-up is performed. This avoids having
565- * issue with
626+ * issue with revursivity, a circuit breaker is used
566627 *
567- * @param parentnode
568- * @param circuitbreaker
628+ * @param parentnode node to process
629+ * @param circuitbreaker recursive level
569630 */
570631 private void rollupamount (Node parentnode , int circuitbreaker ) {
571632 if (circuitbreaker > 50 )
@@ -578,12 +639,13 @@ private void rollupamount(Node parentnode, int circuitbreaker) {
578639 rollupamount (childnode , circuitbreaker + 1 );
579640 for (int j = 0 ; j < this .consolidators .length ; j ++)
580641 consolidators [j ].consolidate (parentnode .element , childnode .element );
581-
642+
582643 }
583- if (complexconsolidator != null ) {
644+ if (complexconsolidator != null ) {
584645 ArrayList <E > allchildren = new ArrayList <E >();
585- for (int i =0 ;i <orderedchildrenkeys .size ();i ++) allchildren .add (parentnode .getChild (orderedchildrenkeys .get (i )).getElement ());
586- complexconsolidator .consolidateWithFullData (parentnode .element ,allchildren );
646+ for (int i = 0 ; i < orderedchildrenkeys .size (); i ++)
647+ allchildren .add (parentnode .getChild (orderedchildrenkeys .get (i )).getElement ());
648+ complexconsolidator .consolidateWithFullData (parentnode .element , allchildren );
587649 }
588650
589651 }
@@ -597,8 +659,12 @@ private void addChildren(NodeTree<E> nodetree, Node parentnode, int circuitbreak
597659 Collections .sort (orderedchildrenkeys );
598660 for (int i = 0 ; i < orderedchildrenkeys .size (); i ++) {
599661 Node childnode = parentnode .getChild (orderedchildrenkeys .get (i ));
600- nodetree .addChild (parentnode .getElement (), childnode .getElement ());
601- addChildren (nodetree , childnode , circuitbreaker + 1 );
662+ if (childnode .significant ) {
663+ nodetree .addChild (parentnode .getElement (), childnode .getElement ());
664+ addChildren (nodetree , childnode , circuitbreaker + 1 );
665+ } else {
666+ logger .fine ("Node dropped " +childnode .getElement ());
667+ }
602668 }
603669 }
604670
0 commit comments