Java tutorial
/** * Copyright 2017 Open Source Osijek Community * * 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 org.blip.workflowengine.transferobject; import com.google.common.collect.Iterables; import java.nio.file.Path; import java.nio.file.Paths; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; /** * Created by root on 04.01.17.. */ final class PathFinder { private static boolean isFakeProperty(final Property property) { final boolean isPropertyNode = property.value().isPropertyNode(); return isPropertyNode && property.value().asPropertyNode().hasProperty("#fakeEmpty#"); } static List<Map.Entry<String[], Property>> find2(final PropertyNode propertyNode) { return PathFinder.find1(propertyNode).stream() .map(p -> new AbstractMap.SimpleEntry<>(Iterables.toArray(p.getKey(), String.class), p.getValue())) .collect(Collectors.toList()); } static List<Map.Entry<Path, Property>> find3(final PropertyNode propertyNode) { return PathFinder.find1(propertyNode).stream() .map(p -> new AbstractMap.SimpleEntry<>(Paths.get(String.join("/", p.getKey())), p.getValue())) .collect(Collectors.toList()); } static List<Map.Entry<List<String>, Property>> find1(final PropertyNode propertyNode) { Objects.requireNonNull(propertyNode, "propertyNode argument is null"); if (propertyNode.isEmpty()) { return Collections.emptyList(); } else { final class PathFinderX { private List<Map.Entry<List<String>, Property>> deepDeleteLast(final PropertyNode originalNode, final PropertyNode subNode, final List<Map.Entry<List<String>, Property>> fullKeyList, final List<String> midKeyList) { if (Objects.isNull(originalNode) || originalNode.isEmpty()) { return fullKeyList; } final Property property = subNode.last(null); if (Objects.nonNull(property)) { if (isFakeProperty(property)) { subNode.removeLast(); return deepDeleteLast(originalNode, originalNode, fullKeyList, new ArrayList<>()); } midKeyList.add(property.key()); final boolean isPropertyNode = property.value().isPropertyNode(); if (isPropertyNode) { final boolean hasProperties = property.value().asPropertyNode().nonEmpty(); if (hasProperties) { final PropertyNode nextPropertyNode = property.value().asPropertyNode(); return deepDeleteLast(originalNode, nextPropertyNode, fullKeyList, midKeyList); } else { // empty property node, "{}" final Map.Entry entry = new AbstractMap.SimpleImmutableEntry<>(midKeyList, property); fullKeyList.add(entry); if (subNode.nonEmpty()) { subNode.removeLast(); } return deepDeleteLast(originalNode, originalNode, fullKeyList, new ArrayList<>()); } } else { final Map.Entry entry = new AbstractMap.SimpleImmutableEntry<>(midKeyList, property); fullKeyList.add(entry); if (subNode.nonEmpty()) { subNode.removeLast(); } if (originalNode.isEmpty()) { return fullKeyList; } if (subNode.isEmpty()) { subNode.addNull("#fakeEmpty#"); // mark this node for real deletion ! } return deepDeleteLast(originalNode, originalNode, fullKeyList, new ArrayList<>()); } } else { return fullKeyList; } } } // class PathFinderX final PropertyNode originalNode = propertyNode.copy(); // deep copy final List<Map.Entry<List<String>, Property>> fullKeyList = new ArrayList<>(); final List<String> midKeyList = new ArrayList<>(); final PathFinderX pathFinderX = new PathFinderX(); return pathFinderX.deepDeleteLast(originalNode, originalNode, fullKeyList, midKeyList); } } }