1 19 20 package org.openide.filesystems; 21 22 import java.beans.PropertyVetoException ; 23 import java.io.ByteArrayInputStream ; 24 import java.io.ByteArrayOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.io.OutputStream ; 28 import java.lang.ref.Reference ; 29 import java.util.Collections ; 30 import java.util.Date ; 31 import java.util.Enumeration ; 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.Iterator ; 35 import java.util.Map ; 36 import java.util.Set ; 37 import java.util.concurrent.ConcurrentHashMap ; 38 import java.util.logging.Level ; 39 import java.util.logging.Logger ; 40 41 45 final class MemoryFileSystem extends AbstractFileSystem implements AbstractFileSystem.Info, AbstractFileSystem.Change, AbstractFileSystem.List, AbstractFileSystem.Attr { 46 private static final Logger ERR = Logger.getLogger(MemoryFileSystem.class.getName()); 47 48 51 private java.util.Date created = new java.util.Date (); 52 53 54 private Map <String , Entry> entries = initEntry(); 55 56 @SuppressWarnings ("deprecation") private void _setSystemName(String s) throws PropertyVetoException { 58 setSystemName(s); 59 } 60 61 62 public MemoryFileSystem() { 63 attr = this; 64 list = this; 65 change = this; 66 info = this; 67 68 69 try { 70 _setSystemName("MemoryFileSystem" + String.valueOf(System.identityHashCode(this))); 71 } catch (PropertyVetoException ex) { 72 ex.printStackTrace(); 73 } 74 } 75 76 77 public MemoryFileSystem(String [] resources) { 78 this(); 79 80 StringBuffer sb = new StringBuffer (); 81 82 for (int i = 0; i < resources.length; i++) { 83 sb.append(resources[i]); 84 85 if (resources[i].endsWith("/")) { 86 getOrCreateEntry(resources[i]).data = null; 88 } else { 89 getOrCreateEntry(resources[i]).data = new byte[0]; 90 } 91 } 92 } 93 94 95 private Entry getOrCreateEntry(String n) { 96 if ((n.length() > 0) && (n.charAt(0) == '/')) { 97 n = n.substring(1); 98 } 99 100 boolean isValidEntry = isValidEntry(n); 101 synchronized(entries) { 102 Entry x = entries.get(n); 103 104 if (x == null || !isValidEntry) { 105 x = new Entry(n); 106 entries.put(n, x); 107 } 108 109 return x; 110 } 111 } 112 113 114 115 private boolean isValidEntry(String n) { 116 return isValidEntry(n, null); 117 } 118 119 120 private boolean isValidEntry(String n, Boolean expectedResult) { 121 boolean retval = (n.length() == 0) ? true : false; 122 123 if ((n.length() > 0) && (n.charAt(0) == '/')) { 124 n = n.substring(1); 125 } 126 127 Entry x = entries.get(n); 128 FileObject fo = null; 129 130 if (x != null) { 131 Reference ref = findReference(n); 132 if (ref != null) { 133 fo = (FileObject)ref.get(); 134 retval = (fo != null) ? fo.isValid() : true; 135 } 136 } 137 138 if (ERR.isLoggable(Level.FINE) && expectedResult != null && retval != expectedResult.booleanValue()) { 139 logMessage("entry: " + x + " isValidReference.fo: " + ((fo == null) ? "null" : (fo.isValid() ? "valid" : "invalid"))); } 142 143 return (retval); 144 } 145 146 public String getDisplayName() { 147 return "MemoryFileSystem"; 148 } 149 150 public boolean isReadOnly() { 151 return false; 152 } 153 154 public Enumeration <String > attributes(String name) { 155 if (!isValidEntry(name)) { 156 return org.openide.util.Enumerations.empty(); 157 } 158 return Collections.enumeration(getOrCreateEntry(name).attrs.keySet()); 159 } 160 161 public String [] children(String f) { 162 if ((f.length() > 0) && (f.charAt(0) == '/')) { 163 f = f.substring(1); 164 } 165 166 if ((f.length() > 0) && !f.endsWith("/")) { 167 f = f + "/"; 168 } 169 170 Set <String > l = new HashSet <String >(); 171 172 synchronized(entries) { 174 Iterator it = entries.keySet().iterator(); 175 176 while (it.hasNext()) { 177 String name = (String ) it.next(); 178 179 if (name.startsWith(f) || (f.trim().length() == 0)) { 180 int i = name.indexOf('/', f.length()); 181 String child = null; 182 183 if (i > 0) { 184 child = name.substring(f.length(), i); 185 } else { 186 child = name.substring(f.length()); 187 } 188 189 if (child.trim().length() > 0) { 190 l.add(child); 191 } 192 } 193 } 194 195 return l.toArray(new String [0]); 196 } 197 } 198 199 public void createData(String name) throws IOException { 200 if (isValidEntry(name, Boolean.FALSE)) { 201 StringBuffer message = new StringBuffer (); 202 message.append("File already exists: ").append(name); 203 throw new IOException (message.toString()); } 205 206 getOrCreateEntry(name).data = new byte[0]; 207 } 208 209 public void createFolder(String name) throws java.io.IOException { 210 if (isValidEntry(name, Boolean.FALSE)) { 211 StringBuffer message = new StringBuffer (); 212 message.append("Folder already exists: ").append(name); 213 throw new IOException (message.toString()); } 215 216 getOrCreateEntry(name).data = null; 217 } 218 219 public void delete(String name) throws IOException { 220 if (entries.remove(name) == null) { 221 throw new IOException ("No file to delete: " + name); } 223 } 224 225 public void deleteAttributes(String name) { 226 } 227 228 public boolean folder(String name) { 229 return getOrCreateEntry(name).data == null; 230 } 231 232 public InputStream inputStream(String name) throws java.io.FileNotFoundException { 233 byte[] arr = getOrCreateEntry(name).data; 234 235 if (arr == null) { 236 arr = new byte[0]; 237 } 238 239 return new ByteArrayInputStream (arr); 240 } 241 242 public java.util.Date lastModified(String name) { 243 java.util.Date d = getOrCreateEntry(name).last; 244 245 return (d == null) ? created : d; 246 } 247 248 public void lock(String name) throws IOException { 249 } 250 251 public void markUnimportant(String name) { 252 } 253 254 public String mimeType(String name) { 255 return (String ) getOrCreateEntry(name).attrs.get("mimeType"); 256 } 257 258 public OutputStream outputStream(final String name) 259 throws java.io.IOException { 260 class Out extends ByteArrayOutputStream { 261 public void close() throws IOException { 262 super.close(); 263 264 getOrCreateEntry(name).data = toByteArray(); 265 getOrCreateEntry(name).last = new Date (); 266 } 267 } 268 269 return new Out(); 270 } 271 272 public Object readAttribute(String name, String attrName) { 273 return isValidEntry(name) ? getOrCreateEntry(name).attrs.get(attrName) : null; 274 } 275 276 public boolean readOnly(String name) { 277 return false; 278 } 279 280 public void rename(String oldName, String newName) 281 throws IOException { 282 if (!isValidEntry(oldName)) { 283 throw new IOException ("The file to rename does not exist."); 284 } 285 286 if (isValidEntry(newName)) { 287 throw new IOException ("Cannot rename to existing file"); 288 } 289 290 if ((newName.length() > 0) && (newName.charAt(0) == '/')) { 291 newName = newName.substring(1); 292 } 293 294 Entry e = getOrCreateEntry(oldName); 295 entries.remove(oldName); 296 entries.put(newName, e); 297 } 298 299 public void renameAttributes(String oldName, String newName) { 300 } 301 302 public long size(String name) { 303 byte[] d = getOrCreateEntry(name).data; 304 305 return (d == null) ? 0 : d.length; 306 } 307 308 public void unlock(String name) { 309 } 310 311 public void writeAttribute(String name, String attrName, Object value) 312 throws IOException { 313 getOrCreateEntry(name).attrs.put(attrName, value); 314 } 315 316 private Map <String , Entry> initEntry() { 317 if (!ERR.isLoggable(Level.FINE)) { 318 return new ConcurrentHashMap <String , MemoryFileSystem.Entry>(); 319 } 320 321 return new ConcurrentHashMap <String , MemoryFileSystem.Entry>() { 322 public MemoryFileSystem.Entry get(String key) { 323 MemoryFileSystem.Entry retval = super.get(key); 324 logMessage("called: GET" + " key: "+key + " result: " + retval); return retval; 326 } 327 328 public MemoryFileSystem.Entry put(String key, MemoryFileSystem.Entry value) { 329 MemoryFileSystem.Entry retval = super.put(key, value); 330 logMessage("called: PUT" + " key: "+key + " value: "+value+ " result: " + retval); return retval; 332 } 333 334 public MemoryFileSystem.Entry remove(String key) { 335 MemoryFileSystem.Entry retval = super.remove(key); 336 logMessage("called: REMOVE" + " key: "+key + " result: " + retval); return retval; 338 } 339 }; 340 } 341 342 static final class Entry { 343 344 public Map <String , Object > attrs = new HashMap <String , Object >(); 345 public byte[] data; 346 public java.util.Date last; 347 private final String entryName; 348 349 Entry(String entryName) { 350 this.entryName = entryName; 351 } 352 353 354 public String toString() { 355 StringBuffer sb = new StringBuffer (); 356 sb.append(" [").append(entryName); sb.append(" -> ").append(super.toString()); sb.append("] "); 359 return sb.toString(); 360 } 361 } 362 363 364 private static void logMessage(final String message) { 365 StringBuffer sb = new StringBuffer (); 366 sb.append(" -> ").append(message); 367 368 375 ERR.fine(sb.toString()); 376 } 377 378 } 379 | Popular Tags |