| View Changeset
/hippo
Jump to revision: Previous Next
Author: wgrevink
Date: Thu Feb 1 10:57:07 2007 UTC (13 years, 5 months ago)
Log Message:
WCL-1

Implemented correct caching for the fetchDocumentById(), fetchMetadataById() and fetchContentById() methods in the WebdavService.

This implementation is much simpler than the proposed implementation using a dedicated ID cache with references to the 'real' cache.
The problem with that solution is that it introduces a new level of complexity (two tightly coupled cache instances) that can 
potentially be the source of a whole new category of bugs and instability. Even if the two caches are based on the same instance, it 
remains that a new and potentially problematic concept -'reference to a cache entry in a cache entry'- is introduced.

This implementation reuses existing concepts and is based on the following two observations:
1)A fetch..ById() method in the WebdavService allways binds the result of the inbuilt find-by-id dasl in order to retrieve the 
DocumentPath to the Document to be fetched. This means that we DO have the DocumentPath at our disposal during the execute of 
a fetch..ById() method.
2)We have the NOPCachingService at our disposal which enables us to do anything without the real cache knowing about it.

To cut a long story short, here's the code:

	public Document fetchDocumentById(String documentId) throws ClientException {
		assertDocumentIdIsEnabled();
		
		WebdavCacheKey key = new WebdavCacheKey(config, documentId, "ID-DOCUMENT");
		Object result = cache.get(key);
		if (result == null) {
			CachingService nullCache = new NOPCachingService();
			DocumentPath path = documentFactory.resolvePath(nullCache, documentId);
			if (path != null) {
				result = documentFactory.fetchDocument(nullCache, path);
				store(cache, key, result, path);
			}
		}
		return (Document) result;
	}

	private void store(CachingService cache, WebdavCacheKey key, Object object, DocumentPath path) throws ClientException {
		if (object == null) {
			return;
		}
		try {
			EventValidity eventValidity = new EventValidityImpl(path.getDocumentPath());
			CachedResponse cr = new CachedResponseImpl(eventValidity, object);
			cache.store(key, cr);
		} catch (IOException e) {
			throw new ClientException("Exception while caching the response", e);
		}
	}

The JMSEventCacheTest contains some tests to verify that this actually does what we want: Te cache entry is evicted only on a change event 
on the Document itself: testFindDocumentById(), testFindMetadataById() and testFindContentById()


Some more refactorings:
*) Removed getPath() method from interface CacheKey, it is webdav-eventcaching specific and doesn't belong in this general interface. 
   It's webdav-clientlib implementation (WebdavCacheKey) still has it and it is only used inside this lib.
*) Split up huge method in BindingFactory into several smaller methods: no functional change, just cleaning up.
*) Fixed compilation error in JMSEventCacheTest that was introduced by yesterday's change in constructing a JCSDefaultCache()

Changed paths