1 19 package org.netbeans.modules.timers; 20 21 import java.beans.PropertyChangeListener ; 22 import java.beans.PropertyChangeSupport ; 23 import java.lang.ref.Reference ; 24 import java.lang.ref.WeakReference ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.LinkedHashMap ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.WeakHashMap ; 31 import javax.swing.event.ChangeEvent ; 32 import javax.swing.event.ChangeListener ; 33 import org.openide.filesystems.FileChangeAdapter; 34 import org.openide.filesystems.FileEvent; 35 import org.openide.filesystems.FileObject; 36 import org.openide.util.RequestProcessor; 37 import org.openide.util.Utilities; 38 39 43 public final class TimesCollectorPeer { 44 45 private List <Reference <FileObject>> files; 46 private Map <FileObject, Map <String , Description>> fo2Key2Desc; 47 48 private static final TimesCollectorPeer INSTANCE = new TimesCollectorPeer(); 49 50 private PropertyChangeSupport pcs; 51 52 public static TimesCollectorPeer getDefault() { 53 return INSTANCE; 54 } 55 56 57 private TimesCollectorPeer() { 58 files = new ArrayList <Reference <FileObject>>(); 59 fo2Key2Desc = new WeakHashMap <FileObject, Map <String , Description>>(); 60 61 pcs = new PropertyChangeSupport (this); 62 } 63 64 public void reportTime(FileObject fo, String key, String message, long time) { 65 Map <String , Description> key2Desc = getKey2Desc(fo); 66 Description desc = new Description(message, time); 67 68 key2Desc.put(key, desc); 69 70 pcs.firePropertyChange("PROP", fo, key); 71 } 72 73 public void reportReference( FileObject fo, String key, String message, Object object ) { 74 Map <String , Description> key2Desc = getKey2Desc(fo); 75 76 Description d = key2Desc.get( key ); 78 assert d == null || d instanceof ObjectCountDescripton : "Illegal state"; 79 80 ObjectCountDescripton ocd = d == null ? new ObjectCountDescripton( this, fo, key, message ) : (ObjectCountDescripton)d; 81 ocd.add( object ); 82 83 key2Desc.put(key, ocd); 84 pcs.firePropertyChange("PROP", fo, key); 85 } 86 87 private synchronized Map <String , Description> getKey2Desc(final FileObject fo) { 88 Map <String , Description> result = fo2Key2Desc.get(fo); 89 90 if (result == null) { 91 files.add(new CleanableWeakReference<FileObject>(fo)); 92 fo2Key2Desc.put(fo, result = new LinkedHashMap <String , Description>()); 93 pcs.firePropertyChange("fos", null, fo); 94 if (fo != null) { 95 fo.addFileChangeListener(new FileChangeAdapter() { 96 public void fileDeleted(FileEvent ev) { 97 for (Reference <FileObject> r : files) { 98 if (r.get() == fo) { 99 files.remove(r); 100 break; 101 } 102 } 103 fo2Key2Desc.remove(fo); 104 pcs.firePropertyChange("fos", null, null); 105 } 106 }); 107 } 108 } 109 110 return result; 111 } 112 113 public Description getDescription(FileObject fo, String key) { 114 return getKey2Desc(fo).get(key); 115 } 116 117 public Collection <String > getKeysForFile(FileObject fo) { 118 return getKey2Desc(fo).keySet(); 119 } 120 121 public Collection <FileObject> getFiles() { 122 List <FileObject> result = new ArrayList <FileObject>(); 123 124 for (Reference <FileObject> r : files) { 125 FileObject f = r.get(); 126 127 if (f != null) 128 result.add(f); 129 } 130 return result; 131 } 132 133 public void addPropertyChangeListener(PropertyChangeListener l) { 134 pcs.addPropertyChangeListener(l); 135 } 136 137 public void removePropertyChangeListener(PropertyChangeListener l) { 138 pcs.removePropertyChangeListener(l); 139 } 140 141 public void select(FileObject fo) { 142 getKey2Desc(fo); 143 pcs.firePropertyChange("selected", null, fo); 144 } 145 146 public static class Description { 147 private String message; 148 private long time; 149 150 public Description(String message, long time) { 151 this.message = message; 152 this.time = time; 153 } 154 155 public String getMessage() { 156 return message; 157 } 158 159 public long getTime() { 160 return time; 161 } 162 163 } 164 165 public static class ObjectCountDescripton extends Description implements ChangeListener { 166 167 private TimesCollectorPeer tcp; 168 private Reference <FileObject> fo; 169 private String key; 170 private InstanceWatcher iw = new InstanceWatcher(); 171 172 173 public ObjectCountDescripton( TimesCollectorPeer tcp, FileObject fo, String key, String message ) { 174 super( message, 0 ); 175 this.tcp = tcp; 176 this.fo = new WeakReference <FileObject>(fo); 177 this.key = key; 178 iw.addChangeListener( this ); 179 } 180 181 public long getTime( ) { 182 return iw.size(); 183 } 184 185 public Collection getInstances() { 186 return iw.getInstances(); 187 } 188 189 private void add( Object o ) { 190 iw.add( o ); 191 } 192 193 public void stateChanged(ChangeEvent e) { 194 FileObject file = fo.get(); 195 196 if (file != null) { 197 tcp.pcs.firePropertyChange("PROP", file, key); 198 } 199 } 200 201 } 202 203 private class CleanableWeakReference<T> extends WeakReference <T> implements Runnable { 204 205 public CleanableWeakReference(T o) { 206 super(o, Utilities.activeReferenceQueue()); 207 } 208 209 public void run() { 210 files.remove(this); 211 RequestProcessor.getDefault().post(new Runnable () { 212 public void run() { 213 pcs.firePropertyChange("fos", null, null); 214 } 215 }); 216 } 217 218 } 219 } 220 | Popular Tags |