reschke commented on code in PR #131:
URL: 
https://github.com/apache/sling-org-apache-sling-resourceresolver/pull/131#discussion_r1923537689


##########
src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntryIterator.java:
##########
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.resourceresolver.impl.mapping;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.function.Function;
+
+/**
+ * An {@link Iterator} that combines existing {@link MapEntry}s (usually from 
the "global" list)
+ * with entries from the vanity path map.
+ */
+public class MapEntryIterator implements Iterator<MapEntry> {
+
+    private String key;
+    private MapEntry next;
+
+    private MapEntry nextGlobal;
+    private MapEntry nextSpecial;
+
+    private final @NotNull Iterator<MapEntry> globalListIterator;
+    private @NotNull Iterator<MapEntry> specialIterator = 
Collections.emptyIterator();
+
+    private final @NotNull Function<String, Iterator<MapEntry>> 
getCurrentMapEntryIteratorForVanityPath;
+
+    private final boolean vanityPathPrecedence;
+
+    /**
+     * Creates the combined iterator
+     * @param startKey The path from which to start when finding vanity paths 
(which includes entries from ancestors aswell)
+     * @param globalList The "global" list of map entries
+     * @param getCurrentMapEntryIteratorForVanityPath a function that gets the 
current vanity path entry for a given key (the callback should take care about 
which phase the vanity path initialization is in)
+     * @param vanityPathPrecedence when {@code true}, vanity paths (if 
present) will always come first, otherwise it depends on the length of the map 
entry's match pattern (see {@link MapEntry#getPattern()})
+     */
+    public MapEntryIterator(final @Nullable String startKey, @NotNull 
List<MapEntry> globalList,
+                            final @NotNull Function<String, 
Iterator<MapEntry>> getCurrentMapEntryIteratorForVanityPath,
+                            final boolean vanityPathPrecedence) {
+        this.key = startKey;
+        this.globalListIterator = globalList.iterator();
+        this.vanityPathPrecedence = vanityPathPrecedence;
+        this.getCurrentMapEntryIteratorForVanityPath = 
getCurrentMapEntryIteratorForVanityPath;
+        this.seek();
+    }
+
+    @Override
+    public boolean hasNext() {
+        return this.next != null;
+    }
+
+    @Override
+    public MapEntry next() {
+        if (this.next == null) {
+            throw new NoSuchElementException();
+        }
+        final MapEntry result = this.next;
+        this.seek();
+        return result;
+    }
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+
+    private void seek() {
+
+        // compute candidate for next entry from global list
+
+        if (this.nextGlobal == null && this.globalListIterator.hasNext()) {
+            this.nextGlobal = this.globalListIterator.next();
+        }
+
+        // compute candidate for next entry from "special" vanity path list
+
+        if (this.nextSpecial == null) {
+            // reset specialIterator when exhausted
+            if (!this.specialIterator.hasNext()) {
+                this.specialIterator = Collections.emptyIterator();
+            }
+
+            // given the vanity path in key, walk up the hierarchy until we 
find
+            // map entries for that path (or stop when root is reached)
+            while (!this.specialIterator.hasNext() && this.key != null) {
+                this.key = removeSelectorsAndExtension(this.key);
+                this.specialIterator = 
this.getCurrentMapEntryIteratorForVanityPath.apply(this.key);
+                this.key = getParent(key);
+            }
+
+            if (this.specialIterator.hasNext()) {

Review Comment:
   The only way it could be null is when the 
getCurrentMapEntryIteratorForVanityPath function returns null.
   
   But yes, that's a good idea.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to