Updated dbException. Fixed the resource update service.

Change-Id: Ie3762953927411b8db121f460fed59661df6f659
diff --git a/src/main/java/de/ids_mannheim/korap/exceptions/dbException.java b/src/main/java/de/ids_mannheim/korap/exceptions/dbException.java
index 076797b..495971e 100644
--- a/src/main/java/de/ids_mannheim/korap/exceptions/dbException.java
+++ b/src/main/java/de/ids_mannheim/korap/exceptions/dbException.java
@@ -16,9 +16,9 @@
     }
 
 
-    public dbException (Object userid, String target, Integer status,
+    public dbException (Object userid, String target, Integer status, String message,
                         String ... args) {
-        this(userid, status, "", Arrays.asList(args).toString());
+        this(userid, status, message, Arrays.asList(args).toString());
         AuditRecord record = new AuditRecord(AuditRecord.CATEGORY.DATABASE);
         record.setUserid(String.valueOf(userid));
         record.setStatus(status);
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java b/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
index 3ef97bb..0c0468e 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/EntityDao.java
@@ -17,6 +17,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.dao.DataAccessException;
+import org.springframework.dao.DuplicateKeyException;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
@@ -38,6 +39,7 @@
     private static Logger jlog = LoggerFactory.getLogger(EntityDao.class);
     private NamedParameterJdbcTemplate jdbcTemplate;
 
+
     public EntityDao (PersistenceClient client) {
         this.jdbcTemplate = (NamedParameterJdbcTemplate) client.getSource();
     }
@@ -46,8 +48,8 @@
     // usersettings are fetched plus basic account info, no details, since i rarely use them anyway!
     @Override
     public User getAccount (String username) throws KustvaktException {
-        Map<String, String> namedParameters = Collections.singletonMap(
-                "username", username);
+        Map<String, String> namedParameters = Collections
+                .singletonMap("username", username);
         final String sql = "select a.* from korap_users as a where a.username=:username;";
         User user;
         try {
@@ -61,7 +63,9 @@
         catch (DataAccessException e) {
             jlog.error("Could not retrieve user for name: " + username, e);
             throw new dbException(username, "korap_users",
-                    StatusCodes.DB_GET_FAILED, username);
+                    StatusCodes.DB_GET_FAILED,
+                    "Could not retrieve the user with username: " + username,
+                    username);
         }
         return user;
     }
@@ -117,7 +121,9 @@
                     "Could not update user account for user: " + user.getId(),
                     e);
             throw new dbException(user.getId(), "korap_users",
-                    StatusCodes.DB_UPDATE_FAILED, user.toString());
+                    StatusCodes.DB_UPDATE_FAILED,
+                    "Could not update user account for user: " + user.getId(),
+                    user.toString());
         }
     }
 
@@ -199,13 +205,19 @@
                     new String[] { "id" });
             user.setId(holder.getKey().intValue());
         }
-        catch (DataAccessException e) {
+        catch (DuplicateKeyException e) {
             jlog.error("Could not create user account with username: {}",
                     user.getUsername());
             throw new dbException(user.getUsername(), "korap_users",
-                    StatusCodes.ENTRY_EXISTS, user.getUsername());
+                    StatusCodes.ENTRY_EXISTS, "Username exists.",
+                    user.getUsername());
         }
-        
+        catch (DataAccessException e) {
+            throw new dbException(user.getUsername(), "korap_users",
+                    StatusCodes.ENTRY_EXISTS, "Username exists.",
+                    user.getUsername());
+        }
+
         return r;
     }
 
@@ -217,8 +229,8 @@
 
         try {
             int r;
-            r = this.jdbcTemplate.update(
-                    "DELETE FROM korap_users WHERE id=:user", s);
+            r = this.jdbcTemplate
+                    .update("DELETE FROM korap_users WHERE id=:user", s);
             //            if (user instanceof KorAPUser)
             //                r = this.jdbcTemplate
             //                        .update("DELETE FROM korap_users WHERE username=:user",
@@ -235,7 +247,9 @@
             jlog.error("Could not delete account for user: " + userid, e);
             //            throw new KorAPException(e, StatusCodes.CONNECTION_ERROR);
             throw new dbException(userid, "korap_users",
-                    StatusCodes.DB_DELETE_FAILED, userid.toString());
+                    StatusCodes.DB_DELETE_FAILED,
+                    "Could not delete account for user: " + userid,
+                    userid.toString());
         }
 
     }
@@ -270,8 +284,9 @@
         catch (DataAccessException e) {
             jlog.error("Could not reset password for name: " + username, e);
             throw new dbException(username, "korap_users",
-                    StatusCodes.DB_UPDATE_FAILED, username, uriToken,
-                    passphrase);
+                    StatusCodes.DB_UPDATE_FAILED,
+                    "Could not reset password for username: " + username,
+                    username, uriToken, passphrase);
         }
     }
 
@@ -291,9 +306,12 @@
             return this.jdbcTemplate.update(query, np);
         }
         catch (DataAccessException e) {
-            jlog.error("Could not confirm registration for name " + username, e);
+            jlog.error("Could not confirm registration for name " + username,
+                    e);
             throw new dbException(username, "korap_users",
-                    StatusCodes.DB_UPDATE_FAILED, username, uriToken);
+                    StatusCodes.DB_UPDATE_FAILED,
+                    "Could not confirm registration for username " + username,
+                    username, uriToken);
         }
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/ResourceDao.java b/src/main/java/de/ids_mannheim/korap/handlers/ResourceDao.java
index 6abc72b..3f0f7e1 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/ResourceDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/ResourceDao.java
@@ -28,8 +28,8 @@
  * Created by hanl on 7/21/14.
  */
 //todo: auditing // testing
-public class ResourceDao<T extends KustvaktResource> implements
-        ResourceOperationIface<T> {
+public class ResourceDao<T extends KustvaktResource>
+        implements ResourceOperationIface<T> {
 
     private static Logger log = LoggerFactory.getLogger(ResourceDao.class);
     protected final NamedParameterJdbcTemplate jdbcTemplate;
@@ -59,10 +59,13 @@
                     new RowMapperFactory.ResourceMapper());
         }
         catch (DataAccessException e) {
-            log.error("Exception during database retrieval for ids '" + ids
-                    + "'", e);
+            log.error(
+                    "Exception during database retrieval for ids '" + ids + "'",
+                    e);
             throw new dbException(user.getId(), "resource_store",
-                    StatusCodes.DB_GET_FAILED, ids.toString());
+                    StatusCodes.DB_GET_FAILED,
+                    "Exception during database retrieval for ids '" + ids,
+                    ids.toString());
         }
 
     }
@@ -74,17 +77,17 @@
         source.addValue("id", resource.getPersistentID());
         source.addValue("name", resource.getName());
         source.addValue("desc", resource.getDescription());
-        source.addValue("data", resource.getData());
+        source.addValue("data", resource.getStringData());
         final String sql = "UPDATE resource_store set name=:name, data=:data, description=:desc where persistent_id=:id;";
         try {
             return this.jdbcTemplate.update(sql, source);
         }
         catch (DataAccessException e) {
-            log.error(
-                    "Exception during database update for id '"
-                            + resource.getPersistentID() + "'", e);
+            log.error("Exception during database update for id '"
+                    + resource.getPersistentID() + "'", e);
             throw new dbException(user.getId(), "resource_store",
-                    StatusCodes.DB_UPDATE_FAILED, resource.toString());
+                    StatusCodes.DB_UPDATE_FAILED, "Exception during database update for id '"
+                            + resource.getPersistentID(), resource.toString());
         }
     }
 
@@ -109,7 +112,7 @@
                     new RowMapperFactory.ResourceMapper());
         }
         catch (DataAccessException e) {
-        	// empty results
+            // empty results
             return null;
         }
     }
@@ -170,7 +173,8 @@
         b.insert(Attributes.NAME, Attributes.PARENT_ID,
                 Attributes.PERSISTENT_ID, Attributes.DESCRIPTION,
                 Attributes.CREATOR, Attributes.TYPE, Attributes.CREATED);
-        b.params(":name, :parent, :pid, :desc, :ow, :type, :created, :dtype, :data");
+        b.params(
+                ":name, :parent, :pid, :desc, :ow, :type, :created, :dtype, :data");
 
         if (resource.getParentID() == null) {
             sql = "INSERT INTO resource_store (name, parent_id, persistent_id, description, creator, type, created, data) "
@@ -195,15 +199,17 @@
         source.addValue("data", resource.getStringData());
 
         try {
-            this.jdbcTemplate
-                    .update(sql, source, holder, new String[] { "id" });
+            this.jdbcTemplate.update(sql, source, holder,
+                    new String[] { "id" });
         }
         catch (DataAccessException e) {
-            log.error(
-                    "Exception during database store for id '"
-                            + resource.getPersistentID() + "'", e);
+            log.error("Exception during database store for id '"
+                    + resource.getPersistentID() + "'", e);
             throw new dbException(user.getId(), "resource_store",
-                    StatusCodes.DB_INSERT_FAILED, resource.toString());
+                    StatusCodes.DB_INSERT_FAILED,
+                    "Exception during database store for id '"
+                            + resource.getPersistentID(),
+                    resource.toString());
         }
         resource.setId(holder.getKey().intValue());
         return resource.getId();
