All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.umbraltech.rxchange.adapter.collections.ListChangeAdapter Maven / Gradle / Ivy

/*
 * Copyright 2018 - present, RxChange contributors
 *
 * 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 com.umbraltech.rxchange.adapter.collections;

import com.google.common.collect.ImmutableList;
import com.umbraltech.rxchange.message.ChangeMessage;
import com.umbraltech.rxchange.message.MetaChangeMessage;
import com.umbraltech.rxchange.type.ChangeType;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;

import java.util.ArrayList;
import java.util.List;

/**
 * An adapter that implements the reactive change model for lists
 *
 * @param  the type of data held by the list
 */
public class ListChangeAdapter {
    private final PublishSubject>> publishSubject = PublishSubject.create();
    private final List dataList = new ArrayList<>();

    /**
     * Default constructor
     */
    public ListChangeAdapter() {
        // Stub
    }

    /**
     * Initializes the adapter with a list of elements, without emitting a change message
     *
     * @param initialDataList the initial list of elements
     */
    public ListChangeAdapter(final List initialDataList) {
        dataList.addAll(initialDataList);
    }

    /**
     * Adds an element to the list and emits a change message to surrounding observers
     * 

* The metadata in the emitted change message will contain the element that was just added * * @param data the data to be added to the list * @return {@code true} always */ public boolean add(final D data) { final List oldListSnapshot = ImmutableList.copyOf(dataList); dataList.add(data); final List newListSnapshot = ImmutableList.copyOf(dataList); // Signal addition publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.ADD, data)); return true; } /** * Adds an element to the list at the specified index and emits a change message to surrounding observers *

* The metadata in the emitted change message will contain the element that was just added * * @param index the index at which the element is added * @param data the data to be added to the list * @return {@code true} if the data was added to the list, {@code false} otherwise */ public boolean addAt(final int index, final D data) { // Validate index if (index < 0 || index > dataList.size()) { return false; } final List oldListSnapshot = ImmutableList.copyOf(dataList); dataList.add(index, data); final List newListSnapshot = ImmutableList.copyOf(dataList); // Signal addition publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.ADD, data)); return true; } /** * Adds a list of elements and emits a change message to surrounding observers *

* The metadata in the emitted change message will contain a snapshot of the list * of elements that were just added * * @param dataList the list of elements to be added * @return {@code true} always */ public boolean addAll(final List dataList) { final List oldListSnapshot = ImmutableList.copyOf(this.dataList); this.dataList.addAll(dataList); final List newListSnapshot = ImmutableList.copyOf(this.dataList); final List changeSnapshot = ImmutableList.copyOf(dataList); // Signal addition publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.ADD, changeSnapshot)); return true; } /** * Removes the specified element and emits a change message to surrounding observers *

* The metadata in the emitted change message will contain the element that was just removed * * @param data the element to be removed * @return {@code true} if the element was removed, {@code false} otherwise */ public boolean remove(final D data) { // Validate item if (!dataList.contains(data)) { return false; } final List oldListSnapshot = ImmutableList.copyOf(dataList); dataList.remove(data); final List newListSnapshot = ImmutableList.copyOf(dataList); // Signal removal publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.REMOVE, data)); return true; } /** * Removes the element at a specified index and emits a change message to surrounding observers *

* The metadata in the emitted change message will contain the element that was just removed * * @param index the index of the element to be removed * @return {@code true} if the element was removed, {@code false} otherwise */ public boolean removeAt(final int index) { // Validate index if ((index < 0) || (index >= dataList.size())) { return false; } final List oldListSnapshot = ImmutableList.copyOf(dataList); final D data = dataList.remove(index); final List newListSnapshot = ImmutableList.copyOf(dataList); // Signal removal publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.REMOVE, data)); return true; } /** * Removes the specified list of elements and emits a change message to surrounding observers *

* The metadata in the emitted change message will contain the collection that was just removed * * @param dataList the list of elements to be removed * @return {@code true} if all of the elements removed, {@code false} otherwise */ public boolean removeAll(final List dataList) { // Validate items if (!this.dataList.containsAll(dataList)) { return false; } final List oldListSnapshot = ImmutableList.copyOf(this.dataList); this.dataList.removeAll(dataList); final List newListSnapshot = ImmutableList.copyOf(this.dataList); final List changeSnapshot = ImmutableList.copyOf(dataList); // Signal removal publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.REMOVE, changeSnapshot)); return true; } /** * Updates the element at the specified index with new data *

* The metadata in the emitted change message will contain the value * of the element that was just updated * * @param index the index of the element within the list * @param data the new data for the element * @return {@code true} if the element was updated, {@code false} otherwise */ public boolean update(final int index, final D data) { // Validate index if ((index < 0) || (index >= dataList.size())) { return false; } final List oldListSnapshot = ImmutableList.copyOf(dataList); dataList.set(index, data); final List newListSnapshot = ImmutableList.copyOf(dataList); // Signal update publishSubject.onNext(new MetaChangeMessage<>(oldListSnapshot, newListSnapshot, ChangeType.UPDATE, data)); return true; } /** * Returns the value of the element within the list * * @param index the index of the element * @return the element at the specified index */ public D get(final int index) { return dataList.get(index); } /** * Returns an immutable snapshot of the current list * * @return the list of elements */ public List getAll() { return ImmutableList.copyOf(dataList); } /** * Returns a reference to the observable used for listening to change messages * * @return the observable reference */ public Observable>> getObservable() { return publishSubject; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy