Skip to content

Commit

Permalink
Merge pull request #691 from IDgis/690-unique-name-validation
Browse files Browse the repository at this point in the history
unique name validation moved to service
  • Loading branch information
copierrj committed Jun 9, 2015
2 parents 9c13ed1 + dbf83dd commit f50f033
Show file tree
Hide file tree
Showing 7 changed files with 399 additions and 273 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package nl.idgis.publisher.domain.query;

import java.util.Objects;

import nl.idgis.publisher.domain.response.UniqueNameValidationResult;

public class ValidateUniqueName implements DomainQuery<UniqueNameValidationResult> {

private static final long serialVersionUID = -8948822157181419535L;

private final String name;

public ValidateUniqueName(String name) {
this.name = Objects.requireNonNull(name);
}

public String name() {
return name;
}

@Override
public String toString() {
return "ValidateUniqueName [name=" + name + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package nl.idgis.publisher.domain.response;

import java.util.Objects;

public class UniqueNameValidationResult implements ValidationResult {

private static final long serialVersionUID = -3800481429856190153L;

public enum ConflictType {
LAYER,
LAYERGROUP,
SERVICE
}

private final ConflictType conflictType;

private UniqueNameValidationResult(ConflictType conflictType) {
this.conflictType = conflictType;
}

public static UniqueNameValidationResult valid() {
return new UniqueNameValidationResult(null);
}

public static UniqueNameValidationResult conflict(ConflictType conflictType) {
return new UniqueNameValidationResult(Objects.requireNonNull(conflictType, "conflict type missing"));
}

public boolean isValid() {
return conflictType == null;
}

public ConflictType conflictType() {
if(conflictType == null) {
throw new IllegalStateException("no conflict");
}

return conflictType;
}

@Override
public String toString() {
return "UniqueNameValidationResult [conflictType=" + conflictType + "]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package nl.idgis.publisher.domain.response;

import java.io.Serializable;

public interface ValidationResult extends Serializable {

boolean isValid();
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@
import java.util.stream.Collectors;

import nl.idgis.publisher.database.AsyncSQLQuery;

import nl.idgis.publisher.domain.query.GetLayerParentGroups;
import nl.idgis.publisher.domain.query.GetLayerParentServices;
import nl.idgis.publisher.domain.query.ListLayerKeywords;
import nl.idgis.publisher.domain.query.ListLayerStyles;
import nl.idgis.publisher.domain.query.ListLayers;
import nl.idgis.publisher.domain.query.PutLayerKeywords;
import nl.idgis.publisher.domain.query.PutLayerStyles;
import nl.idgis.publisher.domain.query.ValidateUniqueName;
import nl.idgis.publisher.domain.response.Page;
import nl.idgis.publisher.domain.response.Response;
import nl.idgis.publisher.domain.response.UniqueNameValidationResult;
import nl.idgis.publisher.domain.service.CrudOperation;
import nl.idgis.publisher.domain.service.CrudResponse;
import nl.idgis.publisher.domain.web.Layer;
Expand All @@ -40,16 +43,16 @@
import nl.idgis.publisher.domain.web.Service;
import nl.idgis.publisher.domain.web.Style;
import nl.idgis.publisher.domain.web.TiledLayer;
import nl.idgis.publisher.utils.StreamUtils;

import nl.idgis.publisher.utils.TypedList;

import akka.actor.ActorRef;
import akka.actor.Props;

import com.mysema.query.Tuple;
import com.mysema.query.sql.SQLSubQuery;
import com.mysema.query.types.ConstantImpl;
import com.mysema.query.types.Expression;
import com.mysema.query.types.Path;
import com.mysema.query.types.expr.DslExpression;
import com.mysema.query.types.path.PathBuilder;

Expand Down Expand Up @@ -82,6 +85,30 @@ protected void preStartAdmin() {

doQuery (GetLayerParentGroups.class, this::handleGetLayerParentGroups);
doQuery (GetLayerParentServices.class, this::handleGetLayerParentServices);

doQuery(ValidateUniqueName.class, this::handleValidateUniqueName);
}

private CompletableFuture<UniqueNameValidationResult> handleValidateUniqueName(ValidateUniqueName validateUniqueName) {
return db.query()
.from(genericLayer)
.leftJoin(leafLayer).on(leafLayer.genericLayerId.eq(genericLayer.id))
.leftJoin(service).on(service.genericLayerId.eq(genericLayer.id))
.where(genericLayer.name.eq(validateUniqueName.name()))
.singleResult(leafLayer.id, service.id).thenApply(optionalResult ->
optionalResult
.map(result -> {
if(result.get(leafLayer.id) != null) {
return UniqueNameValidationResult.conflict(UniqueNameValidationResult.ConflictType.LAYER);
}

if(result.get(service.id) != null) {
return UniqueNameValidationResult.conflict(UniqueNameValidationResult.ConflictType.SERVICE);
}

return UniqueNameValidationResult.conflict(UniqueNameValidationResult.ConflictType.LAYERGROUP);
})
.orElse(UniqueNameValidationResult.valid()));
}

private CompletableFuture<Page<Layer>> handleListLayers () {
Expand Down
168 changes: 88 additions & 80 deletions publisher-web/app/controllers/Groups.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import com.fasterxml.jackson.databind.node.ObjectNode;

import scala.runtime.AbstractFunction1;

import models.Domain;
import models.Domain.Function;
import models.Domain.Function2;
import models.Domain.Function3;
import models.Domain.Function5;

import nl.idgis.publisher.domain.query.GetGroupParentGroups;
import nl.idgis.publisher.domain.query.GetGroupParentServices;
import nl.idgis.publisher.domain.query.GetGroupStructure;
Expand All @@ -21,6 +23,7 @@
import nl.idgis.publisher.domain.query.ListLayerGroups;
import nl.idgis.publisher.domain.query.ListLayers;
import nl.idgis.publisher.domain.query.PutGroupStructure;
import nl.idgis.publisher.domain.query.ValidateUniqueName;
import nl.idgis.publisher.domain.response.Page;
import nl.idgis.publisher.domain.response.Response;
import nl.idgis.publisher.domain.service.CrudOperation;
Expand All @@ -29,6 +32,7 @@
import nl.idgis.publisher.domain.web.LayerGroup;
import nl.idgis.publisher.domain.web.Service;
import nl.idgis.publisher.domain.web.tree.GroupLayer;

import play.Logger;
import play.Play;
import play.api.mvc.Call;
Expand All @@ -46,6 +50,7 @@
import views.html.layers.layerPagerFooter;
import views.html.layers.layerPagerHeader;
import actions.DefaultAuthenticator;

import akka.actor.ActorSelection;

@Security.Authenticated (DefaultAuthenticator.class)
Expand All @@ -68,97 +73,100 @@ public Result apply (final Page<LayerGroup> groups, final Page<Layer> layers) th

}

public static Promise<Result> submitCreateUpdate () {
final ActorSelection database = Akka.system().actorSelection (databaseRef);
private static Promise<Result> performCreateUpdate(final ActorSelection database, final Form<GroupForm> form) {
if (form.field("structure").value() == null){
form.reject("structure", Domain.message("web.application.page.groups.form.field.structure.validation.error"));
}

if (form.hasErrors ()) {
return renderCreateForm (form);
}
// validation end

final GroupForm groupForm = form.get ();
final List<String> layerIds = (groupForm.structure == null)?(new ArrayList<String>()):(groupForm.structure);
Logger.debug ("Group structure list: " + layerIds);

final List<String> layerStyleIds = groupForm.styles == null ? new ArrayList<>() : groupForm.styles;
Logger.debug ("Group layer style list: " + layerStyleIds);

final LayerGroup group = new LayerGroup(groupForm.id, groupForm.name.trim (), groupForm.title,
groupForm.abstractText,(groupForm.enabled ? groupForm.getTiledLayer() : null), false);

return from (database)
.list (LayerGroup.class)
.list (Layer.class)
.list (Service.class)
.executeFlat (new Function3<Page<LayerGroup>, Page<Layer>, Page<Service>, Promise<Result>> () {

.put(group)
.executeFlat (new Function<Response<?>, Promise<Result>> () {
@Override
public Promise<Result> apply (final Page<LayerGroup> groups, final Page<Layer> layers, final Page<Service> services) throws Throwable {
final Form<GroupForm> form = Form.form (GroupForm.class).bindFromRequest ();
Logger.debug ("submit Group: " + form.field("name").value());

// validation start
if (form.field("id").value().equals(ID)){
for (LayerGroup layerGroup : groups.values()) {
if (form.field("name").value().trim ().equals(layerGroup.name())){
form.reject("name", Domain.message("web.application.page.groups.form.field.name.validation.groupexists.error"));
}
}
for (Layer layer : layers.values()) {
if (form.field("name").value().trim ().equals(layer.name())){
form.reject("name", Domain.message("web.application.page.groups.form.field.name.validation.layerexists.error"));
}
}
for (final Service service: services.values ()) {
if (form.field ("name").value ().trim ().equals (service.name ())) {
form.reject ("name", Domain.message("web.application.page.groups.form.field.name.validation.serviceexists.error"));
}
}
}
if (form.field("structure").value() == null){
form.reject("structure", Domain.message("web.application.page.groups.form.field.structure.validation.error"));
}

if (form.hasErrors ()) {
return renderCreateForm (form);
}
// validation end

final GroupForm groupForm = form.get ();
final List<String> layerIds = (groupForm.structure == null)?(new ArrayList<String>()):(groupForm.structure);
Logger.debug ("Group structure list: " + layerIds);

final List<String> layerStyleIds = groupForm.styles == null ? new ArrayList<>() : groupForm.styles;
Logger.debug ("Group layer style list: " + layerStyleIds);

final LayerGroup group = new LayerGroup(groupForm.id, groupForm.name.trim (), groupForm.title,
groupForm.abstractText,(groupForm.enabled ? groupForm.getTiledLayer() : null), false);

public Promise<Result> apply (final Response<?> response) throws Throwable {
// Get the id of the layer we just put
String groupId = response.getValue().toString();
PutGroupStructure putGroupStructure = new PutGroupStructure (groupId, layerIds, layerStyleIds);
return from (database)
.put(group)
.query(putGroupStructure)
.executeFlat (new Function<Response<?>, Promise<Result>> () {
@Override
public Promise<Result> apply (final Response<?> response) throws Throwable {
// Get the id of the layer we just put
String groupId = response.getValue().toString();
PutGroupStructure putGroupStructure = new PutGroupStructure (groupId, layerIds, layerStyleIds);
return from (database)
.query(putGroupStructure)
.executeFlat (new Function<Response<?>, Promise<Result>> () {
@Override
public Promise<Result> apply (final Response<?> response) throws Throwable {
if (CrudOperation.CREATE.equals (response.getOperation())) {
Logger.debug ("Created group " + group);
if (response.getOperationResponse().equals(CrudResponse.NOK)){
flash("danger", Domain.message("web.application.page.groups.form.field.structure.validation.cycle", response.getValue().toString()));
form.reject("structure", Domain.message("web.application.page.groups.form.field.structure.validation.error"));
return Promise.pure (redirect (routes.Groups.edit(groupId)));
} else {
flash ("success", Domain.message("web.application.page.groups.name") + " " + groupForm.getName () + " is " + Domain.message("web.application.added").toLowerCase());
}
}else{
Logger.debug ("Updated group " + group);
if (response.getOperationResponse().equals(CrudResponse.NOK)){
flash("danger", Domain.message("web.application.page.groups.form.field.structure.validation.cycle", response.getValue().toString()));
form.reject("structure", Domain.message("web.application.page.groups.form.field.structure.validation.error"));
return Promise.pure (redirect (routes.Groups.edit(groupId)));
} else {
flash ("success", Domain.message("web.application.page.groups.name") + " " + groupForm.getName () + " is " + Domain.message("web.application.updated").toLowerCase());
}
}
return Promise.pure (redirect (routes.Groups.list (null, 1)));
}
});
if (CrudOperation.CREATE.equals (response.getOperation())) {
Logger.debug ("Created group " + group);
if (response.getOperationResponse().equals(CrudResponse.NOK)){
flash("danger", Domain.message("web.application.page.groups.form.field.structure.validation.cycle", response.getValue().toString()));
form.reject("structure", Domain.message("web.application.page.groups.form.field.structure.validation.error"));
return Promise.pure (redirect (routes.Groups.edit(groupId)));
} else {
flash ("success", Domain.message("web.application.page.groups.name") + " " + groupForm.getName () + " is " + Domain.message("web.application.added").toLowerCase());
}
}else{
Logger.debug ("Updated group " + group);
if (response.getOperationResponse().equals(CrudResponse.NOK)){
flash("danger", Domain.message("web.application.page.groups.form.field.structure.validation.cycle", response.getValue().toString()));
form.reject("structure", Domain.message("web.application.page.groups.form.field.structure.validation.error"));
return Promise.pure (redirect (routes.Groups.edit(groupId)));
} else {
flash ("success", Domain.message("web.application.page.groups.name") + " " + groupForm.getName () + " is " + Domain.message("web.application.updated").toLowerCase());
}
}
return Promise.pure (redirect (routes.Groups.list (null, 1)));
}
});
}
});
}

public static Promise<Result> submitCreateUpdate () {
final ActorSelection database = Akka.system().actorSelection (databaseRef);

final Form<GroupForm> form = Form.form (GroupForm.class).bindFromRequest ();
final String name = form.field ("name").valueOr (null);

if (name == null) {
return performCreateUpdate(database, form);
} else {
return from (database)
.query (new ValidateUniqueName (name))
.executeFlat (validationResult -> {
if(validationResult.isValid ()) {
Logger.debug("name is valid: " + name);
} else {
Logger.debug("name is already in use: " + name);

switch(validationResult.conflictType ()) {
case LAYER:
form.reject ("name", "web.application.page.groups.form.field.name.validation.layerexists.error");
break;
case LAYERGROUP:
form.reject ("name", "web.application.page.groups.form.field.name.validation.groupexists.error");
break;
case SERVICE:
form.reject ("name", "web.application.page.groups.form.field.name.validation.serviceexists.error");
break;
default:
break;
}
}

return performCreateUpdate (database, form);
});

}
}

public static Promise<Result> list (final String query, final long page) {
Expand Down
Loading

0 comments on commit f50f033

Please sign in to comment.