/* * @see org.alfresco.repo.content.ContentStore#delete(java.lang.String) */ @Override public boolean delete(String contentUrl) { ReentrantReadWriteLock readWriteLock = readWriteLock(contentUrl); ReadLock readLock = readWriteLock.readLock(); readLock.lock(); try { if (!cache.contains(contentUrl)) { // The item isn't in the cache, so simply delete from the backing store return backingStore.delete(contentUrl); } } finally { readLock.unlock(); } WriteLock writeLock = readWriteLock.writeLock(); writeLock.lock(); try { // Double check the content still exists in the cache if (cache.contains(contentUrl)) { // The item is in the cache, so remove. cache.remove(contentUrl); } // Whether the item was in the cache or not, it must still be deleted from the backing store. return backingStore.delete(contentUrl); } finally { writeLock.unlock(); } }
private ContentReader attemptCacheAndRead(String url) { ContentReader reader = null; try { if (!cache.contains(url)) { if (cache.put(url, backingStore.getReader(url))) { reader = cache.getReader(url); } } else { reader = cache.getReader(url); } } catch (CacheMissException e) { cache.remove(url); } return reader; }
/* * @see org.alfresco.repo.content.ContentStore#getWriter(org.alfresco.repo.content.ContentContext) */ @Override public ContentWriter getWriter(final ContentContext context) { if (cacheOnInbound) { final ContentWriter bsWriter = backingStore.getWriter(context); // write to cache final ContentWriter cacheWriter = cache.getWriter(bsWriter.getContentUrl()); cacheWriter.addListener( new ContentStreamListener() { @Override public void contentStreamClosed() throws ContentIOException { // Finished writing to the cache, so copy to the backing store - // ensuring that the encoding attributes are set to the same as for the cache writer. bsWriter.setEncoding(cacheWriter.getEncoding()); bsWriter.setLocale(cacheWriter.getLocale()); bsWriter.setMimetype(cacheWriter.getMimetype()); bsWriter.putContent(cacheWriter.getReader()); } }); return cacheWriter; } else { // No need to invalidate the cache for this content URL, since a content URL // is only ever written to once. return backingStore.getWriter(context); } }
public void ensureFileCacheSynchedFor(Integer changesetNumber, String changesetIdentifier) { if (contentCache.isCached(changesetNumber)) { return; } Map<String, String> baseContent; if (changesetNumber.equals(0)) { baseContent = new HashMap<String, String>(); } else { baseContent = contentCache.readFor(changesetNumber - 1); } if (changesetIdentifier == null) { changesetIdentifier = hgClient.logForRev(String.valueOf(changesetNumber)).getIdentifier(); } contentBuilder.buildContent(changesetIdentifier, baseContent); contentCache.writeFor(changesetNumber, baseContent); }
/* * @see org.alfresco.repo.content.ContentStore#getReader(java.lang.String) */ @Override public ContentReader getReader(String contentUrl) { // Use pool of locks - which one is determined by a hash of the URL. // This will stop the content from being read/cached multiple times from the backing store // when it should only be read once - cached versions should be returned after that. ReadLock readLock = readWriteLock(contentUrl).readLock(); readLock.lock(); try { if (cache.contains(contentUrl)) { return cache.getReader(contentUrl); } } catch (CacheMissException e) { // Fall through to cacheAndRead(url); } finally { readLock.unlock(); } return cacheAndRead(contentUrl); }
public Node node(String path, Integer changesetNumber, String changesetIdentifier) { Map<String, String> rawContent = contentCache.readFor(changesetNumber); if (!path.equals("") && rawContent.containsKey(path)) { return new FileNode(this, path, changesetNumber, changesetIdentifier, rawContent.get(path)); } else { DirNode dirNode = new DirNode(this, path, changesetNumber, changesetIdentifier, rawContent.get(path) + "/"); dirNode.setChildren(childNodesFor(dirNode, rawContent)); return dirNode; } }
/** * Determines if the given URN is valid. * * @param urn * @param observer * @param timeout */ public void request(URN urn, ContentResponseObserver observer, long timeout) { ContentResponseData response = CACHE.getResponse(urn); if (response != null || !ContentSettings.isManagementActive()) { if (LOG.isDebugEnabled()) LOG.debug("Immediate response for URN: " + urn + ", response: " + response); observer.handleResponse(urn, response); } else { if (LOG.isDebugEnabled()) LOG.debug("Scheduling request for URN: " + urn); scheduleRequest(urn, observer, timeout); } }
public Node tipNode(String path, Integer likelyTipNumber, String likelyTipIdentifier) { for (int i = likelyTipNumber; i >= 1; i--) { if (contentCache.isCached(i)) { if (likelyTipNumber.equals(i)) { return node(path, likelyTipNumber, likelyTipIdentifier); } else { HgLogEntry logEntry = hgClient.logForRev(String.valueOf(i)); return node(path, logEntry.getRevNumber(), logEntry.getIdentifier()); } } } HgLogEntry entry0 = hgClient.logForRev("0"); ensureFileCacheSynchedFor(0, entry0.getIdentifier()); return node(path, 0, entry0.getIdentifier()); }
public Node[] childNodesFor(DirNode dirNode, Map<String, String> rawChangesetContent) { if (rawChangesetContent == null) { rawChangesetContent = contentCache.readFor(dirNode.changesetNumber()); } List<Node> children = new ArrayList<Node>(); String dirPath = dirNode.isRootNode() ? "" : dirNode.path() + "/"; List<String> paths = new ArrayList<String>(rawChangesetContent.keySet()); Collections.sort(paths); String lastAddedChildPath = ""; for (String path : paths) { if (path.indexOf(lastAddedChildPath + "/") != 0) { if (path.indexOf(dirPath) == 0 && path.length() > dirPath.length() && !path.equals("/")) { if (path.endsWith("/")) { lastAddedChildPath = path.substring(0, path.length() - 1); children.add( new DirNode( this, path.substring(0, path.length() - 1), dirNode.changesetNumber(), dirNode.changesetIdentifier(), rawChangesetContent.get(path))); } else { lastAddedChildPath = path; children.add( new FileNode( this, path, dirNode.changesetNumber(), dirNode.changesetIdentifier(), rawChangesetContent.get(path))); } } } } return children.toArray(new Node[0]); }
/** Notification that a ContentResponse was given. */ public void handleContentResponse(ContentResponse responseMsg) { URN urn = responseMsg.getURN(); // Only process if we requested this msg. // (Don't allow arbitrary responses to be processed) if (urn != null && REQUESTED.remove(urn)) { ContentResponseData response = new ContentResponseData(responseMsg); CACHE.addResponse(urn, response); if (LOG.isDebugEnabled()) LOG.debug("Adding response (" + response + ") for URN: " + urn); Collection<Responder> responders = OBSERVERS.remove(urn); if (responders != null) { removeResponders(responders); for (Responder next : responders) next.observer.handleResponse(next.urn, response); } } else if (LOG.isWarnEnabled()) { if (urn == null) { LOG.debug("No URN in response: " + responseMsg); } else { LOG.debug("Didn't request URN: " + urn + ", msg: " + responseMsg); } } }
/** Shuts down this ContentManager. */ public void stop() { shutdown = true; CACHE.writeToDisk(); }
/** Initializes this content manager. */ public void start() { CACHE.initialize(); startProcessingThread(); }
/** Gets a response if one exists. */ public ContentResponseData getResponse(URN urn) { return CACHE.getResponse(urn); }
/** * Determines if we've already tried sending a request & waited the time for a response for the * given URN. */ public boolean isVerified(URN urn) { return !ContentSettings.isManagementActive() || CACHE.hasResponseFor(urn) || TIMEOUTS.contains(urn); }
/** Gets the number of items in the cache. */ public int getCacheSize() { return CACHE.getSize(); }
public boolean isCached(Integer revisionNumber) { return contentCache.isCached(revisionNumber); }
public Map<String, String> rawFileCacheContent(Integer revisionNumber) { return contentCache.readFor(revisionNumber); }
public void cleanUpObsoleteCacheFiles() { contentCache.cleanUpObsoleteCacheFiles(); }