Code review

This commit is contained in:
Claudio Maggioni 2020-04-21 17:36:17 +02:00
parent 4357606187
commit db21aa0a26
9 changed files with 60 additions and 47 deletions

View file

@ -6,10 +6,10 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.GenericDeviceSaveReguest;
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.SwitchOperationRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.SwitchOperationRequest;
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import ch.usi.inf.sa4.sanmarinoes.smarthut.service.DeviceService;
import java.security.Principal; import java.security.Principal;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid; import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.*;
@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.*;
public class SwitchController extends InputDeviceConnectionController<Switch, Switchable> { public class SwitchController extends InputDeviceConnectionController<Switch, Switchable> {
private SwitchRepository switchRepository; private SwitchRepository switchRepository;
private SwitchableRepository<Switchable> switchableRepository; private DeviceService deviceService;
/** /**
* Contstructs the controller by requiring essential object for the controller implementation * Contstructs the controller by requiring essential object for the controller implementation
@ -31,10 +31,12 @@ public class SwitchController extends InputDeviceConnectionController<Switch, Sw
*/ */
@Autowired @Autowired
protected SwitchController( protected SwitchController(
SwitchRepository inputRepository, SwitchableRepository<Switchable> outputRepository) { SwitchRepository inputRepository,
SwitchableRepository<Switchable> outputRepository,
DeviceService deviceService) {
super(inputRepository, outputRepository, Switchable.SWITCH_SWITCHABLE_CONNECTOR); super(inputRepository, outputRepository, Switchable.SWITCH_SWITCHABLE_CONNECTOR);
this.switchRepository = inputRepository; this.switchRepository = inputRepository;
this.switchableRepository = outputRepository; this.deviceService = deviceService;
} }
@GetMapping @GetMapping
@ -57,7 +59,7 @@ public class SwitchController extends InputDeviceConnectionController<Switch, Sw
} }
@PutMapping("/operate") @PutMapping("/operate")
public Set<Switchable> operate( public List<Switchable> operate(
@Valid @RequestBody final SwitchOperationRequest sr, final Principal principal) @Valid @RequestBody final SwitchOperationRequest sr, final Principal principal)
throws NotFoundException { throws NotFoundException {
final Switch s = final Switch s =
@ -77,9 +79,8 @@ public class SwitchController extends InputDeviceConnectionController<Switch, Sw
break; break;
} }
switchableRepository.saveAll(s.getOutputs()); deviceService.save(s);
return deviceService.saveAll(s.getOutputs());
return s.getOutputs();
} }
@DeleteMapping("/{id}") @DeleteMapping("/{id}")

View file

@ -4,13 +4,9 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.CascadeType; import javax.persistence.*;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Automation { public class Automation {
@Id @Id
@ -19,11 +15,11 @@ public class Automation {
@ApiModelProperty(hidden = true) @ApiModelProperty(hidden = true)
private long id; private long id;
@OneToMany(mappedBy = "trigger", orphanRemoval = true) @OneToMany(mappedBy = "automation", orphanRemoval = true)
@GsonExclude @GsonExclude
private Set<Trigger<?>> triggers = new HashSet<>(); private Set<Trigger<?>> triggers = new HashSet<>();
@OneToMany(mappedBy = "scenes", cascade = CascadeType.REMOVE) @OneToMany(mappedBy = "automation", cascade = CascadeType.REMOVE)
@GsonExclude @GsonExclude
private Set<ScenePriority> scenes = new HashSet<>(); private Set<ScenePriority> scenes = new HashSet<>();

View file

@ -25,7 +25,7 @@ public class BooleanTrigger<D extends Device & BooleanTriggerable> extends Trigg
} }
@Override @Override
public <T extends Device> boolean check() { public boolean triggered() {
return getDevice().readTriggerState() == isOn(); return getDevice().readTriggerState() == isOn();
} }
} }

View file