@@ -220,7 +226,8 @@
         }
         catch (DataAccessException e) {
             throw new dbException(user.getId(), "resource_store",
-                    StatusCodes.DB_DELETE_FAILED, id);
+                    StatusCodes.DB_DELETE_FAILED, "Operation DELETE failed.",
+                    id);
         }
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/UserDetailsDao.java b/src/main/java/de/ids_mannheim/korap/handlers/UserDetailsDao.java
index ddfe851..ec704d5 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/UserDetailsDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/UserDetailsDao.java
@@ -96,7 +96,8 @@
         }
         catch (DataAccessException e) {
             throw new dbException(-1, "userDetails",
-                    StatusCodes.REQUEST_INVALID, String.valueOf(id));
+                    StatusCodes.REQUEST_INVALID, "The request is invalid.",
+                    String.valueOf(id));
         }
     }
 
@@ -127,7 +128,7 @@
         }
         catch (DataAccessException e) {
             throw new dbException(user.getId(), "userDetails",
-                    StatusCodes.REQUEST_INVALID);
+                    StatusCodes.REQUEST_INVALID, "The request is invalid.");
         }
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/handlers/UserSettingsDao.java b/src/main/java/de/ids_mannheim/korap/handlers/UserSettingsDao.java
index fdc6ba5..a1d29fe 100644
--- a/src/main/java/de/ids_mannheim/korap/handlers/UserSettingsDao.java
+++ b/src/main/java/de/ids_mannheim/korap/handlers/UserSettingsDao.java
@@ -88,8 +88,8 @@
                         @Override
                         public UserSettings mapRow (ResultSet rs, int rowNum)
                                 throws SQLException {
-                            UserSettings details = new UserSettings(rs
-                                    .getInt("user_id"));
+                            UserSettings details = new UserSettings(
+                                    rs.getInt("user_id"));
                             details.setId(rs.getInt("id"));
                             details.setData(rs.getString("data"));
                             return details;
@@ -102,7 +102,8 @@
         }
         catch (DataAccessException e) {
             throw new dbException(-1, "userSettings",
-                    StatusCodes.REQUEST_INVALID, String.valueOf(id));
+                    StatusCodes.REQUEST_INVALID, "The request is invalid.",
+                    String.valueOf(id));
         }
     }
 
