gt:         ContentStore store = getStore();
context: /*
   * Copyright (C) 2005-2014 Alfresco Software Limited.
   *
   * This file is part of Alfresco
   *
   * Alfresco is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Lesser General Public License as published by
   * the Free Software Foundation, either version 3 of the License, or
   * (at your option) any later version.
   *
   * Alfresco is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public License
   * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
   */
  package org.alfresco.repo.content;
  
  import java.nio.ByteBuffer;
  import java.nio.channels.FileChannel;
  import java.nio.channels.ReadableByteChannel;
  import java.util.HashSet;
  import java.util.Set;
  
  import javax.transaction.UserTransaction;
  
  import org.alfresco.repo.content.ContentStore.ContentUrlHandler;
  import org.alfresco.service.cmr.repository.ContentReader;
  import org.alfresco.service.transaction.TransactionService;
  import org.alfresco.util.ApplicationContextHelper;
  import org.alfresco.util.BaseApplicationContextHelper;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.junit.After;
  import org.junit.Before;
  import org.junit.BeforeClass;
  import org.junit.Rule;
  import org.junit.Test;
  import org.junit.rules.TestName;
  import org.springframework.context.ApplicationContext;
  
  import static org.junit.Assert.assertFalse;
  import static org.junit.Assert.assertNotNull;
  import static org.junit.Assert.assertTrue;
  import static org.junit.Assert.fail;
  
  /**
   * Abstract base class that provides a set of tests for implementations
   * of {@link ContentStore}.
   * 
   * @see ContentStore
   * @see org.alfresco.service.cmr.repository.ContentReader
   * @see org.alfresco.service.cmr.repository.ContentWriter
   * 
   * @author sglover
   * @author Derek Hulley
   */
  public abstract class AbstractReadOnlyContentStoreTest
  {
  	protected static ApplicationContext ctx;
  
      private static Log logger = LogFactory.getLog(AbstractReadOnlyContentStoreTest.class);
  
  	@Rule public TestName name = new TestName();
  
  	protected String getName()
  	{
  		return name.getMethodName();
  	}
  
      protected TransactionService transactionService;
      private UserTransaction txn;
      
      public AbstractReadOnlyContentStoreTest()
      {
          super();
      }
  
      @BeforeClass
      public static void beforeClass() throws Exception
      {
      	ctx = BaseApplicationContextHelper.getApplicationContext(ApplicationContextHelper.CONFIG_LOCATIONS);
      }
  
      /**
       * Starts a transaction
       */
      @Before
      public void before() throws Exception
      {
          transactionService = (TransactionService) ctx.getBean("TransactionService");
          txn = transactionService.getUserTransaction();
          txn.begin();
      }
      
      /**
       * Rolls back the transaction
       */
      @After
      public void after() throws Exception
      {
          try { txn.rollback(); } catch (Throwable e) {e.printStackTrace();}
      }
      
      /**
       * Fetch the store to be used during a test.  This method is invoked once per test - it is
       * therefore safe to use <code>setUp</code> to initialise resources.
       * <p>
       * Usually tests will construct a static instance of the store to use throughout all the
       * tests.
       * 
       * @return Returns the <b>same instance</b> of a store for all invocations.
       */
      protected abstract ContentStore getStore();
      
      /**
       * Gets a reader for the given content URL from the store
       * 
       * @see #getStore()
       */
      protected final ContentReader getReader(String contentUrl)
      {
          return getStore().getReader(contentUrl);
      }
      
      /**
       * Fetch a valid URL from the store.  The default implementation will attempt to get
       * all the available URLs from the store and pick the first one.  Writable store tests
       * can create some content to be sure of its existence.
       * 
       * @return
       *      Return any valid URL for the store, or <tt>null</tt> if the store is empty.
       */
      @SuppressWarnings("deprecation")
      protected String getExistingContentUrl()
      {
          ContentStore store = getStore();
          try
          {
              final Set<String> contentUrls = new HashSet<String>(5);
              ContentUrlHandler handler = new ContentUrlHandler()
              {
                  public void handle(String contentUrl)
                  {
                      if (contentUrls.size() < 50)
                      {
                          contentUrls.add(contentUrl);
                      }
                  }
              };
              store.getUrls(handler);
              if (contentUrls.size() > 0)
              {
                  return (String) contentUrls.toArray()[0];
              }
              else
              {
                  // We can't do anything with this
                  return null;
              }
          }
          catch (UnsupportedOperationException e)
          {
              // The store doesn't support this
              return null;
          }
      }
      
      @Test
      public void testSetUp() throws Exception
      {
          // check that the store remains the same
          ContentStore store = getStore();
          assertNotNull("No store provided", store);
          assertTrue("The same instance of the store must be returned for getStore", store == getStore());
      }
  
      /**
       * Helper to ensure that illegal content URLs are flagged for
       * <b>getReader()</b> and <b>exists()</b> requests.
       */
      private void checkIllegalReadContentUrl(ContentStore store, String contentUrl)
      {
          assertFalse("This check is for unsupported content URLs only", store.isContentUrlSupported(contentUrl));
          try
          {
              store.getReader(contentUrl);
              fail("Expected UnsupportedContentUrlException for getReader(), but got nothing: " + contentUrl);
          }
          catch (UnsupportedContentUrlException e)
          {
              // Expected
          }
          try
          {
              store.exists(contentUrl);
              fail("Expected UnsupportedContentUrlException for exists(), but got nothing: " + contentUrl);
          }
          catch (UnsupportedContentUrlException e)
          {
              // Expected
          }
      }
      
      /**
       * Checks that the error handling for <i>inappropriate</i> content URLs
       */
      @Test
      public void testIllegalReadableContentUrls()
      {
          ContentStore store = getStore();
          checkIllegalReadContentUrl(store, "://bogus");
          checkIllegalReadContentUrl(store, "bogus://");
          checkIllegalReadContentUrl(store, "bogus://bogus");
      }
      
      /**
       * Checks that the various methods of obtaining a reader are supported.
       */
      @Test
      public void testGetReaderForExistingContentUrl() throws Exception
      {
          ContentStore store = getStore();
          String contentUrl = getExistingContentUrl();
          if (contentUrl == null)
          {
              logger.warn("Store test testGetReaderForExistingContentUrl not possible on " + store.getClass().getName());
              return;
          }
          // Get the reader
          assertTrue("URL returned in set seems to no longer exist", store.exists(contentUrl));
          ContentReader reader = store.getReader(contentUrl);
          assertNotNull("Reader should never be null", reader);
          assertTrue("Reader says content doesn't exist", reader.exists());
          assertFalse("Reader should not be closed before a read", reader.isClosed());
          assertFalse("The reader channel should not be open yet", reader.isChannelOpen());
          
          // Open the channel
          ReadableByteChannel readChannel = reader.getReadableChannel();
          readChannel.read(ByteBuffer.wrap(new byte[500]));
          assertFalse("Reader should not be closed during a read", reader.isClosed());
          assertTrue("The reader channel should be open during a read", reader.isChannelOpen());
          
          // Close the channel
          readChannel.close();
          assertTrue("Reader should be closed after a read", reader.isClosed());
          assertFalse("The reader channel should be closed after a read", reader.isChannelOpen());
      }
      
      /**
       * Tests random access reading
       * <p>
       * Only executes if the reader implements {@link RandomAccessContent}.
       */
      @Test
      public void testRandomAccessRead() throws Exception
      {
  