You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ja...@apache.org on 2013/10/10 15:58:03 UTC

svn commit: r1530981 - in /ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl: RepositoryFactory.java RepositoryImpl.java

Author: jawi
Date: Thu Oct 10 13:58:02 2013
New Revision: 1530981

URL: http://svn.apache.org/r1530981
Log:
Improved the readability/understandability of the code a bit.


Modified:
    ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryFactory.java
    ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryImpl.java

Modified: ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryFactory.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryFactory.java?rev=1530981&r1=1530980&r2=1530981&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryFactory.java (original)
+++ ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryFactory.java Thu Oct 10 13:58:02 2013
@@ -18,16 +18,23 @@
  */
 package org.apache.ace.repository.impl;
 
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_BASE_DIR;
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_CUSTOMER;
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_FILE_EXTENSION;
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_INITIAL_CONTENT;
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_LIMIT;
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_MASTER;
+import static org.apache.ace.repository.impl.constants.RepositoryConstants.REPOSITORY_NAME;
+
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 import org.apache.ace.repository.Repository;
 import org.apache.ace.repository.RepositoryReplication;
-import org.apache.ace.repository.impl.constants.RepositoryConstants;
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.BundleContext;
@@ -44,61 +51,43 @@ import org.osgi.service.prefs.Preference
  */
 public class RepositoryFactory implements ManagedServiceFactory {
 
-    private final Map<String, Component> m_instances = new HashMap<String, Component>();
+    private final ConcurrentMap<String, Component> m_instances = new ConcurrentHashMap<String, Component>();
     private final DependencyManager m_manager;
 
-    private volatile LogService m_log; /* injected by dependency manager */
-    private volatile BundleContext m_context; /* injected by dependency manager */
-    private volatile PreferencesService m_prefsService; /* injected by dependency manager */
+    /* injected by dependency manager */
+    private volatile LogService m_log;
+    private volatile BundleContext m_context;
+    private volatile PreferencesService m_prefsService;
 
     private File m_tempDir;
-    private File m_baseDir;
-    private Preferences m_prefs;
 
     public RepositoryFactory(DependencyManager manager) {
         m_manager = manager;
     }
 
-    @Override
-    public String getName() {
-        return "RepositoryFactory";
-    }
-
-    public synchronized void init() {
-        m_tempDir = m_context.getDataFile("tmp");
-        if ((m_tempDir != null) && !m_tempDir.isDirectory() && !m_tempDir.mkdirs()) {
-            throw new IllegalArgumentException("Unable to create temp directory (" + m_tempDir.getAbsolutePath() + ")");
-        }
-    }
-
-    public synchronized void deleted(String pid) {
-        // pull service
+    public void deleted(String pid) {
+        // remove repository service...
         Component service = m_instances.remove(pid);
         if (service != null) {
+            File repoDir = ((RepositoryImpl) service.getService()).getDir();
+
             m_manager.remove(service);
-        }
 
-        // remove persisted data
-        String name = (String) service.getServiceProperties().get(RepositoryConstants.REPOSITORY_NAME);
-        File dir = new File(m_baseDir, pid);
-        if (dir.isDirectory()) {
-            File[] files = dir.listFiles();
-            for (int i = 0; (files != null) && (i < files.length); i++) {
-                files[i].delete();
-            }
-            if (!dir.delete()) {
-                m_log.log(LogService.LOG_WARNING, "Unable to clean up files ( in " + dir.getAbsolutePath() + ") after removing repository");
-            }
-        }
-        try {
-            m_prefs.node(pid).removeNode();
-            m_prefs.sync();
-        }
-        catch (BackingStoreException e) {
-            // Not much we can do
+            // remove persisted data...
+            deleteRepositoryStore(pid, repoDir);
+            deleteRepositoryPrefs(pid);
         }
     }
 
+    @Override
+    public String getName() {
+        return "RepositoryFactory";
+    }
+
+    public void init() {
+        m_tempDir = ensureDirectoryAvailable(m_context.getDataFile("tmp"));
+    }
+
     /**
      * Creates a new instance if the supplied dictionary contains a valid configuration. A configuration is valid if
      * <code>RepositoryConstants.REPOSITORY_NAME</code> and <code>RepositoryConstants.REPOSITORY_CUSTOMER</code>
@@ -106,107 +95,168 @@ public class RepositoryFactory implement
      * instances. Finally a property <code>RepositoryConstants.REPOSITORY_MASTER</code> should be present and be either
      * <code>true</code> or <code>false</code>.
      * 
-     * @param pid A unique identifier for the instance, generated by <code>ConfigurationAdmin</code> normally.
-     * @param dict The configuration properties for the instance, see description above.
-     * @throws ConfigurationException If any of the above explanation fails <b>or</b>when there is an internal error
-     *             creating the repository.
+     * @param pid
+     *            A unique identifier for the instance, generated by <code>ConfigurationAdmin</code> normally.
+     * @param dict
+     *            The configuration properties for the instance, see description above.
+     * @throws ConfigurationException
+     *             If any of the above explanation fails <b>or</b>when there is an internal error creating the
+     *             repository.
      */
     @SuppressWarnings("unchecked")
-    public synchronized void updated(String pid, Dictionary dict) throws ConfigurationException {
-
-        String customer = (String) dict.get(RepositoryConstants.REPOSITORY_CUSTOMER);
+    public void updated(String pid, Dictionary dict) throws ConfigurationException {
+        String customer = (String) dict.get(REPOSITORY_CUSTOMER);
         if ((customer == null) || "".equals(customer)) {
-            throw new ConfigurationException(RepositoryConstants.REPOSITORY_CUSTOMER, "Repository customer has to be specified.");
+            throw new ConfigurationException(REPOSITORY_CUSTOMER, "Repository customer has to be specified.");
         }
 
-        String name = (String) dict.get(RepositoryConstants.REPOSITORY_NAME);
+        String name = (String) dict.get(REPOSITORY_NAME);
         if ((name == null) || "".equals(name)) {
-            throw new ConfigurationException(RepositoryConstants.REPOSITORY_NAME, "Repository name has to be specified.");
+            throw new ConfigurationException(REPOSITORY_NAME, "Repository name has to be specified.");
         }
 
-        String master = (String) dict.get(RepositoryConstants.REPOSITORY_MASTER);
+        String master = (String) dict.get(REPOSITORY_MASTER);
         if (!("false".equalsIgnoreCase(master.trim()) || "true".equalsIgnoreCase(master.trim()))) {
-            throw new ConfigurationException(RepositoryConstants.REPOSITORY_MASTER, "Have to specify whether the repository is the master or a slave.");
+            throw new ConfigurationException(REPOSITORY_MASTER, "Have to specify whether the repository is the master or a slave.");
         }
         boolean isMaster = Boolean.parseBoolean(master);
 
-        String fileExtension = (String) dict.get(RepositoryConstants.REPOSITORY_FILE_EXTENSION);
+        String fileExtension = (String) dict.get(REPOSITORY_FILE_EXTENSION);
         if ((fileExtension == null) || "".equals(fileExtension.trim())) {
             fileExtension = "";
         }
 
-        String baseDir = (String) dict.get(RepositoryConstants.REPOSITORY_BASE_DIR);
-        if (baseDir == null || baseDir.trim().length() == 0) {
-            m_baseDir = m_context.getDataFile("repos");
+        String baseDirName = (String) dict.get(REPOSITORY_BASE_DIR);
+        File baseDir;
+        if (baseDirName == null || "".equals(baseDirName.trim())) {
+            baseDir = m_context.getDataFile("repos");
         }
         else {
-            m_baseDir = new File(baseDir);
+            baseDir = new File(baseDirName);
         }
-        if ((m_baseDir != null) && !m_baseDir.isDirectory() && !m_baseDir.mkdirs()) {
-            throw new IllegalArgumentException("Unable to create base directory (" + m_baseDir.getAbsolutePath() + ")");
-        }
-        
-        String limit = (String) dict.get(RepositoryConstants.REPOSITORY_LIMIT);
+
+        String limit = (String) dict.get(REPOSITORY_LIMIT);
         long limitValue = Long.MAX_VALUE;
         if (limit != null) {
             try {
                 limitValue = Long.parseLong(limit);
             }
             catch (NumberFormatException nfe) {
-                throw new ConfigurationException(RepositoryConstants.REPOSITORY_LIMIT, "Limit has to be a number, was: " + limit);
+                throw new ConfigurationException(REPOSITORY_LIMIT, "Limit has to be a number, was: " + limit);
             }
             if (limitValue < 1) {
-                throw new ConfigurationException(RepositoryConstants.REPOSITORY_LIMIT, "Limit has to be at least 1, was " + limit);
+                throw new ConfigurationException(REPOSITORY_LIMIT, "Limit has to be at least 1, was " + limit);
             }
         }
 
-        String initialContents = (String) dict.get(RepositoryConstants.REPOSITORY_INITIAL_CONTENT);
-        if (m_prefs == null) {
-            m_prefs = m_prefsService.getSystemPreferences();
+        String initialContents = (String) dict.get(REPOSITORY_INITIAL_CONTENT);
+
+        Component service = m_manager.createComponent()
+            .setInterface(new String[] { RepositoryReplication.class.getName(), Repository.class.getName() }, dict)
+            .setImplementation(createRepositoryStore(pid, baseDir, isMaster, limitValue, fileExtension, initialContents))
+            .add(m_manager.createServiceDependency().setService(LogService.class).setRequired(false));
+
+        Component oldService = m_instances.putIfAbsent(pid, service);
+        if (oldService == null) {
+            // new instance...
+            createRepositoryPrefs(pid, customer, name);
+
+            m_manager.add(service);
         }
+        else {
+            // update existing instance...
+            RepositoryImpl store = (RepositoryImpl) oldService.getService();
+
+            // be a little pedantic about the ignored properties...
+            if (!baseDir.equals(store.getDir())) {
+                m_log.log(LogService.LOG_WARNING, "Cannot update base directory of repository from " + store.getDir() + " to " + baseDir);
+            }
+            if (!fileExtension.equals(store.getFileExtension())) {
+                m_log.log(LogService.LOG_WARNING, "Cannot update file extension of repository from " + store.getFileExtension() + " to " + fileExtension);
+            }
+
+            store.updated(isMaster, limitValue);
+        }
+    }
+
+    private void createRepositoryPrefs(String pid, String customer, String name) throws ConfigurationException {
+        Preferences systemPrefs = m_prefsService.getSystemPreferences();
 
         String[] nodes;
         try {
-            nodes = m_prefs.childrenNames();
+            nodes = systemPrefs.childrenNames();
         }
         catch (BackingStoreException e) {
-            throw new ConfigurationException("none", "Internal error while validating configuration.");
+            throw new ConfigurationException(null, "Internal error while validating configuration.");
         }
-        for (int i = 0; i < nodes.length; i++) {
-            Preferences node = m_prefs.node(nodes[i]);
-            if (name.equalsIgnoreCase(node.get(RepositoryConstants.REPOSITORY_NAME, "")) && name.equalsIgnoreCase(node.get(RepositoryConstants.REPOSITORY_CUSTOMER, ""))) {
-                throw new ConfigurationException("name and customer", "Name and customer combination already exists");
+        for (String nodeName : nodes) {
+            if (pid.equals(nodeName)) {
+                // avoid failing on our own node (in case we're updating)...
+                continue;
+            }
+
+            Preferences prefs = systemPrefs.node(nodeName);
+            String repoName = prefs.get(REPOSITORY_NAME, "");
+            String repoCustomer = prefs.get(REPOSITORY_CUSTOMER, "");
+
+            if (name.equalsIgnoreCase(repoName) && name.equalsIgnoreCase(repoCustomer)) {
+                throw new ConfigurationException(null, "Name and customer combination already exists");
             }
         }
 
-        Preferences node = m_prefs.node(pid);
-        node.put(RepositoryConstants.REPOSITORY_NAME, name);
-        node.put(RepositoryConstants.REPOSITORY_CUSTOMER, customer);
-
-        Component service = m_instances.get(pid);
-        if (service == null) {
-            // new instance
-            File dir = new File(m_baseDir, pid);
-            RepositoryImpl store = new RepositoryImpl(dir, m_tempDir, fileExtension, isMaster, limitValue);
-            if ((initialContents != null) && isMaster) {
-                try {
-                    store.commit(new ByteArrayInputStream(initialContents.getBytes()), 0);
-                }
-                catch (IOException e) {
-                    m_log.log(LogService.LOG_ERROR, "Unable to set initial contents of the repository.", e);
-                }
-            }
-            service = m_manager.createComponent()
-                .setInterface(new String[] { RepositoryReplication.class.getName(), Repository.class.getName() }, dict)
-                .setImplementation(store)
-                .add(m_manager.createServiceDependency().setService(LogService.class).setRequired(false));
-            m_manager.add(service);
-            m_instances.put(pid, service);
+        Preferences node = systemPrefs.node(pid);
+        node.put(REPOSITORY_NAME, name);
+        node.put(REPOSITORY_CUSTOMER, customer);
+    }
+
+    private RepositoryImpl createRepositoryStore(String pid, File baseDir, boolean isMaster, long limitValue, String fileExtension, String initialContents) {
+        File dir = ensureDirectoryAvailable(new File(baseDir, pid));
+        RepositoryImpl store = new RepositoryImpl(dir, m_tempDir, fileExtension, isMaster, limitValue);
+        if ((initialContents != null) && isMaster) {
+            try {
+                store.commit(new ByteArrayInputStream(initialContents.getBytes()), 0);
+            }
+            catch (IOException e) {
+                m_log.log(LogService.LOG_ERROR, "Unable to set initial contents of the repository.", e);
+            }
         }
-        else {
-            // update existing instance
-            RepositoryImpl store = (RepositoryImpl) service.getService();
-            store.updated(isMaster, limitValue);
+        return store;
+    }
+
+    private void deleteRepositoryPrefs(String pid) {
+        try {
+            Preferences prefs = m_prefsService.getSystemPreferences();
+
+            prefs.node(pid).removeNode();
+            prefs.sync();
+        }
+        catch (BackingStoreException e) {
+            // Not much we can do
+        }
+    }
+
+    private void deleteRepositoryStore(String pid, File repoDir) {
+        if (repoDir.exists() && repoDir.isDirectory()) {
+            File[] files = repoDir.listFiles();
+            for (int i = 0; (files != null) && (i < files.length); i++) {
+                files[i].delete();
+            }
+            if (!repoDir.delete()) {
+                m_log.log(LogService.LOG_WARNING, "Unable to clean up files in " + repoDir.getAbsolutePath() + " after removing repository!");
+            }
+        }
+    }
+
+    private File ensureDirectoryAvailable(File dir) {
+        if (dir == null) {
+            throw new IllegalArgumentException("Unable to use file system!");
+        }
+        if (dir.exists() && dir.isFile()) {
+            dir.delete();
+        }
+        if (!dir.exists() && !dir.mkdirs()) {
+            throw new IllegalArgumentException("Unable to create directory: " + dir.getAbsolutePath() + "!");
         }
+        return dir;
     }
 }

Modified: ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryImpl.java?rev=1530981&r1=1530980&r2=1530981&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryImpl.java (original)
+++ ace/trunk/org.apache.ace.repository/src/org/apache/ace/repository/impl/RepositoryImpl.java Thu Oct 10 13:58:02 2013
@@ -59,11 +59,14 @@ public class RepositoryImpl implements R
     /**
      * Creates a new repository.
      * 
-     * @param dir Directory to be used for storage of the repository data, will be created if needed.
-     * @param temp Directory to be used as temp directory, will be created if needed.
-     * @param isMaster True if this repository is a master repository, false otherwise.
-     * @throws IllegalArgumentException If <code>dir</code> and/or <code>temp</code> could not be created or is not a
-     *             directory.
+     * @param dir
+     *            Directory to be used for storage of the repository data, will be created if needed.
+     * @param temp
+     *            Directory to be used as temp directory, will be created if needed.
+     * @param isMaster
+     *            True if this repository is a master repository, false otherwise.
+     * @throws IllegalArgumentException
+     *             If <code>dir</code> and/or <code>temp</code> could not be created or is not a directory.
      */
     public RepositoryImpl(File dir, File temp, boolean isMaster) {
         this(dir, temp, "", isMaster);
@@ -72,41 +75,54 @@ public class RepositoryImpl implements R
     /**
      * Creates a new repository.
      * 
-     * @param dir Directory to be used for storage of the repository data, will be created if needed.
-     * @param temp Directory to be used as temp directory, will be created if needed.
-     * @param fileExtension Extension to be used for repository files.
-     * @param isMaster True if this repository is a master repository, false otherwise.
-     * @throws IllegalArgumentException If <code>dir</code> and/or <code>temp</code> could not be created or is not a
-     *             directory.
+     * @param dir
+     *            Directory to be used for storage of the repository data, will be created if needed.
+     * @param temp
+     *            Directory to be used as temp directory, will be created if needed.
+     * @param isMaster
+     *            True if this repository is a master repository, false otherwise.
+     * @param limit
+     *            The maximum number of versions to store in this repository.
+     * @throws IllegalArgumentException
+     *             If <code>dir</code> and/or <code>temp</code> could not be created or is not a directory.
      */
-    public RepositoryImpl(File dir, File temp, String fileExtension, boolean isMaster) {
-        this(dir, temp, fileExtension, isMaster, Long.MAX_VALUE);
+    public RepositoryImpl(File dir, File temp, boolean isMaster, long limit) {
+        this(dir, temp, "", isMaster, limit);
     }
 
     /**
      * Creates a new repository.
      * 
-     * @param dir Directory to be used for storage of the repository data, will be created if needed.
-     * @param temp Directory to be used as temp directory, will be created if needed.
-     * @param isMaster True if this repository is a master repository, false otherwise.
-     * @param limit The maximum number of versions to store in this repository.
-     * @throws IllegalArgumentException If <code>dir</code> and/or <code>temp</code> could not be created or is not a
-     *             directory.
+     * @param dir
+     *            Directory to be used for storage of the repository data, will be created if needed.
+     * @param temp
+     *            Directory to be used as temp directory, will be created if needed.
+     * @param fileExtension
+     *            Extension to be used for repository files.
+     * @param isMaster
+     *            True if this repository is a master repository, false otherwise.
+     * @throws IllegalArgumentException
+     *             If <code>dir</code> and/or <code>temp</code> could not be created or is not a directory.
      */
-    public RepositoryImpl(File dir, File temp, boolean isMaster, long limit) {
-        this(dir, temp, "", isMaster, limit);
+    public RepositoryImpl(File dir, File temp, String fileExtension, boolean isMaster) {
+        this(dir, temp, fileExtension, isMaster, Long.MAX_VALUE);
     }
-    
+
     /**
      * Creates a new repository.
      * 
-     * @param dir Directory to be used for storage of the repository data, will be created if needed.
-     * @param temp Directory to be used as temp directory, will be created if needed.
-     * @param fileExtension Extension to be used for repository files.
-     * @param isMaster True if this repository is a master repository, false otherwise.
-     * @param limit The maximum number of versions to store in this repository.
-     * @throws IllegalArgumentException If <code>dir</code> and/or <code>temp</code> could not be created or is not a
-     *             directory.
+     * @param dir
+     *            Directory to be used for storage of the repository data, will be created if needed.
+     * @param temp
+     *            Directory to be used as temp directory, will be created if needed.
+     * @param fileExtension
+     *            Extension to be used for repository files.
+     * @param isMaster
+     *            True if this repository is a master repository, false otherwise.
+     * @param limit
+     *            The maximum number of versions to store in this repository.
+     * @throws IllegalArgumentException
+     *             If <code>dir</code> and/or <code>temp</code> could not be created or is not a directory.
      */
     public RepositoryImpl(File dir, File temp, String fileExtension, boolean isMaster, long limit) {
         m_isMaster = isMaster;
@@ -127,17 +143,85 @@ public class RepositoryImpl implements R
         m_fileExtension = fileExtension;
         m_limit = limit;
     }
-    
+
+    public InputStream checkout(long version) throws IOException, IllegalArgumentException {
+        if (version <= 0) {
+            throw new IllegalArgumentException("Version must be greater than 0.");
+        }
+
+        InputStream result = null;
+        File file = getFilename(version);
+        if (file.isFile()) {
+            result = new FileInputStream(file);
+        }
+        return result;
+    }
+
+    public boolean commit(InputStream data, long fromVersion) throws IOException, IllegalArgumentException {
+        if (!m_isMaster) {
+            throw new IllegalStateException("Commit is only permitted on master repositories");
+        }
+        if (fromVersion < 0) {
+            throw new IllegalArgumentException("Version must be greater than or equal to 0.");
+        }
+
+        long[] versions = getVersions();
+        if (versions.length == 0) {
+            if (fromVersion == 0) {
+                put(data, 1);
+
+                return true;
+            }
+            else {
+                return false;
+            }
+        }
+
+        long lastVersion = versions[versions.length - 1];
+        if (lastVersion == fromVersion) {
+            put(data, fromVersion + 1);
+            // Make sure we do not exceed our max limit...
+            purgeOldFiles(getVersions(), m_limit);
+
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
 
     public InputStream get(long version) throws IOException, IllegalArgumentException {
         return checkout(version);
     }
 
+    /**
+     * @return the directory in which this repository stores its files.
+     */
+    public File getDir() {
+        return m_dir;
+    }
+
+    /**
+     * @return the file extension used for this repository.
+     */
+    public String getFileExtension() {
+        return m_fileExtension;
+    }
+
+    @Override
+    public long getLimit() {
+        return m_limit;
+    }
+
+    public SortedRangeSet getRange() throws IOException {
+        return new SortedRangeSet(getVersions());
+    }
+
     public boolean put(InputStream data, long version) throws IOException, IllegalArgumentException {
         if (version <= 0) {
             throw new IllegalArgumentException("Version must be greater than 0.");
         }
-        File file = new File(m_dir, Long.toString(version) + m_fileExtension);
+        File file = getFilename(version);
         if (file.exists()) {
             return false;
         }
@@ -181,53 +265,61 @@ public class RepositoryImpl implements R
         return true;
     }
 
-    public InputStream checkout(long version) throws IOException, IllegalArgumentException {
-        if (version <= 0) {
-            throw new IllegalArgumentException("Version must be greater than 0.");
-        }
-        File file = new File(m_dir, String.valueOf(version) + m_fileExtension);
-        return (file.isFile()) ? new FileInputStream(file) : null;
-    }
-
-    public boolean commit(InputStream data, long fromVersion) throws IOException, IllegalArgumentException {
-        if (!m_isMaster) {
-            throw new IllegalStateException("Commit is only permitted on master repositories");
-        }
-        if (fromVersion < 0) {
-            throw new IllegalArgumentException("Version must be greater than or equal to 0.");
+    /**
+     * Updates the repository configuration.
+     * 
+     * @param isMaster
+     *            True if the repository is a master repository, false otherwise.
+     * @throws ConfigurationException
+     *             If it was impossible to use the new configuration.
+     */
+    public void updated(boolean isMaster, long limit) throws ConfigurationException {
+        if (limit < 1) {
+            throw new ConfigurationException(RepositoryConstants.REPOSITORY_LIMIT, "Limit must be at least 1, was " + limit);
         }
-
-        long[] versions = getVersions();
-        if (versions.length == 0) {
-            if (fromVersion == 0) {
-                put(data, 1);
-
-                return true;
+        m_isMaster = isMaster;
+        if (limit < m_limit) {
+            // limit was decreased, we might need to delete some old versions
+            try {
+                purgeOldFiles(getVersions(), limit);
             }
-            else {
-                return false;
+            catch (IOException e) {
+                throw new ConfigurationException(RepositoryConstants.REPOSITORY_LIMIT, "Could not set new limit to " + limit, e);
             }
         }
+        m_limit = limit;
+    }
 
-        long lastVersion = versions[versions.length - 1];
-        if (lastVersion == fromVersion) {
-            put(data, fromVersion + 1);
-            long length = versions.length + 1;
-            int index = 0;
-            while (length > m_limit) {
-                delete(versions[index]);
-                index++;
-                length--;
+    /**
+     * Safely closes a given resource, ignoring any I/O exceptions that might occur by this.
+     * 
+     * @param resource
+     *            the resource to close, can be <code>null</code>.
+     */
+    private void closeQuietly(Closeable resource) {
+        try {
+            if (resource != null) {
+                resource.close();
             }
-            return true;
         }
-        else {
-            return false;
+        catch (IOException e) {
+            // Ignored...
         }
     }
 
-    public SortedRangeSet getRange() throws IOException {
-        return new SortedRangeSet(getVersions());
+    private boolean delete(long version) throws IOException, IllegalArgumentException {
+        if (version <= 0) {
+            throw new IllegalArgumentException("Version must be greater than 0.");
+        }
+        File file = getFilename(version);
+        if (file.exists()) {
+            return file.delete();
+        }
+        return false;
+    }
+
+    private File getFilename(long version) {
+        return new File(m_dir, String.format("%d%s", version, m_fileExtension));
     }
 
     /* returns list of all versions present in ascending order */
@@ -252,81 +344,15 @@ public class RepositoryImpl implements R
     }
 
     /**
-     * Updates the repository configuration.
-     * 
-     * @param isMaster True if the repository is a master repository, false otherwise.
-     * @throws ConfigurationException If it was impossible to use the new configuration.
-     */
-    public void updated(boolean isMaster, long limit) throws ConfigurationException {
-        if (limit < 1) {
-            throw new ConfigurationException(RepositoryConstants.REPOSITORY_LIMIT, "Limit must be at least 1, was " + limit);
-        }
-        m_isMaster = isMaster;
-        if (limit < m_limit) {
-            // limit was decreased, we might need to delete some old versions
-            try {
-                long[] versions = getVersions();
-                int length = versions.length;
-                int index = 0;
-                while (length > limit) {
-                    delete(versions[index]);
-                    length--;
-                    index++;
-                }
-            }
-            catch (IOException e) {
-                throw new ConfigurationException(RepositoryConstants.REPOSITORY_LIMIT, "Could not set new limit to " + limit, e);
-            }
-        }
-        m_limit = limit;
-    }
-    
-    @Override
-    public long getLimit() {
-        return m_limit;
-    }
-
-    /**
-     * Renames a given source file to a new destination file.
-     * <p>
-     * This avoids the problem mentioned in ACE-155.<br/>
-     * The moveFile method from Commons-IO is not used, as it would mean that we need to include this JAR in several
-     * placed for only a few lines of code.
-     * </p>
-     * 
-     * @param source the file to rename;
-     * @param dest the file to rename to.
-     */
-    private void renameFile(File source, File dest) throws IOException {
-        boolean renameOK = false;
-        int attempts = 0;
-        while (!renameOK && (attempts++ < 10)) {
-            try {
-                renameOK = source.renameTo(dest);
-                if (!renameOK) {
-                    renameOK = moveFile(source, dest);
-                }
-            }
-            catch (IOException e) {
-                // In all other cases, we assume the source file is still locked and cannot be removed;
-            }
-        }
-
-        if (!renameOK) {
-            if (m_log != null) {
-                m_log.log(LogService.LOG_ERROR, "Unable to move new repository file to it's final location.");
-            }
-            throw new IOException("Could not move temporary file (" + source.getAbsolutePath() + ") to it's final location (" + dest.getAbsolutePath() + ")");
-        }
-    }
-
-    /**
      * Moves a given source file to a destination location, effectively resulting in a rename.
      * 
-     * @param source the source file to move;
-     * @param dest the destination file to move the file to.
+     * @param source
+     *            the source file to move;
+     * @param dest
+     *            the destination file to move the file to.
      * @return <code>true</code> if the move succeeded.
-     * @throws IOException in case of I/O problems.
+     * @throws IOException
+     *             in case of I/O problems.
      */
     private boolean moveFile(File source, File dest) throws IOException {
         final int bufferSize = 1024 * 1024; // 1MB
@@ -369,27 +395,49 @@ public class RepositoryImpl implements R
         return true;
     }
 
+    private void purgeOldFiles(long[] versions, long limit) throws IOException {
+        int length = versions.length;
+        int index = 0;
+        while (length > limit) {
+            delete(versions[index]);
+            length--;
+            index++;
+        }
+    }
+
     /**
-     * Safely closes a given resource, ignoring any I/O exceptions that might occur by this.
+     * Renames a given source file to a new destination file.
+     * <p>
+     * This avoids the problem mentioned in ACE-155.<br/>
+     * The moveFile method from Commons-IO is not used, as it would mean that we need to include this JAR in several
+     * placed for only a few lines of code.
+     * </p>
      * 
-     * @param resource the resource to close, can be <code>null</code>.
+     * @param source
+     *            the file to rename;
+     * @param dest
+     *            the file to rename to.
      */
-    private void closeQuietly(Closeable resource) {
-        try {
-            if (resource != null) {
-                resource.close();
+    private void renameFile(File source, File dest) throws IOException {
+        boolean renameOK = false;
+        int attempts = 0;
+        while (!renameOK && (attempts++ < 10)) {
+            try {
+                renameOK = source.renameTo(dest);
+                if (!renameOK) {
+                    renameOK = moveFile(source, dest);
+                }
+            }
+            catch (IOException e) {
+                // In all other cases, we assume the source file is still locked and cannot be removed;
             }
         }
-        catch (IOException e) {
-            // Ignored...
-        }
-    }
 
-    private boolean delete(long version) throws IOException, IllegalArgumentException {
-        if (version <= 0) {
-            throw new IllegalArgumentException("Version must be greater than 0.");
+        if (!renameOK) {
+            if (m_log != null) {
+                m_log.log(LogService.LOG_ERROR, "Unable to move new repository file to it's final location.");
+            }
+            throw new IOException("Could not move temporary file (" + source.getAbsolutePath() + ") to it's final location (" + dest.getAbsolutePath() + ")");
         }
-        File file = new File(m_dir, String.valueOf(version) + m_fileExtension);
-        return file.delete();
     }
 }