com.adobe.acs.commons.util.visitors.SimpleFilteringResourceVisitor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of acs-aem-commons-bundle Show documentation
Show all versions of acs-aem-commons-bundle Show documentation
Core ACS AEM Commons OSGi Bundle. Includes commons utilities.
/*
* #%L
* ACS AEM Commons Bundle
* %%
* Copyright (C) 2017 Adobe
* %%
* Licensed 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.
* #L%
*/
package com.adobe.acs.commons.util.visitors;
import com.adobe.acs.commons.functions.CheckedBiConsumer;
import com.adobe.acs.commons.functions.CheckedFunction;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.apache.sling.api.resource.Resource;
public class SimpleFilteringResourceVisitor {
public enum TraversalMode {
DEPTH, BREADTH
}
TraversalMode mode = TraversalMode.BREADTH;
CheckedBiConsumer, Integer> propertyVisitor = null;
CheckedBiConsumer resourceVisitor = null;
CheckedBiConsumer leafVisitor = null;
LinkedList stack = new LinkedList<>();
CheckedFunction propertyFilter = s -> true;
CheckedFunction traversalFilter = r -> true;
public void setPropertyFilter(Function filter) {
propertyFilter = CheckedFunction.from(filter);
}
public void setPropertyFilterChecked(CheckedFunction filter) {
propertyFilter = filter;
}
public final void setTraversalFilter(Function filter) {
traversalFilter = CheckedFunction.from(filter);
}
public final void setTraversalFilterChecked(CheckedFunction filter) {
traversalFilter = filter;
}
public final void setResourceVisitor(BiConsumer handler) {
resourceVisitor = CheckedBiConsumer.from(handler);
}
public final void setResourceVisitorChecked(CheckedBiConsumer handler) {
resourceVisitor = handler;
}
public final void setLeafVisitor(BiConsumer handler) {
leafVisitor = CheckedBiConsumer.from(handler);
}
public final void setLeafVisitorChecked(CheckedBiConsumer handler) {
leafVisitor = handler;
}
public final void setPropertyVisitor(BiConsumer, Integer> handler) {
propertyVisitor = CheckedBiConsumer.from(handler);
}
public final void setPropertyVisitorChecked(CheckedBiConsumer, Integer> handler) {
propertyVisitor = handler;
}
public final void setBreadthFirstMode() {
mode = TraversalMode.BREADTH;
}
public final void setDepthFirstMode() {
mode = TraversalMode.DEPTH;
}
public void accept(final Resource head) throws TraversalException {
if (head == null) {
return;
}
stack.clear();
stack.add(head);
int headLevel = getDepth(head.getPath());
while (!stack.isEmpty()) {
visitNodesInStack(headLevel);
}
}
private void visitNodesInStack(int headLevel) throws TraversalException {
Resource res = stack.poll();
int level = getDepth(res.getPath()) - headLevel;
if (propertyVisitor != null) {
visitProperties(res, level);
}
try {
if (traversalFilter == null || traversalFilter.apply(res)) {
traverseChildren(res, level);
} else if (leafVisitor != null) {
leafVisitor.accept(res, level);
}
} catch (Exception e) {
throw new TraversalException(e);
}
}
private void visitProperties(Resource res, int level) throws TraversalException {
try {
for (Entry entry : res.getValueMap().entrySet()) {
if (propertyFilter == null || propertyFilter.apply(entry.getKey())) {
propertyVisitor.accept(entry, level);
}
}
} catch (Exception e) {
throw new TraversalException(e);
}
}
private void traverseChildren(Resource res, int level) throws TraversalException {
if (resourceVisitor != null) {
try {
resourceVisitor.accept(res, level);
} catch (Exception e) {
throw new TraversalException(e);
}
}
switch (mode) {
case BREADTH:
stack.addAll(toList(res.getChildren()));
break;
default:
stack.addAll(0, toList(res.getChildren()));
}
}
public static List toList(final Iterable iterable) {
return StreamSupport.stream(iterable.spliterator(), false)
.collect(Collectors.toList());
}
public static int getDepth(String path) {
return (int) path.chars().filter(c -> c == '/').count() - 1;
}
}