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

Java tutorial

Introduction

Here is the source code for org.blip.workflowengine.transferobject.ModifiablePropertyNode.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.ImmutableList;
import com.google.common.collect.Iterables;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Predicate;

/**
 * @author Kresimir Popovic
 * @since 27.11.2016
 */
public final class ModifiablePropertyNode implements PropertyNode {

    private final List<Property> mutablePropertyList;

    public static ModifiablePropertyNode create() {
        return new ModifiablePropertyNode(10);
    }

    public static ModifiablePropertyNode create(final int initialCapacity) {
        return new ModifiablePropertyNode(initialCapacity);
    }

    @SuppressWarnings(value = "all")
    private ModifiablePropertyNode() {
        throw new IllegalStateException("Default constructor not allowed to be used !");
    }

    private ModifiablePropertyNode(final int initialCapacity) {
        this.mutablePropertyList = new ArrayList<>(initialCapacity);
    }

    private ModifiablePropertyNode internalSetValue(final boolean checkNullValue, final int index,
            final Object value) {
        if (checkNullValue) {
            Objects.requireNonNull(value);
        }

        final Property currentProperty = mutablePropertyList.get(index);
        final Value newValue = ImmutableValue.of(value);
        final Property newProperty = ImmutableProperty.of(currentProperty.key(), newValue);
        mutablePropertyList.set(index, newProperty);

        return this;
    }

    private ModifiablePropertyNode internalAdd(final boolean checkNullValue, final String key, final Object value,
            final Attribute[] attributes) {

        Objects.requireNonNull(key);
        Objects.requireNonNull(attributes);

        if (checkNullValue) {
            Objects.requireNonNull(value);
        }

        final boolean hasAttributes = attributes.length > 0;

        if (value instanceof Value) {
            final Value theValue = (Value) value;
            if (hasAttributes) {
                final Property property = ImmutableProperty.of(key, theValue).withAttributes(attributes);
                mutablePropertyList.add(property);
            } else {
                final Property property = ImmutableProperty.of(key, theValue);
                mutablePropertyList.add(property);
            }
        } else {
            final Value theValue = ImmutableValue.of(value);
            if (hasAttributes) {
                final Property property = ImmutableProperty.of(key, theValue).withAttributes(attributes);
                mutablePropertyList.add(property);
            } else {
                final Property property = ImmutableProperty.of(key, theValue);
                mutablePropertyList.add(property);
            }
        }

        return this;
    }

    @Override
    public PropertyNode add(final Property property) {
        mutablePropertyList.add(ImmutableProperty.copyOf(property));
        return this;
    }

