Added a PUT VC request and aliases to some VC controllers, merged VC
access list controllers

Change-Id: I7f1c09410737ba6c4e7e1c340d746d27cece7e70
diff --git a/full/Changes b/full/Changes
index a83aed6..bcc23a1 100644
--- a/full/Changes
+++ b/full/Changes
@@ -13,6 +13,10 @@
    - Added OAuth2 client info tests (margaretha)
 14/01/2019
    - Added retrieveVCByName and deleteVCByName controllers (margaretha)
+16/01/2019
+   - Added a PUT request for both creating and editing vc (margaretha)
+   - Added aliases to some VC controllers (margaretha)
+   - Merged VC access list controllers (margaretha)  
 
 # version 0.61.4
 14/11/2018
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java
index 9e6a7eb..80cdf3b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusAccessDao.java
@@ -6,6 +6,7 @@
 import javax.persistence.NoResultException;
 import javax.persistence.PersistenceContext;
 import javax.persistence.Query;
+import javax.persistence.TypedQuery;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Join;
@@ -60,7 +61,6 @@
     }
 
     // for vca admins
-    @SuppressWarnings("unchecked")
     public List<VirtualCorpusAccess> retrieveActiveAccessByVC (int vcId)
             throws KustvaktException {
         ParameterChecker.checkIntegerValue(vcId, "vcId");
@@ -80,12 +80,37 @@
                         VirtualCorpusAccessStatus.ACTIVE));
         query.select(access);
         query.where(p);
-        Query q = entityManager.createQuery(query);
+        TypedQuery<VirtualCorpusAccess> q = entityManager.createQuery(query);
+        return q.getResultList();
+    }
+
+    public List<VirtualCorpusAccess> retrieveActiveAccessByVC (String vcCreator,
+            String vcName) throws KustvaktException {
+        ParameterChecker.checkStringValue(vcCreator, "vcCreator");
+        ParameterChecker.checkStringValue(vcCreator, "vcName");
+
+        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<VirtualCorpusAccess> query =
+                builder.createQuery(VirtualCorpusAccess.class);
+
+        Root<VirtualCorpusAccess> access =
+                query.from(VirtualCorpusAccess.class);
+        Join<VirtualCorpusAccess, VirtualCorpus> accessVC =
+                access.join(VirtualCorpusAccess_.virtualCorpus);
+
+        Predicate p = builder.and(
+                builder.equal(accessVC.get(VirtualCorpus_.name), vcName),
+                builder.equal(accessVC.get(VirtualCorpus_.createdBy), vcCreator),
+                builder.equal(access.get(VirtualCorpusAccess_.status),
+                        VirtualCorpusAccessStatus.ACTIVE));
+        query.select(access);
+        query.where(p);
+        TypedQuery<VirtualCorpusAccess> q = entityManager.createQuery(query);
         return q.getResultList();
     }
 
     // for system admins
-    @SuppressWarnings("unchecked")
+    @Deprecated
     public List<VirtualCorpusAccess> retrieveAllAccessByVC (int vcId)
             throws KustvaktException {
         ParameterChecker.checkIntegerValue(vcId, "vcId");
@@ -101,11 +126,34 @@
 
         query.select(access);
         query.where(builder.equal(accessVC.get(VirtualCorpus_.id), vcId));
-        Query q = entityManager.createQuery(query);
+        TypedQuery<VirtualCorpusAccess> q = entityManager.createQuery(query);
         return q.getResultList();
     }
 
-    @SuppressWarnings("unchecked")
+    public List<VirtualCorpusAccess> retrieveAllAccessByVC (String vcCreator,
+            String vcName) throws KustvaktException {
+        ParameterChecker.checkStringValue(vcCreator, "vcCreator");
+        ParameterChecker.checkStringValue(vcCreator, "vcName");
+
+        CriteriaBuilder builder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<VirtualCorpusAccess> query =
+                builder.createQuery(VirtualCorpusAccess.class);
+
+        Root<VirtualCorpusAccess> access =
+                query.from(VirtualCorpusAccess.class);
+        Join<VirtualCorpusAccess, VirtualCorpus> accessVC =
+                access.join(VirtualCorpusAccess_.virtualCorpus);
+
+        Predicate conditions = builder.and(
+                builder.equal(accessVC.get(VirtualCorpus_.createdBy),
+                        vcCreator),
+                builder.equal(accessVC.get(VirtualCorpus_.name), vcName));
+        query.select(access);
+        query.where(conditions);
+        TypedQuery<VirtualCorpusAccess> q = entityManager.createQuery(query);
+        return q.getResultList();
+    }
+
     public List<VirtualCorpusAccess> retrieveAllAccessByGroup (int groupId)
             throws KustvaktException {
         ParameterChecker.checkIntegerValue(groupId, "groupId");
@@ -121,11 +169,10 @@
 
         query.select(access);
         query.where(builder.equal(accessVC.get(UserGroup_.id), groupId));
-        Query q = entityManager.createQuery(query);
+        TypedQuery<VirtualCorpusAccess> q = entityManager.createQuery(query);
         return q.getResultList();
     }
 
-    @SuppressWarnings("unchecked")
     public List<VirtualCorpusAccess> retrieveActiveAccessByGroup (int groupId)
             throws KustvaktException {
         ParameterChecker.checkIntegerValue(groupId, "groupId");
@@ -146,7 +193,7 @@
 
         query.select(access);
         query.where(p);
-        Query q = entityManager.createQuery(query);
+        TypedQuery<VirtualCorpusAccess> q = entityManager.createQuery(query);
         return q.getResultList();
     }
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
index 0a16309..0e64821 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
@@ -75,7 +75,7 @@
     public void editVirtualCorpus (VirtualCorpus vc, String name,
             VirtualCorpusType type, CorpusAccess requiredAccess,
             String koralQuery, String definition, String description,
-            String status) throws KustvaktException {
+            String status, boolean isCached) throws KustvaktException {
 
         if (name != null && !name.isEmpty()) {
             vc.setName(name);
@@ -98,6 +98,7 @@
         if (status != null && !status.isEmpty()) {
             vc.setStatus(status);
         }
+        vc.setCached(isCached);
         entityManager.merge(vc);
     }
 
@@ -207,11 +208,14 @@
             vc = (VirtualCorpus) q.getSingleResult();
         }
         catch (NoResultException e) {
-            String vcCode = createdBy + "/" + vcName;
-            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND,
-                    "No result found for query: retrieve virtual corpus by name "
-                            + vcCode,
-                    String.valueOf(vcCode), e);
+            return null;
+            // String vcCode = createdBy + "/" + vcName;
+            // throw new
+            // KustvaktException(StatusCodes.NO_RESULT_FOUND,
+            // "No result found for query: retrieve virtual corpus by
+            // name "
+            // + vcCode,
+            // String.valueOf(vcCode), e);
         }
         catch (NonUniqueResultException e) {
             String vcCode = createdBy + "/" + vcName;
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
index 15da11f..c711009 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
@@ -83,15 +83,17 @@
         return createVCDtos(vcList);
     }
 
-    public List<VirtualCorpusDto> listAvailableVCForUser (String authenticatedUsername,
-            String username) throws KustvaktException {
+    public List<VirtualCorpusDto> listAvailableVCForUser (
+            String authenticatedUsername, String username)
+            throws KustvaktException {
 
         boolean isAdmin = adminDao.isAdmin(authenticatedUsername);
 
         if (username != null) {
             if (!username.equals(authenticatedUsername) && !isAdmin) {
                 throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
-                        "Unauthorized operation for user: " + authenticatedUsername,
+                        "Unauthorized operation for user: "
+                                + authenticatedUsername,
                         authenticatedUsername);
             }
         }
@@ -184,7 +186,15 @@
 
         VirtualCorpus vc = vcDao.retrieveVCByName(vcName, createdBy);
 
-        if (vc.getCreatedBy().equals(username) || adminDao.isAdmin(username)) {
+        if (vc == null) {
+            String vcCode = createdBy + "/" + vcName;
+            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND,
+                    "No result found for query: retrieve virtual corpus by name "
+                            + vcCode,
+                    String.valueOf(vcCode));
+        }
+        else if (vc.getCreatedBy().equals(username)
+                || adminDao.isAdmin(username)) {
 
             if (vc.getType().equals(VirtualCorpusType.PUBLISHED)) {
                 VirtualCorpusAccess access =
@@ -201,13 +211,35 @@
         }
     }
 
+    @Deprecated
     public void editVC (VirtualCorpusJson vcJson, String username)
             throws KustvaktException {
         ParameterChecker.checkIntegerValue(vcJson.getId(), "id");
-        int vcId = vcJson.getId();
-        VirtualCorpus vc = vcDao.retrieveVCById(vcId);
+        VirtualCorpus vc = vcDao.retrieveVCById(vcJson.getId());
+        editVC(vc, vcJson, vcJson.getName(), username);
+    }
 
-        if (!username.equals(vc.getCreatedBy())
+    public void handlePutRequest (String username, String vcCreator,
+            String vcName, VirtualCorpusJson vcJson) throws KustvaktException {
+        if (!username.equals(vcCreator)) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+                    "VC creator verification failed. Path parameter vcCreator "
+                            + "must be the same as the authenticated username.");
+        }
+        
+        VirtualCorpus vc = vcDao.retrieveVCByName(vcName, vcCreator);
+        if (vc == null) {
+            storeVC(vcJson, vcName, username);
+        }
+        else {
+            editVC(vc, vcJson, vcName, username);
+        }
+    }
+
+    public void editVC (VirtualCorpus existingVC, VirtualCorpusJson newVC,
+            String vcName, String username) throws KustvaktException {
+
+        if (!username.equals(existingVC.getCreatedBy())
                 && !adminDao.isAdmin(username)) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
@@ -215,19 +247,20 @@
 
         String koralQuery = null;
         CorpusAccess requiredAccess = null;
-        if (vcJson.getCorpusQuery() != null
-                && vcJson.getCorpusQuery().isEmpty()) {
-            koralQuery = serializeCorpusQuery(vcJson.getCorpusQuery());
-            requiredAccess = determineRequiredAccess(koralQuery);
+        String corpusQuery = newVC.getCorpusQuery();
+        if (corpusQuery != null && corpusQuery.isEmpty()) {
+            koralQuery = serializeCorpusQuery(corpusQuery);
+            requiredAccess = determineRequiredAccess(newVC.isCached(), vcName,
+                    koralQuery);
         }
 
-        VirtualCorpusType type = vcJson.getType();
+        VirtualCorpusType type = newVC.getType();
         if (type != null) {
-            if (vc.getType().equals(VirtualCorpusType.PUBLISHED)) {
+            if (existingVC.getType().equals(VirtualCorpusType.PUBLISHED)) {
                 // withdraw from publication
                 if (!type.equals(VirtualCorpusType.PUBLISHED)) {
                     VirtualCorpusAccess hiddenAccess =
-                            accessDao.retrieveHiddenAccess(vcId);
+                            accessDao.retrieveHiddenAccess(existingVC.getId());
                     deleteVCAccess(hiddenAccess.getId(), "system");
                     int groupId = hiddenAccess.getUserGroup().getId();
                     userGroupService.deleteAutoHiddenGroup(groupId, "system");
@@ -235,13 +268,13 @@
                 // else remains the same
             }
             else if (type.equals(VirtualCorpusType.PUBLISHED)) {
-                publishVC(vcJson.getId());
+                publishVC(existingVC.getId());
             }
         }
 
-        vcDao.editVirtualCorpus(vc, vcJson.getName(), vcJson.getType(),
-                requiredAccess, koralQuery, vcJson.getDefinition(),
-                vcJson.getDescription(), vcJson.getStatus());
+        vcDao.editVirtualCorpus(existingVC, vcName, type, requiredAccess,
+                koralQuery, newVC.getDefinition(), newVC.getDescription(),
+                newVC.getStatus(), newVC.isCached());
     }
 
     private void publishVC (int vcId) throws KustvaktException {
@@ -264,14 +297,14 @@
         }
     }
 
-    public int storeVC (VirtualCorpusJson vc, String username)
+    public int storeVC (VirtualCorpusJson vc, String name, String createdBy)
             throws KustvaktException {
+
         ParameterChecker.checkStringValue(vc.getCorpusQuery(), "corpusQuery");
         String koralQuery = serializeCorpusQuery(vc.getCorpusQuery());
 
-        return storeVC(vc.getName(), vc.getType(), koralQuery,
-                vc.getDefinition(), vc.getDescription(), vc.getStatus(),
-                vc.isCached(), username);
+        return storeVC(name, vc.getType(), koralQuery, vc.getDefinition(),
+                vc.getDescription(), vc.getStatus(), vc.isCached(), createdBy);
     }
 
     public int storeVC (String name, VirtualCorpusType type, String koralQuery,
@@ -293,20 +326,8 @@
                     "Unauthorized operation for user: " + username, username);
         }
 
-        CorpusAccess requiredAccess;
-        if (isCached) {
-            KoralCollectionQueryBuilder koral =
-                    new KoralCollectionQueryBuilder();
-            koral.with("referTo " + name);
-            String vcRef = koral.toJSON();
-            if (DEBUG) {
-                jlog.debug("Determine vc access with vc ref: " + vcRef);
-            }
-            requiredAccess = determineRequiredAccess(vcRef);
-        }
-        else {
-            requiredAccess = determineRequiredAccess(koralQuery);
-        }
+        CorpusAccess requiredAccess =
+                determineRequiredAccess(isCached, name, koralQuery);
 
         if (DEBUG) jlog.debug("Storing VC " + name + "in the database ");
         int vcId = 0;
@@ -354,8 +375,19 @@
         return koralQuery;
     }
 
-    public CorpusAccess determineRequiredAccess (String koralQuery)
-            throws KustvaktException {
+    public CorpusAccess determineRequiredAccess (boolean isCached, String name,
+            String koralQuery) throws KustvaktException {
+
+        if (isCached) {
+            KoralCollectionQueryBuilder koral =
+                    new KoralCollectionQueryBuilder();
+            koral.with("referTo " + name);
+            koralQuery = koral.toJSON();
+            if (DEBUG) {
+                jlog.debug("Determine vc access with vc ref: " + koralQuery);
+            }
+
+        }
 
         if (findDocWithLicense(koralQuery, config.getAllOnlyRegex())) {
             return CorpusAccess.ALL;
@@ -385,6 +417,7 @@
         return (numberOfDoc > 0) ? true : false;
     }
 
+    @Deprecated
     public List<VirtualCorpusAccess> retrieveAllVCAccess (int vcId)
             throws KustvaktException {
         return accessDao.retrieveAllAccessByVC(vcId);
@@ -425,8 +458,9 @@
                 throw new KustvaktException(StatusCodes.DB_INSERT_FAILED,
                         cause.getMessage());
             }
+            
             vcDao.editVirtualCorpus(vc, null, VirtualCorpusType.PUBLISHED, null,
-                    null, null, null, null);
+                    null, null, null, null, vc.isCached());
         }
     }
 
@@ -458,6 +492,7 @@
     // }
     // }
 
+    @Deprecated
     public List<VirtualCorpusAccessDto> listVCAccessByVC (String username,
             int vcId) throws KustvaktException {
 
@@ -479,6 +514,27 @@
         return accessConverter.createVCADto(accessList);
     }
 
