001 002 package org.objectweb.jac.util; 003 004 import java.lang.ref.Reference; 005 import java.lang.ref.ReferenceQueue; 006 import java.lang.ref.WeakReference; 007 import java.util.AbstractList; 008 import java.util.ArrayList; 009 import java.util.List; 010 import org.apache.log4j.Logger; 011 012 public class WeakList extends AbstractList { 013 static Logger logger = Logger.getLogger("weak.collections"); 014 015 /** 016 * Reference queue for cleared weak references 017 */ 018 private final ReferenceQueue queue = new ReferenceQueue(); 019 020 private final List list=new ArrayList(); 021 022 public boolean add(Object o) { 023 expungeStaleEntries(); 024 return list.add(new ListEntry(o,queue)); 025 } 026 027 public Object get(int i) { 028 expungeStaleEntries(); 029 return ((Reference)list.get(i)).get(); 030 } 031 032 public int size() { 033 //new Exception().printStackTrace(); 034 expungeStaleEntries(); 035 return list.size(); 036 } 037 038 public Object remove(int index) { 039 return ((ListEntry)list.remove(index)).get(); 040 } 041 042 /** 043 * Expunge stale entries from the list. 044 */ 045 private void expungeStaleEntries() { 046 Object r; 047 while ( (r = queue.poll()) != null) { 048 ListEntry e = (ListEntry)r; 049 int i=list.indexOf(r); 050 if(i!=-1) { 051 logger.debug("removing from list "+r+" ("+i+")"); 052 list.remove(i); 053 } 054 } 055 } 056 057 private static class ListEntry extends WeakReference { 058 String objectString; 059 public ListEntry(Object o,ReferenceQueue queue) { 060 super(o,queue); 061 objectString=o.toString(); 062 } 063 public boolean equals(Object o) { 064 if(o==null) { 065 return false; 066 } else { 067 if((o instanceof ListEntry)) { 068 return o.hashCode()==this.hashCode(); 069 } else { 070 if(this.get()==null) return false; 071 return this.get().equals(o); 072 } 073 } 074 } 075 public String toString() { 076 if(this.get()==null) { 077 return "'entry "+objectString+" <GARBAGED>'"; 078 } else { 079 return "'entry "+this.get()+"'"; 080 } 081 } 082 083 } 084 }