1 19 20 package org.openide.loaders; 21 22 import java.lang.ref.Reference ; 23 import java.lang.ref.SoftReference ; 24 25 import java.io.IOException ; 26 import java.util.*; 27 28 import org.openide.filesystems.*; 29 import org.openide.loaders.DataFolder.SortMode; 30 31 32 36 final class FolderOrder extends Object implements Comparator<DataObject> { 37 40 private static final char SEP = '/'; 41 42 44 private static final WeakHashMap<FileObject, Reference <FolderOrder>> map = 45 new WeakHashMap<FileObject, Reference <FolderOrder>> (101); 46 54 private static final Map<FileObject, Object > knownOrders = 55 Collections.synchronizedMap(new WeakHashMap<FileObject, Object >(50)); 56 57 58 59 private Map<String ,Integer > order; 60 61 private FileObject folder; 62 63 private boolean ignorePartials; 64 65 private SortMode sortMode; 66 67 private Object previous; 68 69 72 private FolderOrder (FileObject folder) { 73 this.folder = folder; 74 } 75 76 77 80 public void setSortMode (SortMode mode) throws IOException { 81 sortMode = mode; 83 mode.write (folder); 85 } 87 88 90 public SortMode getSortMode () { 91 if (sortMode == null) { 92 sortMode = SortMode.read (folder); 93 } 94 return sortMode; 95 } 96 97 99 public synchronized void setOrder (DataObject[] arr) throws IOException { 100 if (arr != null) { 101 order = new HashMap<String , Integer > (arr.length * 4 / 3 + 1); 102 103 Enumeration en = org.openide.util.Enumerations.removeDuplicates ( 105 org.openide.util.Enumerations.array (arr) 106 ); 107 108 int i = 0; 109 while (en.hasMoreElements ()) { 110 DataObject obj = (DataObject)en.nextElement (); 111 FileObject fo = obj.getPrimaryFile (); 112 if (folder.equals (fo.getParent ())) { 113 order.put (fo.getNameExt (), Integer.valueOf (i++)); 115 } 116 } 117 ignorePartials = true; 120 } else { 121 order = null; 122 } 123 124 write (); 126 127 } 129 130 136 public synchronized Map<DataObject, List<DataObject>> getOrderingConstraints(Collection<DataObject> objects) { 137 final Set<String > partials = readPartials (); 138 if (partials.isEmpty ()) { 139 return null; 140 } else { 141 Map<String , DataObject> objectsByName = new HashMap<String , DataObject>(); 142 for (DataObject d: objects) { 143 objectsByName.put(d.getPrimaryFile().getNameExt(), d); 144 } 145 Map<DataObject, List<DataObject>> m = new HashMap<DataObject, List<DataObject>>(); 146 for (String constraint: partials) { 147 int idx = constraint.indexOf(SEP); 148 String a = constraint.substring(0, idx); 149 String b = constraint.substring(idx + 1); 150 if (ignorePartials && (order.containsKey(a) || order.containsKey(b))) { 151 continue; 152 } 153 DataObject ad = objectsByName.get(a); 154 if (ad == null) { 155 continue; 156 } 157 DataObject bd = objectsByName.get(b); 158 if (bd == null) { 159 continue; 160 } 161 List<DataObject> l = m.get(ad); 162 if (l == null) { 163 m.put(ad, l = new LinkedList<DataObject>()); 164 } 165 l.add(bd); 166 } 167 return m; 168 } 169 } 170 171 175 private Set<String > readPartials () { 176 Enumeration<String > e = folder.getAttributes (); 177 Set<String > s = new HashSet<String > (); 178 while (e.hasMoreElements ()) { 179 String name = e.nextElement (); 180 if (name.indexOf (SEP) != -1) { 181 Object value = folder.getAttribute (name); 182 if ((value instanceof Boolean ) && ((Boolean ) value).booleanValue ()) 183 s.add (name); 184 } 185 } 186 return s; 187 } 188 189 191 public int compare (DataObject obj1, DataObject obj2) { 192 Integer i1 = (order == null) ? null : order.get (obj1.getPrimaryFile ().getNameExt ()); 193 Integer i2 = (order == null) ? null : order.get (obj2.getPrimaryFile ().getNameExt ()); 194 195 if (i1 == null) { 196 if (i2 != null) return 1; 197 198 return getSortMode ().compare (obj1, obj2); 200 } else { 201 if (i2 == null) return -1; 202 if (i1.intValue () == i2.intValue ()) return 0; 204 if (i1.intValue () < i2.intValue ()) return -1; 205 return 1; 206 } 207 } 208 209 211 public void write () throws IOException { 212 if (order == null) { 215 folder.setAttribute (DataFolder.EA_ORDER, null); 217 } else { 218 java.util.Iterator <Map.Entry<String , Integer >> it = order.entrySet ().iterator (); 220 String [] filenames = new String [order.size ()]; 221 while (it.hasNext ()) { 222 Map.Entry<String , Integer > en = it.next (); 223 String fo = en.getKey (); 224 int indx = en.getValue ().intValue (); 225 filenames[indx] = fo; 226 } 227 StringBuffer buf = new StringBuffer (255); 228 for (int i = 0; i < filenames.length; i++) { 229 if (i > 0) { 230 buf.append ('/'); 231 } 232 buf.append (filenames[i]); 233 } 234 235 Set<String > p = ignorePartials ? readPartials() : null; 238 239 folder.setAttribute (DataFolder.EA_ORDER, buf.toString ()); 240 241 if (ignorePartials) { 242 if (! p.isEmpty ()) { 245 Set<String > f = new HashSet<String > (); 246 for (String fo: order.keySet()) { 247 f.add (fo); 248 } 249 for (String s: p) { 250 int idx = s.indexOf (SEP); 251 if (f.contains (s.substring (0, idx)) && 252 f.contains (s.substring (idx + 1))) { 253 folder.setAttribute (s, null); 254 } 255 } 256 } 257 ignorePartials = false; 259 } 260 } 261 } 262 263 265 private void read () { 266 Object o = folder.getAttribute (DataFolder.EA_ORDER); 267 268 if ((previous == null && o == null) || 269 (previous != null && previous.equals (o))) { 270 return; 272 } 273 274 if ((o instanceof Object []) && (previous instanceof Object [])) { 275 if (compare((Object []) o, (Object []) previous)) { 276 return; 277 } 278 } 279 280 doRead (o); 281 282 previous = o; 283 if (previous != null) { 284 knownOrders.put(folder, previous); 285 } 286 287 FolderList.changedFolderOrder (folder); 288 } 289 290 291 private static boolean compare(Object [] a, Object [] b) { 292 if (a == b) { 293 return true; 294 } 295 296 int len = Math.min(a.length, b.length); 297 for (int i = 0; i < len; i++) { 298 if (a[i] != b[i]) { 299 if (a[i] == null) { 300 return false; 301 } 302 303 if (a[i].equals(b[i])) { 304 continue; 305 } 306 307 if ((a[i] instanceof Object []) && (b[i] instanceof Object [])) { 308 if (compare((Object []) a[i], (Object []) b[i])) { 309 continue; 310 } else { 311 return false; 312 } 313 } else { 314 return false; 315 } 316 } 317 } 318 319 Object [] arr = (a.length > b.length) ? a : b; 320 if (checkNonNull(arr, len)) { 321 return false; 322 } 323 324 return true; 325 } 326 327 private static boolean checkNonNull(Object [] a, int from) { 328 for (int i = from; i < a.length; i++) { 329 if (a[i] != null) { 330 return true; 331 } 332 } 333 334 return false; 335 } 336 337 340 private void doRead (Object o) { 341 if (o == null) { 342 order = null; 343 return; 344 } else if (o instanceof String [][]) { 345 String [][] namesExts = (String [][]) o; 347 348 if (namesExts.length != 2) { 349 order = null; 350 return; 351 } 352 String [] names = namesExts[0]; 353 String [] exts = namesExts[1]; 354 355 if (names == null || exts == null || names.length != exts.length) { 356 order = null; 358 return; 359 } 360 361 362 Map<String , Integer > set = new HashMap<String , Integer > (names.length); 363 364 for (int i = 0; i < names.length; i++) { 365 set.put (names[i], Integer.valueOf (i)); 366 } 367 order = set; 368 return; 369 370 } else if (o instanceof String ) { 371 String sepnames = (String ) o; 373 Map<String , Integer > set = new HashMap<String , Integer > (); 374 StringTokenizer tok = new StringTokenizer (sepnames, "/"); int i = 0; 376 while (tok.hasMoreTokens ()) { 377 String file = tok.nextToken (); 378 set.put (file, Integer.valueOf (i)); 379 i++; 380 } 381 382 order = set; 383 return; 384 } else { 385 order = null; 387 return; 388 } 389 } 390 391 392 396 public static FolderOrder findFor (FileObject folder) { 397 FolderOrder order = null; 398 synchronized (map) { 399 Reference <FolderOrder> ref = map.get (folder); 400 order = ref == null ? null : ref.get (); 401 if (order == null) { 402 order = new FolderOrder (folder); 403 order.previous = knownOrders.get(folder); 404 order.doRead(order.previous); 405 406 map.put (folder, new SoftReference <FolderOrder> (order)); 407 } 408 } 409 synchronized (order) { 411 order.read (); 412 return order; 413 } 414 } 415 416 417 418 } 419 | Popular Tags |