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();
}
}