3939import cds .gen .adminservice .GenreHierarchy ;
4040import cds .gen .adminservice .GenreHierarchy_ ;
4141
42+ import static cds .gen .adminservice .AdminService_ .GENRE_HIERARCHY ;
43+
4244@ Component
4345@ Profile ("default" )
4446@ ServiceName (AdminService_ .CDS_NAME )
@@ -47,8 +49,8 @@ public class HierarchyHandler implements EventHandler {
4749 private final PersistenceService db ;
4850
4951 HierarchyHandler (PersistenceService db ) {
50- this .db = db ;
51- }
52+ this .db = db ;
53+ }
5254
5355 @ Before (event = CqnService .EVENT_READ , entity = GenreHierarchy_ .CDS_NAME )
5456 public void readGenreHierarchy (CdsReadEventContext event ) {
@@ -58,12 +60,12 @@ public void readGenreHierarchy(CdsReadEventContext event) {
5860 if (trafos .size () < 1 ) {
5961 return ;
6062 }
61-
63+
6264 if (getTopLevels (trafos ) instanceof CqnTopLevelsTransformation topLevels ) {
6365 result = topLevels (topLevels , CQL .TRUE );
6466 } else if (trafos .get (0 ) instanceof CqnDescendantsTransformation descendants ) {
6567 result = handleDescendants (descendants );
66- } else if (trafos .get (0 ) instanceof CqnAncestorsTransformation ancestors ) {
68+ } else if (trafos .get (0 ) instanceof CqnAncestorsTransformation ancestors ) {
6769 if (trafos .size () == 2 && trafos .get (1 ) instanceof CqnTopLevelsTransformation topLevels ) {
6870 result = handleAncestors (ancestors , topLevels );
6971 } else if (trafos .size () == 3 && trafos .get (2 ) instanceof CqnTopLevelsTransformation topLevels ) {
@@ -77,7 +79,8 @@ public void readGenreHierarchy(CdsReadEventContext event) {
7779 private CqnTopLevelsTransformation getTopLevels (List <CqnTransformation > trafos ) {
7880 if (trafos .get (0 ) instanceof CqnTopLevelsTransformation topLevels ) {
7981 return topLevels ;
80- } else if (trafos .size () == 2 && trafos .get (0 ) instanceof CqnOrderByTransformation && trafos .get (1 ) instanceof CqnTopLevelsTransformation topLevels ) {
82+ } else if (trafos .size () == 2 && trafos .get (0 ) instanceof CqnOrderByTransformation
83+ && trafos .get (1 ) instanceof CqnTopLevelsTransformation topLevels ) {
8184 return topLevels ;
8285 }
8386 return null ;
@@ -92,16 +95,17 @@ private void setResult(CdsReadEventContext event, List<GenreHierarchy> result) {
9295 }
9396
9497 private void addDrillState (List <GenreHierarchy > ghs ) {
95- List <Integer > ids = ghs .stream ().map (gh -> gh .getNodeId ()).toList ();
96- Set <Integer > parents = ghs .stream ().map (gh -> gh .getParentId ()).filter (p -> p != 0 ).collect (Collectors .toSet ());
97- CqnSelect q = Select .from (AdminService_ .GENRE_HIERARCHY , gh -> gh .parent ()).columns (gh -> gh .node_id ())
98- .where (gh -> gh .node_id ().in (ids ));
98+ List <Integer > ids = ghs .stream ().map (gh -> gh .getId ()).toList ();
99+ Set <Integer > parents = ghs .stream ().map (gh -> gh .getParntId ()).filter (p -> p != null )
100+ .collect (Collectors .toSet ());
101+ CqnSelect q = Select .from (GENRE_HIERARCHY ).columns (gh -> gh .parnt_ID ().as ("id" ))
102+ .where (gh -> gh .parnt_ID ().in (ids ));
99103 Set <Object > nonLeafs = db
100104 .run (q )
101- .stream ().map (r -> r .get (GenreHierarchy . NODE_ID )).collect (Collectors .toSet ());
105+ .stream ().map (r -> r .get ("id" )).collect (Collectors .toSet ());
102106
103107 for (GenreHierarchy gh : ghs ) {
104- Integer id = gh .getNodeId ();
108+ Integer id = gh .getId ();
105109 if (nonLeafs .contains (id )) {
106110 if (parents .contains (id )) {
107111 gh .setDrillState ("expanded" );
@@ -111,42 +115,43 @@ private void addDrillState(List<GenreHierarchy> ghs) {
111115 } else {
112116 gh .setDrillState ("leaf" );
113117 }
114- }
118+ }
115119 }
116-
117- private List <GenreHierarchy > handleDescendants (CqnDescendantsTransformation descendants ) {
118- Map <Integer , GenreHierarchy > lookup = new HashMap <>();
119- CqnFilterTransformation filter = (CqnFilterTransformation ) descendants .transformations ().get (0 );
120- CqnSelect getRoot = Select .from (AdminService_ .GENRE_HIERARCHY ).where (filter .filter ());
121- GenreHierarchy root = db .run (getRoot ).single (GenreHierarchy .class );
122- lookup .put (root .getNodeId (), root );
123120
124- CqnPredicate parentFilter = CQL .copy (filter .filter (), new Modifier () {
121+ private CqnPredicate descendantsFilter (CqnDescendantsTransformation descendants ) {
122+ CqnTransformation trafo = descendants .transformations ().get (0 );
123+ CqnPredicate start = ((CqnFilterTransformation ) trafo ).filter ();
124+ CqnPredicate result = CQL .FALSE ;
125+ if (descendants .keepStart ()) {
126+ result = CQL .or (result , start );
127+ }
128+ CqnPredicate children = CQL .copy (start , new Modifier () {
125129 @ Override
126130 public CqnValue ref (CqnElementRef ref ) {
127- return CQL .get (GenreHierarchy .PARENT_ID );
131+ return CQL .get (GenreHierarchy .PARNT_ID );
128132 }
129133 });
134+ result = CQL .or (result , children );
130135
131- CqnSelect childrenCQN = Select .from (AdminService_ .GENRE_HIERARCHY ).where (parentFilter );
132- List <GenreHierarchy > children = db .run (childrenCQN ).listOf (GenreHierarchy .class );
133- children .forEach (gh -> lookup .put (gh .getNodeId (), gh ));
134- children .forEach (gh -> gh .setParent (lookup .get (gh .getParentId ())));
135-
136- return children .stream ().sorted (new Sorter ()).toList ();
136+ return result ;
137137 }
138138
139- private List < GenreHierarchy > handleAncestors (CqnAncestorsTransformation ancestors , CqnTopLevelsTransformation topLevels ) {
139+ private CqnPredicate ancestorsFilter (CqnAncestorsTransformation ancestors ) {
140140 CqnTransformation trafo = ancestors .transformations ().get (0 );
141- Select <GenreHierarchy_ > inner = Select .from (AdminService_ . GENRE_HIERARCHY ).columns (gh -> gh .node_id ());
141+ Select <GenreHierarchy_ > inner = Select .from (GENRE_HIERARCHY ).columns (gh -> gh .ID ());
142142 if (trafo instanceof CqnFilterTransformation filter ) {
143143 inner .where (filter .filter ());
144144 } else if (trafo instanceof CqnSearchTransformation search ) {
145145 inner .search (search .search ());
146146 }
147- Select <GenreHierarchy_ > outer = Select .from (AdminService_ .GENRE_HIERARCHY ).columns (gh -> gh .node_id ().as ("i0" ), gh -> gh .parent ().node_id ().as ("i1" ),
148- gh -> gh .parent ().parent ().node_id ().as ("i2" ), gh -> gh .parent ().parent ().parent ().node_id ().as ("i3" ),
149- gh -> gh .parent ().parent ().parent ().parent ().node_id ().as ("i4" )).where (gh -> gh .node_id ().in (inner ));
147+
148+ Select <GenreHierarchy_ > outer = Select .from (GENRE_HIERARCHY )
149+ .columns (gh -> gh .ID ().as ("i0" ),
150+ gh -> gh .parnt ().ID ().as ("i1" ),
151+ gh -> gh .parnt ().parnt ().ID ().as ("i2" ),
152+ gh -> gh .parnt ().parnt ().parnt ().ID ().as ("i3" ),
153+ gh -> gh .parnt ().parnt ().parnt ().parnt ().ID ().as ("i4" ))
154+ .where (gh -> gh .ID ().in (inner ));
150155
151156 Set <Integer > ancestorIds = new HashSet <>();
152157 db .run (outer ).stream ().forEach (r -> {
@@ -157,7 +162,30 @@ private List<GenreHierarchy> handleAncestors(CqnAncestorsTransformation ancestor
157162 addIfNotNull (ancestorIds , r , "i4" );
158163 });
159164
160- CqnPredicate filter = CQL .get ("node_id" ).in (ancestorIds .stream ().toList ());
165+ return CQL .get (GenreHierarchy_ .ID ).in (ancestorIds .stream ().toList ());
166+ }
167+
168+ private List <GenreHierarchy > handleDescendants (CqnDescendantsTransformation descendants ) {
169+ CqnPredicate filter = descendantsFilter (descendants );
170+ CqnSelect childrenCQN = Select .from (GENRE_HIERARCHY ).where (filter );
171+ List <GenreHierarchy > nodes = db .run (childrenCQN ).listOf (GenreHierarchy .class );
172+
173+ connect (nodes );
174+
175+ return nodes .stream ().sorted (new Sorter ()).toList ();
176+ }
177+
178+ private static void connect (List <GenreHierarchy > nodes ) {
179+ Map <Integer , GenreHierarchy > lookup = new HashMap <>();
180+ nodes .forEach (gh -> lookup .put (gh .getId (), gh ));
181+ nodes .forEach (gh -> gh .setParnt (lookup .get (gh .getParntId ())));
182+ nodes .forEach (gh -> gh .setDistanceFromRoot (distanceFromRoot (gh )));
183+ }
184+
185+ private List <GenreHierarchy > handleAncestors (CqnAncestorsTransformation ancestors ,
186+ CqnTopLevelsTransformation topLevels ) {
187+ CqnPredicate filter = ancestorsFilter (ancestors );
188+
161189 return topLevels (topLevels , filter );
162190 }
163191
@@ -166,7 +194,7 @@ private void addIfNotNull(Set<Integer> ancestorIds, Row r, String key) {
166194 if (id != null ) {
167195 ancestorIds .add (id );
168196 }
169- }
197+ }
170198
171199 private List <GenreHierarchy > topLevels (CqnTopLevelsTransformation topLevels , CqnPredicate filter ) {
172200 return topLevels .levels () < 0 ? topLevelsAll (filter ) : topLevelsLimit (topLevels , filter );
@@ -177,40 +205,41 @@ private List<GenreHierarchy> topLevelsLimit(CqnTopLevelsTransformation topLevels
177205 Map <Integer , GenreHierarchy > lookup = new HashMap <>();
178206 Map <Object , Long > expandLevels = topLevels .expandLevels ();
179207
180- CqnSelect getRoots = Select .from (AdminService_ . GENRE_HIERARCHY ).where (gh -> gh .parent_id ().eq ( 0 ).and (filter ));
208+ CqnSelect getRoots = Select .from (GENRE_HIERARCHY ).where (gh -> gh .parnt_ID ().isNull ( ).and (filter ));
181209 List <GenreHierarchy > roots = db .run (getRoots ).listOf (GenreHierarchy .class );
182210 roots .forEach (root -> {
183211 root .setDistanceFromRoot (0l );
184- lookup .put (root .getNodeId (), root );
185- List <Integer > parents = List .of (root .getNodeId ());
212+ lookup .put (root .getId (), root );
213+ List <Integer > parents = List .of (root .getId ());
186214 for (long i = 1 ; i < limit ; i ++) {
187215 List <Integer > ps = parents ;
188- CqnSelect getChildren = Select .from (AdminService_ .GENRE_HIERARCHY ).where (gh -> gh .parent_id ().in (ps ).and (filter ));
216+ CqnSelect getChildren = Select .from (GENRE_HIERARCHY )
217+ .where (gh -> gh .parnt_ID ().in (ps ).and (filter ));
189218 List <GenreHierarchy > children = db .run (getChildren ).listOf (GenreHierarchy .class );
190219 if (children .isEmpty ()) {
191220 break ;
192221 }
193222 long dfr = i ;
194223 parents = children .stream ().peek (gh -> {
195- gh .setParent (lookup .get (gh .getParentId ()));
224+ gh .setParnt (lookup .get (gh .getParntId ()));
196225 gh .setDistanceFromRoot (dfr );
197- lookup .put (gh .getNodeId (), gh );
198- }).map (GenreHierarchy ::getNodeId ).toList ();
226+ lookup .put (gh .getId (), gh );
227+ }).map (GenreHierarchy ::getId ).toList ();
199228 }
200229 });
201230
202231 if (!expandLevels .isEmpty ()) {
203232 List <Integer > expandedIds = expandLevels .keySet ().stream ().map (key -> (Integer ) key ).toList ();
204233 CqnSelect expandedCQN = Select .from (AdminService_ .GENRE_HIERARCHY ).where (gh ->
205234 CQL .and (filter ,
206- CQL .or (gh .node_id ().in (expandedIds ), gh .parent_id ().in (expandedIds ))));
235+ CQL .or (gh .ID ().in (expandedIds ), gh .parnt_ID ().in (expandedIds ))));
207236
208237 List <GenreHierarchy > expanded = db .run (expandedCQN ).listOf (GenreHierarchy .class );
209238 expanded .forEach (gh -> {
210- if (!lookup .keySet ().contains (gh .getNodeId ())) {
211- gh .setParent (lookup .get (gh .getParentId ()));
239+ if (!lookup .keySet ().contains (gh .getId ())) {
240+ gh .setParnt (lookup .get (gh .getParntId ()));
212241 gh .setDistanceFromRoot (distanceFromRoot (gh ));
213- lookup .put (gh .getNodeId (), gh );
242+ lookup .put (gh .getId (), gh );
214243 }
215244 });
216245
@@ -220,22 +249,19 @@ private List<GenreHierarchy> topLevelsLimit(CqnTopLevelsTransformation topLevels
220249 }
221250
222251 private List <GenreHierarchy > topLevelsAll (CqnPredicate filter ) {
223- Map <Integer , GenreHierarchy > lookup = new HashMap <>();
224-
225- CqnSelect allCqn = Select .from (AdminService_ .GENRE_HIERARCHY ).where (filter );
252+ CqnSelect allCqn = Select .from (GENRE_HIERARCHY ).where (filter );
226253 var all = db .run (allCqn ).listOf (GenreHierarchy .class );
227- all .forEach (gh -> lookup .put (gh .getNodeId (), gh ));
228- all .forEach (gh -> gh .setParent (lookup .get (gh .getParentId ())));
229- all .forEach (gh -> gh .setDistanceFromRoot (distanceFromRoot (gh )));
254+
255+ connect (all );
230256
231257 return all .stream ().sorted (new Sorter ()).toList ();
232258 }
233259
234260 private static long distanceFromRoot (GenreHierarchy gh ) {
235261 long dfr = 0 ;
236- while (gh .getParent () != null ) {
262+ while (gh .getParnt () != null ) {
237263 dfr ++;
238- gh = gh .getParent ();
264+ gh = gh .getParnt ();
239265 }
240266
241267 return dfr ;
@@ -260,14 +286,14 @@ public int compare(GenreHierarchy gh1, GenreHierarchy gh2) {
260286 return res ;
261287 }
262288
263- Deque <String > getPath (GenreHierarchy gh ){
289+ Deque <String > getPath (GenreHierarchy gh ) {
264290 Deque <String > path = new ArrayDeque <>();
265291 do {
266292 path .push (gh .getName ());
267- gh = gh .getParent ();
268- } while (gh != null );
293+ gh = gh .getParnt ();
294+ } while (gh != null );
269295
270296 return path ;
271- }
297+ }
272298 }
273299}
0 commit comments