/* * Copyright 2014 Daniel Bechler * * 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. */ package de.danielbechler.diff.path; import de.danielbechler.diff.selector.ElementSelector; import de.danielbechler.diff.selector.RootElementSelector; import de.danielbechler.util.Assert; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * @author Daniel Bechler * @see de.danielbechler.diff.inclusion.ValueNode * @deprecated The ConfigNode provides a much more powerful way to store values for NodePaths. */ @Deprecated public class NodePathValueHolder<T> { private final Map<ElementSelector, NodePathValueHolder<T>> elementValueHolders = new HashMap<ElementSelector, NodePathValueHolder<T>>(); private T value; public static <T> NodePathValueHolder<T> of(final Class<T> type) { Assert.notNull(type, "type"); return new NodePathValueHolder<T>(); } public NodePathValueHolder<T> put(final NodePath nodePath, final T value) { put(nodePath.getElementSelectors(), value); return this; } private void put(final List<ElementSelector> elementSelectors, final T value) { if (elementSelectors.isEmpty()) { return; } final ElementSelector elementSelector = elementSelectors.get(0); NodePathValueHolder<T> nodePathValueHolder = valueHolderForElementSelector(elementSelector); if (nodePathValueHolder == null) { nodePathValueHolder = new NodePathValueHolder<T>(); elementValueHolders.put(elementSelector, nodePathValueHolder); } if (elementSelectors.size() == 1) { nodePathValueHolder.value = value; } else { final List<ElementSelector> nodePathElementsTail = new ArrayList<ElementSelector>(elementSelectors.size() - 1); nodePathElementsTail.addAll(elementSelectors.subList(1, elementSelectors.size())); nodePathValueHolder.put(nodePathElementsTail, value); } } private T visit(final List<T> accumulator, final Iterator<ElementSelector> elementIterator) { if (value != null) { accumulator.add(value); } if (elementIterator.hasNext()) { final ElementSelector selector = elementIterator.next(); final NodePathValueHolder<T> valueHolder = valueHolderForElementSelector(selector); if (valueHolder != null) { return valueHolder.visit(accumulator, elementIterator); } return null; } return value; } private NodePathValueHolder<T> valueHolderForElementSelector(final ElementSelector elementSelector) { return elementValueHolders.get(elementSelector); } public T valueForNodePath(final NodePath nodePath) { return visit(new LinkedList<T>(), nodePath.getElementSelectors().iterator()); } public List<T> accumulatedValuesForNodePath(final NodePath nodePath) { final List<T> accumulator = new LinkedList<T>(); visit(accumulator, nodePath.getElementSelectors().iterator()); return accumulator; } public boolean containsValue(final T value) { if (value == null && this.value == null) { return true; } else if (value != null && value.equals(this.value)) { return true; } else { for (final NodePathValueHolder<T> valueHolder : elementValueHolders.values()) { if (valueHolder.containsValue(value)) { return true; } } return false; } } public void collect(final Collector<T> collector) { collect(null, collector); } private void collect(final NodePath nodePath, final Collector<T> collector) { if (nodePath != null && value != null) { collector.it(nodePath, value); } for (final Map.Entry<ElementSelector, NodePathValueHolder<T>> entry : elementValueHolders.entrySet()) { final NodePath childNodePath; final ElementSelector elementSelector = entry.getKey(); final NodePathValueHolder<T> valueHolder = entry.getValue(); if (elementSelector == RootElementSelector.getInstance()) { childNodePath = NodePath.withRoot(); } else { childNodePath = NodePath.startBuildingFrom(nodePath).element(elementSelector).build(); } if (valueHolder != null) { valueHolder.collect(childNodePath, collector); } } } @Override public String toString() { final StringBuilder stringBuilder = new StringBuilder(); collect(new Collector<T>() { public void it(final NodePath path, final T value) { stringBuilder.append(path.toString()).append(" => ").append(value).append('\n'); } }); return stringBuilder.toString(); } public void hasChildMatchingValue(NodePath nodePath, T inclusion) { } public static interface Collector<T> { void it(NodePath path, T value); } }