@@ -120,8 +121,8 @@
                         @Override
                         public UserSettings mapRow (ResultSet rs, int rowNum)
                                 throws SQLException {
-                            UserSettings details = new UserSettings(rs
-                                    .getInt("user_id"));
+                            UserSettings details = new UserSettings(
+                                    rs.getInt("user_id"));
                             details.setId(rs.getInt("id"));
                             details.setData(rs.getString("data"));
                             return details;
@@ -134,7 +135,7 @@
         }
         catch (DataAccessException e) {
             throw new dbException(-1, "userSettings",
-                    StatusCodes.REQUEST_INVALID);
+                    StatusCodes.REQUEST_INVALID, "The request is invalid.");
         }
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java
index 7fe20c6..e8fb3c6 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/ValidatorIface.java
@@ -10,7 +10,7 @@
 public interface ValidatorIface {
 
 
-    Map<String, Object> validateMap (Map<String, Object> map);
+    Map<String, Object> validateMap (Map<String, Object> map) throws KustvaktException;
 
 
     String validateEntry (String input, String type)
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java
index 8d420ec..1b9477a 100644
--- a/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/defaults/ApacheValidator.java
@@ -21,14 +21,16 @@
 
     private static Logger jlog = LoggerFactory.getLogger(ApacheValidator.class);
 
-    private static final String STRING_PATTERN ="^[\\.;:,&\\|@\\[\\]\\=\\*\\/\\/_()\\-0-9\\p{L}\\p{Space}]{0,1024}$";
+    private static final String STRING_PATTERN = "^[\\.;:,&\\|@\\[\\]\\=\\*\\/\\/_()\\-0-9\\p{L}\\p{Space}]{0,1024}$";
 
     private Map<String, RegexValidator> validators;
 
+
     public ApacheValidator () throws IOException {
         this.validators = load();
     }
 
+
     private static Map<String, RegexValidator> load () throws IOException {
         Map<String, RegexValidator> validatorMap = new HashMap<>();
         Properties p = ConfigLoader.loadProperties("validation.properties");
@@ -36,7 +38,8 @@
         for (String property : p.stringPropertyNames()) {
             if (property.startsWith("Validator")) {
                 String name = property.replace("Validator.", "");
-                RegexValidator v = new RegexValidator(p.get(property).toString());
+                RegexValidator v = new RegexValidator(
+                        p.get(property).toString());
                 validatorMap.put(name, v);
             }
         }
@@ -46,31 +49,38 @@
 
 
     @Override
-    public Map<String, Object> validateMap (Map<String, Object> map) {
+    public Map<String, Object> validateMap (Map<String, Object> map)
+            throws KustvaktException {
         Map<String, Object> safeMap = new HashMap<>();
         KustvaktMap kmap = new KustvaktMap(map);
 
         if (map != null) {
-                loop : for (String key : kmap.keySet()) {
-                    Object value = kmap.getRaw(key);
-                    if (value instanceof List) {
-                        List list = (List) value;
-                        for (int i =0;i<list.size();i++) {
-                            if (!isValid(String.valueOf(list.get(i)), key))
-                                list.remove(i);
+            loop: for (String key : kmap.keySet()) {
+                Object value = kmap.getRaw(key);
+                if (value instanceof List) {
+                    List list = (List) value;
+                    for (int i = 0; i < list.size(); i++) {
+                        if (!isValid(String.valueOf(list.get(i)), key)) {
+                            //                                list.remove(i);
+                            throw new KustvaktException(
+                                    StatusCodes.ILLEGAL_ARGUMENT,
+                                    "The value for the parameter " + key
+                                            + " is not valid or acceptable.");
                         }
-
-                        if (list.size() == 1)
-                            value = list.get(0);
-                        else
-                            value = list;
-                    } else {
-                        if (!isValid(kmap.get(key), key))
-                          continue loop;
                     }
-                    safeMap.put(key, value);
+
+                    if (list.size() == 1)
+                        value = list.get(0);
+                    else
+                        value = list;
                 }
+                else {
+                    if (!isValid(kmap.get(key), key))
+                        continue loop;
+                }
+                safeMap.put(key, value);
             }
+        }
         return safeMap;
     }
 
@@ -84,26 +94,31 @@
         return input;
     }
 
+
     @Override
-    public boolean isValid(String input, String type) {
+    public boolean isValid (String input, String type) {
         boolean valid = false;
         RegexValidator validator = this.validators.get(type);
         if (validator != null) {
             valid = validator.isValid(input);
-        } else {
+        }
+        else {
             if (Attributes.EMAIL.equals(type)) {
                 valid = EmailValidator.getInstance().isValid(input);
-            } else if ("date".equals(type)) {
+            }
+            else if ("date".equals(type)) {
                 valid = DateValidator.getInstance().isValid(input);
-            } else if ("string".equals(type) && !this.validators.containsKey("string")) {
+            }
+            else if ("string".equals(type)
+                    && !this.validators.containsKey("string")) {
                 RegexValidator regex = new RegexValidator(STRING_PATTERN);
                 valid = regex.isValid(input);
             }
             else
                 return this.isValid(input, "string");
         }
-        jlog.debug("validating entry '{}' of type '{}': {}",
-                input, type, valid ? "Is valid!" : "Is not valid!");
+        jlog.debug("validating entry '{}' of type '{}': {}", input, type,
+                valid ? "Is valid!" : "Is not valid!");
         return valid;
     }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
index 43c4ea9..5de3726 100644
--- a/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
+++ b/src/main/java/de/ids_mannheim/korap/security/ac/PolicyDao.java
@@ -67,15 +67,18 @@
 
         if (policy.getTarget() == null)
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.NO_POLICY_TARGET, policy.toString());
+                    StatusCodes.NO_POLICY_TARGET, "Persistent id is missing.",
+                    policy.toString());
 
         if (policy.getConditions().isEmpty())
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.NO_POLICY_CONDITION);
+                    StatusCodes.NO_POLICY_CONDITION,
+                    "Policy conditions are missing.");
 
         if (policy.getPermissionByte() == 0)
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.NO_POLICY_PERMISSION);
+                    StatusCodes.NO_POLICY_PERMISSION,
+                    "Policy permissions are missing.");
 
         KeyHolder keyHolder = new GeneratedKeyHolder();
         MapSqlParameterSource np = new MapSqlParameterSource();
@@ -201,7 +204,11 @@
                         "Operation (SELECT) not possible for '{}' for user '{}'",
                         policy.getTarget(), user.getId());
                 throw new dbException(user.getId(), "policy_store",
-                        StatusCodes.DB_GET_FAILED, policy.toString());
+                        StatusCodes.DB_GET_FAILED,
+                        "Operation (SELECT) is not possible for "
+                                + policy.getTarget() + " for user "
+                                + user.getUsername(),
+                        policy.toString());
             }
         }
     }
@@ -284,11 +291,12 @@
         }
     }
 
