mirror of https://github.com/YTVanced/VancedMicroG
Implement DataHolder compatible with old public API
This commit is contained in:
parent
cfd7c4e70e
commit
4991c5c05b
|
@ -17,39 +17,57 @@
|
||||||
package com.google.android.gms.common.data;
|
package com.google.android.gms.common.data;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.ContentValues;
|
||||||
import android.database.AbstractWindowedCursor;
|
import android.database.AbstractWindowedCursor;
|
||||||
|
import android.database.CharArrayBuffer;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.CursorWindow;
|
import android.database.CursorWindow;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcel;
|
||||||
|
|
||||||
|
import org.microg.gms.common.PublicApi;
|
||||||
import org.microg.safeparcel.AutoSafeParcelable;
|
import org.microg.safeparcel.AutoSafeParcelable;
|
||||||
import org.microg.safeparcel.SafeParceled;
|
import org.microg.safeparcel.SafeParceled;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for accessing collections of data, organized into columns. This provides the backing
|
* Class for accessing collections of data, organized into columns. This provides the backing
|
||||||
* support for DataBuffer. Much like a cursor, the holder supports the notion of a current
|
* support for DataBuffer. Much like a cursor, the holder supports the notion of a current
|
||||||
* position, and has methods for extracting various types of data from named columns.
|
* position, and has methods for extracting various types of data from named columns.
|
||||||
*/
|
*/
|
||||||
public class DataHolder extends AutoSafeParcelable {
|
@PublicApi(until = "1")
|
||||||
|
public class DataHolder extends AutoSafeParcelable implements Closeable {
|
||||||
@SafeParceled(1000)
|
@SafeParceled(1000)
|
||||||
private int versionCode = 1;
|
private int versionCode = 1;
|
||||||
|
|
||||||
@SafeParceled(1)
|
@SafeParceled(1)
|
||||||
public final String[] columns;
|
private final String[] columns;
|
||||||
|
|
||||||
@SafeParceled(2)
|
@SafeParceled(2)
|
||||||
public final CursorWindow[] windows;
|
private final CursorWindow[] windows;
|
||||||
|
|
||||||
@SafeParceled(3)
|
@SafeParceled(3)
|
||||||
public final int statusCode;
|
private final int statusCode;
|
||||||
|
|
||||||
@SafeParceled(4)
|
@SafeParceled(4)
|
||||||
public final Bundle metadata;
|
private final Bundle metadata;
|
||||||
|
|
||||||
|
private boolean closed = false;
|
||||||
|
private Map<String, Integer> columnIndizes;
|
||||||
|
|
||||||
|
protected static final int FIELD_TYPE_NULL = 0;
|
||||||
|
protected static final int FIELD_TYPE_INTEGER = 1;
|
||||||
|
protected static final int FIELD_TYPE_FLOAT = 2;
|
||||||
|
protected static final int FIELD_TYPE_STRING = 3;
|
||||||
|
protected static final int FIELD_TYPE_BLOB = 4;
|
||||||
|
|
||||||
private DataHolder() {
|
private DataHolder() {
|
||||||
columns = null;
|
columns = null;
|
||||||
|
@ -58,18 +76,81 @@ public class DataHolder extends AutoSafeParcelable {
|
||||||
metadata = null;
|
metadata = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a data holder with the specified data.
|
||||||
|
*
|
||||||
|
* @param columns The column names corresponding to the data in the given windows.
|
||||||
|
* @param windows The {@link CursorWindow} instances holding the data.
|
||||||
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @param metadata The metadata associated with this {@link DataHolder} (may be null).
|
||||||
|
*/
|
||||||
public DataHolder(String[] columns, CursorWindow[] windows, int statusCode, Bundle metadata) {
|
public DataHolder(String[] columns, CursorWindow[] windows, int statusCode, Bundle metadata) {
|
||||||
this.columns = columns;
|
this.columns = columns;
|
||||||
this.windows = windows;
|
this.windows = windows;
|
||||||
this.statusCode = statusCode;
|
this.statusCode = statusCode;
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
|
validateContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static final int FIELD_TYPE_BLOB = 4;
|
/**
|
||||||
protected static final int FIELD_TYPE_FLOAT = 2;
|
* Creates a data holder wrapping the provided cursor, with provided status code and metadata.
|
||||||
protected static final int FIELD_TYPE_INTEGER = 1;
|
*
|
||||||
protected static final int FIELD_TYPE_NULL = 0;
|
* @param cursor The cursor containing the data.
|
||||||
protected static final int FIELD_TYPE_STRING = 3;
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @param metadata The metadata associated with this {@link DataHolder} (may be null).
|
||||||
|
*/
|
||||||
|
public DataHolder(AbstractWindowedCursor cursor, int statusCode, Bundle metadata) {
|
||||||
|
this(cursor.getColumnNames(), createCursorWindows(cursor), statusCode, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a data holder wrapping the provided cursor, with provided status code and metadata.
|
||||||
|
*
|
||||||
|
* @param cursor The cursor containing the data.
|
||||||
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @param metadata The metadata associated with this {@link DataHolder} (may be null).
|
||||||
|
*/
|
||||||
|
public DataHolder(Cursor cursor, int statusCode, Bundle metadata) {
|
||||||
|
this(cursor.getColumnNames(), createCursorWindows(cursor), statusCode, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link DataHolder.Builder} to create a new {@link DataHolder} manually.
|
||||||
|
*
|
||||||
|
* @param columns The array of column names that the object supports.
|
||||||
|
* @param uniqueColumn The non-null column name that must contain unique values. New rows added to the builder with the same value in this column will replace any older rows.
|
||||||
|
* @return {@link DataHolder.Builder} object to work with.
|
||||||
|
*/
|
||||||
|
public static Builder builder(String[] columns, String uniqueColumn) {
|
||||||
|
return new Builder(columns, uniqueColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a {@link DataHolder.Builder} to create a new {@link DataHolder} manually.
|
||||||
|
*
|
||||||
|
* @param columns The array of column names that the object supports.
|
||||||
|
* @return {@link DataHolder.Builder} object to work with.
|
||||||
|
*/
|
||||||
|
public static Builder builder(String[] columns) {
|
||||||
|
return builder(columns, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @param metadata The metadata associated with this {@link DataHolder} (may be null).
|
||||||
|
* @return An empty {@link DataHolder} object with the given status and metadata.
|
||||||
|
*/
|
||||||
|
public static DataHolder empty(int statusCode, Bundle metadata) {
|
||||||
|
return new DataHolder(new String[0], new CursorWindow[0], statusCode, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @return An empty {@link DataHolder} object with the given status and null metadata.
|
||||||
|
*/
|
||||||
|
public static DataHolder empty(int statusCode) {
|
||||||
|
return empty(statusCode, null);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
|
@ -98,46 +179,166 @@ public class DataHolder extends AutoSafeParcelable {
|
||||||
throw new RuntimeException("Unsupported cursor on this platform!");
|
throw new RuntimeException("Unsupported cursor on this platform!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataHolder fromCursor(Cursor cursor, int statusCode, Bundle metadata) {
|
/**
|
||||||
|
* Closes the data holder, releasing all of its resources and making it completely invalid.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
synchronized (this) {
|
||||||
|
if (!closed) {
|
||||||
|
closed = true;
|
||||||
|
for (CursorWindow window : windows) {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies the String content in the given column at the provided position into a {@link CharArrayBuffer}.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @param dataOut The {@link CharArrayBuffer} to copy into.
|
||||||
|
*/
|
||||||
|
public void copyToBuffer(String column, int row, int windowIndex, CharArrayBuffer dataOut) {
|
||||||
|
throw new RuntimeException("Not yet available");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private static CursorWindow[] createCursorWindows(Builder builder) {
|
||||||
|
if (builder.columns.length == 0) return new CursorWindow[0];
|
||||||
List<CursorWindow> windows = new ArrayList<CursorWindow>();
|
List<CursorWindow> windows = new ArrayList<CursorWindow>();
|
||||||
CursorWindow cursorWindow = null;
|
try {
|
||||||
int row = 0;
|
CursorWindow current = null;
|
||||||
|
for (int rowIndex = 0; rowIndex < builder.rows.size(); rowIndex++) {
|
||||||
|
Map<String, Object> row = builder.rows.get(rowIndex);
|
||||||
|
if (current == null || !current.allocRow()) {
|
||||||
|
current = new CursorWindow(false);
|
||||||
|
current.setStartPosition(rowIndex);
|
||||||
|
current.setNumColumns(builder.columns.length);
|
||||||
|
windows.add(current);
|
||||||
|
if (!current.allocRow()) {
|
||||||
|
windows.remove(current);
|
||||||
|
return windows.toArray(new CursorWindow[windows.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int columnIndex = 0; columnIndex < builder.columns.length; columnIndex++) {
|
||||||
|
Object val = row.get(builder.columns[columnIndex]);
|
||||||
|
if (val == null) {
|
||||||
|
current.putNull(rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof String) {
|
||||||
|
current.putString((String) val, rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof Long) {
|
||||||
|
current.putLong((Long) val, rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof Integer) {
|
||||||
|
current.putLong((Integer) val, rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof Boolean) {
|
||||||
|
if ((Boolean) val)
|
||||||
|
current.putLong(1, rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof byte[]) {
|
||||||
|
current.putBlob((byte[]) val, rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof Double) {
|
||||||
|
current.putDouble((Double) val, rowIndex, columnIndex);
|
||||||
|
} else if (val instanceof Float) {
|
||||||
|
current.putDouble((Float) val, rowIndex, columnIndex);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported object for column " + columnIndex + ": " + val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
for (CursorWindow window : windows) {
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return windows.toArray(new CursorWindow[windows.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CursorWindow[] createCursorWindows(Cursor cursor) {
|
||||||
|
if (cursor.getColumnCount() == 0) return new CursorWindow[0];
|
||||||
|
List<CursorWindow> windows = new ArrayList<CursorWindow>();
|
||||||
|
CursorWindow current = null;
|
||||||
|
int rowIndex = 0;
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
if (cursorWindow == null || !cursorWindow.allocRow()) {
|
if (current == null || !current.allocRow()) {
|
||||||
cursorWindow = new CursorWindow(false);
|
current = new CursorWindow(false);
|
||||||
cursorWindow.setNumColumns(cursor.getColumnCount());
|
current.setStartPosition(rowIndex);
|
||||||
windows.add(cursorWindow);
|
current.setNumColumns(cursor.getColumnCount());
|
||||||
if (!cursorWindow.allocRow())
|
windows.add(current);
|
||||||
throw new RuntimeException("Impossible to store Cursor in CursorWindows");
|
if (!current.allocRow()) {
|
||||||
row = 0;
|
windows.remove(current);
|
||||||
|
return windows.toArray(new CursorWindow[windows.size()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
for (int i = 0; i < cursor.getColumnCount(); i++) {
|
||||||
switch (getCursorType(cursor, i)) {
|
switch (getCursorType(cursor, i)) {
|
||||||
case FIELD_TYPE_NULL:
|
case FIELD_TYPE_NULL:
|
||||||
cursorWindow.putNull(row, i);
|
current.putNull(rowIndex, i);
|
||||||
break;
|
break;
|
||||||
case FIELD_TYPE_BLOB:
|
case FIELD_TYPE_BLOB:
|
||||||
cursorWindow.putBlob(cursor.getBlob(i), row, i);
|
current.putBlob(cursor.getBlob(i), rowIndex, i);
|
||||||
break;
|
break;
|
||||||
case FIELD_TYPE_FLOAT:
|
case FIELD_TYPE_FLOAT:
|
||||||
cursorWindow.putDouble(cursor.getDouble(i), row, i);
|
current.putDouble(cursor.getDouble(i), rowIndex, i);
|
||||||
break;
|
break;
|
||||||
case FIELD_TYPE_INTEGER:
|
case FIELD_TYPE_INTEGER:
|
||||||
cursorWindow.putLong(cursor.getLong(i), row, i);
|
current.putLong(cursor.getLong(i), rowIndex, i);
|
||||||
break;
|
break;
|
||||||
case FIELD_TYPE_STRING:
|
case FIELD_TYPE_STRING:
|
||||||
cursorWindow.putString(cursor.getString(i), row, i);
|
current.putString(cursor.getString(i), rowIndex, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row++;
|
rowIndex++;
|
||||||
}
|
}
|
||||||
DataHolder dataHolder = new DataHolder(cursor.getColumnNames(), windows.toArray(new CursorWindow[windows.size()]), statusCode, metadata);
|
|
||||||
cursor.close();
|
cursor.close();
|
||||||
return dataHolder;
|
return windows.toArray(new CursorWindow[windows.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PublicApi(exclude = true)
|
||||||
|
@Deprecated
|
||||||
|
public static DataHolder fromCursor(Cursor cursor, int statusCode, Bundle metadata) {
|
||||||
|
return new DataHolder(cursor, statusCode, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the boolean value for a given column at the provided position.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return The boolean value in that column.
|
||||||
|
*/
|
||||||
|
public boolean getBoolean(String column, int row, int windowIndex) {
|
||||||
|
return windows[windowIndex].getLong(row, columnIndizes.get(column)) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the byte array value for a given column at the provided position.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return The byte array value in that column.
|
||||||
|
*/
|
||||||
|
public byte[] getByteArray(String column, int row, int windowIndex) {
|
||||||
|
return windows[windowIndex].getBlob(row, columnIndizes.get(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of rows in the data holder.
|
||||||
|
*
|
||||||
|
* @return the number of rows in the data holder.
|
||||||
|
*/
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
int c = 0;
|
int c = 0;
|
||||||
if (windows != null) {
|
if (windows != null) {
|
||||||
|
@ -148,6 +349,88 @@ public class DataHolder extends AutoSafeParcelable {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the integer value for a given column at the provided position.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return The integer value in that column.
|
||||||
|
*/
|
||||||
|
public int getInteger(String column, int row, int windowIndex) {
|
||||||
|
return windows[windowIndex].getInt(row, columnIndizes.get(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the long value for a given column at the provided position.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return The long value in that column.
|
||||||
|
*/
|
||||||
|
public long getLong(String column, int row, int windowIndex) {
|
||||||
|
return windows[windowIndex].getLong(row, columnIndizes.get(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the string value for a given column at the provided position.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return The string value in that column.
|
||||||
|
*/
|
||||||
|
public String getString(String column, int row, int windowIndex) {
|
||||||
|
return windows[windowIndex].getString(row, columnIndizes.get(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given column at the provided position contains null.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return Whether the column value is null at this position.
|
||||||
|
*/
|
||||||
|
public boolean isNull(String column, int row, int windowIndex) {
|
||||||
|
return windows[windowIndex].isNull(row, columnIndizes.get(column));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isClosed() {
|
||||||
|
synchronized (this) {
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the column data at the provided position as a URI if possible, checking for null values.
|
||||||
|
* This will throw an {@link IllegalArgumentException} if the column does not exist, the
|
||||||
|
* position is invalid, or the data holder has been closed.
|
||||||
|
*
|
||||||
|
* @param column The column to retrieve.
|
||||||
|
* @param row The row to retrieve the data from.
|
||||||
|
* @param windowIndex Index of the cursor window to extract the data from.
|
||||||
|
* @return The column data as a URI, or null if not present.
|
||||||
|
*/
|
||||||
|
public Uri parseUri(String column, int row, int windowIndex) {
|
||||||
|
String string = getString(column, row, windowIndex);
|
||||||
|
if (string != null) return Uri.parse(string);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DataHolder{" +
|
return "DataHolder{" +
|
||||||
|
@ -158,5 +441,119 @@ public class DataHolder extends AutoSafeParcelable {
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<DataHolder> CREATOR = new AutoCreator<DataHolder>(DataHolder.class);
|
public void validateContents() {
|
||||||
|
columnIndizes = new HashMap<String, Integer>();
|
||||||
|
for (int i = 0; i < columns.length; i++) {
|
||||||
|
columnIndizes.put(columns[i], i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to build {@link DataHolder} instances containing arbitrary data.
|
||||||
|
* <p/>
|
||||||
|
* Note that the constructor is private; use DataHolder.builder() to create instances of this class.
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
private final String[] columns;
|
||||||
|
private final ArrayList<Map<String, Object>> rows;
|
||||||
|
private final String uniqueColumn;
|
||||||
|
private final Map<Object, Integer> uniqueIndizes;
|
||||||
|
|
||||||
|
private Builder(String[] columns, String uniqueColumn) {
|
||||||
|
this.columns = columns;
|
||||||
|
this.rows = new ArrayList<Map<String, Object>>();
|
||||||
|
this.uniqueColumn = uniqueColumn;
|
||||||
|
this.uniqueIndizes = new HashMap<Object, Integer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate an {@link DataHolder} from this {@link DataHolder.Builder} with the given status code and metadata.
|
||||||
|
*
|
||||||
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @param metadata The metadata associated with this {@link DataHolder} (may be null).
|
||||||
|
* @return {@link DataHolder} representation of this object.
|
||||||
|
*/
|
||||||
|
public DataHolder build(int statusCode, Bundle metadata) {
|
||||||
|
return new DataHolder(columns, createCursorWindows(this), statusCode, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate an {@link DataHolder} from this {@link DataHolder.Builder} with the given status code and null metadata.
|
||||||
|
*
|
||||||
|
* @param statusCode The status code of this {@link DataHolder}.
|
||||||
|
* @return {@link DataHolder} representation of this object.
|
||||||
|
*/
|
||||||
|
public DataHolder build(int statusCode) {
|
||||||
|
return build(statusCode, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of rows that the resulting DataHolder will contain.
|
||||||
|
*/
|
||||||
|
public int getCount() {
|
||||||
|
return rows.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort the rows in this builder based on the standard data type comparisons for the value in the provided column.
|
||||||
|
* Calling this multiple times with the same column will not change the sort order of the builder.
|
||||||
|
* Note that any data which is added after this call will not be sorted.
|
||||||
|
*
|
||||||
|
* @param sortColumn The column to sort the rows in this builder by.
|
||||||
|
* @return {@link DataHolder.Builder} to continue construction.
|
||||||
|
*/
|
||||||
|
public Builder sort(String sortColumn) {
|
||||||
|
throw new RuntimeException("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new row of data to the {@link DataHolder} this {@link DataHolder.Builder} will create. Note that the data must contain an entry for all columns
|
||||||
|
* <p/>
|
||||||
|
* Currently the only supported value types that are supported are String, Long, and Boolean (Integer is also accepted and will be stored as a Long).
|
||||||
|
*
|
||||||
|
* @param values {@link ContentValues} containing row data.
|
||||||
|
* @return {@link DataHolder.Builder} to continue construction.
|
||||||
|
*/
|
||||||
|
public Builder withRow(ContentValues values) {
|
||||||
|
HashMap<String, Object> row = new HashMap<String, Object>();
|
||||||
|
for (Map.Entry<String, Object> entry : values.valueSet()) {
|
||||||
|
row.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
return withRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new row of data to the {@link DataHolder} this {@link DataHolder.Builder} will create. Note that the data must contain an entry for all columns
|
||||||
|
* <p/>
|
||||||
|
* Currently the only supported value types that are supported are String, Long, and Boolean (Integer is also accepted and will be stored as a Long).
|
||||||
|
*
|
||||||
|
* @param row Map containing row data.
|
||||||
|
* @return {@link DataHolder.Builder} to continue construction.
|
||||||
|
*/
|
||||||
|
public Builder withRow(HashMap<String, Object> row) {
|
||||||
|
if (uniqueColumn != null) {
|
||||||
|
Object val = row.get(uniqueColumn);
|
||||||
|
if (val != null) {
|
||||||
|
Integer old = uniqueIndizes.get(val);
|
||||||
|
if (old != null) {
|
||||||
|
rows.set(old, row);
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
uniqueIndizes.put(val, rows.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rows.add(row);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Creator<DataHolder> CREATOR = new AutoCreator<DataHolder>(DataHolder.class) {
|
||||||
|
@Override
|
||||||
|
public DataHolder createFromParcel(Parcel parcel) {
|
||||||
|
DataHolder res = super.createFromParcel(parcel);
|
||||||
|
res.validateContents();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue