Package com.sonyericsson.hudson.plugins.metadata.model.values

Source Code of com.sonyericsson.hudson.plugins.metadata.model.values.ParentUtil

/*
*  The MIT License
*
*  Copyright 2011 Sony Ericsson Mobile Communications. All rights reserved.
*  Copyright 2012 Sony Mobile Communications AB. All rights reserved.
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the "Software"), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  The above copyright notice and this permission notice shall be included in
*  all copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/
package com.sonyericsson.hudson.plugins.metadata.model.values;

import com.sonyericsson.hudson.plugins.metadata.model.JsonUtils;
import com.sonyericsson.hudson.plugins.metadata.model.Metadata;
import com.sonyericsson.hudson.plugins.metadata.model.MetadataContainer;
import com.sonyericsson.hudson.plugins.metadata.model.MetadataParent;
import com.sonyericsson.hudson.plugins.metadata.model.definitions.MetadataDefinition;
import com.sonyericsson.hudson.plugins.metadata.model.definitions.TreeNodeMetadataDefinition;
import net.sf.json.JSON;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
* Utility class for handling merge operation inside
* {@link com.sonyericsson.hudson.plugins.metadata.model.MetadataParent}s.
*
* @author Robert Sandell <robert.sandell@sonyericsson.com>
*/
public final class ParentUtil {

    /**
     * Utility constructor.
     */
    private ParentUtil() {

    }

    /**
     * Removes a child from a parent.
     *
     * @param parent the parent.
     * @param child the child to remove.
     */
    public static void removeChild(MetadataParent parent, Metadata child) {
        if (child == null) {
            throw new IllegalArgumentException("The child value is null");
        }
        Metadata metadata = parent.getChild(child.getName());
        if (metadata != null) {
            parent.getChildren().remove(metadata);
            metadata.setParent(null);
        }
    }

    /**
     * Removes a child from a list of children.
     *
     * @param list the list.
     * @param value the child to remove.
     */
    public static void removeChild(Collection<? extends Metadata> list, Metadata value) {
        if (value == null) {
            throw new IllegalArgumentException("The child value is null");
        }
        Metadata metadata = TreeStructureUtil.getLeaf(list, value.getFullPath());
        if (metadata != null) {
            list.remove(metadata);
            metadata.setParent(null);
        }
    }

    /**
     * Removes all tree nodes without children from the parent.
     *
     * @param parent the parent to start with.
     */
    public static void removeEmptyBranches(MetadataParent parent) {
        Collection<Metadata> children = parent.getChildren();
        removeEmptyBranches(children);
    }

    /**
     * Removes all tree nodes without children from the collection.
     *
     * @param collection the collection to remove empty trees from.
     * @param <T> the Metadata type.
     */
    public static <T extends Metadata> void removeEmptyBranches(Collection<T> collection) {
        Iterator<T> iterator = collection.iterator();
        while (iterator.hasNext()) {
            Metadata m = iterator.next();
            if (m instanceof MetadataParent) {
                removeEmptyBranches((MetadataParent)m);
                if (((MetadataParent)m).getChildren().size() == 0) {
                    m.setParent(null);
                    iterator.remove();
                }
            }
        }
    }

    /**
     * Replaces an existing value amongst the parent's children.
     *
     * @param parent the parent to add/replace the child to
     * @param value the value to replace
     */
    public static void replaceChild(MetadataParent<MetadataValue> parent, MetadataValue value) {
        if (value == null) {
            throw new IllegalArgumentException("The child value is null");
        }
        MetadataValue metadata = parent.getChild(value.getName());
        if (metadata != null) {
            if (metadata instanceof MetadataParent && value instanceof MetadataParent) {
                MetadataParent<MetadataValue> myParent = (MetadataParent<MetadataValue>)metadata;
                MetadataParent<MetadataValue> valueParent = (MetadataParent<MetadataValue>)value;
                if (myParent.requiresReplacement() || valueParent.requiresReplacement()) {
                    parent.setChild(parent.indexOf(metadata.getName()), value);
                    value.setParent(parent);
                    value.replacementOf(metadata);
                    metadata.setParent(null); //It should be prepared to be gc'ed
                } else {
                    replaceChildren(myParent, new ArrayList<MetadataValue>(valueParent.getChildren()));
                }
            } else {
                //it exists! then it is time to replace it.
                parent.setChild(parent.indexOf(metadata.getName()), value);
                value.setParent(parent);
                value.replacementOf(metadata);
                metadata.setParent(null); //It should be prepared to be gc'ed
            }
        } else {
            //didn't exist lets just add it.
            parent.getChildren().add(value);
            value.setParent(parent);
        }
    }

    /**
     * Adds the children in a list to a parent, replacing any existing children already present.
     *
     * @param parent   the parent to add to.
     * @param children the children to add/replace
     */
    public static void replaceChildren(MetadataParent<MetadataValue> parent, List<MetadataValue> children) {
        for (MetadataValue child : children) {
            replaceChild(parent, child);
        }
    }

