Android Open Source - sloop Data Collection Impl






From Project

Back to project page sloop.

License

The source code is released under:

NON-LICENSE The Sloop data-browser source code is hereby released into the Public Domain. The original author, David Megginson, Megginson Technologies Ltd., and Acclar Open Ltd. provide no warranty:...

If you think the Android project sloop listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.megginson.sloop.model.impl;
/* w  ww . ja  v a 2  s  .c o  m*/
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.megginson.sloop.model.DataCollection;
import com.megginson.sloop.model.DataRecord;
import com.megginson.sloop.model.ValueFilter;

/**
 * A collection of data records (i.e. internal representation of a CSV file).
 * 
 * This represents tabular data: a list of lists, where the child lists are all
 * the same length. From a Java Collections point of view, this is a read-only
 * {@link List} of {@link DataRecordImpl} objects. The list of headers is set at
 * creation time, and can't be changed afterwards. To add a row of new values,
 * use the {@link addRecord} objects.
 * 
 * The collection can filter itself to show only some of its members (or none at
 * all) using a {@link ValueFilter}. For example, to show only records where the
 * <code>foo</code> column has the value <code>bar</code>, you could use the
 * following code:
 * 
 * <pre>
 * dataCollection.putFilter("foo", new ValueFilter() {
 *   public boolean isMatch (value) { return "bar".equals(value); }
 * });
 * 
 * dataCollection.setFiltered(true);
 * </pre>
 * 
 * @author David Megginson
 * @see DataRecordImpl
 */
class DataCollectionImpl implements DataCollection {

  private String mHeaders[];

  private List<String[]> mRecords = new ArrayList<String[]>();

  private ValueFilter mColumnFilters[];

  private ValueFilter mTextFilter;

  private boolean mColumnFilterFlags[];

  private List<Integer> mFilteredIndices = new ArrayList<Integer>();

  private boolean mIsFiltered = false;

  private boolean mIsCacheDirty = true;

  private FilteredRecordList mFilteredRecordList;

  private UnfilteredRecordList mUnfilteredRecordList;

  protected DataCollectionImpl(String headers[]) {
    super();
    mHeaders = headers;
    mColumnFilters = new ValueFilter[headers.length];
    mColumnFilterFlags = new boolean[headers.length];
  }

  @Override
  public List<String> getHeaders() {
    return Arrays.asList(mHeaders);
  }

  @Override
  public List<DataRecord> getFilteredRecords() {
    // create only if needed
    if (mFilteredRecordList == null) {
      mFilteredRecordList = new FilteredRecordList();
    }
    return mFilteredRecordList;
  }

  @Override
  public List<DataRecord> getRecords() {
    // create only if needed
    if (mUnfilteredRecordList == null) {
      mUnfilteredRecordList = new UnfilteredRecordList();
    }
    return mUnfilteredRecordList;
  }

  @Override
  public boolean isFilteringEnabled() {
    return mIsFiltered;
  }

  public void setFilteringEnabled(boolean isFiltered) {
    mIsFiltered = isFiltered;
  }

  @Override
  public boolean hasFilters() {
    for (ValueFilter filter : mColumnFilters) {
      if (filter != null) {
        return true;
      }
    }
    return false;
  }

  @Override
  public void putColumnFilter(String name, ValueFilter filter) {
    int index = indexOf(name);
    if (index > -1) {
      mColumnFilters[index] = filter;
      mColumnFilterFlags[index] = (filter != null);
      mIsCacheDirty = true;
    }
  }

  @Override
  public ValueFilter getColumnFilter(String name) {
    return mColumnFilters[indexOf(name)];
  }

  @Override
  public void setTextFilter(ValueFilter filter) {
    mTextFilter = filter;
    mIsCacheDirty = true;
  }

  @Override
  public ValueFilter getTextFilter() {
    return mTextFilter;
  }

  @Override
  public void clearFilters() {
    setTextFilter(null);
    for (int i = 0; i < mColumnFilters.length; i++) {
      mColumnFilters[i] = null;
      mColumnFilterFlags[i] = false;
    }
    setFilteringEnabled(false);
  }

  /**
   * Add a row to the collection as a string array.
   * 
   * The class will convert this to a {@link DataRecordImpl} for display as
   * required.
   * 
   * @param record
   *            an array of strings representing a row.
   */
  protected void addRecord(String record[]) {
    mRecords.add(record.clone());
    mIsCacheDirty = true;
  }

  /**
   * Get the index of a header (first occurrence only).
   * 
   * @param header
   *            the header string.
   * @return the zero-based index, or -1 if not found.
   */
  private int indexOf(String header) {
    for (int i = 0; i < mHeaders.length; i++) {
      if (header.equals(mHeaders[i])) {
        return i;
      }
    }
    return -1;
  }

