org.blip.workflowengine.transferobject.PathFinder.java Source code

Java tutorial

Introduction

Here is the source code for org.blip.workflowengine.transferobject.PathFinder.java

Source

/**
 *     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);

        }
    }

}