1 19 20 package org.netbeans.modules.editor.mimelookup.impl; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.beans.PropertyChangeSupport ; 25 import java.lang.ref.WeakReference ; 26 import java.util.ArrayList ; 27 import java.util.Collections ; 28 import java.util.Enumeration ; 29 import java.util.HashMap ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.logging.Logger ; 33 import org.openide.filesystems.FileAttributeEvent; 34 import org.openide.filesystems.FileChangeAdapter; 35 import org.openide.filesystems.FileEvent; 36 import org.openide.filesystems.FileObject; 37 import org.openide.filesystems.FileRenameEvent; 38 import org.openide.filesystems.Repository; 39 40 44 public final class FolderChildren { 45 46 public static final String PROP_CHILDREN = "FolderChildren.PROP_CHILDREN"; public static final String PROP_CHILD_CHANGED = "FolderChildren.PROP_CHILD_CHANGED"; public static final String PROP_ATTRIBUTES = "FolderChildren.PROP_ATTRIBUTES"; 50 private static final Logger LOG = Logger.getLogger(FolderChildren.class.getName()); 51 52 private String [] pathElement; 53 private boolean includeSubfolders; 54 55 private final String LOCK = new String ("FolderChildren.LOCK"); 57 private FileObject currentFolder = null; 58 private boolean isTargetFolder = false; 59 60 private FolderListener listener = new FolderListener(this); 61 62 private List children = Collections.EMPTY_LIST; 63 64 private PropertyChangeSupport pcs = new PropertyChangeSupport (this); 65 66 public FolderChildren(String path) { 67 this(path, true); 68 } 69 70 71 public FolderChildren(String path, boolean includeSubfolders) { 72 this.pathElement = path.split("/"); this.includeSubfolders = includeSubfolders; 74 rebuild(); 75 } 76 77 public List getChildren() { 78 synchronized (LOCK) { 79 return children; 80 } 81 } 82 83 public Map getFolderAttributes() { 84 synchronized (LOCK) { 85 if (!isTargetFolder) { 86 return Collections.EMPTY_MAP; 87 } 88 89 HashMap attrs = new HashMap (); 90 for (Enumeration e = currentFolder.getAttributes(); e.hasMoreElements(); ) { 91 String attrName = (String ) e.nextElement(); 92 Object attrValue = currentFolder.getAttribute(attrName); 93 94 if (!attrs.containsKey(attrName)) { 95 attrs.put(attrName, attrValue); 96 } 97 } 98 99 return attrs; 100 } 101 } 102 103 public void addPropertyChangeListener(PropertyChangeListener l) { 104 pcs.addPropertyChangeListener(l); 105 } 106 107 public void removePropertyChangeListener(PropertyChangeListener l) { 108 pcs.removePropertyChangeListener(l); 109 } 110 111 private void rebuild() { 112 PropertyChangeEvent event = null; 113 114 synchronized (LOCK) { 115 Object [] result = findTarget(pathElement); 116 FileObject f = (FileObject) result[0]; 117 boolean isTarget = ((Boolean ) result[1]).booleanValue(); 118 119 if (f != currentFolder) { 121 if (currentFolder != null) { 123 currentFolder.removeFileChangeListener(listener); 124 } 125 126 currentFolder = f; 128 isTargetFolder = isTarget; 129 130 LOG.finest("Setting currentFolder = '" + currentFolder.getPath() + "'"); LOG.finest("Setting isTargetFolder = '" + isTargetFolder + "'"); 133 currentFolder.addFileChangeListener(listener); 135 } 136 137 List newChildren; 139 if (isTargetFolder) { 140 FileObject [] files = currentFolder.getChildren(); 141 newChildren = new ArrayList (files.length); 142 143 for (int i = 0; i < files.length; i++) { 144 if (includeSubfolders || !files[i].isFolder()) { 145 newChildren.add(files[i]); 146 } 147 } 148 149 newChildren = Collections.unmodifiableList(newChildren); 150 } else { 151 newChildren = Collections.EMPTY_LIST; 152 } 153 154 if (!children.equals(newChildren)) { 155 event = new PropertyChangeEvent (this, PROP_CHILDREN, children, newChildren); 156 children = newChildren; 157 } 158 } 159 160 if (event != null) { 161 pcs.firePropertyChange(event); 162 } 163 } 164 165 private void fileContentChanged(FileObject file) { 166 PropertyChangeEvent event = null; 167 168 synchronized (LOCK) { 169 if (isTargetFolder) { 170 event = new PropertyChangeEvent (this, PROP_CHILD_CHANGED, file, file); 171 } 172 } 173 174 if (event != null) { 175 pcs.firePropertyChange(event); 176 } 177 } 178 179 private void attributeChanged(FileObject file, String attribName, Object oldValue, Object newValue) { 180 PropertyChangeEvent event = null; 181 182 synchronized (LOCK) { 183 if (isTargetFolder && currentFolder == file) { 184 event = new PropertyChangeEvent (this, PROP_ATTRIBUTES, null, null); 185 } 186 } 187 188 if (event != null) { 189 pcs.firePropertyChange(event); 190 } 191 } 192 193 private Object [] findTarget(String [] path) { 194 FileObject target = Repository.getDefault().getDefaultFileSystem().getRoot(); 195 boolean isTarget = 0 == path.length; 196 197 for (int i = 0; i < path.length; i++) { 198 FileObject f = target.getFileObject(path[i]); 199 200 if (f == null || !f.isFolder() || !f.isValid() || f.isVirtual()) { 201 break; 202 } else { 203 target = f; 204 isTarget = i + 1 == path.length; 205 } 206 } 207 208 return new Object [] { target, Boolean.valueOf(isTarget) }; 209 } 210 211 private static class FolderListener extends FileChangeAdapter { 212 213 private WeakReference ref = null; 214 215 public FolderListener(FolderChildren folderChildren) { 216 this.ref = new WeakReference (folderChildren); 217 } 218 219 public void fileRenamed(FileRenameEvent fe) { 220 handleRebuildEvent(fe); 221 } 222 223 public void fileDeleted(FileEvent fe) { 224 handleRebuildEvent(fe); 225 } 226 227 public void fileFolderCreated(FileEvent fe) { 228 handleRebuildEvent(fe); 229 } 230 231 public void fileAttributeChanged(FileAttributeEvent fe) { 232 FolderChildren folderChildren = (FolderChildren) ref.get(); 233 if (folderChildren != null) { 234 folderChildren.attributeChanged(fe.getFile(), fe.getName(), fe.getOldValue(), fe.getNewValue()); 235 } else { 236 ((FileObject) fe.getSource()).removeFileChangeListener(this); 237 } 238 } 239 240 public void fileDataCreated(FileEvent fe) { 241 handleRebuildEvent(fe); 242 } 243 244 public void fileChanged(FileEvent fe) { 245 FolderChildren folderChildren = (FolderChildren) ref.get(); 246 if (folderChildren != null) { 247 folderChildren.fileContentChanged(fe.getFile()); 248 } else { 249 ((FileObject) fe.getSource()).removeFileChangeListener(this); 250 } 251 } 252 253 private void handleRebuildEvent(FileEvent fe) { 254 FolderChildren folderChildren = (FolderChildren) ref.get(); 255 if (folderChildren != null) { 256 folderChildren.rebuild(); 257 } else { 258 ((FileObject) fe.getSource()).removeFileChangeListener(this); 259 } 260 } 261 262 } } 264 | Popular Tags |