  /**
   * Make a cached list of indices for a filtered view.
   */
  private void rebuildCache() {
    mFilteredIndices.clear();
    for (int i = 0; i < mRecords.size(); i++) {
      if (doFilterRecord(mRecords.get(i))) {
        mFilteredIndices.add(i);
      }
    }
    mIsCacheDirty = false;
  }

  /**
   * Run all appropriate filters against a single record.
   * 
   * @param record
   *            the record to filter (in its String array form).
   * @return true if the record matches the filters.
   */
  private boolean doFilterRecord(String record[]) {
    boolean foundTextMatch = false;

    for (int i = 0; i < mHeaders.length; i++) {

      // No filters to apply, so keep going ...
      if (mTextFilter == null && mColumnFilters[i] == null) {
        continue;
      }

      // If there's a column filter, it has to pass
      if (mColumnFilters[i] != null) {
        if (i >= record.length || !mColumnFilters[i].isMatch(record[i])) {
          return false;
        }
      }

      // If there's a text filter, it has to pass once for whole record
      if (!foundTextMatch && mTextFilter != null) {
        if (i < record.length && mTextFilter.isMatch(record[i])) {
          foundTextMatch = true;
        }
      }
    }

    // Success if there's no text filter, or a match for the text filter.
    return (mTextFilter == null || foundTextMatch);
  }

  /**
   * List wrapper showing only filtered records.
   * 
   * If filtering is off (see
   * {@link DataCollection#setFilteringEnabled(boolean)}), then this will
   * behave identically to an {@link UnfilteredRecordList}.
   * 
   * @author David Megginson
   * @see DataCollection#getFilteredRecords()
   * @see DataCollection#isFilteringEnabled()
   */
  private class FilteredRecordList extends AbstractList<DataRecord> {

    @Override
    public int size() {
      if (mIsFiltered) {
        if (mIsCacheDirty) {
          rebuildCache();
        }
        return mFilteredIndices.size();
      } else {
        return mRecords.size();
      }
    }

    @Override
    public DataRecord get(int location) {
      int rawLocation;
      if (mIsFiltered) {
        if (mIsCacheDirty) {
          rebuildCache();
        }
        rawLocation = mFilteredIndices.get(location);
      } else {
        rawLocation = location;
      }
      return new DataRecordImpl(mHeaders, mRecords.get(rawLocation),
          mColumnFilterFlags);
    }

  }

  /**
   * List wrapper showing all records.
   * 
   * This list wrapper will include all records, even when filtering is turned
   * on.
   * 
   * @author David Megginson
   * @see DataCollection#getRecords()
   * @see DataCollection#isFilteringEnabled()
   */
  private class UnfilteredRecordList extends AbstractList<DataRecord> {

    @Override
    public int size() {
      return mRecords.size();
    }

    @Override
    public DataRecord get(int location) {
      return new DataRecordImpl(mHeaders, mRecords.get(location),
          mColumnFilterFlags);
    }
  }

}




Java Source Code List

com.megginson.sloop.activities.ActivitiesUtil.java
com.megginson.sloop.activities.AddressActionProvider.java
com.megginson.sloop.activities.BookmarkEditActivity.java
com.megginson.sloop.activities.BookmarkListActivity.java
com.megginson.sloop.activities.InfoBarFragment.java
com.megginson.sloop.activities.MainActivity.java
com.megginson.sloop.activities.MainDisplayFragment.java
com.megginson.sloop.activities.TextFilterFragment.java
com.megginson.sloop.activities.package-info.java
com.megginson.sloop.model.Bookmark.java
com.megginson.sloop.model.DataCollection.java
com.megginson.sloop.model.DataEntry.java
com.megginson.sloop.model.DataRecord.java
com.megginson.sloop.model.Util.java
com.megginson.sloop.model.ValueFilter.java
com.megginson.sloop.model.impl.ContainsStringFilter.java
com.megginson.sloop.model.impl.DataCollectionIO.java
com.megginson.sloop.model.impl.DataCollectionImpl.java
com.megginson.sloop.model.impl.DataEntryImpl.java
com.megginson.sloop.model.impl.DataRecordImpl.java
com.megginson.sloop.model.impl.EqualsStringFilter.java
com.megginson.sloop.model.impl.package-info.java
com.megginson.sloop.model.package-info.java
com.megginson.sloop.ui.BookmarkListAdapter.java
com.megginson.sloop.ui.DataCollectionLoader.java
com.megginson.sloop.ui.DataCollectionPagerAdapter.java
com.megginson.sloop.ui.DataCollectionResult.java
com.megginson.sloop.ui.DataRecordFragment.java
com.megginson.sloop.ui.DataRecordListAdapter.java
com.megginson.sloop.ui.package-info.java