diff --git a/scm-core/src/main/java/sonia/scm/store/Store.java b/scm-core/src/main/java/sonia/scm/store/Store.java new file mode 100644 index 0000000000..4661d8b2f3 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/store/Store.java @@ -0,0 +1,62 @@ +/** + * 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; + +/** + * + * @author Sebastian Sdorra + * + * @param + */ +public interface Store +{ + + /** + * Method description + * + * + * @return + */ + public T get(); + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param obejct + */ + public void set(T obejct); +} diff --git a/scm-core/src/main/java/sonia/scm/StoreException.java b/scm-core/src/main/java/sonia/scm/store/StoreException.java similarity index 98% rename from scm-core/src/main/java/sonia/scm/StoreException.java rename to scm-core/src/main/java/sonia/scm/store/StoreException.java index 64c745ee32..2029302ab2 100644 --- a/scm-core/src/main/java/sonia/scm/StoreException.java +++ b/scm-core/src/main/java/sonia/scm/store/StoreException.java @@ -31,7 +31,7 @@ -package sonia.scm; +package sonia.scm.store; /** * diff --git a/scm-core/src/main/java/sonia/scm/store/StoreFactory.java b/scm-core/src/main/java/sonia/scm/store/StoreFactory.java new file mode 100644 index 0000000000..949f226868 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/store/StoreFactory.java @@ -0,0 +1,62 @@ +/** + * 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 sonia.scm.Initable; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Closeable; + +/** + * + * @author Sebastian Sdorra + */ +public interface StoreFactory extends Initable, Closeable +{ + + /** + * Method description + * + * + * @param type + * @param name + * @param + * + * @return + */ + public Store getStore(Class type, String name); +} diff --git a/scm-test/src/main/java/sonia/scm/ManagerTestBase.java b/scm-test/src/main/java/sonia/scm/ManagerTestBase.java index 0fb53fe465..3ade2d1831 100644 --- a/scm-test/src/main/java/sonia/scm/ManagerTestBase.java +++ b/scm-test/src/main/java/sonia/scm/ManagerTestBase.java @@ -105,11 +105,9 @@ public abstract class ManagerTestBase manager; + /** Field description */ + protected SCMContextProvider provider; + /** Field description */ protected File tempDirectory; } diff --git a/scm-webapp/src/main/java/sonia/scm/ContextListener.java b/scm-webapp/src/main/java/sonia/scm/ContextListener.java index 371663bf4b..a362e9ce37 100644 --- a/scm-webapp/src/main/java/sonia/scm/ContextListener.java +++ b/scm-webapp/src/main/java/sonia/scm/ContextListener.java @@ -43,6 +43,7 @@ import com.google.inject.servlet.GuiceServletContextListener; import sonia.scm.plugin.DefaultPluginManager; import sonia.scm.plugin.PluginManager; import sonia.scm.repository.RepositoryManager; +import sonia.scm.store.StoreFactory; import sonia.scm.user.UserManager; import sonia.scm.util.IOUtil; import sonia.scm.web.security.AuthenticationManager; @@ -81,6 +82,9 @@ public class ContextListener extends GuiceServletContextListener // close UserManager IOUtil.close(injector.getInstance(UserManager.class)); + + // close StoreFactory + IOUtil.close(injector.getInstance(StoreFactory.class)); } super.contextDestroyed(servletContextEvent); @@ -110,15 +114,19 @@ public class ContextListener extends GuiceServletContextListener moduleList.add(0, main); injector = Guice.createInjector(moduleList); + SCMContextProvider context = SCMContext.getContext(); + + // init StoreFactory + injector.getInstance(StoreFactory.class).init(context); + // init RepositoryManager - injector.getInstance(RepositoryManager.class).init(SCMContext.getContext()); + injector.getInstance(RepositoryManager.class).init(context); // init UserManager - injector.getInstance(UserManager.class).init(SCMContext.getContext()); + injector.getInstance(UserManager.class).init(context); // init Authenticator - injector.getInstance(AuthenticationManager.class).init( - SCMContext.getContext()); + injector.getInstance(AuthenticationManager.class).init(context); return injector; } diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index f459f2c265..cab9cf8dec 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -53,6 +53,8 @@ import sonia.scm.repository.xml.XmlRepositoryManager; import sonia.scm.security.EncryptionHandler; import sonia.scm.security.MessageDigestEncryptionHandler; import sonia.scm.security.SecurityContext; +import sonia.scm.store.JAXBStoreFactory; +import sonia.scm.store.StoreFactory; import sonia.scm.user.UserManager; import sonia.scm.user.xml.XmlUserManager; import sonia.scm.util.DebugServlet; @@ -152,6 +154,7 @@ public class ScmServletModule extends ServletModule ScmConfiguration config = getScmConfiguration(context); + bind(StoreFactory.class).to(JAXBStoreFactory.class); bind(ScmConfiguration.class).toInstance(config); bind(PluginManager.class).toInstance(pluginManager); bind(EncryptionHandler.class).to(MessageDigestEncryptionHandler.class); diff --git a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryDatabase.java b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryDatabase.java index 4820894ff6..e7731f9211 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryDatabase.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryDatabase.java @@ -54,11 +54,38 @@ import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; * * @author Sebastian Sdorra */ -@XmlRootElement +@XmlRootElement(name = "repository-db") @XmlAccessorType(XmlAccessType.FIELD) public class XmlRepositoryDatabase { + /** + * Method description + * + * + * @param type + * @param name + * + * @return + */ + static String createKey(String type, String name) + { + return type.concat(":").concat(name); + } + + /** + * Method description + * + * + * @param repository + * + * @return + */ + static String createKey(Repository repository) + { + return createKey(repository.getType(), repository.getName()); + } + /** * Method description * @@ -220,35 +247,6 @@ public class XmlRepositoryDatabase this.lastModified = lastModified; } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param type - * @param name - * - * @return - */ - static String createKey(String type, String name) - { - return type.concat(":").concat(name); - } - - /** - * Method description - * - * - * @param repository - * - * @return - */ - static String createKey(Repository repository) - { - return createKey(repository.getType(), repository.getName()); - } - //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java index fd450c7cc6..4b091ef50b 100644 --- a/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java +++ b/scm-webapp/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java @@ -46,7 +46,6 @@ import sonia.scm.ConfigurationException; import sonia.scm.HandlerEvent; import sonia.scm.SCMContext; import sonia.scm.SCMContextProvider; -import sonia.scm.StoreException; import sonia.scm.Type; import sonia.scm.repository.AbstractRepositoryManager; import sonia.scm.repository.PermissionType; @@ -57,13 +56,14 @@ import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryHandlerNotFoundException; import sonia.scm.security.SecurityContext; +import sonia.scm.store.Store; +import sonia.scm.store.StoreFactory; import sonia.scm.user.User; import sonia.scm.util.AssertUtil; import sonia.scm.util.IOUtil; //~--- JDK imports ------------------------------------------------------------ -import java.io.File; import java.io.IOException; import java.util.Collection; @@ -74,11 +74,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; - /** * * @author Sebastian Sdorra @@ -88,8 +83,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager { /** Field description */ - public static final String DATABASEFILE = - "config".concat(File.separator).concat("repositories.xml"); + public static final String STORE_NAME = "repositories"; /** Field description */ private static final Logger logger = @@ -103,14 +97,16 @@ public class XmlRepositoryManager extends AbstractRepositoryManager * * * @param securityContextProvider + * @param storeFactory * @param handlerSet */ @Inject public XmlRepositoryManager( Provider securityContextProvider, - Set handlerSet) + StoreFactory storeFactory, Set handlerSet) { this.securityContextProvider = securityContextProvider; + this.store = storeFactory.getStore(XmlRepositoryDatabase.class, STORE_NAME); handlerMap = new HashMap(); types = new HashSet(); @@ -118,19 +114,6 @@ public class XmlRepositoryManager extends AbstractRepositoryManager { addHandler(handler); } - - try - { - JAXBContext context = - JAXBContext.newInstance(XmlRepositoryDatabase.class); - - marshaller = context.createMarshaller(); - unmarshaller = context.createUnmarshaller(); - } - catch (JAXBException ex) - { - throw new StoreException(ex); - } } //~--- methods -------------------------------------------------------------- @@ -239,17 +222,10 @@ public class XmlRepositoryManager extends AbstractRepositoryManager @Override public void init(SCMContextProvider context) { - File directory = context.getBaseDirectory(); + repositoryDB = store.get(); - repositoryDBFile = new File(directory, DATABASEFILE); - - if (repositoryDBFile.exists()) + if (repositoryDB == null) { - loadDB(); - } - else - { - IOUtil.mkdirs(repositoryDBFile.getParentFile()); repositoryDB = new XmlRepositoryDatabase(); repositoryDB.setCreationTime(System.currentTimeMillis()); } @@ -508,38 +484,13 @@ public class XmlRepositoryManager extends AbstractRepositoryManager PermissionType.READ); } - /** - * Method description - * - */ - private void loadDB() - { - try - { - repositoryDB = - (XmlRepositoryDatabase) unmarshaller.unmarshal(repositoryDBFile); - } - catch (JAXBException ex) - { - throw new StoreException(ex); - } - } - /** * Method description * */ private void storeDB() { - try - { - repositoryDB.setLastModified(System.currentTimeMillis()); - marshaller.marshal(repositoryDB, repositoryDBFile); - } - catch (JAXBException ex) - { - throw new StoreException(ex); - } + store.set(repositoryDB); } //~--- get methods ---------------------------------------------------------- @@ -609,24 +560,18 @@ public class XmlRepositoryManager extends AbstractRepositoryManager //~--- fields --------------------------------------------------------------- + /** Field description */ + private final Store store; + /** Field description */ private Map handlerMap; - /** Field description */ - private Marshaller marshaller; - /** Field description */ private XmlRepositoryDatabase repositoryDB; - /** Field description */ - private File repositoryDBFile; - /** Field description */ private Provider securityContextProvider; /** Field description */ private Set types; - - /** Field description */ - private Unmarshaller unmarshaller; } diff --git a/scm-webapp/src/main/java/sonia/scm/store/JAXBStore.java b/scm-webapp/src/main/java/sonia/scm/store/JAXBStore.java new file mode 100644 index 0000000000..fe76fb0c5a --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/store/JAXBStore.java @@ -0,0 +1,153 @@ +/** + * 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 org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +/** + * + * @author Sebastian Sdorra + * + * @param + */ +public class JAXBStore implements Store +{ + + /** the logger for JAXBStore */ + private static final Logger logger = LoggerFactory.getLogger(JAXBStore.class); + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param type + * @param configFile + */ + public JAXBStore(Class type, File configFile) + { + try + { + JAXBContext context = JAXBContext.newInstance(type); + + marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + unmarshaller = context.createUnmarshaller(); + this.configFile = configFile; + } + catch (JAXBException ex) + { + throw new StoreException(ex); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public T get() + { + T result = null; + + if (configFile.exists()) + { + try + { + result = (T) unmarshaller.unmarshal(configFile); + } + catch (JAXBException ex) + { + throw new StoreException(ex); + } + } + + return result; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param object + */ + @Override + public void set(T object) + { + if (logger.isDebugEnabled()) + { + logger.debug("store {} to {}", object.getClass().getName(), + configFile.getPath()); + } + + try + { + marshaller.marshal(object, configFile); + } + catch (JAXBException ex) + { + throw new StoreException(ex); + } + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File configFile; + + /** Field description */ + private Marshaller marshaller; + + /** Field description */ + private Unmarshaller unmarshaller; +} diff --git a/scm-webapp/src/main/java/sonia/scm/store/JAXBStoreFactory.java b/scm-webapp/src/main/java/sonia/scm/store/JAXBStoreFactory.java new file mode 100644 index 0000000000..a5806d8f94 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/store/JAXBStoreFactory.java @@ -0,0 +1,128 @@ +/** + * 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 +{ + + /** Field description */ + public static final String CONFIGDIRECTORY_NAME = "config"; + + /** Field description */ + public static final String FILE_EXTENSION = ".xml"; + + /** 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(), + CONFIGDIRECTORY_NAME); + IOUtil.mkdirs(configDirectory); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param type + * @param name + * @param + * + * @return + */ + @Override + public Store getStore(Class type, String name) + { + File configFile = new File(configDirectory, name.concat(FILE_EXTENSION)); + + if (logger.isDebugEnabled()) + { + logger.debug("create store for {} at {}", type.getName(), + configFile.getPath()); + } + + return new JAXBStore(type, configFile); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File configDirectory; +} diff --git a/scm-webapp/src/main/java/sonia/scm/user/xml/XmlUserManager.java b/scm-webapp/src/main/java/sonia/scm/user/xml/XmlUserManager.java index bdc488471b..da78b80b06 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/xml/XmlUserManager.java +++ b/scm-webapp/src/main/java/sonia/scm/user/xml/XmlUserManager.java @@ -43,9 +43,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.SCMContextProvider; -import sonia.scm.StoreException; import sonia.scm.security.ScmSecurityException; import sonia.scm.security.SecurityContext; +import sonia.scm.store.Store; +import sonia.scm.store.StoreFactory; import sonia.scm.user.AbstractUserManager; import sonia.scm.user.User; import sonia.scm.user.UserAllreadyExistException; @@ -56,7 +57,6 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ -import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -64,10 +64,6 @@ import java.util.Collection; import java.util.LinkedList; import javax.xml.bind.JAXB; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; /** * @@ -81,8 +77,7 @@ public class XmlUserManager extends AbstractUserManager public static final String ADMIN_PATH = "/sonia/scm/config/admin-account.xml"; /** Field description */ - public static final String DATABASEFILE = - "config".concat(File.separator).concat("users.xml"); + public static final String STORE_NAME = "users"; /** Field description */ public static final String TYPE = "xml"; @@ -98,23 +93,14 @@ public class XmlUserManager extends AbstractUserManager * * * @param scurityContextProvider + * @param storeFactory */ @Inject - public XmlUserManager(Provider scurityContextProvider) + public XmlUserManager(Provider scurityContextProvider, + StoreFactory storeFactory) { this.scurityContextProvider = scurityContextProvider; - - try - { - JAXBContext context = JAXBContext.newInstance(XmlUserDatabase.class); - - marshaller = context.createMarshaller(); - unmarshaller = context.createUnmarshaller(); - } - catch (JAXBException ex) - { - throw new StoreException(ex); - } + this.store = storeFactory.getStore(XmlUserDatabase.class, STORE_NAME); } //~--- methods -------------------------------------------------------------- @@ -235,17 +221,10 @@ public class XmlUserManager extends AbstractUserManager @Override public void init(SCMContextProvider context) { - File directory = context.getBaseDirectory(); + userDB = store.get(); - userDBFile = new File(directory, DATABASEFILE); - - if (userDBFile.exists()) + if (userDB == null) { - loadDB(); - } - else - { - IOUtil.mkdirs(userDBFile.getParentFile()); userDB = new XmlUserDatabase(); userDB.setCreationTime(System.currentTimeMillis()); createAdminAccount(); @@ -395,53 +374,24 @@ public class XmlUserManager extends AbstractUserManager } } - /** - * Method description - * - */ - private void loadDB() - { - try - { - userDB = (XmlUserDatabase) unmarshaller.unmarshal(userDBFile); - } - catch (JAXBException ex) - { - throw new StoreException(ex); - } - } - /** * Method description * */ private void storeDB() { - try - { - userDB.setLastModified(System.currentTimeMillis()); - marshaller.marshal(userDB, userDBFile); - } - catch (JAXBException ex) - { - throw new StoreException(ex); - } + userDB.setLastModified(System.currentTimeMillis()); + store.set(userDB); } //~--- fields --------------------------------------------------------------- - /** Field description */ - private Marshaller marshaller; - /** Field description */ private Provider scurityContextProvider; /** Field description */ - private Unmarshaller unmarshaller; + private Store store; /** Field description */ private XmlUserDatabase userDB; - - /** Field description */ - private File userDBFile; } diff --git a/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java index a56255a7ab..742fe71519 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/XmlRepositoryManagerTest.java @@ -37,6 +37,8 @@ package sonia.scm.repository; import sonia.scm.Manager; import sonia.scm.repository.xml.XmlRepositoryManager; +import sonia.scm.store.JAXBStoreFactory; +import sonia.scm.store.StoreFactory; //~--- JDK imports ------------------------------------------------------------ @@ -63,7 +65,11 @@ public class XmlRepositoryManagerTest extends RepositoryManagerTestBase handlerSet.add(new DummyRepositoryHandler()); - return new XmlRepositoryManager(getAdminSecurityContextProvider(), + StoreFactory factory = new JAXBStoreFactory(); + + factory.init(provider); + + return new XmlRepositoryManager(getAdminSecurityContextProvider(), factory, handlerSet); } } diff --git a/scm-webapp/src/test/java/sonia/scm/user/XmlUserManagerTest.java b/scm-webapp/src/test/java/sonia/scm/user/XmlUserManagerTest.java index 48edb01ba3..70414d7688 100644 --- a/scm-webapp/src/test/java/sonia/scm/user/XmlUserManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/user/XmlUserManagerTest.java @@ -35,6 +35,8 @@ package sonia.scm.user; //~--- non-JDK imports -------------------------------------------------------- +import sonia.scm.store.JAXBStoreFactory; +import sonia.scm.store.StoreFactory; import sonia.scm.user.xml.XmlUserManager; /** @@ -53,6 +55,10 @@ public class XmlUserManagerTest extends UserManagerTestBase @Override public UserManager createManager() { - return new XmlUserManager(getAdminSecurityContextProvider()); + StoreFactory factory = new JAXBStoreFactory(); + + factory.init(provider); + + return new XmlUserManager(getAdminSecurityContextProvider(), factory); } }