KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lobobrowser > util > History


1 /*
2     GNU LESSER GENERAL PUBLIC LICENSE
3     Copyright (C) 2006 The Lobo Project
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19     Contact info: xamjadmin@users.sourceforge.net
20 */

21 /*
22  * Created on Jun 6, 2005
23  */

24 package org.lobobrowser.util;
25
26 import java.util.*;
27
28 /**
29  * @author J. H. S.
30  */

31 public class History implements java.io.Serializable JavaDoc {
32     private static final long serialVersionUID = 2257845000800300100L;
33
34     private transient ArrayList historySequence;
35     
36     private final SortedSet historySortedSet = new TreeSet();
37     private final Map historyMap = new HashMap();
38     private final SortedSet historyTimedSet = new TreeSet();
39
40     private int sequenceCapacity;
41     private int commonEntriesCapacity;
42
43     private transient int sequenceIndex;
44     
45     /**
46      * @param sequenceCapacity
47      * @param commonEntriesCapacity
48      */

49     public History(int sequenceCapacity, int commonEntriesCapacity) {
50         super();
51         this.historySequence = new ArrayList();
52         this.sequenceIndex = -1;
53         this.sequenceCapacity = sequenceCapacity;
54         this.commonEntriesCapacity = commonEntriesCapacity;
55     }
56     
57     private void readObject(java.io.ObjectInputStream JavaDoc in) throws ClassNotFoundException JavaDoc, java.io.IOException JavaDoc {
58         this.historySequence = new ArrayList();
59         this.sequenceIndex = -1;
60         in.defaultReadObject();
61     }
62     
63     /**
64      * @return Returns the commonEntriesCapacity.
65      */

66     public int getCommonEntriesCapacity() {
67         return commonEntriesCapacity;
68     }
69     
70     /**
71      * @param commonEntriesCapacity The commonEntriesCapacity to set.
72      */

73     public void setCommonEntriesCapacity(int commonEntriesCapacity) {
74         this.commonEntriesCapacity = commonEntriesCapacity;
75     }
76     /**
77      * @return Returns the sequenceCapacity.
78      */

79     public int getSequenceCapacity() {
80         return sequenceCapacity;
81     }
82     /**
83      * @param sequenceCapacity The sequenceCapacity to set.
84      */

85     public void setSequenceCapacity(int sequenceCapacity) {
86         this.sequenceCapacity = sequenceCapacity;
87     }
88
89     public String JavaDoc getCurrentItem() {
90         if(this.sequenceIndex >= 0) {
91             return (String JavaDoc) this.historySequence.get(this.sequenceIndex);
92         }
93         else {
94             return null;
95         }
96     }
97
98     public String JavaDoc back() {
99         if(this.sequenceIndex > 0) {
100             this.sequenceIndex--;
101             return this.getCurrentItem();
102         }
103         else {
104             return null;
105         }
106     }
107
108     public String JavaDoc forward() {
109         if(this.sequenceIndex + 1 < this.historySequence.size()) {
110             this.sequenceIndex++;
111             return this.getCurrentItem();
112         }
113         else {
114             return null;
115         }
116     }
117     
118     public Collection getRecentItems(int maxNumItems) {
119         Collection items = new LinkedList();
120         Iterator i = this.historyTimedSet.iterator();
121         int count = 0;
122         while(i.hasNext() && count++ < maxNumItems) {
123             TimedEntry entry = (TimedEntry) i.next();
124             items.add(entry.value);
125         }
126         return items;
127     }
128     
129     public Collection getHeadMatchItems(String JavaDoc item, int maxNumItems) {
130         Object JavaDoc[] array = this.historySortedSet.toArray();
131         int idx = Arrays.binarySearch(array, item);
132         int startIdx = idx >= 0 ? idx : (-idx - 1);
133         int count = 0;
134         Collection items = new LinkedList();
135         for(int i = startIdx; i < array.length && (count++ < maxNumItems); i++) {
136             String JavaDoc potentialItem = (String JavaDoc) array[i];
137             if(potentialItem.startsWith(item)) {
138                 items.add(potentialItem);
139             }
140             else {
141                 break;
142             }
143         }
144         return items;
145     }
146     
147     public void addAsRecentOnly(String JavaDoc item) {
148         TimedEntry entry = (TimedEntry) this.historyMap.get(item);
149         if(entry != null) {
150             this.historyTimedSet.remove(entry);
151             entry.touch();
152             this.historyTimedSet.add(entry);
153         }
154         else {
155             entry = new TimedEntry(item);
156             this.historyTimedSet.add(entry);
157             this.historyMap.put(item, entry);
158             this.historySortedSet.add(item);
159             if(this.historyTimedSet.size() > this.commonEntriesCapacity) {
160                 // Most outdated goes last
161
TimedEntry entryToRemove = (TimedEntry) this.historyTimedSet.last();
162                 this.historyMap.remove(entryToRemove.value);
163                 this.historySortedSet.remove(entryToRemove.value);
164                 this.historyTimedSet.remove(entryToRemove);
165             }
166         }
167     }
168     
169     public void addItem(String JavaDoc item, boolean updateAsRecent) {
170         int newIndex = this.sequenceIndex + 1;
171         
172         while(newIndex >= this.historySequence.size()) {
173             this.historySequence.add(null);
174         }
175         this.historySequence.set(newIndex, item);
176         this.sequenceIndex = newIndex;
177
178         int expectedSize = newIndex + 1;
179         while(this.historySequence.size() > expectedSize) {
180             this.historySequence.remove(expectedSize);
181         }
182
183         while(this.historySequence.size() > this.sequenceCapacity) {
184             this.historySequence.remove(0);
185             this.sequenceIndex--;
186         }
187         
188         if(updateAsRecent) {
189             this.addAsRecentOnly(item);
190         }
191     }
192     
193     private class TimedEntry implements Comparable JavaDoc, java.io.Serializable JavaDoc {
194         private static final long serialVersionUID = 2257845000000000200L;
195         private long timestamp = System.currentTimeMillis();
196         private final String JavaDoc value;
197         
198         /**
199          * @param value
200          */

201         public TimedEntry(String JavaDoc value) {
202             this.value = value;
203         }
204         
205         public void touch() {
206             this.timestamp = System.currentTimeMillis();
207         }
208
209         public boolean equals(Object JavaDoc obj) {
210             TimedEntry other = (TimedEntry) obj;
211             return other.value.equals(this.value);
212         }
213         
214         /* (non-Javadoc)
215          * @see java.lang.Comparable#compareTo(java.lang.Object)
216          */

217         public int compareTo(Object JavaDoc arg0) {
218             if(this.equals(arg0)) {
219                 return 0;
220             }
221             TimedEntry other = (TimedEntry) arg0;
222             long time1 = this.timestamp;
223             long time2 = other.timestamp;
224             if(time1 > time2) {
225                 // More recent goes first
226
return -1;
227             }
228             else if(time2 > time1){
229                 return +1;
230             }
231             else {
232                 int diff = System.identityHashCode(this) - System.identityHashCode(other);
233                 if(diff == 0) {
234                     return +1;
235                 }
236                 return diff;
237             }
238         }
239     }
240
241 }
242
Popular Tags