+
     // EM: should only return one policy
     @Override
     public List<SecurityPolicy> getPoliciesByPersistentId (
-            PolicyCondition condition, Class<? extends KustvaktResource> clazz, byte perm,
-            String persistentId) {
+            PolicyCondition condition, Class<? extends KustvaktResource> clazz,
+            byte perm, String persistentId) {
 
         MapSqlParameterSource param = new MapSqlParameterSource();
         param.addValue("cond", condition.getSpecifier());
@@ -300,8 +308,7 @@
                 + "rh.depth, (select max(depth) from resource_tree "
                 + "where child_id=rh.child_id) as max_depth from policy_view as pv "
                 + "inner join resource_tree as rh on rh.parent_id=pv.id "
-                + "where "
-                + "pv.persistent_id =:persistentId and "
+                + "where " + "pv.persistent_id =:persistentId and "
                 + "pv.enable <= :en and (pv.expire > :en or pv.expire is NULL) and "
                 + "pv.group_id=:cond and pv.type=:type";
 
@@ -471,7 +478,10 @@
                     "Permission Denied for retrieval for path '{}' for user '{}'",
                     path, user.getId());
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.DB_GET_FAILED, path, clazz.toString());
+                    StatusCodes.DB_GET_FAILED,
+                    "Permission is denied for retrieval for path " + path
+                            + " for user " + user.getUsername(),
+                    path, clazz.toString());
         }
     }
 
@@ -528,7 +538,10 @@
                     "Permission Denied for retrieval for path '{}' for user '{}'",
                     name, user.getId());
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.DB_GET_FAILED, name, clazz.toString());
+                    StatusCodes.DB_GET_FAILED,
+                    "Permission is denied for retrieval for path " + name
+                            + "for user" + user.getUsername() + ".",
+                    name, clazz.toString());
         }
     }
 
@@ -555,7 +568,9 @@
             jlog.error("Operation (DELETE) not possible for '{}' for user '{}'",
                     policy.toString(), user.getId());
             throw new dbException(user.getId(), "policy_store, group_ref",
-                    StatusCodes.DB_DELETE_FAILED, policy.toString());
+                    StatusCodes.DB_DELETE_FAILED,
+                    "Operation (DELETE) is not possible for user.",
+                    policy.toString());
         }
     }
 
@@ -573,7 +588,10 @@
             jlog.error("Operation (DELETE) not possible for '{}' for user '{}'",
                     id, user.getId());
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.DB_DELETE_FAILED, id);
+                    StatusCodes.DB_DELETE_FAILED,
+                    "Operation (DELETE) is not possible for user "
+                            + user.getUsername(),
+                    id);
         }
     }
 
@@ -597,7 +615,10 @@
             jlog.error("Operation (UPDATE) not possible for '{}' for user '{}'",
                     policy.toString(), user.getId());
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.DB_UPDATE_FAILED, policy.toString());
+                    StatusCodes.DB_UPDATE_FAILED,
+                    "Operation (UPDATE) on " + policy.toString()
+                            + " is not possible for user" + user.getUsername(),
+                    policy.toString());
         }
     }
 
@@ -619,7 +640,10 @@
             jlog.error("Operation (SELECT) not possible for '{}' for user '{}'",
                     policy.getTarget(), user.getId());
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.DB_GET_FAILED, policy.toString());
+                    StatusCodes.DB_GET_FAILED,
+                    "Operation (SELECT) on " + policy.getTarget()
+                            + " is not possible for user " + user.getUsername(),
+                    policy.toString());
         }
     }
 
@@ -660,7 +684,10 @@
             jlog.error("Operation (SELECT) not possible for '{}' for user '{}'",
                     group, user.getId());
             throw new dbException(user.getId(), "policy_store",
-                    StatusCodes.DB_GET_FAILED, group);
+                    StatusCodes.DB_GET_FAILED,
+                    "Operation (SELECT) is not possible for user "
+                            + user.getUsername(),
+                    group);
         }
     }
 
@@ -683,7 +710,9 @@
             jlog.error("Operation (INSERT) not possible for '{}'",
                     condition.toString());
             throw new dbException(user.getId(), "group_store",
-                    StatusCodes.DB_INSERT_FAILED, condition.toString());
+                    StatusCodes.DB_INSERT_FAILED,
+                    "Operation (INSERT) is not possible for",
+                    condition.toString());
         }
     }
 
@@ -710,7 +739,10 @@
                         "Operation (INSERT) not possible for '{}' for user '{}'",
                         condition.toString(), username);
                 throw new dbException(null, "group_store",
-                        StatusCodes.DB_INSERT_FAILED, condition.toString());
+                        StatusCodes.DB_INSERT_FAILED,
+                        "Operation (INSERT) on " + condition.toString()
+                                + " is not possible for user " + username,
+                        condition.toString());
             }
             return 0;
         }
diff --git a/src/main/java/de/ids_mannheim/korap/user/DataFactory.java b/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
index 0e59f53..5d3f85f 100644
--- a/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
+++ b/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
@@ -50,7 +50,7 @@
 
     public abstract Collection<Object> values (Object data);
 
-    public abstract Object validate(Object data, ValidatorIface validator);
+    public abstract Object validate(Object data, ValidatorIface validator) throws KustvaktException;
 
     @Deprecated
     public abstract Map<String, Object> fields (Object data);
@@ -123,7 +123,7 @@
         }
 
         @Override