+    public List<VirtualCorpusAccessDto> listVCAccessByVC (String username,
+            String vcCreator, String vcName) throws KustvaktException {
+
+        List<VirtualCorpusAccess> accessList;
+        if (adminDao.isAdmin(username)) {
+            accessList = accessDao.retrieveAllAccessByVC(vcCreator, vcName);
+        }
+        else {
+            accessList = accessDao.retrieveActiveAccessByVC(vcCreator, vcName);
+            List<VirtualCorpusAccess> filteredAccessList = new ArrayList<>();
+            for (VirtualCorpusAccess access : accessList) {
+                UserGroup userGroup = access.getUserGroup();
+                if (isVCAccessAdmin(userGroup, username)) {
+                    filteredAccessList.add(access);
+                }
+            }
+            accessList = filteredAccessList;
+        }
+        return accessConverter.createVCADto(accessList);
+    }
+
     public List<VirtualCorpusAccessDto> listVCAccessByGroup (String username,
             int groupId) throws KustvaktException {
         UserGroup userGroup = userGroupService.retrieveUserGroupById(groupId);
@@ -517,6 +573,13 @@
     public VirtualCorpus searchVCByName (String username, String vcName,
             String createdBy) throws KustvaktException {
         VirtualCorpus vc = vcDao.retrieveVCByName(vcName, createdBy);
+        if (vc == null) {
+            String vcCode = createdBy + "/" + vcName;
+            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND,
+                    "No result found for query: retrieve virtual corpus by name "
+                            + vcCode,
+                    String.valueOf(vcCode));
+        }
         checkVCAccess(vc, username);
         return vc;
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
index fbafcff..86104e6 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
@@ -25,7 +25,6 @@
 import de.ids_mannheim.korap.constant.UserGroupStatus;
 import de.ids_mannheim.korap.dto.UserGroupDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.oauth2.service.OAuth2ScopeService;
 import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.service.UserGroupService;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
index 06d0d90..a2aa625 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/VirtualCorpusController.java
@@ -7,6 +7,7 @@
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
@@ -78,6 +79,7 @@
     @POST
     @Path("create")
     @Consumes("application/json")
+    @Deprecated
     public Response createVC (@Context SecurityContext securityContext,
             VirtualCorpusJson vc) {
         try {
@@ -86,7 +88,7 @@
                     (TokenContext) securityContext.getUserPrincipal();
 
             scopeService.verifyScope(context, OAuth2Scope.CREATE_VC);
-            service.storeVC(vc, context.getUsername());
+            service.storeVC(vc, vc.getName(), context.getUsername());
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
@@ -110,6 +112,7 @@
     @POST
     @Path("edit")
     @Consumes("application/json")
+    @Deprecated
     public Response editVC (@Context SecurityContext securityContext,
             VirtualCorpusJson vc) throws KustvaktException {
         TokenContext context =
@@ -125,6 +128,27 @@
         return Response.ok().build();
     }
 
+    // EM: changing vc name is disabled
+    @PUT
+    @Path("/{vcCreator}/{vcName}")
+    @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public Response editVC (@Context SecurityContext securityContext,
+            @PathParam("vcCreator") String vcCreator,
+            @PathParam("vcName") String vcName,
+            VirtualCorpusJson vc) throws KustvaktException {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+
+        try {
+            scopeService.verifyScope(context, OAuth2Scope.EDIT_VC);
+            service.handlePutRequest(context.getUsername(),vcCreator, vcName, vc);
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+
     /**
      * Searches for a specific VC given the VC id.
      * 
@@ -181,8 +205,7 @@
     }
 
     /**
-     * Lists not only owned virtual corpora but all virtual corpora
-     * available to the authenticated user.
+     * Lists all virtual corpora available to the authenticated user.
      *
      * System-admins can list available vc for a specific user by
      * specifiying the username parameter.
@@ -201,9 +224,18 @@
     @GET
     @Path("list")
     @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    @Deprecated
     public List<VirtualCorpusDto> listVCByUser (
             @Context SecurityContext securityContext,
             @QueryParam("username") String username) {
+        return listAvailableVC(securityContext, username);
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusDto> listAvailableVC (
+            @Context SecurityContext securityContext,
+            @QueryParam("username") String username) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
@@ -216,6 +248,8 @@
         }
     }
 
+    // EM: TODO: change path to @Path("{createdBy}"), currently
+    // conflicted with /{vcId}
     /**
      * Lists all virtual corpora created by a user
      * 
@@ -328,6 +362,7 @@
         return Response.ok().build();
     }
 
+    // EM: TODO: replace vcId with vcCreator and vcUsername
     /**
      * VC can only be shared with a group, not individuals.
      * Only VCA admins are allowed to share VC and the VC must have
@@ -373,8 +408,17 @@
      */
     @DELETE
     @Path("access/delete/{accessId}")
+    @Deprecated
     public Response deleteVCAccess (@Context SecurityContext securityContext,
             @PathParam("accessId") int accessId) {
+        return deleteVCAccessById(securityContext, accessId);
+    }
+
+    @DELETE
+    @Path("access/{accessId}")
+    public Response deleteVCAccessById (
+            @Context SecurityContext securityContext,
+            @PathParam("accessId") int accessId) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
@@ -405,6 +449,7 @@
     @GET
     @Path("access/list")
     @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    @Deprecated
     public List<VirtualCorpusAccessDto> listVCAccess (
             @Context SecurityContext securityContext,
             @QueryParam("vcId") int vcId) {
@@ -420,6 +465,45 @@
     }
 
     /**
+     * Lists active VC-accesses available to a given VC or user-group.
+     * 
+     * Only available to VCA and system admins.
+     * For system admins, list all VCA for the group.
+     * 
+     * @param securityContext
+     * @param vcCreator
+     *            the username of a VC creator
+     * @param vcName
+     *            the name of a VC
+     * @param groupId
+     *            a group id number
+     * @return
+     */
+    @GET
+    @Path("access")
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public List<VirtualCorpusAccessDto> listVCAccesses (
+            @Context SecurityContext securityContext,
+            @QueryParam("vcCreator") String vcCreator,
+            @QueryParam("vcName") String vcName,
+            @QueryParam("groupId") int groupId) {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+        try {
+            scopeService.verifyScope(context, OAuth2Scope.VC_ACCESS_INFO);
+            if (groupId > 0) {
+                return service.listVCAccessByGroup(context.getUsername(),
+                        groupId);
+            }
+            return service.listVCAccessByVC(context.getUsername(), vcCreator,
+                    vcName);
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
+
+    /**
      * Lists active VC-accesses available for a user-group.
      * Only available to VCA and system admins.
      * For system admins, list all VCA for the group.
@@ -435,6 +519,7 @@
     @GET
     @Path("access/list/byGroup")
     @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    @Deprecated
     public List<VirtualCorpusAccessDto> listVCAccessByGroup (
             @Context SecurityContext securityContext,
             @QueryParam("groupId") int groupId) {
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/VirtualCorpusJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/VirtualCorpusJson.java
index 3d34d24..419eff4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/input/VirtualCorpusJson.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/VirtualCorpusJson.java
@@ -2,7 +2,6 @@
 
 
 import de.ids_mannheim.korap.constant.VirtualCorpusType;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.service.VirtualCorpusService;
 import de.ids_mannheim.korap.web.controller.VirtualCorpusController;
 import lombok.Getter;
@@ -18,25 +17,21 @@
 @Getter
 @Setter
 public class VirtualCorpusJson {
-
+    // required
+    private boolean isCached;
+    
     // required in creating VCs
+    @Deprecated
     private String name;
     private VirtualCorpusType type;
     private String corpusQuery;
     
     // required in editing VCs
+    @Deprecated
     private int id;
     
     // optional
     private String definition;
     private String description;
     private String status;
-    private boolean isCached;
-
-
-    public void setCorpusQuery (String corpusQuery)
-            throws KustvaktException {
-        
-        this.corpusQuery = corpusQuery;
-    }
 }
\ No newline at end of file
diff --git a/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java
index 3cca102..6b9608b 100644
--- a/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/service/VirtualCorpusServiceTest.java
@@ -42,7 +42,7 @@
         vc.setCorpusQuery("corpusSigle=GOE");
         vc.setName("dory VC");
         vc.setType(VirtualCorpusType.PRIVATE);
-        vcService.storeVC(vc, "dory");
+        vcService.storeVC(vc, vc.getName(), "dory");
     }
 
     @Test
@@ -53,7 +53,7 @@
         vc.setCorpusQuery("corpusSigle=GOE");
         vc.setName("new published vc");
         vc.setType(VirtualCorpusType.PUBLISHED);
-        int vcId = vcService.storeVC(vc, "VirtualCorpusServiceTest");
+        int vcId = vcService.storeVC(vc,vc.getName(), "VirtualCorpusServiceTest");
 
         List<VirtualCorpusAccess> accesses =
                 vcService.retrieveAllVCAccess(vcId);
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
index 6530e7d..6c1f4e3 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
@@ -256,7 +256,7 @@
     public void testListVCByOtherUser () throws UniformInterfaceException,
             ClientHandlerException, KustvaktException {
         ClientResponse response = resource().path(API_VERSION).path("vc")
-                .path("list").queryParam("createdBy", "dory")
+                .path("list").queryParam("username", "dory")
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
                         .createBasicAuthorizationHeaderValue("pearl", "pass"))