    @Override
    public PropertyNode add(String key, Boolean value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(String key, Boolean value, Attribute[] attributes) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(String key, Boolean value, Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final Byte value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final byte[] value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final Integer value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final Long value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final Double value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final Float value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final String value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final Instant value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final PropertyNode value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public <V> PropertyNode add(final String key, final Collection<? extends V> value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(final String key, final Byte value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Byte value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(String key, Short value) {
        return internalAdd(true, key, value, Attribute.empty());
    }

    @Override
    public PropertyNode add(String key, Short value, Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(String key, Short value, Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final byte[] value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final byte[] value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final Integer value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Integer value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final Long value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Long value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final Float value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Float value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final Double value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Double value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final String value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final String value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final Instant value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Instant value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode add(final String key, final PropertyNode value, final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final PropertyNode value, final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public <V> PropertyNode add(final String key, final Collection<? extends V> value,
            final Attribute[] attributes) {
        return internalAdd(true, key, value, attributes);
    }

    @Override
    public PropertyNode add(final String key, final Collection<Object> value,
            final Collection<Attribute> attributes) {
        return internalAdd(true, key, value, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode addNull(final String key) {
        return internalAdd(false, key, null, Attribute.empty());
    }

    @Override
    public PropertyNode addNull(final String key, final Attribute[] attributes) {
        return internalAdd(false, key, null, attributes);
    }

    @Override
    public PropertyNode addNull(final String key, final Collection<Attribute> attributes) {
        return internalAdd(false, key, null, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public List<Property> properties() {
        return new ImmutableList.Builder<Property>().addAll(mutablePropertyList).build();
    }

    @Override
    public boolean containsAll(final Collection<Property> propertyCollection) {
        return mutablePropertyList.containsAll(propertyCollection);
    }

    @Override
    public PropertyNode set(final int index, final Property property) {
        mutablePropertyList.set(index, ImmutableProperty.copyOf(property));
        return this;
    }

    @Override
    public PropertyNode setAttr(final int index, final Attribute[] attributes) {
        final Property currentProperty = mutablePropertyList.get(index);
        final Property newProperty = ImmutableProperty.copyOf(currentProperty).withAttributes(attributes);
        mutablePropertyList.set(index, newProperty);

        return this;
    }

    @Override
    public PropertyNode setAttr(final int index, final Collection<Attribute> attributes) {
        return setAttr(index, Iterables.toArray(attributes, Attribute.class));
    }

    @Override
    public PropertyNode setKey(final int index, final String key) {
        final Property currentProperty = mutablePropertyList.get(index);
        final Property newProperty = ImmutableProperty.copyOf(currentProperty).withKey(key);
        mutablePropertyList.set(index, newProperty);

        return this;
    }

    @Override
    public PropertyNode setNull(final int index) {
        return internalSetValue(false, index, null);
    }

    @Override
    public PropertyNode setValue(int index, Boolean value) {
        return internalSetValue(false, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Byte value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final byte[] value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Short value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Integer value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Long value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Float value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Double value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final String value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final Instant value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public <V> PropertyNode setValue(int index, Collection<? extends V> value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode setValue(final int index, final PropertyNode value) {
        return internalSetValue(true, index, value);
    }

    @Override
    public PropertyNode removeFirst() {
        mutablePropertyList.remove(0);
        return this;
    }

    @Override
    public PropertyNode removeFirst(final String key) {
        if (hasProperty(key)) {
            for (final Map.Entry<Integer, Property> zipped : zipWithIndex()) {
                if (zipped.getValue().key().equals(key)) {
                    mutablePropertyList.remove(zipped.getKey().intValue());
                    break;
                }
            }
        } else {
            final String errorText = String.format("Property key=<%s> doesn't exists", key);
            throw new NoSuchElementException(errorText);
        }

        return this;
    }

    @Override
    public PropertyNode removeLast() {
        mutablePropertyList.remove(size() - 1);
        return this;
    }

    @Override
    public PropertyNode removeLast(final String key) {
        final Property propertyToRemove = lastKey(key, null);
        if (Objects.nonNull(propertyToRemove)) {
            mutablePropertyList.remove(propertyToRemove);
        } else {
            final String errorText = String.format("Property key=<%s> doesn't exists", key);
            throw new NoSuchElementException(errorText);
        }

        return this;
    }

    @Override
    public PropertyNode remove(final int index) {
        mutablePropertyList.remove(index);
        return this;
    }

    @Override
    public PropertyNode removeAll(final Collection<Property> propertyCollection) {
        mutablePropertyList.removeAll(propertyCollection);
        return this;
    }

    @Override
    public PropertyNode removeAll(final String key) {
        for (final Property property : toArray()) {
            if (property.key().equals(key)) {
                mutablePropertyList.remove(property);
            }
        }

        return this;
    }

    @Override
    public PropertyNode removeAll() {
        mutablePropertyList.clear();
        return this;
    }

    @Override
    public PropertyNode removeRange(final int fromIndex, final int toIndex) {
        final List<Property> listView = mutablePropertyList.subList(fromIndex, toIndex);
        mutablePropertyList.removeAll(listView);

        return this;
    }

    @Override
    public PropertyNode removeIf(final Predicate<? super Property> filter) {
        Objects.requireNonNull(filter);
        for (final Property property : toArray()) {
            if (filter.test(property)) {
                mutablePropertyList.remove(property);
            }
        }

        return this;
    }

    @Override
    public PropertyNode retainAll(final Collection<Property> propertyCollection) {
        mutablePropertyList.retainAll(propertyCollection);
        return this;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final ModifiablePropertyNode node = (ModifiablePropertyNode) o;
        return com.google.common.base.Objects.equal(mutablePropertyList, node.mutablePropertyList);
    }

    @Override
    public int hashCode() {
        return com.google.common.base.Objects.hashCode(mutablePropertyList);
    }

    @Override
    public String toString() {
        if (isEmpty()) {
            return "{}";
        }

        final StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("{").append("\n");
        for (final Property property : this) {
            stringBuilder.append("   ").append(property).append("\n");
        }
        stringBuilder.append("}");

        return stringBuilder.toString();
    }
}