/*
   * @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;
   }
 }
Beispiel #7
0
 /**
  * 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]);
  }
Beispiel #10
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);
      }
    }
  }
Beispiel #11
0
 /** Shuts down this ContentManager. */
 public void stop() {
   shutdown = true;
   CACHE.writeToDisk();
 }
Beispiel #12
0
 /** Initializes this content manager. */
 public void start() {
   CACHE.initialize();
   startProcessingThread();
 }
Beispiel #13
0
 /** Gets a response if one exists. */
 public ContentResponseData getResponse(URN urn) {
   return CACHE.getResponse(urn);
 }
Beispiel #14
0
 /**
  * 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);
 }
Beispiel #15
0
 /** 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();
 }