From 2c7fee14e8282f0bfbe6620d145364b770a060aa Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 7 Nov 2010 15:19:00 +0100 Subject: [PATCH] improve XmlUserHandler --- .../src/main/java/sonia/scm/user/User.java | 26 ++- .../sonia/scm/user/xml/XmlUserDatabase.java | 185 ++++++++++++++++++ .../scm/user/{ => xml}/XmlUserHandler.java | 137 ++++++------- .../java/sonia/scm/user/xml/XmlUserList.java | 123 ++++++++++++ .../sonia/scm/user/xml/XmlUserMapAdapter.java | 93 +++++++++ .../java/sonia/scm/xml/XmlDateAdapter.java | 84 ++++++++ .../scm/xml/XmlTimestampDateAdapter.java | 84 ++++++++ .../sonia/scm/user/UserHandlerTestBase.java | 34 +++- .../sonia/scm/user/XmlUserHandlerTest.java | 2 + .../main/java/sonia/scm/ScmServletModule.java | 2 +- .../scm/web/security/XmlAuthenticator.java | 2 +- 11 files changed, 702 insertions(+), 70 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/user/xml/XmlUserDatabase.java rename scm-core/src/main/java/sonia/scm/user/{ => xml}/XmlUserHandler.java (75%) create mode 100644 scm-core/src/main/java/sonia/scm/user/xml/XmlUserList.java create mode 100644 scm-core/src/main/java/sonia/scm/user/xml/XmlUserMapAdapter.java create mode 100644 scm-core/src/main/java/sonia/scm/xml/XmlDateAdapter.java create mode 100644 scm-core/src/main/java/sonia/scm/xml/XmlTimestampDateAdapter.java diff --git a/scm-core/src/main/java/sonia/scm/user/User.java b/scm-core/src/main/java/sonia/scm/user/User.java index 7f710de4b9..a7b93578db 100644 --- a/scm-core/src/main/java/sonia/scm/user/User.java +++ b/scm-core/src/main/java/sonia/scm/user/User.java @@ -58,7 +58,7 @@ import javax.xml.bind.annotation.XmlType; { "name", "displayName", "mail", "password", "type" }) -public class User implements TypedObject, Principal, Serializable +public class User implements TypedObject, Principal, Cloneable, Serializable { /** Field description */ @@ -89,6 +89,30 @@ public class User implements TypedObject, Principal, Serializable //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @return + * + */ + @Override + public User clone() + { + User user = null; + + try + { + user = (User) super.clone(); + } + catch (CloneNotSupportedException ex) + { + throw new RuntimeException(ex); + } + + return user; + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/user/xml/XmlUserDatabase.java b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserDatabase.java new file mode 100644 index 0000000000..b159147e50 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserDatabase.java @@ -0,0 +1,185 @@ +/** + * 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.user.xml; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.user.User; +import sonia.scm.xml.XmlTimestampDateAdapter; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "user-db") +@XmlAccessorType(XmlAccessType.FIELD) +public class XmlUserDatabase +{ + + /** + * Method description + * + * + * @param user + */ + public void add(User user) + { + userMap.put(user.getName(), user); + } + + /** + * Method description + * + * + * @param username + * + * @return + */ + public boolean contains(String username) + { + return userMap.containsKey(username); + } + + /** + * Method description + * + * + * @param username + * + * @return + */ + public User remove(String username) + { + return userMap.remove(username); + } + + /** + * Method description + * + * + * @return + */ + public Collection values() + { + return userMap.values(); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param username + * + * @return + */ + public User get(String username) + { + return userMap.get(username); + } + + /** + * Method description + * + * + * @return + */ + public long getCreationTime() + { + return creationTime; + } + + /** + * Method description + * + * + * @return + */ + public long getLastModified() + { + return lastModified; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param creationTime + */ + public void setCreationTime(long creationTime) + { + this.creationTime = creationTime; + } + + /** + * Method description + * + * + * @param lastModified + */ + public void setLastModified(long lastModified) + { + this.lastModified = lastModified; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @XmlJavaTypeAdapter(XmlTimestampDateAdapter.class) + private Long creationTime; + + /** Field description */ + @XmlJavaTypeAdapter(XmlTimestampDateAdapter.class) + private Long lastModified; + + /** Field description */ + @XmlJavaTypeAdapter(XmlUserMapAdapter.class) + @XmlElement(name = "users") + private Map userMap = new LinkedHashMap(); +} diff --git a/scm-core/src/main/java/sonia/scm/user/XmlUserHandler.java b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserHandler.java similarity index 75% rename from scm-core/src/main/java/sonia/scm/user/XmlUserHandler.java rename to scm-core/src/main/java/sonia/scm/user/xml/XmlUserHandler.java index e0185c8d8d..42ab029854 100644 --- a/scm-core/src/main/java/sonia/scm/user/XmlUserHandler.java +++ b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserHandler.java @@ -31,7 +31,7 @@ -package sonia.scm.user; +package sonia.scm.user.xml; //~--- non-JDK imports -------------------------------------------------------- @@ -42,19 +42,20 @@ import org.slf4j.LoggerFactory; import sonia.scm.SCMContextProvider; import sonia.scm.Type; +import sonia.scm.user.User; +import sonia.scm.user.UserAllreadyExistException; +import sonia.scm.user.UserException; +import sonia.scm.user.UserHandler; import sonia.scm.util.IOUtil; //~--- JDK imports ------------------------------------------------------------ import java.io.File; -import java.io.FileOutputStream; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; +import java.util.LinkedList; import javax.xml.bind.JAXB; @@ -66,9 +67,6 @@ import javax.xml.bind.JAXB; public class XmlUserHandler implements UserHandler { - /** Field description */ - public static final String ADMIN_FILE = "scmadmin.xml"; - /** Field description */ public static final String ADMIN_PATH = "/sonia/scm/config/admin-account.xml"; @@ -85,8 +83,8 @@ public class XmlUserHandler implements UserHandler public static final Type type = new Type(TYPE_NAME, TYPE_DISPLAYNAME); /** Field description */ - public static final String DIRECTORY = - "user".concat(File.separator).concat("xml"); + public static final String DATABASEFILE = + "config".concat(File.separator).concat("users.xml"); /** the logger for XmlUserHandler */ private static final Logger logger = @@ -119,14 +117,18 @@ public class XmlUserHandler implements UserHandler @Override public void create(User user) throws UserException, IOException { - File file = getFile(user.getName()); - - if (file.exists()) + if (userDB.contains(user.getName())) { throw new UserAllreadyExistException(); } - JAXB.marshal(user, file); + user.setType(TYPE_NAME); + + synchronized (XmlUserHandler.class) + { + userDB.add(user.clone()); + storeDB(); + } } /** @@ -141,11 +143,15 @@ public class XmlUserHandler implements UserHandler @Override public void delete(User user) throws UserException, IOException { - File file = getFile(user.getName()); + String name = user.getName(); - if (file.exists()) + if (userDB.contains(name)) { - IOUtil.delete(file); + synchronized (XmlUserHandler.class) + { + userDB.remove(name); + storeDB(); + } } else { @@ -164,11 +170,17 @@ public class XmlUserHandler implements UserHandler { File directory = context.getBaseDirectory(); - userDirectory = new File(directory, DIRECTORY); + userDBFile = new File(directory, DATABASEFILE); - if (!userDirectory.exists()) + if (userDBFile.exists()) { - IOUtil.mkdirs(userDirectory); + loadDB(); + } + else + { + IOUtil.mkdirs(userDBFile.getParentFile()); + userDB = new XmlUserDatabase(); + userDB.setCreationTime(System.currentTimeMillis()); createAdminAccount(); } } @@ -185,11 +197,18 @@ public class XmlUserHandler implements UserHandler @Override public void modify(User user) throws UserException, IOException { - File file = getFile(user.getName()); + String name = user.getName(); - if (file.exists()) + if (userDB.contains(name)) { - JAXB.marshal(user, file); + user.setType(TYPE_NAME); + + synchronized (XmlUserHandler.class) + { + userDB.remove(name); + userDB.add(user.clone()); + storeDB(); + } } else { @@ -209,7 +228,7 @@ public class XmlUserHandler implements UserHandler @Override public void refresh(User user) throws UserException, IOException { - User fresh = get(user.getName()); + User fresh = userDB.get(user.getName()); if (fresh == null) { @@ -235,12 +254,11 @@ public class XmlUserHandler implements UserHandler @Override public User get(String id) { - User user = null; - File file = getFile(id); + User user = userDB.get(id); - if (file.exists()) + if (user != null) { - user = JAXB.unmarshal(file, User.class); + user = user.clone(); } return user; @@ -255,31 +273,11 @@ public class XmlUserHandler implements UserHandler @Override public Collection getAll() { - List users = new ArrayList(); - File[] userFiles = userDirectory.listFiles(new FilenameFilter() - { - @Override - public boolean accept(File dir, String name) - { - return name.endsWith(FILE_EXTENSION); - } - }); + LinkedList users = new LinkedList(); - for (File userFile : userFiles) + for (User user : userDB.values()) { - try - { - User user = JAXB.unmarshal(userFile, User.class); - - if (user != null) - { - users.add(user); - } - } - catch (Exception ex) - { - logger.error(ex.getMessage(), ex); - } + users.add(user.clone()); } return users; @@ -306,7 +304,7 @@ public class XmlUserHandler implements UserHandler @Override public boolean isConfigured() { - return (userDirectory != null) && userDirectory.exists(); + return (userDBFile != null) && userDBFile.exists(); } //~--- methods -------------------------------------------------------------- @@ -318,41 +316,48 @@ public class XmlUserHandler implements UserHandler private void createAdminAccount() { InputStream input = XmlUserHandler.class.getResourceAsStream(ADMIN_PATH); - FileOutputStream output = null; try { - output = new FileOutputStream(new File(userDirectory, ADMIN_FILE)); - IOUtil.copy(input, output); + User user = JAXB.unmarshal(input, User.class); + + userDB.add(user); + storeDB(); } - catch (IOException ex) + catch (Exception ex) { logger.error("could not create AdminAccount", ex); } finally { IOUtil.close(input); - IOUtil.close(output); } } - //~--- get methods ---------------------------------------------------------- - /** * Method description * - * - * @param id - * - * @return */ - private File getFile(String id) + private void loadDB() { - return new File(userDirectory, id.concat(FILE_EXTENSION)); + userDB = JAXB.unmarshal(userDBFile, XmlUserDatabase.class); + } + + /** + * Method description + * + */ + private void storeDB() + { + userDB.setLastModified(System.currentTimeMillis()); + JAXB.marshal(userDB, userDBFile); } //~--- fields --------------------------------------------------------------- /** Field description */ - private File userDirectory; + private XmlUserDatabase userDB; + + /** Field description */ + private File userDBFile; } diff --git a/scm-core/src/main/java/sonia/scm/user/xml/XmlUserList.java b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserList.java new file mode 100644 index 0000000000..e76f008b92 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserList.java @@ -0,0 +1,123 @@ +/** + * 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.user.xml; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.user.User; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "users") +@XmlAccessorType(XmlAccessType.FIELD) +public class XmlUserList implements Iterable +{ + + /** + * Constructs ... + * + */ + public XmlUserList() {} + + /** + * Constructs ... + * + * + * + * @param userMap + */ + public XmlUserList(Map userMap) + { + this.users = new LinkedList(userMap.values()); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public Iterator iterator() + { + return users.iterator(); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public LinkedList getUsers() + { + return users; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param users + */ + public void setUsers(LinkedList users) + { + this.users = users; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @XmlElement(name = "user") + private LinkedList users; +} diff --git a/scm-core/src/main/java/sonia/scm/user/xml/XmlUserMapAdapter.java b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserMapAdapter.java new file mode 100644 index 0000000000..f5573310d5 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/user/xml/XmlUserMapAdapter.java @@ -0,0 +1,93 @@ +/** + * 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.user.xml; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.user.User; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * + * @author Sebastian Sdorra + */ +public class XmlUserMapAdapter + extends XmlAdapter> +{ + + /** + * Method description + * + * + * @param userMap + * + * @return + * + * @throws Exception + */ + @Override + public XmlUserList marshal(Map userMap) throws Exception + { + return new XmlUserList(userMap); + } + + /** + * Method description + * + * + * @param users + * + * @return + * + * @throws Exception + */ + @Override + public Map unmarshal(XmlUserList users) throws Exception + { + Map userMap = new LinkedHashMap(); + + for (User user : users) + { + userMap.put(user.getName(), user); + } + + return userMap; + } +} diff --git a/scm-core/src/main/java/sonia/scm/xml/XmlDateAdapter.java b/scm-core/src/main/java/sonia/scm/xml/XmlDateAdapter.java new file mode 100644 index 0000000000..1cd7ddf1f8 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/xml/XmlDateAdapter.java @@ -0,0 +1,84 @@ +/** + * 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.xml; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Date; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * + * @author Sebastian Sdorra + */ +public class XmlDateAdapter extends XmlAdapter +{ + + /** + * Method description + * + * + * @param date + * + * @return + * + * @throws Exception + */ + @Override + public String marshal(Date date) throws Exception + { + return Util.formatDate(date); + } + + /** + * Method description + * + * + * @param value + * + * @return + * + * @throws Exception + */ + @Override + public Date unmarshal(String value) throws Exception + { + return Util.parseDate(value); + } +} diff --git a/scm-core/src/main/java/sonia/scm/xml/XmlTimestampDateAdapter.java b/scm-core/src/main/java/sonia/scm/xml/XmlTimestampDateAdapter.java new file mode 100644 index 0000000000..ca81c1e5b7 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/xml/XmlTimestampDateAdapter.java @@ -0,0 +1,84 @@ +/** + * 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.xml; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Date; + +import javax.xml.bind.annotation.adapters.XmlAdapter; + +/** + * + * @author Sebastian Sdorra + */ +public class XmlTimestampDateAdapter extends XmlAdapter +{ + + /** + * Method description + * + * + * @param value + * + * @return + * + * @throws Exception + */ + @Override + public String marshal(Long value) throws Exception + { + return Util.formatDate(new Date(value)); + } + + /** + * Method description + * + * + * @param value + * + * @return + * + * @throws Exception + */ + @Override + public Long unmarshal(String value) throws Exception + { + return Util.parseDate(value).getTime(); + } +} diff --git a/scm-core/src/test/java/sonia/scm/user/UserHandlerTestBase.java b/scm-core/src/test/java/sonia/scm/user/UserHandlerTestBase.java index 8d1b28918f..d5af297d00 100644 --- a/scm-core/src/test/java/sonia/scm/user/UserHandlerTestBase.java +++ b/scm-core/src/test/java/sonia/scm/user/UserHandlerTestBase.java @@ -160,7 +160,12 @@ public abstract class UserHandlerTestBase handler.create(zaphod); assertNotNull(handler.get("zaphod")); - handler.get(""); + + // test for reference + zaphod.setDisplayName("Tricia McMillan"); + zaphod = handler.get("zaphod"); + assertNotNull(zaphod); + assertEquals("Zaphod Beeblebrox", zaphod.getDisplayName()); } /** @@ -208,6 +213,33 @@ public abstract class UserHandlerTestBase assertTrue(foundZaphod); assertTrue(foundTrillian); + + // test for reference + trillian = null; + + for (User u : users) + { + if (u.getName().equals("trillian")) + { + trillian = u; + } + } + + assertNotNull(trillian); + trillian.setDisplayName("Zaphod Beeblebrox"); + + User reference = null; + + for (User u : handler.getAll()) + { + if (u.getName().equals("trillian")) + { + reference = u; + } + } + + assertNotNull(reference); + assertEquals(reference.getDisplayName(), "Tricia McMillan"); } /** diff --git a/scm-core/src/test/java/sonia/scm/user/XmlUserHandlerTest.java b/scm-core/src/test/java/sonia/scm/user/XmlUserHandlerTest.java index 60a62d139e..6bb8475175 100644 --- a/scm-core/src/test/java/sonia/scm/user/XmlUserHandlerTest.java +++ b/scm-core/src/test/java/sonia/scm/user/XmlUserHandlerTest.java @@ -33,6 +33,8 @@ package sonia.scm.user; +import sonia.scm.user.xml.XmlUserHandler; + /** * * @author Sebastian Sdorra diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 2d05edaebc..1d9d791d12 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -55,7 +55,7 @@ import sonia.scm.security.MessageDigestEncryptionHandler; import sonia.scm.user.BasicUserManager; import sonia.scm.user.UserHandler; import sonia.scm.user.UserManager; -import sonia.scm.user.XmlUserHandler; +import sonia.scm.user.xml.XmlUserHandler; import sonia.scm.util.DebugServlet; import sonia.scm.util.Util; import sonia.scm.web.plugin.SCMPlugin; diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/XmlAuthenticator.java b/scm-webapp/src/main/java/sonia/scm/web/security/XmlAuthenticator.java index 438efa96f1..5e3ad278d6 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/XmlAuthenticator.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/XmlAuthenticator.java @@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory; import sonia.scm.SCMContextProvider; import sonia.scm.security.EncryptionHandler; import sonia.scm.user.User; -import sonia.scm.user.XmlUserHandler; +import sonia.scm.user.xml.XmlUserHandler; //~--- JDK imports ------------------------------------------------------------