001    package org.wdssii.webindex.servlet;
002    
003    import java.util.Arrays;
004    import java.util.Collection;
005    
006    /**
007     * Transfer object containing a number of IndexRecordBeans corresponding to a
008     * source.
009     * 
010     * @author Lakshman
011     * @version $Id: IndexRecordList.java,v 1.4 2007/10/29 20:46:15 lakshman Exp $
012     */
013    public class IndexRecordList {
014            private String source;
015            private IndexRecordBean[] records;
016            private long lastNumber;
017    
018            /** Name of source */
019            public String getSource() {
020                    return source;
021            }
022    
023            /** The list can be empty, but it won't be null. */
024            public IndexRecordBean[] getRecords() {
025                    return records;
026            }
027    
028            /** returns -ve if no IndexRecords are here. */
029            public long getLastNumber() {
030                    return lastNumber;
031            }
032    
033            /** set state */
034            private void updateLast() {
035                    if (records.length > 0) {
036                            IndexRecordBean last = records[ records.length - 1 ];
037                            this.lastNumber = last.getNumber();
038                    } else {
039                            // FIXME: need to distinguish in case directory got scoured
040                            this.lastNumber = -1;
041                    }
042            }
043    
044            /** the IndexRecords should already be sorted. */
045            private IndexRecordList(String source, IndexRecordBean[] indexRecords, long lastNumber) {
046                    this.source = source;
047                    this.records = indexRecords;
048                    this.lastNumber = lastNumber;
049            }
050            
051            public static final int RETURN_ALL_RECORDS = -1;
052            public static final int RETURN_LATEST_ONLY = -2;
053            
054            /**
055             * Returns a cloned copy of this TO, pruned to the number of the last
056             * IndexRecord specified.
057             */
058            @SuppressWarnings("unchecked")
059            public IndexRecordList newInstance(long lastRead) {
060                    IndexRecordBean[] v = records; // for lastRead == RETURN_ALL_RECORDS
061                    if (lastRead == RETURN_LATEST_ONLY && records.length > 0){
062                            v = new IndexRecordBean[]{ records[records.length-1] };
063                    } else if (lastRead > 0 ){
064                            // the equality check is based purely on number, so this works
065                            IndexRecordBean lastReadItem = new IndexRecordBean(null,null,lastRead);
066                            int loc = Arrays.binarySearch(records,lastReadItem);
067                            if ( loc >= 0 ){
068                                    v = getRecordsAfterIndex(loc+1);
069                            }
070                            // otherwise: not there, so return entire list
071                    }
072                    return new IndexRecordList(source, v, lastNumber);
073            }
074    
075            private IndexRecordBean[] getRecordsAfterIndex(int start){
076                    // subset array
077                    IndexRecordBean[] v = new IndexRecordBean[ records.length - start ];
078                    for (int i = start, j = 0; i < records.length; ++i,++j){
079                            v[j] = records[i];
080                    }
081                    return v;
082            }
083            
084            /** create empty TO */
085            public static IndexRecordList newInstance(String source) {
086                    IndexRecordList to = new IndexRecordList(source,
087                                    new IndexRecordBean[0], -1);
088                    return to;
089            }
090    
091            @SuppressWarnings("unchecked")
092            public void setRecords(Collection<IndexRecordBean> c) {
093                    // need to make sure that the IndexRecords array is ordered by number.
094                    records = c.toArray(new IndexRecordBean[0]);
095                    Arrays.sort(records);
096                    updateLast();
097            }
098            
099            public void pruneToMaxSize(long maxSize){
100                    if ( records.length > maxSize ){
101                            int start = records.length - (int) maxSize;
102                            records = getRecordsAfterIndex(start);
103                    }
104            }
105    }