improve XmlUserHandler

This commit is contained in:
Sebastian Sdorra
2010-11-07 15:19:00 +01:00
parent 148cb4bc7f
commit 2c7fee14e8
11 changed files with 702 additions and 70 deletions

View File

@@ -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
*

View File

@@ -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<User> 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<String, User> userMap = new LinkedHashMap<String, User>();
}

View File

@@ -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<User> getAll()
{
List<User> users = new ArrayList<User>();
File[] userFiles = userDirectory.listFiles(new FilenameFilter()
{
@Override
public boolean accept(File dir, String name)
{
return name.endsWith(FILE_EXTENSION);
}
});
LinkedList<User> users = new LinkedList<User>();
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;
}

View File

@@ -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<User>
{
/**
* Constructs ...
*
*/
public XmlUserList() {}
/**
* Constructs ...
*
*
*
* @param userMap
*/
public XmlUserList(Map<String, User> userMap)
{
this.users = new LinkedList<User>(userMap.values());
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public Iterator<User> iterator()
{
return users.iterator();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public LinkedList<User> getUsers()
{
return users;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param users
*/
public void setUsers(LinkedList<User> users)
{
this.users = users;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@XmlElement(name = "user")
private LinkedList<User> users;
}

View File

@@ -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<XmlUserList, Map<String, User>>
{
/**
* Method description
*
*
* @param userMap
*
* @return
*
* @throws Exception
*/
@Override
public XmlUserList marshal(Map<String, User> userMap) throws Exception
{
return new XmlUserList(userMap);
}
/**
* Method description
*
*
* @param users
*
* @return
*
* @throws Exception
*/
@Override
public Map<String, User> unmarshal(XmlUserList users) throws Exception
{
Map<String, User> userMap = new LinkedHashMap<String, User>();
for (User user : users)
{
userMap.put(user.getName(), user);
}
return userMap;
}
}

View File

@@ -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<String, Date>
{
/**
* 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);
}
}

View File

@@ -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<String, Long>
{
/**
* 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();
}
}

View File

@@ -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");
}
/**

View File

@@ -33,6 +33,8 @@
package sonia.scm.user;
import sonia.scm.user.xml.XmlUserHandler;
/**
*
* @author Sebastian Sdorra

View File

@@ -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;

View File

@@ -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 ------------------------------------------------------------