1 11 package org.eclipse.core.internal.properties; 12 13 import java.util.*; 14 import org.eclipse.core.internal.indexing.IndexCursor; 15 import org.eclipse.core.internal.indexing.ObjectID; 16 import org.eclipse.core.internal.resources.CompatibilityMessages; 17 import org.eclipse.core.internal.resources.ResourceException; 18 import org.eclipse.core.resources.IResource; 19 import org.eclipse.core.resources.IResourceStatus; 20 import org.eclipse.core.runtime.*; 21 import org.eclipse.osgi.util.NLS; 22 23 26 public class PropertyStore { 27 28 protected IndexedStoreWrapper store = null; 30 31 public static final int CREATE = 0; public static final int UPDATE = 1; public static final int SET_UPDATE = 2; public static final int SET_SKIP = 3; 37 public static final int IGNORE_MISSING = 0; 39 public static final int FAIL_MISSING = 1; 40 41 public PropertyStore(IPath location) { 42 store = new IndexedStoreWrapper(location); 43 } 44 45 protected boolean basicExists(StoreKey searchKey) throws CoreException { 46 byte[] searchBytes = searchKey.toBytes(); 47 IndexCursor cursor = store.getCursor(); 48 try { 49 cursor.find(searchBytes); 50 boolean exists = cursor.keyEquals(searchBytes); 51 cursor.close(); 52 return exists; 53 } catch (Exception e) { 54 String message = NLS.bind(CompatibilityMessages.properties_couldNotReadProp, searchKey.getQualifier(), searchKey.getLocalName()); 55 throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, searchKey.getResourceName().getPath(), message, e); 56 } 57 } 58 59 63 protected void basicInsert(StoreKey key, String value) throws CoreException { 64 try { 65 ObjectID valueID = store.createObject(value); 66 store.getIndex().insert(key.toBytes(), valueID); 67 } catch (Exception e) { 68 String message = NLS.bind(CompatibilityMessages.properties_couldNotWriteProp, key.getQualifier(), key.getLocalName()); 69 throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, key.getResourceName().getPath(), message, e); 70 } 71 } 72 73 protected boolean basicRemove(ResourceName resourceName, QualifiedName propertyName) throws CoreException { 74 StoreKey key = new StoreKey(resourceName, propertyName); 75 byte[] keyBytes = key.toBytes(); 76 boolean wasFound = false; 77 IndexCursor cursor = store.getCursor(); 78 try { 79 cursor.find(keyBytes); 80 if (cursor.keyEquals(keyBytes)) { 81 wasFound = true; 82 ObjectID valueID = cursor.getValueAsObjectID(); 83 store.removeObject(valueID); 84 cursor.remove(); 85 } 86 cursor.close(); 87 } catch (Exception e) { 88 String message = NLS.bind(CompatibilityMessages.properties_couldNotDeleteProp, key.getQualifier(), key.getLocalName()); 89 throw new ResourceException(IResourceStatus.FAILED_DELETE_LOCAL, resourceName.getPath(), message, e); 90 } 91 return wasFound; 92 } 93 94 protected void basicUpdate(StoreKey key, String value) throws CoreException { 95 byte[] keyBytes = key.toBytes(); 96 IndexCursor cursor = store.getCursor(); 97 try { 98 cursor.find(keyBytes); 99 if (cursor.keyEquals(keyBytes)) { 100 ObjectID oldID = cursor.getValueAsObjectID(); 101 store.removeObject(oldID); 102 ObjectID newValueId = store.createObject(value); 103 cursor.updateValue(newValueId); 104 } 105 cursor.close(); 106 } catch (Exception e) { 107 String message = NLS.bind(CompatibilityMessages.properties_couldNotWriteProp, key.getQualifier(), key.getLocalName()); 108 throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, key.getResourceName().getPath(), message, e); 109 } 110 } 111 112 protected synchronized void commonSet(ResourceName resourceName, StoredProperty[] properties, int depth, int setMode, QueryResults failures) throws CoreException { 113 if (depth == IResource.DEPTH_ZERO) { 114 for (int i = 0; i < properties.length; i++) { 115 StoredProperty property = properties[i]; 116 StoreKey key = new StoreKey(resourceName, property.getName()); 117 boolean exists = basicExists(key); 118 if ((exists && (setMode == CREATE)) || (!exists && (setMode == UPDATE))) 119 failures.add(resourceName, property); 120 else if (exists && (setMode != SET_SKIP)) 121 basicUpdate(key, property.getStringValue()); 122 else 123 basicInsert(key, property.getStringValue()); 124 } 125 } else { 126 Enumeration resourceNamesEnum = deepResourceNames(resourceName); 127 while (resourceNamesEnum.hasMoreElements()) 128 commonSet((ResourceName) resourceNamesEnum.nextElement(), properties, IResource.DEPTH_ZERO, setMode, failures); 129 } 130 } 131 132 144 public Enumeration deepResourceNames(ResourceName resourceName) throws CoreException { 145 final Set resultHolder = new HashSet(10); 146 IVisitor visitor = new IVisitor() { 147 public void visit(ResourceName resourceName, StoredProperty property, IndexCursor cursor) { 148 resultHolder.add(resourceName); 149 } 150 151 public boolean requiresValue(ResourceName resourceName, QualifiedName propertyName) { 152 return false; 153 } 154 }; 155 recordsDeepMatching(resourceName, visitor); 156 return Collections.enumeration(resultHolder); 157 } 158 159 169 public StoredProperty get(ResourceName resourceName, final QualifiedName propertyName) throws CoreException { 170 final Object [] resultHolder = new Object [1]; 171 IVisitor simpleVisitor = new IVisitor() { 172 public void visit(ResourceName resourceName, StoredProperty property, IndexCursor cursor) { 173 resultHolder[0] = property; 174 } 175 176 public boolean requiresValue(ResourceName resourceName, QualifiedName propertyName) { 177 return true; 178 } 179 }; 180 recordsMatching(resourceName, propertyName, simpleVisitor); 181 return (StoredProperty) resultHolder[0]; 182 } 183 184 197 public QueryResults getAll(ResourceName resourceName, int depth) throws CoreException { 198 final QueryResults result = new QueryResults(); 199 IVisitor visitor = new IVisitor() { 200 public void visit(ResourceName resourceName, StoredProperty property, IndexCursor cursor) { 201 result.add(resourceName, property); 202 } 203 204 public boolean requiresValue(ResourceName resourceName, QualifiedName propertyName) { 205 return true; 206 } 207 }; 208 if (depth == IResource.DEPTH_ZERO) 209 recordsMatching(resourceName, visitor); 210 else 211 recordsDeepMatching(resourceName, visitor); 212 return result; 213 } 214 215 228 public QueryResults getNames(ResourceName resourceName, int depth) throws CoreException { 229 QueryResults results = new QueryResults(); 230 if (depth == IResource.DEPTH_ZERO) 231 recordsMatching(resourceName, propertyNameVisitor(results)); 232 else 233 recordsDeepMatching(resourceName, propertyNameVisitor(results)); 234 return results; 235 } 236 237 241 public boolean isRunning() { 242 return store != null; 243 } 244 245 protected IVisitor propertyNameVisitor(final QueryResults results) { 246 return new IVisitor() { 247 public void visit(ResourceName resourceName, StoredProperty property, IndexCursor cursor) { 248 results.add(resourceName, property.getName()); 249 } 250 251 public boolean requiresValue(ResourceName resourceName, QualifiedName propertyName) { 252 return false; 253 } 254 }; 255 } 256 257 260 protected void recordsDeepMatching(ResourceName resourceName, IVisitor visitor) throws CoreException { 261 262 StoreKey searchKey = new StoreKey(resourceName, true); 264 byte[] searchBytes = searchKey.toBytes(); 265 int probe = searchBytes.length; 266 IndexCursor cursor = store.getCursor(); 268 try { 269 cursor.find(searchBytes); 270 271 while (cursor.keyMatches(searchBytes)) { 273 byte[] matchingBytes = cursor.getKey(); 277 if (probe == 1 || (matchingBytes[probe] == 0) || (matchingBytes[probe] == 47 )) { 280 visitPropertyAt(cursor, visitor); 282 } 283 cursor.next(); 285 } 286 cursor.close(); 287 } catch (Exception e) { 288 throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, resourceName.getPath(), CompatibilityMessages.properties_storeProblem, e); 289 } 290 } 291 292 295 protected void recordsMatching(ResourceName resourceName, IVisitor visitor) throws CoreException { 296 297 StoreKey searchKey = new StoreKey(resourceName, false); 299 byte[] searchBytes = searchKey.toBytes(); 300 IndexCursor cursor = store.getCursor(); 302 try { 303 cursor.find(searchBytes); 304 305 while (cursor.keyMatches(searchBytes)) { 307 visitPropertyAt(cursor, visitor); 308 cursor.next(); 309 } 310 cursor.close(); 311 } catch (Exception e) { 312 store.reset(); 313 throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, resourceName.getPath(), CompatibilityMessages.properties_storeProblem, e); 314 } 315 } 316 317 321 protected void recordsMatching(ResourceName resourceName, QualifiedName propertyName, IVisitor visitor) throws CoreException { 322 323 StoreKey searchKey = new StoreKey(resourceName, propertyName); 325 byte[] searchBytes = searchKey.toBytes(); 326 IndexCursor cursor = store.getCursor(); 328 try { 329 cursor.find(searchBytes); 330 331 if (cursor.keyEquals(searchBytes)) 333 visitPropertyAt(cursor, visitor); 334 cursor.close(); 335 } catch (Exception e) { 336 store.reset(); 337 throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, resourceName.getPath(), CompatibilityMessages.properties_storeProblem, e); 338 } 339 } 340 341 362 public QueryResults remove(ResourceName resourceName, QualifiedName[] propertyNames, int depth, int removeRule) throws CoreException { 363 QueryResults failures = new QueryResults(); 364 if (depth == IResource.DEPTH_ZERO) { 365 for (int i = 0; i < propertyNames.length; i++) { 366 boolean found = basicRemove(resourceName, propertyNames[i]); 367 if (!found && (removeRule == FAIL_MISSING)) 368 failures.add(resourceName, propertyNames[i]); 369 } 370 } else { 371 Enumeration resourceNamesEnum = deepResourceNames(resourceName); 372 while (resourceNamesEnum.hasMoreElements()) { 373 ResourceName resName = (ResourceName) resourceNamesEnum.nextElement(); 374 for (int i = 0; i < propertyNames.length; i++) { 375 boolean found = basicRemove(resName, propertyNames[i]); 376 if (!found && (removeRule == FAIL_MISSING)) 377 failures.add(resName, propertyNames[i]); 378 } 379 } 380 } 381 return failures; 382 } 383 384 394 public void remove(ResourceName resourceName, QualifiedName propertyName) throws CoreException { 395 remove(resourceName, new QualifiedName[] {propertyName}, IResource.DEPTH_ZERO, IGNORE_MISSING); 396 } 397 398 406 public void removeAll(ResourceName resourceName, int depth) throws CoreException { 407 QueryResults namesSearch = getNames(resourceName, depth); 408 Enumeration resourceNamesEnum = namesSearch.getResourceNames(); 409 while (resourceNamesEnum.hasMoreElements()) { 410 ResourceName resName = (ResourceName) resourceNamesEnum.nextElement(); 411 Enumeration propertyNamesEnum = Collections.enumeration(namesSearch.getResults(resName)); 412 while (propertyNamesEnum.hasMoreElements()) { 413 QualifiedName propertyName = (QualifiedName) propertyNamesEnum.nextElement(); 414 basicRemove(resName, propertyName); 415 } 416 } 417 } 418 419 439 public QueryResults set(ResourceName resourceName, StoredProperty[] properties, int depth, int mode) throws CoreException { 440 QueryResults failures = new QueryResults(); 441 commonSet(resourceName, properties, depth, mode, failures); 442 return failures; 443 } 444 445 455 public void set(ResourceName resourceName, StoredProperty property) throws CoreException { 456 commonSet(resourceName, new StoredProperty[] {property}, IResource.DEPTH_ZERO, SET_UPDATE, null); 457 } 458 459 public void shutdown(IProgressMonitor monitor) { 460 if (store == null) 461 return; 462 try { 463 store.close(); 464 } finally { 465 store = null; 467 } 468 } 469 470 public void startup(IProgressMonitor monitor) { 471 } 473 474 protected void visitPropertyAt(IndexCursor cursor, IVisitor visitor) throws CoreException { 475 try { 476 StoreKey key = new StoreKey(cursor.getKey()); 477 ResourceName resourceName = key.getResourceName(); 478 QualifiedName propertyName = key.getPropertyName(); 479 String propertyValue = null; 480 if (visitor.requiresValue(resourceName, propertyName)) 481 propertyValue = store.getObjectAsString(cursor.getValueAsObjectID()); 482 visitor.visit(resourceName, new StoredProperty(propertyName, propertyValue), cursor); 483 } catch (Exception e) { 484 throw new ResourceException(IResourceStatus.FAILED_READ_LOCAL, null, CompatibilityMessages.properties_storeProblem, e); 485 } 486 } 487 488 public void commit() throws CoreException { 489 store.commit(); 490 } 491 } 492 | Popular Tags |