refactor store api

This commit is contained in:
Sebastian Sdorra
2016-12-11 21:31:05 +01:00
parent 837df4b87c
commit 5332ac2466
47 changed files with 323 additions and 802 deletions

View File

@@ -41,13 +41,13 @@ import org.slf4j.LoggerFactory;
import sonia.scm.NotSupportedFeatuerException; import sonia.scm.NotSupportedFeatuerException;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.event.ScmEventBus; import sonia.scm.event.ScmEventBus;
import sonia.scm.store.Store;
import sonia.scm.store.StoreFactory;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import sonia.scm.store.ConfigurationStore;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
@@ -72,7 +72,7 @@ public abstract class AbstractRepositoryHandler<C extends SimpleRepositoryConfig
* *
* @param storeFactory * @param storeFactory
*/ */
protected AbstractRepositoryHandler(StoreFactory storeFactory) protected AbstractRepositoryHandler(ConfigurationStoreFactory storeFactory)
{ {
this.store = storeFactory.getStore(getConfigClass(), getType().getName()); this.store = storeFactory.getStore(getConfigClass(), getType().getName());
} }
@@ -221,5 +221,5 @@ public abstract class AbstractRepositoryHandler<C extends SimpleRepositoryConfig
protected C config; protected C config;
/** Field description */ /** Field description */
protected Store<C> store; protected ConfigurationStore<C> store;
} }

View File