@ -34,6 +34,11 @@ public abstract class Device {
@GsonExclude @GsonExclude
private Room room; private Room room;
@OneToMany(mappedBy = "device", orphanRemoval = true)
@GsonExclude
// @SocketGsonExclude
private Set<Trigger<? extends Device>> triggers = new HashSet<>();
/** /**
* The room this device belongs in, as a foreign key id. To use when updating and inserting from * The room this device belongs in, as a foreign key id. To use when updating and inserting from
* a REST call. * a REST call.

View file

@ -1,12 +1,9 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
import javax.persistence.OneToMany;
/** /**
* A generic abstraction for an input device, i.e. something that captures input either from the * A generic abstraction for an input device, i.e. something that captures input either from the
@ -15,10 +12,6 @@ import javax.persistence.OneToMany;
@Entity @Entity
@Inheritance(strategy = InheritanceType.JOINED) @Inheritance(strategy = InheritanceType.JOINED)
public abstract class InputDevice extends Device { public abstract class InputDevice extends Device {
@OneToMany(mappedBy = "scene", orphanRemoval = true)
@GsonExclude
private Set<Trigger<? extends Device>> triggers = new HashSet<>();
public InputDevice(String kind) { public InputDevice(String kind) {
super(kind, FlowType.INPUT); super(kind, FlowType.INPUT);
} }

View file

@ -1,5 +1,6 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import com.google.gson.annotations.SerializedName;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
@ -8,28 +9,46 @@ import javax.validation.constraints.NotNull;
@Entity @Entity
@Inheritance(strategy = InheritanceType.JOINED) @Inheritance(strategy = InheritanceType.JOINED)
public class RangeTrigger<D extends Device> extends Trigger<D> { public class RangeTrigger<D extends Device & RangeTriggerable> extends Trigger<D> {
@Override @Override
public <T extends Device> boolean check(T d) { public boolean triggered() {
return false; double value = getDevice().readTriggerState();
switch (operator) {
case EQUAL:
return value == range;
case LESS:
return value < range;
case GREATER:
return value > range;
case GREATER_EQUAL:
return value >= range;
case LESS_EQUAL:
return value <= range;
}
throw new IllegalStateException();
} }
enum Operator { enum Operator {
@SerializedName("EQUAL")
EQUAL, EQUAL,
@SerializedName("LESS")
LESS, LESS,
@SerializedName("GREATER")
GREATER, GREATER,
@SerializedName("LESS_EQUAL")
LESS_EQUAL, LESS_EQUAL,
GREATER_EQUAL; @SerializedName("GREATER_EQUAL")
GREATER_EQUAL
} }
@NotNull @NotNull
@Column(nullable = false) @Column(nullable = false)
Operator operator; private Operator operator;
@NotNull @NotNull
@Column(nullable = false) @Column(nullable = false)
private Float range; private double range;
public Operator getOperator() { public Operator getOperator() {
return operator; return operator;
@ -39,7 +58,7 @@ public class RangeTrigger<D extends Device> extends Trigger<D> {
this.operator = operator; this.operator = operator;
} }
public Float getRange() { public double getRange() {
return range; return range;
} }

View file

@ -30,7 +30,7 @@ public class Scene {
@GsonExclude @GsonExclude
private Long userId; private Long userId;
@OneToMany(mappedBy = "states", orphanRemoval = true) @OneToMany(mappedBy = "scene", orphanRemoval = true)
@GsonExclude @GsonExclude
private Set<State<?>> states = new HashSet<>(); private Set<State<?>> states = new HashSet<>();
@ -39,10 +39,6 @@ public class Scene {
@Column(nullable = false) @Column(nullable = false)
private String name; private String name;
@ManyToMany(mappedBy = "automations", cascade = CascadeType.DETACH)
@GsonExclude
private Set<Automation> automations = new HashSet<>();
public String getName() { public String getName() {
return name; return name;
} }
@ -82,8 +78,4 @@ public class Scene {
public void setUserId(Long userId) { public void setUserId(Long userId) {
this.userId = userId; this.userId = userId;
} }
public Set<Automation> getAutomations() {
return automations;
}
} }

View file

@ -12,15 +12,14 @@ import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import javax.persistence.PreRemove; import javax.persistence.PreRemove;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
@Entity @Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"device_id", "scene_id"})})
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Trigger<D extends Device> { public abstract class Trigger<D extends Device> {
public abstract boolean triggered();
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", updatable = false, nullable = false, unique = true) @Column(name = "id", updatable = false, nullable = false, unique = true)
@ -89,8 +88,6 @@ public abstract class Trigger<D extends Device> {
this.automationId = automationId; this.automationId = automationId;
} }
public abstract <T extends Device> boolean check(T d);
@PreRemove @PreRemove
public void removeDeviceAndScene() { public void removeDeviceAndScene() {
this.setDevice(null); this.setDevice(null);

View file

@ -4,7 +4,9 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Device;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DeviceRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DeviceRepository;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Trigger; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Trigger;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.TriggerRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.TriggerRepository;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -26,17 +28,25 @@ public class DeviceService {
@Autowired DeviceRepository<Device> deviceRepository; @Autowired DeviceRepository<Device> deviceRepository;
@Autowired TriggerRepository<Trigger<? extends Device>> triggerRepository; @Autowired TriggerRepository<Trigger<? extends Device>> triggerRepository;
public <T extends Device> List<T> saveAll(Collection<T> devices) {
return devices.stream().map(this::save).collect(Collectors.toList());
}
public <T extends Device> T save(T device) { public <T extends Device> T save(T device) {
final long deviceId = device.getId(); final long deviceId = device.getId();
List<? extends Trigger<? extends Device>> triggers = List<Trigger<? extends Device>> triggers = triggerRepository.findAllByDeviceId(deviceId);
triggerRepository.findAllByDeviceId(deviceId);
List<Trigger<? extends Device>> triggeredTriggers =
triggers.stream().filter(Trigger::triggered).collect(Collectors.toList());
// map activated -> automations // map activated -> automations
// remove duplicates // remove duplicates
// sort automations per priority // sort automations per priority
// sort scenes inside automations per priority // sort scenes inside automations per priority
// apply scenes (SceneService.apply()) // apply scenes (SceneService.apply())
return deviceRepository.save(device);
} }
} }