📄 recordenumerationimpl.java
字号:
/* * @(#)RecordEnumerationImpl.java 1.21 01/08/15 * Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved. * * Copyright 2000 Motorola, Inc. All Rights Reserved. * This notice does not imply publication. * * @version MIDP 1.0 * @author Jim Van Peursem */package javax.microedition.rms;/** * This class implements the RecordEnumeration interface. */class RecordEnumerationImpl implements RecordEnumeration, RecordListener{ /** The associated record store for this enumeration */ private RecordStore recordStore; /** The record filter this enumeration should use, or null if none */ private RecordFilter filter; /** The record comparator this enumeration should use, or null if none */ private RecordComparator comparator; /** True if this should listen to <code>recordStore</code> for changes */ private boolean beObserver; // false by default /** Current pos within the enumeration */ private int index; // 0 by default /** Array of recordId's of records included in the enumeration */ private int[] records; /** * A constant recordId indicating the splice point between the * last and first records in the enumeration. Returned by * <code>nextElement()</code> and <code>prevElement()</code> * when the next or prev element does not exist. */ private static final int NO_SUCH_RECORD = -1; /** * Apps must use <code>RecordStore.enumerateRecords()</code> to get * a <code>RecordEnumeration</code> object. If this constructor * is not declared (as private scope), Javadoc (and Java) * will assume a public constructor. */ private RecordEnumerationImpl() { } /** * Builds an enumeration to traverse a set of records in the * given record store in an optionally specified order.<p> * * The filter, if non-null, will be used to determine what * subset of the record store records will be used.<p> * * The comparator, if non-null, will be used to determine the * order in which the records are returned.<p> * * If both the filter and comparator are null, the enumeration * will traverse all records in the record store in an undefined * order. This is the most efficient way to traverse all of the * records in a record store. * * @param recordStore the RecordStore to enumerate. * @param filter if non-null, will be used to determine what * subset of the record store records will be used. * @param comparator if non-null, will be used to determine the * order in which the records are returned. * @param keepUpdated if true, the enumerator will keep its enumeration * current with any changes in the records of the record store. * Use with caution as there are performance consequences. * * @see #rebuild */ RecordEnumerationImpl(RecordStore recordStore, RecordFilter filter, RecordComparator comparator, boolean keepUpdated) { this.recordStore = recordStore; this.filter = filter; this.comparator = comparator; records = new int[0]; keepUpdated(keepUpdated); if (!keepUpdated) { rebuild(); } } /** * Returns the number of records available in this enumeration's * set. That is, the number of records that have matched the * filter criterion. Note that this forces the RecordEnumeration * to fully build the enumeration by applying the filter to all * records, which may take a non-trivial amount * of time if there are a lot of records in the record store. * * @return the number of records available in this enumeration's * set. That is, the number of records that have matched * the filter criterion. */ public synchronized int numRecords() { checkDestroyed(); return records.length; } /** * Returns a copy of the <i>next</i> record in this enumeration, * where <i>next</i> is defined by the comparator and/or filter * supplied in the constructor of this enumerator. The byte array * returned is a copy of the record. Any changes made to this array * will NOT be reflected in the record store. After calling * this method, the enumeration is advanced to the next available * record. * * @exception InvalidRecordIDException no more records are available * * @return the next record in this enumeration. */ public synchronized byte[] nextRecord() throws InvalidRecordIDException, RecordStoreNotOpenException, RecordStoreException { checkDestroyed(); return recordStore.getRecord(nextRecordId()); } /** * Returns the recordId of the <i>next</i> record in this enumeration, * where <i>next</i> is defined by the comparator and/or filter * supplied in the constructor of this enumerator. After calling * this method, the enumeration is advanced to the next available * record. * * @exception InvalidRecordIDException no more records are available. * * @return the recordId of the next record in this enumeration. */ public synchronized int nextRecordId() throws InvalidRecordIDException { checkDestroyed(); if (index == records.length - 1) throw new InvalidRecordIDException(); if (index == NO_SUCH_RECORD) { index = 0; } else { index++; } return records[index]; } /** * Returns a copy of the <i>previous</i> record in this enumeration, * where <i>previous</i> is defined by the comparator and/or filter * supplied in the constructor of this enumerator. The byte array * returned is a copy of the record. Any changes made to this array * will NOT be reflected in the record store. After calling * this method, the enumeration is advanced to the next (previous) * available record. * * @exception InvalidRecordIDException no more records are available. * * @return the previous record in this enumeration. */ public synchronized byte[] previousRecord() throws InvalidRecordIDException, RecordStoreNotOpenException, RecordStoreException { checkDestroyed(); return recordStore.getRecord(previousRecordId()); } /** * Returns the recordId of the <i>previous</i> record in this enumeration, * where <i>previous</i> is defined by the comparator and/or filter * supplied in the constructor of this enumerator. After this method * is called, the enumeration is advanced to the next (previous) * available record. * * @exception InvalidRecordIDException when no more records are available. * * @return the recordId of the previous record in this enumeration. */ public synchronized int previousRecordId() throws InvalidRecordIDException { checkDestroyed(); if (index == 0 || records.length == 0) throw new InvalidRecordIDException(); if (index == NO_SUCH_RECORD) { index = records.length - 1; } else { index--; } return records[index]; } /** * Returns true if more elements exist in the <i>next</i> direction. * * @return true if more elements exist in the <i>next</i> direction. */ public boolean hasNextElement() { checkDestroyed(); return (index != records.length - 1); } /** * Returns true if more elements exist in the <i>previous</i> direction. * * @return true if more elements exist in the <i>previous</i> direction. */ public boolean hasPreviousElement() { checkDestroyed(); if (records.length == 0) return false; // no records in the enumeration return (index != 0); } /** * Returns the index point of the enumeration to the beginning. */ public void reset() { checkDestroyed(); index = NO_SUCH_RECORD; } /** * Request that the enumeration be updated to reflect the current * record set. Useful for when an application makes a number of * changes to the record store, and then wants an existing * RecordEnumeration to enumerate the new changes. * * @see #keepUpdated */ public void rebuild() { checkDestroyed(); synchronized (recordStore.rsLock) { // don't want rs to change here int[] tmp = recordStore.getRecordIDs(); reFilterSort(tmp); } } /** * Used to set whether the enumeration should be registered * as a listener of the record store, and rebuild its internal * index with every record addition/deletion in the record store. * Note that this should be used carefully due to the potential * performance cost associated with maintaining the * enumeration with every change. * * @param keepUpdated if true, the enumerator will keep its enumeration * current with any changes in the records of the record store. * Use with caution as there are possible performance consequences. * If false, the enumeration will not be kept current and may * return recordIds for records that have been deleted or miss * records that are added later. It may also return records out * of order that have been modified after the enumeration was * built. * * @see #rebuild */ public void keepUpdated(boolean keepUpdated) { checkDestroyed(); if (keepUpdated != beObserver) { beObserver = keepUpdated; if (keepUpdated) { recordStore.addRecordListener(this); rebuild(); } else { recordStore.removeRecordListener(this); } } } /** * Returns true if the enumeration keeps its enumeration * current with any changes in the records. * * @return true if the enumeration keeps its enumeration * current with any changes in the records */ public boolean isKeptUpdated() { checkDestroyed(); return beObserver; } /** * From the RecordListener interface. This method is called if * a record is added to <code>recordStore</code>. * * @param recordStore the record store to which a record was added * @param recordId the record ID of the new record */ public synchronized void recordAdded(RecordStore recordStore, int recordId) { checkDestroyed(); synchronized (recordStore.rsLock) { filterAdd(recordId); } } /** * From the RecordListener interface. This method is called if * a record in <code>recordStor</code> is modified. * * @param recordStore the record store in which a record was modified * @param recordId the record ID of the modified record. */ public synchronized void recordChanged(RecordStore recordStore, int recordId) { checkDestroyed(); int recIndex = findIndexOfRecord(recordId); if (recIndex < 0) return; // not in the enumeration removeRecordAtIndex(recIndex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -