Created
June 12, 2016 08:54
-
-
Save ndefeijter/2191f8a43ce903c5d9ea69f02c7ee7e9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.firebase.ui; | |
import com.firebase.client.DataSnapshot; | |
import com.firebase.client.Query; | |
import com.firebase.ui.FirebaseArray.OnChangedListener; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class FirebaseArrays { | |
private final List<FirebaseArray> arrays = new ArrayList<>(); | |
private final List<OnChangedListenerImpl> listeners = new ArrayList<>(); | |
private OnChangedListener aggregatedListener; | |
public void add(final Query ref) { | |
if (null == ref) throw new IllegalArgumentException("null == ref"); | |
add(new FirebaseArray(ref)); | |
} | |
private void add(final FirebaseArray array) { | |
if (null == array) throw new IllegalArgumentException("null == array"); | |
final OnChangedListenerImpl onChangedListener = new OnChangedListenerImpl(); | |
listeners.add(onChangedListener); | |
arrays.add(array); | |
array.setOnChangedListener(onChangedListener); | |
} | |
public void remove(final Query ref) { | |
throw new UnsupportedOperationException("TODO: implement me"); | |
} | |
private void remove(final FirebaseArray array) { | |
final int arrayIndex = arrays.indexOf(array); | |
if (arrayIndex >= 0) { | |
arrays.remove(arrayIndex); | |
listeners.remove(arrayIndex); | |
array.setOnChangedListener(null); | |
array.cleanup(); | |
} | |
} | |
public void cleanup() { | |
final int count = getCount(); | |
final List<FirebaseArray> arraysCopy = new ArrayList<>(arrays); | |
for (final FirebaseArray array : arraysCopy) { | |
remove(array); | |
} | |
if (aggregatedListener != null) { | |
for (int i = count - 1; i >= 0; i--) { | |
aggregatedListener.onChanged(OnChangedListener.EventType.Removed, i, -1); | |
} | |
} | |
} | |
public int getCount() { | |
int count = 0; | |
for (final FirebaseArray array : arrays) { | |
count += array.getCount(); | |
} | |
return count; | |
} | |
public DataSnapshot getItem(int index) { | |
final int[] arrayIndexAndOffset = getArrayIndexAndOffsetForAggregatedIndex(index); | |
final int arrayIndex = arrayIndexAndOffset[0]; | |
final int arrayOffset = arrayIndexAndOffset[1]; | |
final FirebaseArray array = arrays.get(arrayIndex); | |
final DataSnapshot snapshot = array.getItem(index - arrayOffset); | |
return snapshot; | |
} | |
public void setOnChangedListener(OnChangedListener listener) { | |
aggregatedListener = listener; | |
} | |
private int[] getArrayIndexAndOffsetForAggregatedIndex(final int index) { | |
return getArrayIndexAndOffsetForListenerOrAggregatedIndex(null, index); | |
} | |
private int[] getArrayIndexAndOffsetForListener(final OnChangedListenerImpl listener) { | |
return getArrayIndexAndOffsetForListenerOrAggregatedIndex(listener, -1); | |
} | |
private int[] getArrayIndexAndOffsetForListenerOrAggregatedIndex(final OnChangedListenerImpl listener, final int index) { | |
for (int offset = 0, i = 0; i < listeners.size(); i++) { | |
final FirebaseArray array = arrays.get(i); | |
final int arrayCount = array.getCount(); | |
if (null != listener) { | |
final OnChangedListenerImpl listenerCandidate = listeners.get(i); | |
if (listenerCandidate == listener) { | |
return new int[]{i, offset}; | |
} | |
} else { | |
if (index < offset + arrayCount) { | |
return new int[]{i, offset}; | |
} | |
} | |
offset += arrayCount; | |
} | |
if (null != listener) { | |
throw new IllegalArgumentException("unknown: " + listener); | |
} else { | |
throw new IndexOutOfBoundsException("index=" + index); | |
} | |
} | |
private class OnChangedListenerImpl implements OnChangedListener { | |
@Override | |
public void onChanged(final EventType type, final int index, final int oldIndex) { | |
final int[] arrayIndexAndOffset = getArrayIndexAndOffsetForListener(this); | |
final int arrayIndex = arrayIndexAndOffset[0]; | |
final int arrayOffset = arrayIndexAndOffset[1]; | |
notifyChangedListeners(type, arrayOffset + index, arrayOffset + oldIndex); | |
} | |
private void notifyChangedListeners(OnChangedListener.EventType type, int index, int oldIndex) { | |
if (aggregatedListener != null) { | |
aggregatedListener.onChanged(type, index, oldIndex); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment