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.util.Collections ; 26 import java.util.Enumeration ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Map ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 import org.openide.filesystems.FileObject; 35 import org.openide.util.TopologicalSortException; 36 import org.openide.util.Utilities; 37 38 42 public final class CompoundFolderChildren { 43 44 public static final String PROP_CHILDREN = "FolderChildren.PROP_CHILDREN"; 46 private static final String HIDDEN_SUFFIX = "_hidden"; private static final String HIDDEN_ATTR_NAME = "hidden"; 49 private static final Logger LOG = Logger.getLogger(CompoundFolderChildren.class.getName()); 50 51 private final String LOCK = new String ("CompoundFolderChildren.LOCK"); private FolderChildren [] layers = null; 53 private List children = Collections.EMPTY_LIST; 54 55 private PCL listener = new PCL(); 56 private PropertyChangeSupport pcs = new PropertyChangeSupport (this); 57 58 public CompoundFolderChildren(String [] paths) { 59 this(paths, true); 60 } 61 62 63 public CompoundFolderChildren(String [] paths, boolean includeSubfolders) { 64 this.layers = new FolderChildren [paths.length]; 65 for (int i = 0; i < paths.length; i++) { 66 this.layers[i] = new FolderChildren(paths[i], includeSubfolders); 67 this.layers[i].addPropertyChangeListener(listener); 68 } 69 70 rebuild(); 71 } 72 73 public List getChildren() { 74 synchronized (LOCK) { 75 return children; 76 } 77 } 78 79 public void addPropertyChangeListener(PropertyChangeListener l) { 80 pcs.addPropertyChangeListener(l); 81 } 82 83 public void removePropertyChangeListener(PropertyChangeListener l) { 84 pcs.removePropertyChangeListener(l); 85 } 86 87 private void rebuild() { 88 PropertyChangeEvent event = null; 89 90 synchronized (LOCK) { 91 HashMap visible = new HashMap (); 93 HashMap hidden = new HashMap (); 94 95 for (int i = 0; i < layers.length; i++) { 96 List layerKids = layers[i].getChildren(); 97 for (Iterator j = layerKids.iterator(); j.hasNext(); ) { 98 FileObject f = (FileObject) j.next(); 99 String name = realName(f); 100 101 if (isHidden(f)) { 102 if (!hidden.containsKey(name)) { 103 hidden.put(name, f); 104 } 105 } 106 107 if (!hidden.containsKey(name)) { 108 if (!visible.containsKey(name)) { 109 visible.put(name, f); 110 } 111 } 112 } 113 } 114 115 HashMap edges = new HashMap (); 117 for (int i = 0; i < layers.length; i++) { 118 Map layerAttrs = layers[i].getFolderAttributes(); 119 for (Iterator j = layerAttrs.keySet().iterator(); j.hasNext(); ) { 120 String attrName = (String ) j.next(); 121 Object attrValue = layerAttrs.get(attrName); 122 123 int slashIdx = attrName.indexOf('/'); if (slashIdx == -1 || !(attrValue instanceof Boolean )) { 126 continue; 127 } 128 129 String name1 = attrName.substring(0, slashIdx); 131 String name2 = attrName.substring(slashIdx + 1); 132 if (!((Boolean ) attrValue).booleanValue()) { 133 String s = name1; 135 name1 = name2; 136 name2 = s; 137 } 138 139 FileObject from = (FileObject) visible.get(name1); 141 FileObject to = (FileObject) visible.get(name2); 142 143 if (from != null && to != null) { 144 HashSet vertices = (HashSet ) edges.get(from); 145 if (vertices == null) { 146 vertices = new HashSet (); 147 edges.put(from, vertices); 148 } 149 vertices.add(to); 150 } 151 } 152 } 153 154 List sorted; 156 157 try { 158 sorted = Utilities.topologicalSort(visible.values(), edges); 159 } catch (TopologicalSortException e) { 160 LOG.log(Level.WARNING, "Can't sort folder children.", e); sorted = e.partialSort(); 162 } 163 164 if (!children.equals(sorted)) { 165 event = new PropertyChangeEvent (this, PROP_CHILDREN, children, sorted); 166 children = sorted; 167 } 168 } 169 170 if (event != null) { 171 pcs.firePropertyChange(event); 172 } 173 } 174 175 private boolean isHidden(FileObject fo) { 176 if (fo.getNameExt().endsWith(HIDDEN_SUFFIX)) { 177 return true; 178 } 179 180 for (Enumeration e = fo.getAttributes(); e.hasMoreElements(); ) { 181 String name = (String )e.nextElement(); 182 if (HIDDEN_ATTR_NAME.equals(name)) { 183 Object value = fo.getAttribute(name); 184 if ((value instanceof Boolean ) && ((Boolean ) value).booleanValue()){ 185 return true; 186 } 187 } 188 } 189 190 return false; 191 } 192 193 private String realName(FileObject fo) { 194 String nameExt = fo.getNameExt(); 195 if (nameExt.endsWith(HIDDEN_SUFFIX)) { 196 return nameExt.substring(0, nameExt.length() - HIDDEN_SUFFIX.length()); 197 } else { 198 return nameExt; 199 } 200 } 201 202 private class PCL implements PropertyChangeListener { 203 public void propertyChange(PropertyChangeEvent evt) { 204 if (evt.getPropertyName() != null && 207 FolderChildren.PROP_CHILD_CHANGED.equals(evt.getPropertyName())) 208 { 209 pcs.firePropertyChange(new PropertyChangeEvent (CompoundFolderChildren.this, PROP_CHILDREN, null, null)); 211 } else { 212 rebuild(); 214 } 215 } 216 217 } } 219 | Popular Tags |