-        public Object validate(Object data, ValidatorIface validator) {
+        public Object validate(Object data, ValidatorIface validator) throws KustvaktException {
             if (checkDataType(data) && ((JsonNode) data).isObject()) {
                 try {
                     Map mdata = JsonUtils.read(toStringValue(data), HashMap.class);
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
index 5eb8f1b..ebeb8e2 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/ResourceService.java
@@ -799,32 +799,33 @@
             if (name != null && !name.isEmpty()) {
                 if (description == null) {
                     if (name.equals(resource.getName())) {
-                        return Response.notModified("No change has found.")
-                                .build();
+                        throw new KustvaktException(StatusCodes.NOTHING_CHANGED,
+                                "No change has found.");
                     }
+                    resource.setName(name);
                 }
                 else if (name.equals(resource.getName())
                         && description.equals(resource.getDescription())) {
-                    return Response.notModified("No change has found.").build();
+                    throw new KustvaktException(StatusCodes.NOTHING_CHANGED,
+                            "No change has found.");
                 }
                 else {
                     resource.setName(name);
+                    resource.setDescription(description);
                 }
             }
             else if (description != null && !description.isEmpty()) {
                 resource.setDescription(description);
             }
             else {
-                Response.notModified(
-                        "New name and description are not specified.").build();
+                throw new KustvaktException(StatusCodes.NOTHING_CHANGED,
+                        "The given resource name and description are the same as already stored.");
             }
 
 
             this.resourceHandler.updateResources(user, resource);
         }
-        catch (
-
-        KustvaktException e) {
+        catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
             throw KustvaktResponseHandler.throwit(e);
         }
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
index c998e31..84cab21 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/UserService.java
@@ -41,8 +41,7 @@
     private static Logger jlog = LoggerFactory.getLogger(UserService.class);
     private AuthenticationManagerIface controller;
 
-    private @Context
-    UriInfo info;
+    private @Context UriInfo info;
 
 
     public UserService () {
@@ -76,9 +75,11 @@
         }
         URIParam uri = user.getField(URIParam.class);
         if (uri.hasValues()) {
-            uriBuilder.queryParam(Attributes.QUERY_PARAM_URI,
-                    uri.getUriFragment()).queryParam(
-                    Attributes.QUERY_PARAM_USER, user.getUsername());
+            uriBuilder
+                    .queryParam(Attributes.QUERY_PARAM_URI,
+                            uri.getUriFragment())
+                    .queryParam(Attributes.QUERY_PARAM_USER,
+                            user.getUsername());
             jlog.info("registration was successful for user '{}'",
                     values.get(Attributes.USERNAME));
             Map object = new HashMap();
@@ -100,8 +101,8 @@
     @POST
     @Path("update")
     @Consumes(MediaType.APPLICATION_JSON)
-    @ResourceFilters({ AuthFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
+    @ResourceFilters({ AuthFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
     public Response updateAccount (@Context SecurityContext ctx, String json) {
         TokenContext context = (TokenContext) ctx.getUserPrincipal();
         try {
@@ -149,7 +150,8 @@
     @POST
     @Path("requestReset")
     @Produces(MediaType.TEXT_HTML)
-    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
+    @Consumes({ MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_FORM_URLENCODED })
     public Response requestPasswordReset (@Context Locale locale, String json) {
         JsonNode node = JsonUtils.readTree(json);
         StringBuilder builder = new StringBuilder();
@@ -192,7 +194,8 @@
     @POST
     @Path("reset")
     @Produces(MediaType.TEXT_HTML)
-    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
+    @Consumes({ MediaType.APPLICATION_JSON,
+            MediaType.APPLICATION_FORM_URLENCODED })
     public Response resetPassword (
             @QueryParam(Attributes.QUERY_PARAM_URI) String uri,
             @QueryParam(Attributes.QUERY_PARAM_USER) String username,
@@ -211,8 +214,8 @@
     // todo: refactor and make something out of if --> needs to give some sort of feedback!
     @GET
     @Path("info")
-    @ResourceFilters({ AuthFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
+    @ResourceFilters({ AuthFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
     public Response getStatus (@Context SecurityContext context,
             @QueryParam("scopes") String scopes) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
@@ -228,7 +231,8 @@
             m = Scopes.mapScopes(scopes, data);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwAuthenticationException(ctx.getUsername());
+            throw KustvaktResponseHandler
+                    .throwAuthenticationException(ctx.getUsername());
         }
         return Response.ok(m.toEntity()).build();
     }
@@ -258,9 +262,9 @@
 
     @POST
     @Path("settings")
-    @Consumes({MediaType.APPLICATION_JSON})
-    @ResourceFilters({ AuthFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @ResourceFilters({ AuthFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
     public Response updateSettings (@Context SecurityContext context,
             @Context Locale locale, Map settings) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
@@ -321,9 +325,9 @@
 
     @POST
     @Path("details")
-    @Consumes({MediaType.APPLICATION_JSON})
-    @ResourceFilters({ AuthFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @ResourceFilters({ AuthFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
     public Response updateDetails (@Context SecurityContext context,
             @Context Locale locale, Map details) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
@@ -355,9 +359,10 @@
     @POST
     @Path("queries")
     @Consumes(MediaType.APPLICATION_JSON)
-    @ResourceFilters({ AuthFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response updateQueries (@Context SecurityContext context, String json) {
+    @ResourceFilters({ AuthFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateQueries (@Context SecurityContext context,
+            String json) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         Collection<UserQuery> add = new HashSet<>();
         try {
@@ -407,8 +412,8 @@
 
 
     @DELETE
-    @ResourceFilters({ AuthFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
+    @ResourceFilters({ AuthFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
     public Response deleteUser (@Context SecurityContext context) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         try {
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
index 0226217..a5e91da 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/KustvaktServerTest.java
@@ -5,11 +5,13 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.charset.Charset;
@@ -20,13 +22,18 @@
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.CertificateException;
+import java.util.List;
 import java.util.UUID;
 
 import javax.net.ssl.SSLContext;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
+import org.apache.http.client.ClientProtocolException;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.client.utils.URIBuilder;
@@ -34,6 +41,7 @@
 import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
 import org.apache.http.conn.ssl.SSLContexts;
 import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
+import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -41,8 +49,10 @@
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.io.Files;
 import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeanConfigTest;
@@ -68,10 +78,120 @@
  *
  */
 public class KustvaktServerTest extends BeanConfigTest {
+    private static ObjectMapper mapper = new ObjectMapper();
+
+
+    @Test
+    public void testRegisterBadPassword ()
+            throws URISyntaxException, ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+
+        MultivaluedMap<String, String> map = new MultivaluedMapImpl();
+        map.putSingle("username", "kusvakt");
+        map.putSingle("email", "kustvakt@ids-mannheim.de");
+        map.putSingle("password", "password");
+        map.putSingle("firstName", "kustvakt");
+        map.putSingle("lastName", "user");
+        map.putSingle("address", "Mannheim");
+
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/user/register");
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
+        StringEntity entity = new StringEntity(JsonUtils.toJSON(map));
+        httppost.setEntity(entity);
+        httppost.addHeader(HttpHeaders.CONTENT_TYPE,
+                MediaType.APPLICATION_JSON);
+        httppost.addHeader(HttpHeaders.USER_AGENT, "Apache HTTP Client");
+        httppost.addHeader(HttpHeaders.HOST, "localhost");
+
+        HttpResponse response = httpClient.execute(httppost);
+        assertEquals(ClientResponse.Status.NOT_ACCEPTABLE.getStatusCode(),
+                response.getStatusLine().getStatusCode());
+
+        HttpEntity responseEntity = response.getEntity();
+        JsonNode errorNode = mapper.readTree(responseEntity.getContent());
+        assertEquals(
+                "[The value for the parameter password is not valid or acceptable.]",
+                errorNode.get("errors").get(0).get(2).asText());
+
+    }
+
+
+    @Test
+    public void testRegisterExistingUsername ()
+            throws URISyntaxException, ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+
+        MultivaluedMap<String, String> map = new MultivaluedMapImpl();
+        map.putSingle("username", "kustvakt");
+        map.putSingle("email", "kustvakt@ids-mannheim.de");
+        map.putSingle("password", "password1234");
+        map.putSingle("firstName", "kustvakt");
+        map.putSingle("lastName", "user");
+        map.putSingle("address", "Mannheim");
+
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/user/register");
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
+        StringEntity entity = new StringEntity(JsonUtils.toJSON(map));
+        httppost.setEntity(entity);
+        httppost.addHeader(HttpHeaders.CONTENT_TYPE,
+                MediaType.APPLICATION_JSON);
+        httppost.addHeader(HttpHeaders.USER_AGENT, "Apache HTTP Client");
+        httppost.addHeader(HttpHeaders.HOST, "localhost");
+
+        HttpResponse response = httpClient.execute(httppost);
+        assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
+                response.getStatusLine().getStatusCode());
+
+        HttpEntity responseEntity = response.getEntity();
+        JsonNode errorNode = mapper.readTree(responseEntity.getContent());
+        assertEquals(
+                "[The value for the parameter password is not valid or acceptable.]",
+                errorNode.get("errors").asText());
+    }
+
+
+    @Test
+    public void testRegisterUser ()
+            throws URISyntaxException, ClientProtocolException, IOException {
+        HttpClient httpClient = HttpClients.createDefault();
+
+        MultivaluedMap<String, String> map = new MultivaluedMapImpl();
+        map.putSingle("username", "testUser");
+        map.putSingle("email", "testUser@ids-mannheim.de");
+        map.putSingle("password", "testPassword1234");
+        map.putSingle("firstName", "test");
+        map.putSingle("lastName", "user");
+        map.putSingle("address", "Mannheim");
+
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/user/register");
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
+        StringEntity entity = new StringEntity(JsonUtils.toJSON(map));
+        httppost.setEntity(entity);
+        httppost.addHeader(HttpHeaders.CONTENT_TYPE,
+                MediaType.APPLICATION_JSON);
+        httppost.addHeader(HttpHeaders.USER_AGENT, "Apache HTTP Client");
+        httppost.addHeader(HttpHeaders.HOST, "localhost");
+
+        HttpResponse response = httpClient.execute(httppost);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatusLine().getStatusCode());
+
+    }
+
+
     @Test
     public void testCreatePolicy () throws IOException, URISyntaxException {
 
-        HttpClient httpClient = HttpClients.createDefault();;
+        HttpClient httpClient = HttpClients.createDefault();
 
         String id = UUID.randomUUID().toString();
         URIBuilder builder = new URIBuilder();
@@ -82,8 +202,7 @@
                 .setParameter("description", "Goethe corpus")
                 .setParameter("group", "public")
                 .setParameter("perm", Permission.READ.name())
-                .setParameter("loc", "")
-                .setParameter("expire", "");
+                .setParameter("loc", "").setParameter("expire", "");
 
         URI uri = builder.build();
         HttpPost httppost = new HttpPost(uri);
@@ -101,7 +220,7 @@
     public void testCreatePolicyForFoundry ()
             throws IOException, URISyntaxException {
 
-        HttpClient httpClient = HttpClients.createDefault();;
+        HttpClient httpClient = HttpClients.createDefault();
 
         String id = UUID.randomUUID().toString();
         URIBuilder builder = new URIBuilder();
@@ -131,7 +250,7 @@
     public void testCreatePolicyWithMultiplePermissions ()
             throws IOException, URISyntaxException {
 
-        HttpClient httpClient = HttpClients.createDefault();;
+        HttpClient httpClient = HttpClients.createDefault();
 
         String id = UUID.randomUUID().toString();
         URIBuilder builder = new URIBuilder();
@@ -213,6 +332,24 @@
         return httpclient.execute(httppost);
 
     }
+    
+    @Test
+    public void testResourceUpdate ()
+            throws IOException, URISyntaxException {
+
+        HttpClient httpclient = HttpClients.createDefault();
+        URIBuilder builder = new URIBuilder();
+        builder.setScheme("http").setHost("localhost").setPort(8089)
+                .setPath("/api/v0.1/virtualcollection/00df953b-2227-4c23-84c1-5532c07bf8ce")
+                .setParameter("name", "Goethe collection")
+                .setParameter("description", "Goethe collection");
+        URI uri = builder.build();
+        HttpPost httppost = new HttpPost(uri);
+        httppost.addHeader(Attributes.AUTHORIZATION,
+                BasicHttpAuth.encode("kustvakt", "kustvakt2015"));
+        HttpResponse response = httpclient.execute(httppost);
+
+    }
 
 
     private void checkResourceInDB (String id) throws KustvaktException {
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
index fed448d..544c790 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
@@ -6,19 +6,22 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.IOException;
 import java.util.Iterator;
 
+import org.apache.http.HttpStatus;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.sun.jersey.api.client.ClientResponse;
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.handlers.ResourceDao;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resources.KustvaktResource;
@@ -32,7 +35,8 @@
  * @date 14/01/2016
  */
 public class ResourceServiceTest extends FastJerseyTest {
-	
+    private static ObjectMapper mapper = new ObjectMapper();
+    
     @BeforeClass
     public static void configure () throws Exception {
         FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service.full",
@@ -266,7 +270,7 @@
     }
 
     @Test
-    public void testResourceStore() throws KustvaktException {
+    public void testResourceStore() throws KustvaktException, JsonProcessingException, IOException {
     	// resource store service
         ClientResponse response = resource()
                 .path(getAPIVersion())
@@ -303,7 +307,7 @@
         assertNotNull(res);
         Assert.assertEquals("Goethe",res.getName().toString());
         
-        // no update resource service
+//         no update resource service
         response = resource()
                 .path(getAPIVersion())
                 .path("virtualcollection")
@@ -313,7 +317,11 @@
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .post(ClientResponse.class);
         
-        assertEquals(StatusCodes.NOTHING_CHANGED, response.getStatus());
+        assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
+        JsonNode errorNode = mapper.readTree(response.getEntityInputStream());
+        assertEquals(
+                "[No change has found.]",
+                errorNode.get("errors").get(0).get(2).asText());
         
         // update resource service
         response = resource()
@@ -325,6 +333,9 @@
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
                 .post(ClientResponse.class);
         
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        
         res = dao.findbyId(id,
                 User.UserFactory.getDemoUser());
         assertNotNull(res);