    /**
     * Adds a value as a child to the parent. Help utility for those who implement {@link
     * com.sonyericsson.hudson.plugins.metadata.model.MetadataParent#addChild(Metadata)}
     *
     * @param parent   the parent
     * @param children the direct list of the parents children.
     * @param value    the value to add.
     * @param <T>      the type for parent, children, value and the return value.
     * @return the value(s) that failed to be added.
     */
    public static <T extends Metadata> Collection<T> addChildValue(MetadataParent<T> parent,
                                                                   Collection<T> children,
                                                                   T value) {

        if (value == null) {
            throw new IllegalArgumentException("The added child value is null");
        }
        T my = parent.getChild(value.getName());
        if (my != null) {
            Collection<T> returnList = null;
            if (my instanceof MetadataParent && value instanceof MetadataParent) {
                //they are both a path, let's try to merge as much as possible.
                Collection<T> subValues = ((MetadataParent)value).getChildren();
                Collection<T> leftOvers = ((MetadataParent)my).addChildren(subValues);
                if (leftOvers != null && !leftOvers.isEmpty()) {
                    //some of the children failed to be merged, return them to sender.
                    Metadata treeNode = null;
                    if (value instanceof MetadataValue) {
                        LinkedList<MetadataValue> list = (LinkedList<MetadataValue>)leftOvers;
                        treeNode = new TreeNodeMetadataValue(value.getName(), value.getDescription(),
                                list, value.isExposedToEnvironment());
                    } else if (value instanceof MetadataDefinition) {
                        LinkedList<MetadataDefinition> list = (LinkedList<MetadataDefinition>)leftOvers;
                        treeNode = new TreeNodeMetadataDefinition(value.getName(), value.getDescription(), list, false);
                    }
                    returnList = new LinkedList<T>();
                    returnList.add((T)treeNode);
                    return returnList;
                }

            } else {
                //one or both of them is not a parent, so we fail.
                returnList = new LinkedList<T>();
                returnList.add(value);

            }
            return returnList;
        } else {
            children.add(value);
            value.setParent(parent);
            return null;
        }
    }

    /**
     * Adds the values as children to the parent. Help utility for those who implement {@link
     * com.sonyericsson.hudson.plugins.metadata.model.MetadataParent#
     * addChild(com.sonyericsson.hudson.plugins.metadata.model.Metadata)}
     *
     * @param parent   the parent to add the values to
     * @param children the direct list of the parents children.
     * @param values   the values to add.
     * @param <T>      the type for parent, children, values and the return value.
     * @return the values that failed to be added.
     */
    public static <T extends Metadata> Collection<T> addChildValues(MetadataParent parent,
                                                                    Collection<T> children,
                                                                    Collection<T> values) {
        List<T> leftovers = new LinkedList<T>();
        for (T value : values) {
            Collection<T> returned = addChildValue(parent, children, value);
            if (returned != null) {
                leftovers.addAll(returned);
            }
        }
        if (leftovers.isEmpty()) {
            return null;
        } else {
            return leftovers;
        }
    }

    /**
     * Utility method for {@link com.sonyericsson.hudson.plugins.metadata.model.MetadataParent#getChild(String)}.
     *
     * @param values the list of children.
     * @param name   the name to search.
     * @param <T>    the type for values, name and the return value.
     * @return the child if found or null if not.
     */
    public static <T extends Metadata> T getChildValue(Collection<T> values, String name) {
        for (T value : values) {
            if (value.getName().equalsIgnoreCase(name)) {
                return value;
            }
        }
        return null;
    }

    /**
     * Utility method for {@link com.sonyericsson.hudson.plugins.metadata.model.MetadataParent#indexOf(String)} }.
     *
     * @param children the list of children.
     * @param name     the name to search.
     * @param <T>      the type for values, name and the return value.
     * @return the index of the child if found or -1 if not.
     */
    public static <T extends Metadata> int getChildIndex(List<T> children, String name) {
        for (int i = 0; i < children.size(); i++) {
            if (children.get(i).getName().equalsIgnoreCase(name)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Converts the container into a JSON object. This processing is different from {@link
     * com.sonyericsson.hudson.plugins.metadata.model.values.MetadataValue#toJson()} because it will only convert the
     * children not the entire object, since a container (like
     * {@link com.sonyericsson.hudson.plugins.metadata.model.MetadataJobProperty})
     * in essence doesn't have a name.
     *
     * @param container the container
     * @return the JSON representation.
     */
    public static JSON toJson(MetadataContainer<MetadataValue> container) {
        return JsonUtils.toJson(container.getChildren());
    }

    /**
     * Gets the child names of the given parent.
     *
     * @param parent the parent to get the child names from.
     * @return the child names.
     */
    public static Collection<String> getChildNames(MetadataParent<MetadataValue> parent) {
        Collection<String> childNames = new LinkedList<String>();
        Collection<MetadataValue> children = parent.getChildren();
        if (children != null) {
            for (MetadataValue value : children) {
                childNames.add(value.getName());
            }
        }
        return childNames;
    }
}
TOP

Related Classes of com.sonyericsson.hudson.plugins.metadata.model.values.ParentUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.