@@ -46,7 +46,6 @@ import sonia.scm.ConfigurationException;
import sonia.scm.io.CommandResult; import sonia.scm.io.CommandResult;
import sonia.scm.io.ExtendedCommand; import sonia.scm.io.ExtendedCommand;
import sonia.scm.io.FileSystem; import sonia.scm.io.FileSystem;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -55,6 +54,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -89,7 +89,7 @@ public abstract class AbstractSimpleRepositoryHandler<C extends SimpleRepository
* @param storeFactory * @param storeFactory
* @param fileSystem * @param fileSystem
*/ */
public AbstractSimpleRepositoryHandler(StoreFactory storeFactory, public AbstractSimpleRepositoryHandler(ConfigurationStoreFactory storeFactory,
FileSystem fileSystem) FileSystem fileSystem)
{ {
super(storeFactory); super(storeFactory);

View File

@@ -33,18 +33,35 @@
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
/** /**
* Base class for {@link Store}. * Base class for {@link ConfigurationStore}.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
* @since 1.16 * @since 1.16
* *
* @param <T> type of store objects * @param <T> type of store objects
*/ */
public abstract class AbstractStore<T> implements Store<T> public abstract class AbstractStore<T> implements ConfigurationStore<T> {
{
/**
* stored object
*/
protected T storeObject;
@Override
public T get() {
if (storeObject == null) {
storeObject = readObject();
}
return storeObject;
}
@Override
public void set(T obejct) {
writeObject(obejct);
this.storeObject = obejct;
}
/** /**
* Read the stored object. * Read the stored object.
@@ -61,43 +78,4 @@ public abstract class AbstractStore<T> implements Store<T>
* @param object object to write * @param object object to write
*/ */
protected abstract void writeObject(T object); protected abstract void writeObject(T object);
//~--- get methods ----------------------------------------------------------
/**
* {@inheritDoc}
*
*
* @return
*/
@Override
public T get()
{
if (storeObject == null)
{
storeObject = readObject();
}
return storeObject;
}
//~--- set methods ----------------------------------------------------------
/**
* {@inheritDoc}
*
*
* @param obejct
*/
@Override
public void set(T obejct)
{
writeObject(obejct);
this.storeObject = obejct;
}
//~--- fields ---------------------------------------------------------------
/** stored object */
protected T storeObject;
} }

View File

@@ -44,7 +44,7 @@ import java.util.List;
* *
* @apiviz.uses sonia.scm.store.Blob * @apiviz.uses sonia.scm.store.Blob
*/ */
public interface BlobStore extends StoreBase<Blob> public interface BlobStore extends MultiEntryStore<Blob>
{ {
/** /**

View File

@@ -42,8 +42,7 @@ package sonia.scm.store;
* @apiviz.landmark * @apiviz.landmark
* @apiviz.uses sonia.scm.store.BlobStore * @apiviz.uses sonia.scm.store.BlobStore
*/ */
public interface BlobStoreFactory public interface BlobStoreFactory {
{
/** /**
* Returns a {@link BlobStore} with the given name, if the {@link BlobStore} * Returns a {@link BlobStore} with the given name, if the {@link BlobStore}

View File

@@ -50,8 +50,7 @@ import java.util.Collection;
* @param <V> store value type * @param <V> store value type
* @since 1.31 * @since 1.31
*/ */
public interface ConfigurationEntryStore<V> extends DataStore<V> public interface ConfigurationEntryStore<V> extends DataStore<V> {
{
/** /**
* Return all values matching the given {@link Predicate}. * Return all values matching the given {@link Predicate}.

View File

@@ -34,16 +34,14 @@
package sonia.scm.store; package sonia.scm.store;
/** /**
* Store for configuration objects. <strong>Note:</strong> the default * ConfigurationStore for configuration objects. <strong>Note:</strong> the default
* implementation use JAXB to marshall the configuration objects. * implementation use JAXB to marshall the configuration objects.
*
* TODO for 2.0 rename to ConfigurationStore
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
* *
* @param <T> type of the configuration objects * @param <T> type of the configuration objects
*/ */
public interface Store<T> public interface ConfigurationStore<T>
{ {
/** /**

View File

@@ -30,38 +30,30 @@
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.Initable;
//~--- JDK imports ------------------------------------------------------------
import java.io.Closeable;
/** /**
* The StoreFactory can be used to create new or get existing * The ConfigurationStoreFactory can be used to create new or get existing
* {@link Store}s. * {@link ConfigurationStore} objects.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
* *
* @apiviz.landmark * @apiviz.landmark
* @apiviz.uses sonia.scm.store.Store * @apiviz.uses sonia.scm.store.ConfigurationStore
*/ */
public interface StoreFactory extends Initable, Closeable public interface ConfigurationStoreFactory
{ {
/** /**
* Get an existing {@link Store} or create a new one. * Get an existing {@link ConfigurationStore} or create a new one.
* *
* *
* @param type type of the store objects * @param type type of the store objects
* @param name name of the store * @param name name of the store
* @param <T> type of the store objects * @param <T> type of the store objects
* *
* @return {@link Store} of the given type and name * @return {@link ConfigurationStore} of the given type and name
*/ */
public <T> Store<T> getStore(Class<T> type, String name); public <T> ConfigurationStore<T> getStore(Class<T> type, String name);
} }

View File

@@ -45,8 +45,7 @@ import java.util.Map;
* *
* @param <T> type of store items * @param <T> type of store items
*/ */
public interface DataStore<T> extends StoreBase<T> public interface DataStore<T> extends MultiEntryStore<T> {
{
/** /**
* Put a item with automatically generated id to the store. * Put a item with automatically generated id to the store.

View File

@@ -42,8 +42,7 @@ package sonia.scm.store;
* @apiviz.landmark * @apiviz.landmark
* @apiviz.uses sonia.scm.store.DataStore * @apiviz.uses sonia.scm.store.DataStore
*/ */
public interface DataStoreFactory public interface DataStoreFactory {
{
/** /**
* Get an existing {@link DataStore} or create a new one. * Get an existing {@link DataStore} or create a new one.

View File

@@ -39,10 +39,8 @@ package sonia.scm.store;
* @author Sebastian Sdorra * @author Sebastian Sdorra
* @since 1.23 * @since 1.23
*/ */
public class EntryAlreadyExistsStoreException extends StoreException public class EntryAlreadyExistsStoreException extends StoreException {
{
/** Field description */
private static final long serialVersionUID = 7016781091599951287L; private static final long serialVersionUID = 7016781091599951287L;
//~--- constructors --------------------------------------------------------- //~--- constructors ---------------------------------------------------------
@@ -50,11 +48,9 @@ public class EntryAlreadyExistsStoreException extends StoreException
/** /**
* Constructs new EntryAllreadyExistsStoreException. * Constructs new EntryAllreadyExistsStoreException.
* *
*
* @param message message for the exception * @param message message for the exception
*/ */
public EntryAlreadyExistsStoreException(String message) public EntryAlreadyExistsStoreException(String message) {
{
super(message); super(message);
} }
} }

View File

@@ -40,8 +40,7 @@ package sonia.scm.store;
* *
* @param <T> Type of the stored objects * @param <T> Type of the stored objects
*/ */
public interface StoreBase<T> public interface MultiEntryStore<T> {
{
/** /**
* Remove all items from the store. * Remove all items from the store.

View File

@@ -34,11 +34,11 @@
package sonia.scm.store; package sonia.scm.store;
/** /**
* * The store exception can be used by a store implementation.
*
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public class StoreException extends RuntimeException public class StoreException extends RuntimeException {
{
/** Field description */ /** Field description */
private static final long serialVersionUID = 6974469896007155294L; private static final long serialVersionUID = 6974469896007155294L;
@@ -46,45 +46,21 @@ public class StoreException extends RuntimeException
//~--- constructors --------------------------------------------------------- //~--- constructors ---------------------------------------------------------
/** /**
* Constructs ... * Constructs a new instance.
* *
* @param message exception message
*/ */
public StoreException() public StoreException(String message) {
{
super();
}
/**
* Constructs ...
*
*
* @param message
*/
public StoreException(String message)
{
super(message); super(message);
} }
/** /**
* Constructs ... * Constructs a new instance.
* *
* * @param message exception message
* @param cause * @param cause exception cause
*/ */
public StoreException(Throwable cause) public StoreException(String message, Throwable cause) {
{
super(cause);
}
/**
* Constructs ...
*
*
* @param message
* @param cause
*/
public StoreException(String message, Throwable cause)
{
super(message, cause); super(message, cause);
} }
} }

View File

@@ -39,9 +39,10 @@ import com.google.inject.Singleton;
import sonia.scm.group.Group; import sonia.scm.group.Group;
import sonia.scm.group.GroupDAO; import sonia.scm.group.GroupDAO;
import sonia.scm.store.StoreFactory;
import sonia.scm.xml.AbstractXmlDAO; import sonia.scm.xml.AbstractXmlDAO;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
@@ -63,7 +64,7 @@ public class XmlGroupDAO extends AbstractXmlDAO<Group, XmlGroupDatabase>
* @param storeFactory * @param storeFactory
*/ */
@Inject @Inject
public XmlGroupDAO(StoreFactory storeFactory) public XmlGroupDAO(ConfigurationStoreFactory storeFactory)
{ {
super(storeFactory.getStore(XmlGroupDatabase.class, STORE_NAME)); super(storeFactory.getStore(XmlGroupDatabase.class, STORE_NAME));
} }

View File

@@ -39,8 +39,8 @@ import com.google.inject.Singleton;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryDAO;
import sonia.scm.store.StoreFactory;
import sonia.scm.xml.AbstractXmlDAO; import sonia.scm.xml.AbstractXmlDAO;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -64,7 +64,7 @@ public class XmlRepositoryDAO
* @param storeFactory * @param storeFactory
*/ */
@Inject @Inject
public XmlRepositoryDAO(StoreFactory storeFactory) public XmlRepositoryDAO(ConfigurationStoreFactory storeFactory)
{ {
super(storeFactory.getStore(XmlRepositoryDatabase.class, STORE_NAME)); super(storeFactory.getStore(XmlRepositoryDatabase.class, STORE_NAME));
} }

View File

@@ -50,7 +50,7 @@ import java.io.File;
* *
* @param <T> * @param <T>
*/ */
public abstract class FileBasedStore<T> implements StoreBase<T> public abstract class FileBasedStore<T> implements MultiEntryStore<T>
{ {
/** /**

View File

@@ -28,12 +28,9 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -41,75 +38,52 @@ import sonia.scm.SCMContextProvider;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
/** /**
* * Abstract store factory for file based stores.
*
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public class FileBasedStoreFactory public abstract class FileBasedStoreFactory {
{
/** Field description */
private static final String BASE_DIRECTORY = "var";
/** /**
* the logger for FileBasedStoreFactory * the logger for FileBasedStoreFactory
*/ */
private static final Logger logger = private static final Logger LOG = LoggerFactory.getLogger(FileBasedStoreFactory.class);
LoggerFactory.getLogger(FileBasedStoreFactory.class);
//~--- constructors --------------------------------------------------------- private static final String BASE_DIRECTORY = "var";
/** private final SCMContextProvider context;
* Constructs ...
* private final String dataDirectoryName;
*
* @param context private File dataDirectory;
* @param dataDirectoryName
*/ protected FileBasedStoreFactory(SCMContextProvider context,
public FileBasedStoreFactory(SCMContextProvider context, String dataDirectoryName) {
String dataDirectoryName)
{
this.context = context; this.context = context;
this.dataDirectoryName = dataDirectoryName; this.dataDirectoryName = dataDirectoryName;
} }
//~--- get methods ---------------------------------------------------------- //~--- get methods ----------------------------------------------------------
/** /**
* Method description * Returns data directory for given name.
* *
* @param name name of data directory
* *
* @param name * @return data directory
*
* @return
*/ */
protected File getDirectory(String name) protected File getDirectory(String name) {
{ if (dataDirectory == null) {
if (dataDirectory == null)
{
dataDirectory = new File(context.getBaseDirectory(), dataDirectory = new File(context.getBaseDirectory(),
BASE_DIRECTORY.concat(File.separator).concat(dataDirectoryName)); BASE_DIRECTORY.concat(File.separator).concat(dataDirectoryName));
logger.debug("create data directory {}", dataDirectory); LOG.debug("create data directory {}", dataDirectory);
} }
File storeDirectory = new File(dataDirectory, name); File storeDirectory = new File(dataDirectory, name);
IOUtil.mkdirs(storeDirectory); IOUtil.mkdirs(storeDirectory);
return storeDirectory; return storeDirectory;
} }
//~--- fields ---------------------------------------------------------------
/** Field description */
private final SCMContextProvider context;
/** Field description */
private File dataDirectory;
/** Field description */
private final String dataDirectoryName;
} }

View File

@@ -28,12 +28,9 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@@ -43,87 +40,39 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* File base implementation of {@link Blob}.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public final class FileBlob implements Blob public final class FileBlob implements Blob {
{
/** private final String id;
* Constructs ... private final File file;
*
* FileBlob(String id, File file) {
* @param id
* @param file
*/
public FileBlob(String id, File file)
{
this.id = id; this.id = id;
this.file = file; this.file = file;
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @throws IOException
*/
@Override @Override
public void commit() throws IOException public void commit() throws IOException {
{
// nothing todo // nothing todo
} }
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override @Override
public String getId() public String getId() {
{
return id; return id;
} }
/**
* Method description
*
*
* @return
*
* @throws FileNotFoundException
*/
@Override @Override
public InputStream getInputStream() throws FileNotFoundException public InputStream getInputStream() throws FileNotFoundException {
{
return new FileInputStream(file); return new FileInputStream(file);
} }
/**
* Method description
*
*
* @return
*
* @throws IOException
*/
@Override @Override
public OutputStream getOutputStream() throws IOException public OutputStream getOutputStream() throws IOException {
{
return new FileOutputStream(file); return new FileOutputStream(file);
} }
//~--- fields ---------------------------------------------------------------
/** Field description */
private final File file;
/** Field description */
private final String id;
} }

View File

@@ -28,12 +28,9 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -45,147 +42,86 @@ import org.slf4j.LoggerFactory;
import sonia.scm.security.KeyGenerator; import sonia.scm.security.KeyGenerator;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
/** /**
* File based implementation of {@link BlobStore}.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public class FileBlobStore extends FileBasedStore<Blob> implements BlobStore public class FileBlobStore extends FileBasedStore<Blob> implements BlobStore {
{
/** Field description */
private static final String SUFFIX = ".blob";
/** /**
* the logger for FileBlobStore * the logger for FileBlobStore
*/ */
private static final Logger logger = private static final Logger LOG
LoggerFactory.getLogger(FileBlobStore.class); = LoggerFactory.getLogger(FileBlobStore.class);
//~--- constructors --------------------------------------------------------- private static final String SUFFIX = ".blob";
/** private final KeyGenerator keyGenerator;
* Constructs ...
* FileBlobStore(KeyGenerator keyGenerator, File directory) {
*
* @param keyGenerator
* @param directory
*/
public FileBlobStore(KeyGenerator keyGenerator, File directory)
{
super(directory, SUFFIX); super(directory, SUFFIX);
this.keyGenerator = keyGenerator; this.keyGenerator = keyGenerator;
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override @Override
public Blob create() public Blob create() {
{
return create(keyGenerator.createKey()); return create(keyGenerator.createKey());
} }
/**
* Method description
*
*
* @param id
*
* @return
*/
@Override @Override
public Blob create(String id) public Blob create(String id) {
{
Preconditions.checkArgument(!Strings.isNullOrEmpty(id), Preconditions.checkArgument(!Strings.isNullOrEmpty(id),
"id argument is required"); "id argument is required");
logger.debug("create new blob with id {}", id); LOG.debug("create new blob with id {}", id);
File file = getFile(id); File file = getFile(id);
try try {
{ if (file.exists()) {
if (file.exists())
{
throw new EntryAlreadyExistsStoreException( throw new EntryAlreadyExistsStoreException(
"blob with id ".concat(id).concat(" allready exists")); "blob with id ".concat(id).concat(" allready exists"));
} }
else if (!file.createNewFile()) else if (!file.createNewFile()) {
{
throw new StoreException("could not create blob for id ".concat(id)); throw new StoreException("could not create blob for id ".concat(id));
} }
} }
catch (IOException ex) catch (IOException ex) {
{
throw new StoreException("could not create blob for id ".concat(id), ex); throw new StoreException("could not create blob for id ".concat(id), ex);
} }
return new FileBlob(id, file); return new FileBlob(id, file);
} }
/**
* Method description
*
*
* @param blob
*/
@Override @Override
public void remove(Blob blob) public void remove(Blob blob) {
{
Preconditions.checkNotNull(blob, "blob argument is required"); Preconditions.checkNotNull(blob, "blob argument is required");
remove(blob.getId()); remove(blob.getId());
} }
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override @Override
public List<Blob> getAll() public List<Blob> getAll() {
{ LOG.trace("get all items from data store");
logger.trace("get all items from data store");
Builder<Blob> builder = ImmutableList.builder(); Builder<Blob> builder = ImmutableList.builder();
for (File file : directory.listFiles()) for (File file : directory.listFiles()) {
{
builder.add(read(file)); builder.add(read(file));
} }
return builder.build(); return builder.build();
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param file
*
* @return
*/
@Override @Override
protected FileBlob read(File file) protected FileBlob read(File file) {
{
FileBlob blob = null; FileBlob blob = null;
if (file.exists()) if (file.exists()) {
{
String id = getId(file); String id = getId(file);
blob = new FileBlob(id, file); blob = new FileBlob(id, file);
@@ -194,8 +130,4 @@ public class FileBlobStore extends FileBasedStore<Blob> implements BlobStore
return blob; return blob;
} }
//~--- fields ---------------------------------------------------------------
/** key generator */
private final KeyGenerator keyGenerator;
} }

View File

@@ -28,12 +28,9 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
@@ -44,60 +41,40 @@ import sonia.scm.SCMContextProvider;
import sonia.scm.security.KeyGenerator; import sonia.scm.security.KeyGenerator;
/** /**
* File based store factory.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
@Singleton @Singleton
public class FileBlobStoreFactory extends FileBasedStoreFactory public class FileBlobStoreFactory extends FileBasedStoreFactory implements BlobStoreFactory {
implements BlobStoreFactory
{
/** Field description */
private static final String DIRECTORY_NAME = "blob"; private static final String DIRECTORY_NAME = "blob";
/** /**
* the logger for FileBlobStoreFactory * the logger for FileBlobStoreFactory
*/ */
private static final Logger logger = private static final Logger LOG = LoggerFactory.getLogger(FileBlobStoreFactory.class);
LoggerFactory.getLogger(FileBlobStoreFactory.class);
//~--- constructors --------------------------------------------------------- private final KeyGenerator keyGenerator;
/** /**
* Constructs ... * Constructs a new instance.
* *
* * @param context scm context
* @param context * @param keyGenerator key generator
* @param keyGenerator
*/ */
@Inject @Inject
public FileBlobStoreFactory(SCMContextProvider context, public FileBlobStoreFactory(SCMContextProvider context,
KeyGenerator keyGenerator) KeyGenerator keyGenerator) {
{
super(context, DIRECTORY_NAME); super(context, DIRECTORY_NAME);
this.keyGenerator = keyGenerator; this.keyGenerator = keyGenerator;
} }
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param name
*
* @return
*/
@Override @Override
public BlobStore getBlobStore(String name) public BlobStore getBlobStore(String name) {
{ LOG.debug("create new blob with name {}", name);
logger.debug("create new blob with name {}", name);
return new FileBlobStore(keyGenerator, getDirectory(name)); return new FileBlobStore(keyGenerator, getDirectory(name));
} }
//~--- fields ---------------------------------------------------------------
/** key generator */
private final KeyGenerator keyGenerator;
} }

View File

@@ -80,8 +80,7 @@ import javax.xml.stream.XMLStreamWriter;
* *
* @param <V> * @param <V>
*/ */
public class JAXBConfigurationEntryStore<V> public class JAXBConfigurationEntryStore<V> implements ConfigurationEntryStore<V>
implements ConfigurationEntryStore<V>
{ {
/** Field description */ /** Field description */

View File

@@ -28,18 +28,13 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBContext;
@@ -47,121 +42,81 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller;
/** /**
* JAXB implementation of {@link ConfigurationStore}.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
* *
* @param <T> * @param <T>
*/ */
public class JAXBStore<T> extends AbstractStore<T> public class JAXBConfigurationStore<T> extends AbstractStore<T> {
{
/** the logger for JAXBStore */
private static final Logger logger = LoggerFactory.getLogger(JAXBStore.class);
//~--- constructors ---------------------------------------------------------
/** /**
* Constructs ... * the logger for JAXBConfigurationStore
*
*
* @param type
* @param configFile
*/ */
public JAXBStore(Class<T> type, File configFile) private static final Logger LOG = LoggerFactory.getLogger(JAXBConfigurationStore.class);
{
private Class<T> type;
private File configFile;
private JAXBContext context;
JAXBConfigurationStore(Class<T> type, File configFile) {
this.type = type; this.type = type;
try try {
{
context = JAXBContext.newInstance(type); context = JAXBContext.newInstance(type);
this.configFile = configFile; this.configFile = configFile;
} }
catch (JAXBException ex) catch (JAXBException ex) {
{ throw new StoreException("failed to create jaxb context", ex);
throw new StoreException(ex);
} }
} }
//~--- get methods ----------------------------------------------------------
/** /**
* Method description * Returns type of stored object.
* *
* *
* @return * @return type
*/ */
public Class<T> getType() public Class<T> getType() {
{
return type; return type;
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected T readObject() protected T readObject() {
{ LOG.debug("load {} from store {}", type, configFile);
logger.debug("load {} from store {}", type, configFile);
T result = null; T result = null;
if (configFile.exists()) if (configFile.exists()) {
{ try {
try
{
result = (T) context.createUnmarshaller().unmarshal(configFile); result = (T) context.createUnmarshaller().unmarshal(configFile);
} }
catch (JAXBException ex) catch (JAXBException ex) {
{ throw new StoreException("failed to unmarshall object", ex);
throw new StoreException(ex);
} }
} }
return result; return result;
} }
/**
* Method description
*
*
* @param object
*/
@Override @Override
protected void writeObject(T object) protected void writeObject(T object) {
{ if (LOG.isDebugEnabled()) {
if (logger.isDebugEnabled()) LOG.debug("store {} to {}", object.getClass().getName(),
{
logger.debug("store {} to {}", object.getClass().getName(),
configFile.getPath()); configFile.getPath());
} }
try try {
{
Marshaller marshaller = context.createMarshaller(); Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(object, configFile); marshaller.marshal(object, configFile);
} }
catch (JAXBException ex) catch (JAXBException ex) {
{ throw new StoreException("failed to marshall object", ex);
throw new StoreException(ex);
} }
} }
//~--- fields ---------------------------------------------------------------
/** Field description */
private File configFile;
/** Field description */
private JAXBContext context;
/** Field description */
private Class<T> type;
} }

View File

@@ -28,67 +28,59 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContextProvider; import sonia.scm.SCMContextProvider;
import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------ import java.io.File;
import java.io.IOException;
/** /**
* JAXB implementation of {@link JAXBConfigurationStoreFactory}.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public class MemoryStoreFactory implements StoreFactory @Singleton
{ public class JAXBConfigurationStoreFactory implements ConfigurationStoreFactory {
/** /**
* Method description * the logger for JAXBConfigurationStoreFactory
*
*
* @throws IOException
*/ */
@Override private static final Logger LOG = LoggerFactory.getLogger(JAXBConfigurationStoreFactory.class);
public void close() throws IOException
{
// do nothing private final File configDirectory;
}
/** /**
* Method description * Constructs a new instance.
* *
* * @param context scm context
* @param context
*/ */
@Override @Inject
public void init(SCMContextProvider context) public JAXBConfigurationStoreFactory(SCMContextProvider context) {
{ configDirectory = new File(context.getBaseDirectory(), StoreConstants.CONFIGDIRECTORY_NAME);
IOUtil.mkdirs(configDirectory);
// do nothing
} }
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param type
* @param name
* @param <T>
*
* @return
*/
@Override @Override
public <T> Store<T> getStore(Class<T> type, String name) public <T> JAXBConfigurationStore<T> getStore(Class<T> type, String name) {
{ if (configDirectory == null) {
return new MemoryStore<T>(); throw new IllegalStateException("store factory is not initialized");
}
File configFile = new File(configDirectory, name.concat(StoreConstants.FILE_EXTENSION));
if (LOG.isDebugEnabled()) {
LOG.debug("create store for {} at {}", type.getName(),
configFile.getPath());
}
return new JAXBConfigurationStore<>(type, configFile);
} }
} }

View File

@@ -28,12 +28,9 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableMap.Builder;
@@ -43,7 +40,6 @@ import org.slf4j.LoggerFactory;
import sonia.scm.security.KeyGenerator; import sonia.scm.security.KeyGenerator;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import java.util.Map; import java.util.Map;
@@ -53,87 +49,57 @@ import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller;
/** /**
* Jaxb implementation of {@link DataStore}.
* *
* @author Sebastian Sdorra * @author Sebastian Sdorra
* *
* @param <T> * @param <T> type of stored data.
*/ */
public class JAXBDataStore<T> extends FileBasedStore<T> implements DataStore<T> public class JAXBDataStore<T> extends FileBasedStore<T> implements DataStore<T> {
{
/** /**
* the logger for JAXBDataStore * the logger for JAXBDataStore
*/ */
private static final Logger logger = private static final Logger LOG
LoggerFactory.getLogger(JAXBDataStore.class); = LoggerFactory.getLogger(JAXBDataStore.class);
//~--- constructors --------------------------------------------------------- private final JAXBContext context;
/** private final KeyGenerator keyGenerator;
* Constructs ...
* JAXBDataStore(KeyGenerator keyGenerator, Class<T> type, File directory) {
*
* @param type
* @param keyGenerator
* @param directory
*/
public JAXBDataStore(KeyGenerator keyGenerator, Class<T> type, File directory)
{
super(directory, StoreConstants.FILE_EXTENSION); super(directory, StoreConstants.FILE_EXTENSION);
this.keyGenerator = keyGenerator; this.keyGenerator = keyGenerator;
try try {
{
context = JAXBContext.newInstance(type); context = JAXBContext.newInstance(type);
this.directory = directory; this.directory = directory;
} }
catch (JAXBException ex) catch (JAXBException ex) {
{ throw new StoreException("failed to create jaxb context", ex);
throw new StoreException(ex);
} }
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param id
* @param item
*/
@Override @Override
public void put(String id, T item) public void put(String id, T item) {
{ LOG.debug("put item {} to store", id);
logger.debug("put item {} to store", id);
File file = getFile(id); File file = getFile(id);
try try {
{
Marshaller marshaller = context.createMarshaller(); Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(item, file); marshaller.marshal(item, file);
} }
catch (JAXBException ex) catch (JAXBException ex) {
{
throw new StoreException("could not write object with id ".concat(id), throw new StoreException("could not write object with id ".concat(id),
ex); ex);
} }
} }
/**
* Method description
*
*
* @param item
*
* @return
*/
@Override @Override
public String put(T item) public String put(T item) {
{
String key = keyGenerator.createKey(); String key = keyGenerator.createKey();
put(key, item); put(key, item);
@@ -141,55 +107,31 @@ public class JAXBDataStore<T> extends FileBasedStore<T> implements DataStore<T>
return key; return key;
} }
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override @Override
public Map<String, T> getAll() public Map<String, T> getAll() {
{ LOG.trace("get all items from data store");
logger.trace("get all items from data store");
Builder<String, T> builder = ImmutableMap.builder(); Builder<String, T> builder = ImmutableMap.builder();
for (File file : directory.listFiles()) for (File file : directory.listFiles()) {
{
builder.put(getId(file), read(file)); builder.put(getId(file), read(file));
} }
return builder.build(); return builder.build();
} }
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param file
*
* @return
*/
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected T read(File file) protected T read(File file) {
{
T item = null; T item = null;
if (file.exists()) if (file.exists()) {
{ LOG.trace("try to read {}", file);
logger.trace("try to read {}", file);
try try {
{
item = (T) context.createUnmarshaller().unmarshal(file); item = (T) context.createUnmarshaller().unmarshal(file);
} }
catch (JAXBException ex) catch (JAXBException ex) {
{
throw new StoreException( throw new StoreException(
"could not read object ".concat(file.getPath()), ex); "could not read object ".concat(file.getPath()), ex);
} }
@@ -197,12 +139,4 @@ public class JAXBDataStore<T> extends FileBasedStore<T> implements DataStore<T>
return item; return item;
} }
//~--- fields ---------------------------------------------------------------
/** Field description */
private JAXBContext context;
/** Field description */
private final KeyGenerator keyGenerator;
} }

View File

@@ -95,7 +95,7 @@ public class JAXBDataStoreFactory extends FileBasedStoreFactory
{ {
logger.debug("create new store for type {} with name {}", type, name); logger.debug("create new store for type {} with name {}", type, name);
return new JAXBDataStore<T>(keyGenerator, type, getDirectory(name)); return new JAXBDataStore<>(keyGenerator, type, getDirectory(name));
} }
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------

View File

@@ -1,128 +0,0 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContextProvider;
import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
public class JAXBStoreFactory implements StoreFactory
{
/** the logger for JAXBStoreFactory */
private static final Logger logger =
LoggerFactory.getLogger(JAXBStoreFactory.class);
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @throws IOException
*/
@Override
public void close() throws IOException
{
// do nothing
}
/**
* Method description
*
*
* @param context
*/
@Override
public void init(SCMContextProvider context)
{
configDirectory = new File(context.getBaseDirectory(),
StoreConstants.CONFIGDIRECTORY_NAME);
IOUtil.mkdirs(configDirectory);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param type
* @param name
* @param <T>
*
* @return
*/
@Override
public <T> JAXBStore<T> getStore(Class<T> type, String name)
{
if (configDirectory == null)
{
throw new IllegalStateException("store factory is not initialized");
}
File configFile = new File(configDirectory,
name.concat(StoreConstants.FILE_EXTENSION));
if (logger.isDebugEnabled())
{
logger.debug("create store for {} at {}", type.getName(),
configFile.getPath());
}
return new JAXBStore<T>(type, configFile);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private File configDirectory;
}

View File

@@ -33,7 +33,8 @@
package sonia.scm.store; package sonia.scm.store;
/** /**
* * Store constants for xml implementations.
*
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public interface StoreConstants public interface StoreConstants

View File

@@ -37,10 +37,10 @@ package sonia.scm.user.xml;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import sonia.scm.store.StoreFactory;
import sonia.scm.user.User; import sonia.scm.user.User;
import sonia.scm.user.UserDAO; import sonia.scm.user.UserDAO;
import sonia.scm.xml.AbstractXmlDAO; import sonia.scm.xml.AbstractXmlDAO;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -63,7 +63,7 @@ public class XmlUserDAO extends AbstractXmlDAO<User, XmlUserDatabase>
* @param storeFactory * @param storeFactory
*/ */
@Inject @Inject
public XmlUserDAO(StoreFactory storeFactory) public XmlUserDAO(ConfigurationStoreFactory storeFactory)
{ {
super(storeFactory.getStore(XmlUserDatabase.class, STORE_NAME)); super(storeFactory.getStore(XmlUserDatabase.class, STORE_NAME));
} }

View File

@@ -41,11 +41,11 @@ import org.slf4j.LoggerFactory;
import sonia.scm.GenericDAO; import sonia.scm.GenericDAO;
import sonia.scm.ModelObject; import sonia.scm.ModelObject;
import sonia.scm.group.xml.XmlGroupDAO; import sonia.scm.group.xml.XmlGroupDAO;
import sonia.scm.store.Store;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.util.Collection; import java.util.Collection;
import sonia.scm.store.ConfigurationStore;
/** /**
* *
@@ -76,7 +76,7 @@ public abstract class AbstractXmlDAO<I extends ModelObject,
* *
* @param store * @param store
*/ */
public AbstractXmlDAO(Store<T> store) public AbstractXmlDAO(ConfigurationStore<T> store)
{ {
this.store = store; this.store = store;
db = store.get(); db = store.get();
@@ -290,7 +290,7 @@ public abstract class AbstractXmlDAO<I extends ModelObject,
//~--- fields --------------------------------------------------------------- //~--- fields ---------------------------------------------------------------
/** Field description */ /** Field description */
private final Store<T> store; private final ConfigurationStore<T> store;
/** Field description */ /** Field description */
protected T db; protected T db;

View File

@@ -33,25 +33,15 @@
package sonia.scm.store; package sonia.scm.store;
/** /**
* * Unit tests for {@link JAXBConfigurationStore}.
*
* @author Sebastian Sdorra * @author Sebastian Sdorra
*/ */
public class JAXBStoreTest extends StoreTestBase public class JAXBConfigurationStoreTest extends StoreTestBase {
{
/**
* Method description
*
*
* @return
*/
@Override @Override
protected StoreFactory createStoreFactory() protected ConfigurationStoreFactory createStoreFactory()
{ {
JAXBStoreFactory factory = new JAXBStoreFactory(); return new JAXBConfigurationStoreFactory(contextProvider);
factory.init(contextProvider);
return factory;
} }
} }

View File

@@ -44,12 +44,12 @@ import sonia.scm.Type;
import sonia.scm.io.FileSystem; import sonia.scm.io.FileSystem;
import sonia.scm.plugin.Extension; import sonia.scm.plugin.Extension;
import sonia.scm.repository.spi.GitRepositoryServiceProvider; import sonia.scm.repository.spi.GitRepositoryServiceProvider;
import sonia.scm.store.StoreFactory;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -89,7 +89,7 @@ public class GitRepositoryHandler
* @param fileSystem * @param fileSystem
*/ */
@Inject @Inject
public GitRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem) public GitRepositoryHandler(ConfigurationStoreFactory storeFactory, FileSystem fileSystem)
{ {
super(storeFactory, fileSystem); super(storeFactory, fileSystem);
} }

View File

@@ -36,13 +36,13 @@ package sonia.scm.repository;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*; import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -86,7 +86,7 @@ public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
* @return * @return
*/ */
@Override @Override
protected RepositoryHandler createRepositoryHandler(StoreFactory factory, protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
File directory) File directory)
{ {
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory, GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory,

View File

@@ -56,7 +56,6 @@ import sonia.scm.io.INIConfigurationWriter;
import sonia.scm.io.INISection; import sonia.scm.io.INISection;
import sonia.scm.plugin.Extension; import sonia.scm.plugin.Extension;
import sonia.scm.repository.spi.HgRepositoryServiceProvider; import sonia.scm.repository.spi.HgRepositoryServiceProvider;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
import sonia.scm.util.SystemUtil; import sonia.scm.util.SystemUtil;
import sonia.scm.util.Util; import sonia.scm.util.Util;
@@ -73,6 +72,7 @@ import java.text.MessageFormat;
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -122,7 +122,7 @@ public class HgRepositoryHandler
* @param hgContextProvider * @param hgContextProvider
*/ */
@Inject @Inject
public HgRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem, public HgRepositoryHandler(ConfigurationStoreFactory storeFactory, FileSystem fileSystem,
Provider<HgContext> hgContextProvider) Provider<HgContext> hgContextProvider)
{ {
super(storeFactory, fileSystem); super(storeFactory, fileSystem);

View File

@@ -37,13 +37,13 @@ package sonia.scm.repository;
import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*; import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -83,7 +83,7 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
* @return * @return
*/ */
@Override @Override
protected RepositoryHandler createRepositoryHandler(StoreFactory factory, protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
File directory) File directory)
{ {
HgRepositoryHandler handler = new HgRepositoryHandler(factory, HgRepositoryHandler handler = new HgRepositoryHandler(factory,
@@ -98,3 +98,4 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
return handler; return handler;
} }
} }
//~--- non-JDK imports --------------------------------------------------------

View File

@@ -39,7 +39,7 @@ import org.junit.Assume;
import sonia.scm.SCMContext; import sonia.scm.SCMContext;
import sonia.scm.io.FileSystem; import sonia.scm.io.FileSystem;
import sonia.scm.store.MemoryStoreFactory; import sonia.scm.store.InMemoryConfigurationStoreFactory;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@@ -105,7 +105,7 @@ public final class HgTestUtil
FileSystem fileSystem = mock(FileSystem.class); FileSystem fileSystem = mock(FileSystem.class);
HgRepositoryHandler handler = HgRepositoryHandler handler =
new HgRepositoryHandler(new MemoryStoreFactory(), fileSystem, new HgRepositoryHandler(new InMemoryConfigurationStoreFactory(), fileSystem,
new HgContextProvider()); new HgContextProvider());
handler.init(context); handler.init(context);

View File

@@ -54,7 +54,6 @@ import sonia.scm.io.FileSystem;
import sonia.scm.logging.SVNKitLogger; import sonia.scm.logging.SVNKitLogger;
import sonia.scm.plugin.Extension; import sonia.scm.plugin.Extension;
import sonia.scm.repository.spi.SvnRepositoryServiceProvider; import sonia.scm.repository.spi.SvnRepositoryServiceProvider;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.Util; import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -62,6 +61,7 @@ import sonia.scm.util.Util;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import sonia.scm.repository.spi.HookEventFacade; import sonia.scm.repository.spi.HookEventFacade;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -106,7 +106,7 @@ public class SvnRepositoryHandler
* @param repositoryManager * @param repositoryManager
*/ */
@Inject @Inject
public SvnRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem, public SvnRepositoryHandler(ConfigurationStoreFactory storeFactory, FileSystem fileSystem,
HookEventFacade eventFacade) HookEventFacade eventFacade)
{ {
super(storeFactory, fileSystem); super(storeFactory, fileSystem);

View File

@@ -36,13 +36,13 @@ package sonia.scm.repository;
//~--- non-JDK imports -------------------------------------------------------- //~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*; import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -81,7 +81,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
* @return * @return
*/ */
@Override @Override
protected RepositoryHandler createRepositoryHandler(StoreFactory factory, protected RepositoryHandler createRepositoryHandler(ConfigurationStoreFactory factory,
File directory) File directory)
{ {
SvnRepositoryHandler handler = new SvnRepositoryHandler(factory, SvnRepositoryHandler handler = new SvnRepositoryHandler(factory,

View File

@@ -37,12 +37,12 @@ package sonia.scm.repository;
import sonia.scm.Type; import sonia.scm.Type;
import sonia.scm.io.DefaultFileSystem; import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -69,7 +69,7 @@ public class DummyRepositoryHandler
* *
* @param storeFactory * @param storeFactory
*/ */
public DummyRepositoryHandler(StoreFactory storeFactory) public DummyRepositoryHandler(ConfigurationStoreFactory storeFactory)
{ {
super(storeFactory, new DefaultFileSystem()); super(storeFactory, new DefaultFileSystem());
} }

View File

@@ -38,8 +38,7 @@ package sonia.scm.repository;
import org.junit.Test; import org.junit.Test;
import sonia.scm.AbstractTestBase; import sonia.scm.AbstractTestBase;
import sonia.scm.store.MemoryStoreFactory; import sonia.scm.store.InMemoryConfigurationStoreFactory;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@@ -48,6 +47,7 @@ import static org.junit.Assert.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -74,7 +74,7 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase
* @return * @return
*/ */
protected abstract RepositoryHandler createRepositoryHandler( protected abstract RepositoryHandler createRepositoryHandler(
StoreFactory factory, File directory); ConfigurationStoreFactory factory, File directory);
/** /**
* Method description * Method description
@@ -150,11 +150,8 @@ public abstract class SimpleRepositoryHandlerTestBase extends AbstractTestBase
@Override @Override
protected void postSetUp() throws Exception protected void postSetUp() throws Exception
{ {
MemoryStoreFactory storeFactory = new MemoryStoreFactory(); InMemoryConfigurationStoreFactory storeFactory = new InMemoryConfigurationStoreFactory();
baseDirectory = new File(contextProvider.getBaseDirectory(), "repositories");
storeFactory.init(contextProvider);
baseDirectory = new File(contextProvider.getBaseDirectory(),
"repositories");
IOUtil.mkdirs(baseDirectory); IOUtil.mkdirs(baseDirectory);
handler = createRepositoryHandler(storeFactory, baseDirectory); handler = createRepositoryHandler(storeFactory, baseDirectory);
} }

View File

@@ -28,48 +28,27 @@
* http://bitbucket.org/sdorra/scm-manager * http://bitbucket.org/sdorra/scm-manager
* *
*/ */
package sonia.scm.store; package sonia.scm.store;
/** /**
* * In memory store implementation of {@link ConfigurationStore}.
*
* @author Sebastian Sdorra * @author Sebastian Sdorra
* *
* @param <T> * @param <T> type of stored object
*/ */
public class MemoryStore<T> implements Store<T> public class InMemoryConfigurationStore<T> implements ConfigurationStore<T> {
{
private T object;
/**
* Method description
*
*
* @return
*/
@Override @Override
public T get() public T get() {
{
return object; return object;
} }
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param obejct
*/
@Override @Override
public void set(T obejct) public void set(T obejct) {
{
this.object = obejct; this.object = obejct;
} }
//~--- fields ---------------------------------------------------------------
/** Field description */
private T object;
} }

View File

@@ -0,0 +1,50 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
/**
* In memory configuration store factory for testing purposes.
*
* @author Sebastian Sdorra
*/
public class InMemoryConfigurationStoreFactory implements ConfigurationStoreFactory {
@Override
public <T> ConfigurationStore<T> getStore(Class<T> type, String name)
{
return new InMemoryConfigurationStore<>();
}
}

View File

@@ -56,7 +56,7 @@ public abstract class StoreTestBase extends AbstractTestBase
* *
* @return * @return
*/ */
protected abstract StoreFactory createStoreFactory(); protected abstract ConfigurationStoreFactory createStoreFactory();
/** /**
* Method description * Method description
@@ -65,7 +65,7 @@ public abstract class StoreTestBase extends AbstractTestBase
@Test @Test
public void testGet() public void testGet()
{ {
Store<StoreObject> store = createStoreFactory().getStore(StoreObject.class, ConfigurationStore<StoreObject> store = createStoreFactory().getStore(StoreObject.class,
"test"); "test");
assertNotNull(store); assertNotNull(store);
@@ -82,7 +82,7 @@ public abstract class StoreTestBase extends AbstractTestBase
@Test @Test
public void testSet() public void testSet()
{ {
Store<StoreObject> store = createStoreFactory().getStore(StoreObject.class, ConfigurationStore<StoreObject> store = createStoreFactory().getStore(StoreObject.class,
"test"); "test");
assertNotNull(store); assertNotNull(store);

View File

@@ -54,7 +54,6 @@ import sonia.scm.plugin.DefaultPluginLoader;
import sonia.scm.plugin.ExtensionProcessor; import sonia.scm.plugin.ExtensionProcessor;
import sonia.scm.plugin.PluginWrapper; import sonia.scm.plugin.PluginWrapper;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
import sonia.scm.store.StoreFactory;
import sonia.scm.upgrade.UpgradeManager; import sonia.scm.upgrade.UpgradeManager;
import sonia.scm.user.UserManager; import sonia.scm.user.UserManager;
import sonia.scm.util.IOUtil; import sonia.scm.util.IOUtil;
@@ -119,9 +118,6 @@ public class ScmContextListener extends GuiceServletContextListener
// close UserManager // close UserManager
IOUtil.close(globalInjector.getInstance(UserManager.class)); IOUtil.close(globalInjector.getInstance(UserManager.class));
// close StoreFactory
IOUtil.close(globalInjector.getInstance(StoreFactory.class));
// close CacheManager // close CacheManager
IOUtil.close(globalInjector.getInstance(CacheManager.class)); IOUtil.close(globalInjector.getInstance(CacheManager.class));

View File

@@ -91,8 +91,7 @@ import sonia.scm.store.DataStoreFactory;
import sonia.scm.store.FileBlobStoreFactory; import sonia.scm.store.FileBlobStoreFactory;
import sonia.scm.store.JAXBConfigurationEntryStoreFactory; import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
import sonia.scm.store.JAXBDataStoreFactory; import sonia.scm.store.JAXBDataStoreFactory;
import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.JAXBConfigurationStoreFactory;
import sonia.scm.store.StoreFactory;
import sonia.scm.template.MustacheTemplateEngine; import sonia.scm.template.MustacheTemplateEngine;
import sonia.scm.template.TemplateEngine; import sonia.scm.template.TemplateEngine;
import sonia.scm.template.TemplateEngineFactory; import sonia.scm.template.TemplateEngineFactory;
@@ -127,6 +126,7 @@ import com.sun.jersey.spi.container.servlet.ServletContainer;
import java.util.Map; import java.util.Map;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -227,7 +227,7 @@ public class ScmServletModule extends JerseyServletModule
ScmConfiguration config = getScmConfiguration(); ScmConfiguration config = getScmConfiguration();
CipherUtil cu = CipherUtil.getInstance(); CipherUtil cu = CipherUtil.getInstance();
// bind repository provider // bind repository provider
ThrowingProviderBinder.create(binder()).bind( ThrowingProviderBinder.create(binder()).bind(
RepositoryProvider.class, Repository.class).to( RepositoryProvider.class, Repository.class).to(
@@ -241,9 +241,8 @@ public class ScmServletModule extends JerseyServletModule
bind(ScmEventBus.class).toInstance(ScmEventBus.getInstance()); bind(ScmEventBus.class).toInstance(ScmEventBus.getInstance());
// bind core // bind core
bind(StoreFactory.class, JAXBStoreFactory.class); bind(ConfigurationStoreFactory.class, JAXBConfigurationStoreFactory.class);
bind(ConfigurationEntryStoreFactory.class, bind(ConfigurationEntryStoreFactory.class, JAXBConfigurationEntryStoreFactory.class);
JAXBConfigurationEntryStoreFactory.class);
bind(DataStoreFactory.class, JAXBDataStoreFactory.class); bind(DataStoreFactory.class, JAXBDataStoreFactory.class);
bind(BlobStoreFactory.class, FileBlobStoreFactory.class); bind(BlobStoreFactory.class, FileBlobStoreFactory.class);
bind(ScmConfiguration.class).toInstance(config); bind(ScmConfiguration.class).toInstance(config);

View File

@@ -53,7 +53,6 @@ import sonia.scm.repository.RepositoryHandler;
import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.RepositoryManager;
import sonia.scm.security.Role; import sonia.scm.security.Role;
import sonia.scm.security.ScmSecurityException; import sonia.scm.security.ScmSecurityException;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.SystemUtil; import sonia.scm.util.SystemUtil;
//~--- JDK imports ------------------------------------------------------------ //~--- JDK imports ------------------------------------------------------------
@@ -73,6 +72,7 @@ import javax.ws.rs.GET;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -105,7 +105,7 @@ public class SupportResource
@Inject @Inject
public SupportResource(SCMContextProvider context, public SupportResource(SCMContextProvider context,
ScmConfiguration configuration, PluginManager pluginManager, ScmConfiguration configuration, PluginManager pluginManager,
StoreFactory storeFactory, RepositoryManager repositoryManager, ConfigurationStoreFactory storeFactory, RepositoryManager repositoryManager,
HttpServletRequest request) HttpServletRequest request)
{ {
this.context = context; this.context = context;

View File

@@ -46,8 +46,7 @@ import sonia.scm.repository.api.HookFeature;
import sonia.scm.repository.spi.HookContextProvider; import sonia.scm.repository.spi.HookContextProvider;
import sonia.scm.repository.xml.XmlRepositoryDAO; import sonia.scm.repository.xml.XmlRepositoryDAO;
import sonia.scm.security.DefaultKeyGenerator; import sonia.scm.security.DefaultKeyGenerator;
import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.JAXBConfigurationStoreFactory;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
@@ -61,6 +60,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import org.apache.shiro.authz.UnauthorizedException; import org.apache.shiro.authz.UnauthorizedException;
import org.hamcrest.Matchers;
import org.junit.Rule; import org.junit.Rule;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
@@ -69,6 +69,7 @@ import sonia.scm.Manager;
import sonia.scm.ManagerTestBase; import sonia.scm.ManagerTestBase;
import sonia.scm.event.ScmEventBus; import sonia.scm.event.ScmEventBus;
import sonia.scm.security.KeyGenerator; import sonia.scm.security.KeyGenerator;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* Unit tests for {@link DefaultRepositoryManager}. * Unit tests for {@link DefaultRepositoryManager}.
@@ -282,6 +283,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
* @throws RepositoryException * @throws RepositoryException
*/ */
@Test @Test
@SuppressWarnings("unchecked")
@SubjectAware(username = "dent") @SubjectAware(username = "dent")
public void testGetAllWithPermissions() throws RepositoryException, IOException { public void testGetAllWithPermissions() throws RepositoryException, IOException {
// mock key generator // mock key generator
@@ -316,8 +318,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
// assert returned repositories // assert returned repositories
Collection<Repository> repositories = repositoryManager.getAll(); Collection<Repository> repositories = repositoryManager.getAll();
assertEquals(2, repositories.size()); assertEquals(2, repositories.size());
assertThat(repositories, assertThat(repositories, containsInAnyOrder(
containsInAnyOrder(
hasProperty("id", is("p42")), hasProperty("id", is("p42")),
hasProperty("id", is("hof")) hasProperty("id", is("hof"))
) )
@@ -520,9 +521,7 @@ public class DefaultRepositoryManagerTest extends ManagerTestBase<Repository, Re
private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled, KeyGenerator keyGenerator) { private DefaultRepositoryManager createRepositoryManager(boolean archiveEnabled, KeyGenerator keyGenerator) {
Set<RepositoryHandler> handlerSet = new HashSet<>(); Set<RepositoryHandler> handlerSet = new HashSet<>();
StoreFactory factory = new JAXBStoreFactory(); ConfigurationStoreFactory factory = new JAXBConfigurationStoreFactory(contextProvider);
factory.init(contextProvider);
handlerSet.add(new DummyRepositoryHandler(factory)); handlerSet.add(new DummyRepositoryHandler(factory));
handlerSet.add(new DummyRepositoryHandler(factory) { handlerSet.add(new DummyRepositoryHandler(factory) {
@Override @Override

View File

@@ -42,8 +42,7 @@ import com.google.common.collect.Lists;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.JAXBConfigurationStoreFactory;
import sonia.scm.store.StoreFactory;
import sonia.scm.user.xml.XmlUserDAO; import sonia.scm.user.xml.XmlUserDAO;
import sonia.scm.util.MockUtil; import sonia.scm.util.MockUtil;
@@ -54,6 +53,7 @@ import static org.mockito.Mockito.*;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.junit.Rule; import org.junit.Rule;
import sonia.scm.store.ConfigurationStoreFactory;
/** /**
* *
@@ -120,18 +120,7 @@ public class DefaultUserManagerTest extends UserManagerTestBase
//~--- methods -------------------------------------------------------------- //~--- methods --------------------------------------------------------------
/** private XmlUserDAO createXmlUserDAO() {
* Method description return new XmlUserDAO(new JAXBConfigurationStoreFactory(contextProvider));
*
*
* @return
*/
private XmlUserDAO createXmlUserDAO()
{
StoreFactory factory = new JAXBStoreFactory();
factory.init(contextProvider);
return new XmlUserDAO(factory);
} }
} }