diff --git a/.gitignore b/.gitignore index aca8222..b7101f1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /target/ /.idea/ /.jpb/ +/application.properties /*.db \ No newline at end of file diff --git a/src/main/angular/src/app/api/ISearchService.ts b/src/main/angular/src/app/api/ISearchService.ts index f6a98da..b5e0736 100644 --- a/src/main/angular/src/app/api/ISearchService.ts +++ b/src/main/angular/src/app/api/ISearchService.ts @@ -2,7 +2,7 @@ import {SearchResult} from "./SearchResult"; export interface ISearchService { - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void; + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void; search(term: string, next: (results: SearchResult[]) => void, error: (error: any) => void): void; diff --git a/src/main/angular/src/app/api/Page.ts b/src/main/angular/src/app/api/Page.ts new file mode 100644 index 0000000..9bb8f3a --- /dev/null +++ b/src/main/angular/src/app/api/Page.ts @@ -0,0 +1,26 @@ +import {FromJson} from "./types"; +import {validateListOrEmpty, validateNumberNotNull} from "./validators"; + +export class Page { + + constructor( + readonly page: number, + readonly size: number, + readonly content: T[], + ) { + // nothing + } + + static fromJsonGenerator(fromJson: FromJson): FromJson> { + return (json: any) => this.fromJson2(json, fromJson); + } + + static fromJson2(json: any, fromJson: FromJson): Page { + return new Page( + validateNumberNotNull(json['page']), + validateNumberNotNull(json['size']), + validateListOrEmpty(json['content'], fromJson), + ); + } + +} diff --git a/src/main/angular/src/app/api/abstract-repository.service.ts b/src/main/angular/src/app/api/abstract-repository.service.ts new file mode 100644 index 0000000..1051971 --- /dev/null +++ b/src/main/angular/src/app/api/abstract-repository.service.ts @@ -0,0 +1,62 @@ +import {Injectable} from '@angular/core'; +import {NO_OP} from "./api.service"; +import {Page} from "./Page"; +import {Error, FromJson, IEntity, Next} from "./types"; +import {environment} from "../../environments/environment"; +import {HttpClient} from "@angular/common/http"; +import {map} from "rxjs/operators"; + +@Injectable({ + providedIn: 'root' +}) +export class AbstractRepositoryService { + + constructor( + readonly http: HttpClient, + readonly prefix: string, + readonly fromJson: FromJson, + ) { + // nothing + } + + create(dto: Creator, next: Next = NO_OP, error: Error = NO_OP) { + this._post(['create'], dto, this.fromJson, next, error); + } + + set(entity: Entity, key: string, value: any, next: Next = NO_OP, error: Error = NO_OP) { + this._put(['put', entity.id, key], value, this.fromJson, next, error); + } + + get(id: number, next: Next = NO_OP, error: Error = NO_OP) { + this._get(['get', id], this.fromJson, next, error); + } + + filter(filter: Filter, next: Next> = NO_OP, error: Error = NO_OP) { + this._post(['filter'], filter, Page.fromJsonGenerator(this.fromJson), next, error); + } + + delete(id: number, next: Next = NO_OP, error: Error = NO_OP) { + this._delete(['delete', id], this.fromJson, next, error); + } + + private _get(path: any[], fromJson: FromJson, next: Next, error: Error): void { + this.http.get(this._url(path)).pipe(map(fromJson)).subscribe(next, error); + } + + private _put(path: any[], data: any, fromJson: FromJson, next: Next, error: Error): void { + this.http.put(this._url(path), data).pipe(map(fromJson)).subscribe(next, error); + } + + private _post(path: any[], data: any, fromJson: FromJson, next: Next, error: Error): void { + this.http.post(this._url(path), data).pipe(map(fromJson)).subscribe(next, error); + } + + private _delete(path: any[], fromJson: FromJson, next: Next, error: Error): void { + this.http.delete(this._url(path)).pipe(map(fromJson)).subscribe(next, error); + } + + private _url(path: any[]): string { + return environment.restBase + '/' + this.prefix + '/' + path.join('/'); + } + +} diff --git a/src/main/angular/src/app/api/api.service.spec.ts b/src/main/angular/src/app/api/api.service.spec.ts deleted file mode 100644 index b517af4..0000000 --- a/src/main/angular/src/app/api/api.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {TestBed} from '@angular/core/testing'; - -import {ApiService} from './api.service'; - -describe('ApiService', () => { - let service: ApiService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(ApiService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/src/main/angular/src/app/api/api.service.ts b/src/main/angular/src/app/api/api.service.ts index beaa1ac..984906d 100644 --- a/src/main/angular/src/app/api/api.service.ts +++ b/src/main/angular/src/app/api/api.service.ts @@ -6,6 +6,7 @@ import {Subject} from "rxjs"; import {CompatClient, Stomp} from "@stomp/stompjs"; import {Update} from "./Update"; import {LocationStrategy} from "@angular/common"; +import {Page} from "./Page"; export function NO_OP() { } @@ -48,7 +49,7 @@ export class ApiService { this.updateSubject.pipe(filter(update => update.type === type), map(update => Update.convert(update, fromJson))).subscribe(next); } - getItem(path: string, fromJson: (json: any) => T, next: (item: T) => void = NO_OP, error: (error: any) => void = NO_OP) { + getReturnItem(path: string, fromJson: (json: any) => T, next: (item: T) => void = NO_OP, error: (error: any) => void = NO_OP) { this.http.get(this.restUrl(path)).pipe(map(fromJson)).subscribe(next, errorInterceptor(error)); } @@ -64,6 +65,18 @@ export class ApiService { this.http.post(this.restUrl(path), data).pipe(map(fromJson)).subscribe(next, errorInterceptor(error)); } + putReturnItem(path: string, data: any, fromJson: (json: any) => T, next: (item: T) => void = NO_OP, error: (error: any) => void = NO_OP) { + this.http.put(this.restUrl(path), data).pipe(map(fromJson)).subscribe(next, errorInterceptor(error)); + } + + postReturnPage(path: string, data: any, fromJson: (json: any) => T, next: (page: Page) => void = NO_OP, error: (error: any) => void = NO_OP) { + this.http.post(this.restUrl(path), data).pipe(map(Page.fromJsonGenerator(fromJson))).subscribe(next, errorInterceptor(error)); + } + + deleteReturnItem(path: string, fromJson: (json: any) => T, next: (item: T) => void = NO_OP, error: (error: any) => void = NO_OP) { + this.http.delete(this.restUrl(path)).pipe(map(fromJson)).subscribe(next, errorInterceptor(error)); + } + postReturnList(path: string, data: any, fromJson: (json: any) => T, next: (list: T[]) => void = NO_OP, error: (error: any) => void = NO_OP) { this.http.post(this.restUrl(path), data).pipe(map(list => list.map(fromJson))).subscribe(next, errorInterceptor(error)); } diff --git a/src/main/angular/src/app/api/area/area.service.ts b/src/main/angular/src/app/api/area/area.service.ts index ef4739f..ff124b7 100644 --- a/src/main/angular/src/app/api/area/area.service.ts +++ b/src/main/angular/src/app/api/area/area.service.ts @@ -24,8 +24,8 @@ export class AreaService implements ISearchService { this.api.subscribe("AreaDto", Area.fromJson, next); } - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { - this.api.getItem("area/getById/" + id, SearchResult.fromJson, next, error); + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getReturnItem("area/searchById/" + id, SearchResult.fromJson, next, error); } search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { diff --git a/src/main/angular/src/app/api/bulk/Bulk.ts b/src/main/angular/src/app/api/bulk/Bulk.ts index f5edad5..f61dee1 100644 --- a/src/main/angular/src/app/api/bulk/Bulk.ts +++ b/src/main/angular/src/app/api/bulk/Bulk.ts @@ -4,11 +4,11 @@ import {BulkEntry} from "./BulkEntry"; export class Bulk { private constructor( - public id: number, - public version: number, - public name: string, - public enabled: boolean, - public entries: BulkEntry[], + readonly id: number, + readonly version: number, + readonly name: string, + readonly enabled: boolean, + readonly entries: BulkEntry[], ) { // nothing } diff --git a/src/main/angular/src/app/api/bulk/BulkEntry.ts b/src/main/angular/src/app/api/bulk/BulkEntry.ts index e8c966b..6e5e6d5 100644 --- a/src/main/angular/src/app/api/bulk/BulkEntry.ts +++ b/src/main/angular/src/app/api/bulk/BulkEntry.ts @@ -1,9 +1,13 @@ import {Property} from "../property/Property"; -import {validateNumberNotNull} from "../validators"; +import {validateBooleanNotNull, validateNumberNotNull} from "../validators"; export class BulkEntry { private constructor( + readonly id: number, + readonly version: number, + readonly position: number, + readonly enabled: boolean, readonly property: Property, readonly value: number, ) { @@ -12,6 +16,10 @@ export class BulkEntry { static fromJson(json: any): BulkEntry { return new BulkEntry( + validateNumberNotNull(json['id']), + validateNumberNotNull(json['version']), + validateNumberNotNull(json['position']), + validateBooleanNotNull(json['enabled']), Property.fromJson(json['property']), validateNumberNotNull(json['value']), ); diff --git a/src/main/angular/src/app/api/bulk/bulkService.ts b/src/main/angular/src/app/api/bulk/BulkService.ts similarity index 63% rename from src/main/angular/src/app/api/bulk/bulkService.ts rename to src/main/angular/src/app/api/bulk/BulkService.ts index 0e3cb04..d0861ef 100644 --- a/src/main/angular/src/app/api/bulk/bulkService.ts +++ b/src/main/angular/src/app/api/bulk/BulkService.ts @@ -4,6 +4,7 @@ import {ISearchService} from "../ISearchService"; import {SearchResult} from "../SearchResult"; import {Update} from "../Update"; import {Bulk} from "./Bulk"; +import {BulkEntry} from "./BulkEntry"; @Injectable({ providedIn: 'root' @@ -24,8 +25,12 @@ export class BulkService implements ISearchService { this.api.subscribe("BulkDto", Bulk.fromJson, next); } - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { - this.api.getItem("bulk/getById/" + id, SearchResult.fromJson, next, error); + getById(id: number, next: (results: Bulk) => void, error?: (error: any) => void): void { + this.api.getReturnItem("bulk/getById/" + id, Bulk.fromJson, next, error); + } + + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getReturnItem("bulk/searchById/" + id, SearchResult.fromJson, next, error); } search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { @@ -37,11 +42,15 @@ export class BulkService implements ISearchService { } create(next: (item: Bulk) => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("bulk/create/", Bulk.fromJson, next, error); + this.api.getReturnItem("bulk/create/", Bulk.fromJson, next, error); } delete(bulk: Bulk, next: () => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("bulk/delete/" + bulk.id, _ => _, next, error); + this.api.getReturnItem("bulk/delete/" + bulk.id, _ => _, next, error); + } + + setEntry(entry: BulkEntry, key: string, value: any, next: (result: BulkEntry) => void = NO_OP, error: (error: any) => void = NO_OP): void { + this.api.putReturnItem("BulkEntry/" + entry.id + "/set/" + key, value, next, error); } } diff --git a/src/main/angular/src/app/api/channel/channel.service.ts b/src/main/angular/src/app/api/channel/channel.service.ts index 0ff2d20..22dc82b 100644 --- a/src/main/angular/src/app/api/channel/channel.service.ts +++ b/src/main/angular/src/app/api/channel/channel.service.ts @@ -24,8 +24,8 @@ export class ChannelService implements ISearchService { this.api.subscribe("ChannelDto", Channel.fromJson, next); } - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { - this.api.getItem("channel/getById/" + id, SearchResult.fromJson, next, error); + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getReturnItem("channel/searchById/" + id, SearchResult.fromJson, next, error); } search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { diff --git a/src/main/angular/src/app/api/device/device.service.ts b/src/main/angular/src/app/api/device/device.service.ts index 8b6648c..c0d49b1 100644 --- a/src/main/angular/src/app/api/device/device.service.ts +++ b/src/main/angular/src/app/api/device/device.service.ts @@ -65,7 +65,7 @@ export class DeviceService { } getById(id: number, next: (item: Device) => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("device/getById/" + id, Device.fromJson, next, error); + this.api.getReturnItem("device/searchById/" + id, Device.fromJson, next, error); } create(type: string, next: (item: Device) => void, error: (error: any) => void = NO_OP): void { @@ -73,7 +73,7 @@ export class DeviceService { } delete(device: Device, next: () => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("device/delete/" + device.id, _ => _, next, error); + this.api.getReturnItem("device/delete/" + device.id, _ => _, next, error); } } diff --git a/src/main/angular/src/app/api/property/property.service.ts b/src/main/angular/src/app/api/property/property.service.ts index c80a58e..1aeba15 100644 --- a/src/main/angular/src/app/api/property/property.service.ts +++ b/src/main/angular/src/app/api/property/property.service.ts @@ -24,8 +24,8 @@ export class PropertyService implements ISearchService { this.api.subscribe("PropertyDto", Property.fromJson, next); } - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { - this.api.getItem("property/getById/" + id, SearchResult.fromJson, next, error); + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getReturnItem("property/searchById/" + id, SearchResult.fromJson, next, error); } search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { @@ -37,7 +37,7 @@ export class PropertyService implements ISearchService { } create(next: (item: Property) => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("property/create/", Property.fromJson, next, error); + this.api.getReturnItem("property/create/", Property.fromJson, next, error); } } diff --git a/src/main/angular/src/app/api/room/room.service.ts b/src/main/angular/src/app/api/room/room.service.ts index 0e3623a..97ce6bf 100644 --- a/src/main/angular/src/app/api/room/room.service.ts +++ b/src/main/angular/src/app/api/room/room.service.ts @@ -24,8 +24,8 @@ export class RoomService implements ISearchService { this.api.subscribe("RoomDto", Room.fromJson, next); } - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { - this.api.getItem("room/getById/" + id, SearchResult.fromJson, next, error); + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getReturnItem("room/searchById/" + id, SearchResult.fromJson, next, error); } search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { diff --git a/src/main/angular/src/app/api/scene/scene.service.ts b/src/main/angular/src/app/api/scene/scene.service.ts index 6f7a60c..e69d6f4 100644 --- a/src/main/angular/src/app/api/scene/scene.service.ts +++ b/src/main/angular/src/app/api/scene/scene.service.ts @@ -24,8 +24,8 @@ export class SceneService implements ISearchService { this.api.subscribe("SceneDto", Scene.fromJson, next); } - get(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { - this.api.getItem("scene/getById/" + id, SearchResult.fromJson, next, error); + searchById(id: number, next: (results: SearchResult) => void, error: (error: any) => void): void { + this.api.getReturnItem("scene/searchById/" + id, SearchResult.fromJson, next, error); } search(term: string, next: (results: SearchResult[]) => void = NO_OP, error: (error: any) => void = NO_OP): void { diff --git a/src/main/angular/src/app/api/schedule/entry/schedule-entry.service.ts b/src/main/angular/src/app/api/schedule/entry/schedule-entry.service.ts index a2340ef..d5fcc07 100644 --- a/src/main/angular/src/app/api/schedule/entry/schedule-entry.service.ts +++ b/src/main/angular/src/app/api/schedule/entry/schedule-entry.service.ts @@ -23,11 +23,11 @@ export class ScheduleEntryService { } create(schedule: Schedule, next: (item: ScheduleEntry) => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("schedule/entry/create/" + schedule.id, ScheduleEntry.fromJson, next, error); + this.api.getReturnItem("schedule/entry/create/" + schedule.id, ScheduleEntry.fromJson, next, error); } delete(entry: ScheduleEntry, next: () => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("schedule/entry/delete/" + entry.id, _ => _, next, error); + this.api.getReturnItem("schedule/entry/delete/" + entry.id, _ => _, next, error); } } diff --git a/src/main/angular/src/app/api/schedule/schedule.service.ts b/src/main/angular/src/app/api/schedule/schedule.service.ts index b3c145c..ae8265a 100644 --- a/src/main/angular/src/app/api/schedule/schedule.service.ts +++ b/src/main/angular/src/app/api/schedule/schedule.service.ts @@ -22,15 +22,15 @@ export class ScheduleService { } getById(id: number, next: (item: Schedule) => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("schedule/getById/" + id, Schedule.fromJson, next, error); + this.api.getReturnItem("schedule/searchById/" + id, Schedule.fromJson, next, error); } create(next: (item: Schedule) => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("schedule/create/", Schedule.fromJson, next, error); + this.api.getReturnItem("schedule/create/", Schedule.fromJson, next, error); } delete(schedule: Schedule, next: () => void, error: (error: any) => void = NO_OP): void { - this.api.getItem("schedule/delete/" + schedule.id, _ => _, next, error); + this.api.getReturnItem("schedule/delete/" + schedule.id, _ => _, next, error); } } diff --git a/src/main/angular/src/app/api/types.ts b/src/main/angular/src/app/api/types.ts new file mode 100644 index 0000000..4826ec5 --- /dev/null +++ b/src/main/angular/src/app/api/types.ts @@ -0,0 +1,7 @@ +export type FromJson = (json: any) => T; +export type Next = (entity: T) => void; +export type Error = () => void + +export interface IEntity { + get id(): number; +} diff --git a/src/main/angular/src/app/pages/bulk/bulk-list/bulk-list.component.ts b/src/main/angular/src/app/pages/bulk/bulk-list/bulk-list.component.ts index 7a31cb2..6f5c216 100644 --- a/src/main/angular/src/app/pages/bulk/bulk-list/bulk-list.component.ts +++ b/src/main/angular/src/app/pages/bulk/bulk-list/bulk-list.component.ts @@ -1,5 +1,5 @@ import {Component, OnInit} from '@angular/core'; -import {BulkService} from "../../../api/bulk/bulkService"; +import {BulkService} from "../../../api/bulk/BulkService"; import {Bulk} from "../../../api/bulk/Bulk"; import {faCheckCircle, faCircle, faTimesCircle} from "@fortawesome/free-regular-svg-icons"; diff --git a/src/main/angular/src/app/pages/bulk/bulk/bulk.component.html b/src/main/angular/src/app/pages/bulk/bulk/bulk.component.html index 782a0f0..3f3a3d5 100644 --- a/src/main/angular/src/app/pages/bulk/bulk/bulk.component.html +++ b/src/main/angular/src/app/pages/bulk/bulk/bulk.component.html @@ -1 +1,46 @@ -

bulk works!

+ + + + + + + + + + + + + + + + + + +
EigenschaftWert
+ + + {{entry.value ? "An" : "Aus"}} + + + + + + + + + +   +
diff --git a/src/main/angular/src/app/pages/bulk/bulk/bulk.component.ts b/src/main/angular/src/app/pages/bulk/bulk/bulk.component.ts index f6a33dd..645fe52 100644 --- a/src/main/angular/src/app/pages/bulk/bulk/bulk.component.ts +++ b/src/main/angular/src/app/pages/bulk/bulk/bulk.component.ts @@ -1,4 +1,9 @@ import {Component, OnInit} from '@angular/core'; +import {BulkService} from "../../../api/bulk/BulkService"; +import {Bulk} from "../../../api/bulk/Bulk"; +import {ActivatedRoute} from "@angular/router"; +import {PropertyService} from "../../../api/property/property.service"; +import {BulkEntry} from "../../../api/bulk/BulkEntry"; @Component({ selector: 'app-bulk', @@ -7,10 +12,36 @@ import {Component, OnInit} from '@angular/core'; }) export class BulkComponent implements OnInit { - constructor() { + bulk!: Bulk; + + constructor( + readonly activatedRoute: ActivatedRoute, + readonly bulkService: BulkService, + readonly propertyService: PropertyService, + ) { + // nothing } ngOnInit(): void { + this.activatedRoute.paramMap.subscribe(params => { + const idString: string | null = params.get('id'); + if (idString) { + this.bulkService.getById(parseInt(idString), bulk => this.bulk = bulk); + } + }); + } + + setEntry(entry: BulkEntry, property: string, value: any): void { + this.bulkService.setEntry(entry, property, value, result => this.update(result)); + } + + private update(fresh: BulkEntry): void { + const index: number = this.bulk.entries.findIndex(existing => existing.id === fresh.id); + if (index >= 0) { + this.bulk.entries[index] = fresh; + } else { + this.bulk.entries.splice(fresh.position, 0, fresh); + } } } diff --git a/src/main/angular/src/app/pages/schedule/schedule.component.ts b/src/main/angular/src/app/pages/schedule/schedule.component.ts index e415e7d..25a21da 100644 --- a/src/main/angular/src/app/pages/schedule/schedule.component.ts +++ b/src/main/angular/src/app/pages/schedule/schedule.component.ts @@ -9,7 +9,7 @@ import {DataService} from "../../data.service"; import {PropertyService} from "../../api/property/property.service"; import {Scene} from "../../api/scene/Scene"; import {SceneService} from "../../api/scene/scene.service"; -import {BulkService} from "../../api/bulk/bulkService"; +import {BulkService} from "../../api/bulk/BulkService"; @Component({ selector: 'app-schedule', diff --git a/src/main/angular/src/app/shared/search/search.component.ts b/src/main/angular/src/app/shared/search/search.component.ts index 9c298e0..020c8d8 100644 --- a/src/main/angular/src/app/shared/search/search.component.ts +++ b/src/main/angular/src/app/shared/search/search.component.ts @@ -47,7 +47,7 @@ export class SearchComponent implements OnInit { ngOnInit(): void { if (this.initial) { - this.searchService.get(this.initial, result => this.selected = result, _ => _); + this.searchService.searchById(this.initial, result => this.selected = result, _ => _); } } diff --git a/src/main/java/de/ph87/homeautomation/BackendApplication.java b/src/main/java/de/ph87/homeautomation/BackendApplication.java index 57ac8dd..07cb35f 100644 --- a/src/main/java/de/ph87/homeautomation/BackendApplication.java +++ b/src/main/java/de/ph87/homeautomation/BackendApplication.java @@ -2,13 +2,12 @@ package de.ph87.homeautomation; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication -public class BackendApplication extends SpringBootServletInitializer { +public class BackendApplication { public static void main(String[] args) { - SpringApplication.run(BackendApplication.class); + SpringApplication.run(BackendApplication.class, args); } } \ No newline at end of file diff --git a/src/main/java/de/ph87/homeautomation/DemoDataService.java b/src/main/java/de/ph87/homeautomation/DemoDataService.java index 853854b..ded9a3a 100644 --- a/src/main/java/de/ph87/homeautomation/DemoDataService.java +++ b/src/main/java/de/ph87/homeautomation/DemoDataService.java @@ -1,35 +1,23 @@ package de.ph87.homeautomation; import com.luckycatlabs.sunrisesunset.Zenith; -import de.ph87.homeautomation.bulk.Bulk; +import de.ph87.homeautomation.bulk.BulkController; import de.ph87.homeautomation.bulk.BulkCreateDto; -import de.ph87.homeautomation.bulk.BulkEntryCreateDto; -import de.ph87.homeautomation.bulk.BulkWriter; +import de.ph87.homeautomation.bulk.BulkDto; +import de.ph87.homeautomation.bulk.entry.BulkEntryController; +import de.ph87.homeautomation.bulk.entry.BulkEntryCreateDto; import de.ph87.homeautomation.channel.Channel; -import de.ph87.homeautomation.knx.group.KnxGroup; -import de.ph87.homeautomation.knx.group.KnxGroupReadService; -import de.ph87.homeautomation.logic.Logic; -import de.ph87.homeautomation.logic.LogicOperator; -import de.ph87.homeautomation.logic.LogicRepository; import de.ph87.homeautomation.property.Property; import de.ph87.homeautomation.property.PropertyRepository; import de.ph87.homeautomation.property.PropertyType; -import de.ph87.homeautomation.scene.SceneWriteService; -import de.ph87.homeautomation.schedule.Schedule; -import de.ph87.homeautomation.schedule.ScheduleRepository; -import de.ph87.homeautomation.schedule.entry.ScheduleEntry; +import de.ph87.homeautomation.schedule.ScheduleController; +import de.ph87.homeautomation.schedule.entry.ScheduleEntryController; import de.ph87.homeautomation.schedule.entry.ScheduleEntryType; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.ZonedDateTime; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.stream.Collectors; - @SuppressWarnings({"unchecked", "UnusedReturnValue", "SameParameterValue", "UnusedAssignment", "RedundantSuppression"}) @Slf4j @Service @@ -37,19 +25,17 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class DemoDataService { - private final PropertyRepository propertyRepository; - - private final KnxGroupReadService knxGroupReadService; - - private final SceneWriteService sceneWriteService; - - private final LogicRepository logicRepository; - - private final BulkWriter bulkWriter; - private final Config config; - private final ScheduleRepository scheduleRepository; + private final PropertyRepository propertyRepository; + + private final BulkController bulkController; + + private final BulkEntryController bulkEntryController; + + private final ScheduleController scheduleController; + + private final ScheduleEntryController scheduleEntryController; public void insertDemoData() { if (!config.isInsertDemoData()) { @@ -60,30 +46,13 @@ public class DemoDataService { final Property propertyBulkShutter = createProperty("propertyBulkShutter", PropertyType.SHUTTER, null, null); final Property propertyBulkBrightness = createProperty("propertyBulkBrightness", PropertyType.BRIGHTNESS_PERCENT, null, null); final Property propertyBulkColorTemperature = createProperty("propertyBulkColorTemperature", PropertyType.COLOR_TEMPERATURE, null, null); - final List entries = Arrays.asList( - new BulkEntryCreateDto(propertyBulkBoolean.getId(), 1, 0), - new BulkEntryCreateDto(propertyBulkShutter.getId(), 35, 0), - new BulkEntryCreateDto(propertyBulkBrightness.getId(), 40, 0), - new BulkEntryCreateDto(propertyBulkColorTemperature.getId(), 55, 0) - ); - final Bulk bulk = createBulk("bulk", true, entries.toArray(new BulkEntryCreateDto[0])); - final Schedule schedule = createSchedule(true, "schedule"); - createTime(schedule, true, 12, 0, 0, 0, propertyDirect, 1, bulk); - } - - private Bulk createBulk(final String name, final boolean enabled, final BulkEntryCreateDto... entries) { - return bulkWriter.create(new BulkCreateDto(name, enabled, Arrays.stream(entries).collect(Collectors.toList()))); - } - - private Logic getOrCreateLogic(final String name, final LogicOperator operator, final Property... properties) { - return logicRepository.findByName(name).orElseGet(() -> { - final Logic logic = new Logic(name, operator, new HashSet<>(Arrays.asList(properties))); - return logicRepository.save(logic); - }); - } - - private KnxGroup knx(final int main, final int mid, final int sub) { - return knxGroupReadService.getByAddress(main, mid, sub).orElse(null); + final BulkDto bulk = bulkController.create(new BulkCreateDto("bulk", true)); + bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkBoolean.getId(), 1, 0)); + bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkShutter.getId(), 35, 0)); + bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkBrightness.getId(), 40, 0)); + bulkEntryController.create(new BulkEntryCreateDto(bulk.getId(), propertyBulkColorTemperature.getId(), 55, 0)); + final long scheduleId = createSchedule(true, "schedule"); + createTime(scheduleId, true, 12, 0, 0, 0, propertyDirect, 1, bulk); } private Property createProperty(final String title, final PropertyType type, final Channel readChannel, final Channel writeChannel) { @@ -93,54 +62,31 @@ public class DemoDataService { return property; } - private Schedule createSchedule(final boolean enabled, final String title) { - final Schedule schedule = new Schedule(); - schedule.setEnabled(enabled); - schedule.setTitle(title); - return scheduleRepository.save(schedule); + private long createSchedule(final boolean enabled, final String title) { + final long id = scheduleController.create().getId(); + scheduleController.setEnabled(id, enabled); + scheduleController.setTitle(id, title); + return id; } - private ScheduleEntry createRelative(final Schedule schedule, final boolean enabled, final int inSeconds, final int fuzzySeconds, final Property property, final Object value, final Bulk bulk) { - final ZonedDateTime now = ZonedDateTime.now().plusSeconds(inSeconds).withNano(0); - return createTime(schedule, enabled, now.getHour(), now.getMinute(), now.getSecond(), fuzzySeconds, property, value, bulk); + private void createTime(final long scheduleId, final boolean enabled, final int hour, final int minute, final int second, final int fuzzySeconds, final Property property, final double value, final BulkDto bulk) { + newScheduleEntry(scheduleId, enabled, ScheduleEntryType.TIME, null, hour, minute, second, fuzzySeconds, property, value, bulk); } - private ScheduleEntry createTime(final Schedule schedule, final boolean enabled, final int hour, final int minute, final int second, final int fuzzySeconds, final Property property, final Object value, final Bulk bulk) { - return newScheduleEntry(schedule, enabled, ScheduleEntryType.TIME, null, hour, minute, second, fuzzySeconds, property, value, bulk); - } - - private ScheduleEntry createSunrise(final Schedule schedule, final boolean enabled, final Zenith zenith, final int fuzzySeconds, final Property property, final Object value, final Bulk bulk) { - return newScheduleEntry(schedule, enabled, ScheduleEntryType.SUNRISE, zenith, 0, 0, 0, fuzzySeconds, property, value, bulk); - } - - private ScheduleEntry createSunset(final Schedule schedule, final boolean enabled, final Zenith zenith, final int fuzzySeconds, final Property property, final Object value, final Bulk bulk) { - return newScheduleEntry(schedule, enabled, ScheduleEntryType.SUNSET, zenith, 0, 0, 0, fuzzySeconds, property, value, bulk); - } - - private ScheduleEntry newScheduleEntry(final Schedule schedule, final boolean enabled, final ScheduleEntryType type, final Zenith zenith, final int hour, final int minute, final int second, final int fuzzySeconds, final Property property, final Object value, final Bulk bulk) { - final ScheduleEntry entry = new ScheduleEntry(); - entry.setEnabled(enabled); - entry.setType(type); + private void newScheduleEntry(final long scheduleId, final boolean enabled, final ScheduleEntryType type, final Zenith zenith, final int hour, final int minute, final int second, final int fuzzySeconds, final Property property, final double value, final BulkDto bulk) { + final long id = scheduleEntryController.create(scheduleId).getId(); + scheduleEntryController.setEnabled(id, enabled); + scheduleEntryController.setType(id, type.name()); if (zenith != null) { - entry.setZenith(zenith.degrees().doubleValue()); + scheduleEntryController.setZenith(id, zenith.degrees().doubleValue()); } - entry.setHour(hour); - entry.setMinute(minute); - entry.setSecond(second); - entry.setFuzzySeconds(fuzzySeconds); - entry.setProperty(property); - if (value instanceof Boolean) { - entry.setValue((boolean) value ? 1.0 : 0.0); - } else if (value instanceof Double) { - entry.setValue((Double) value); - } else if (value instanceof Integer) { - entry.setValue((Integer) value); - } else { - throw new RuntimeException(); - } - entry.setBulk(bulk); - schedule.getEntries().add(entry); - return entry; + scheduleEntryController.setHour(id, hour); + scheduleEntryController.setMinute(id, minute); + scheduleEntryController.setSecond(id, second); + scheduleEntryController.setFuzzySeconds(id, fuzzySeconds); + scheduleEntryController.setProperty(id, property == null ? null : property.getId()); + scheduleEntryController.setValue(id, value); + scheduleEntryController.setBulk(id, bulk == null ? null : bulk.getId()); } } diff --git a/src/main/java/de/ph87/homeautomation/bulk/Bulk.java b/src/main/java/de/ph87/homeautomation/bulk/Bulk.java index 374d394..fcb64a2 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/Bulk.java +++ b/src/main/java/de/ph87/homeautomation/bulk/Bulk.java @@ -1,5 +1,6 @@ package de.ph87.homeautomation.bulk; +import de.ph87.homeautomation.bulk.entry.BulkEntry; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -13,6 +14,7 @@ import java.util.List; @Getter @ToString @NoArgsConstructor +@SuppressWarnings("FieldMayBeFinal") public class Bulk { @Id @@ -23,20 +25,24 @@ public class Bulk { private long version; @Setter - private boolean enabled = false; + private boolean enabled; @Setter @Column(nullable = false, unique = true) private String name; - @ElementCollection @ToString.Exclude + @OneToMany(cascade = CascadeType.ALL) private List entries = new ArrayList<>(); - public Bulk(final BulkCreateDto dto, final List entries) { + @ToString.Include + public int entryCount() { + return entries.size(); + } + + public Bulk(final BulkCreateDto dto) { this.enabled = dto.isEnabled(); this.name = dto.getName(); - this.entries = new ArrayList<>(entries); } } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkController.java b/src/main/java/de/ph87/homeautomation/bulk/BulkController.java index 4dd5987..8a08709 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkController.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkController.java @@ -1,7 +1,6 @@ package de.ph87.homeautomation.bulk; -import de.ph87.homeautomation.property.Property; -import de.ph87.homeautomation.property.PropertyReadService; +import de.ph87.homeautomation.property.PropertyReader; import de.ph87.homeautomation.shared.ISearchController; import de.ph87.homeautomation.shared.SearchResult; import lombok.RequiredArgsConstructor; @@ -20,7 +19,7 @@ public class BulkController implements ISearchController { private final BulkReader bulkReader; - private final PropertyReadService propertyReadService; + private final PropertyReader propertyReader; @PostMapping("create") public BulkDto create(@RequestBody final BulkCreateDto dto) { @@ -47,28 +46,15 @@ public class BulkController implements ISearchController { return bulkWriter.set(id, bulk -> bulk.setEnabled(enabled)); } - @PostMapping("entryAdd/{id}") - public BulkDto entryAdd(@PathVariable final long id, @RequestBody final BulkEntryCreateDto dto) { - return bulkWriter.set(id, bulk -> { - final Property property = propertyReadService.getById(dto.getPropertyId()); - bulk.getEntries().add(dto.getIndex(), new BulkEntry(dto, property)); - }); - } - - @PostMapping("entryMove/{id}/{indexFrom}/{indexTo}") - public BulkDto entryMove(@PathVariable final long id, @PathVariable final int indexFrom, @PathVariable final int indexTo) { - return bulkWriter.set(id, bulk -> bulk.getEntries().add(indexTo, bulk.getEntries().remove(indexFrom))); - } - - @PostMapping("entryRemove/{id}/{index}") - public BulkDto entryRemove(@PathVariable final long id, @PathVariable final int index) { - return bulkWriter.set(id, bulk -> bulk.getEntries().remove(index)); + @GetMapping("getById/{id}") + public BulkDto getById(@PathVariable final long id) { + return bulkReader.getDtoById(id); } @Override - @GetMapping("getById/{id}") + @GetMapping("searchById/{id}") @Deprecated(since = "Use 'filter' instead", forRemoval = true) - public SearchResult getById(@PathVariable final long id) { + public SearchResult searchById(@PathVariable final long id) { return toSearchResult(bulkReader.getDtoById(id)); } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkCreateDto.java b/src/main/java/de/ph87/homeautomation/bulk/BulkCreateDto.java index 2ccd3b5..796b871 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkCreateDto.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkCreateDto.java @@ -2,8 +2,6 @@ package de.ph87.homeautomation.bulk; import lombok.Data; -import java.util.List; - @Data public class BulkCreateDto { @@ -11,6 +9,4 @@ public class BulkCreateDto { private final boolean enabled; - private final List entries; - } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkDto.java b/src/main/java/de/ph87/homeautomation/bulk/BulkDto.java index 9980705..a05e9e3 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkDto.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkDto.java @@ -1,5 +1,6 @@ package de.ph87.homeautomation.bulk; +import de.ph87.homeautomation.bulk.entry.BulkEntryDto; import lombok.Data; import java.util.List; diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkEntryCreateDto.java b/src/main/java/de/ph87/homeautomation/bulk/BulkEntryCreateDto.java deleted file mode 100644 index d8a66c2..0000000 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkEntryCreateDto.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.ph87.homeautomation.bulk; - -import lombok.Data; - -@Data -public class BulkEntryCreateDto { - - private final long propertyId; - - private final double value; - - private final int index; - -} diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkEntryDto.java b/src/main/java/de/ph87/homeautomation/bulk/BulkEntryDto.java deleted file mode 100644 index d62156d..0000000 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkEntryDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package de.ph87.homeautomation.bulk; - -import de.ph87.homeautomation.property.PropertyDto; -import lombok.Data; - -@Data -public class BulkEntryDto { - - private final PropertyDto property; - - private final double value; - - public BulkEntryDto(final BulkEntry bulkEntry, final PropertyDto property) { - this.property = property; - this.value = bulkEntry.getValue(); - } - -} diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkFilter.java b/src/main/java/de/ph87/homeautomation/bulk/BulkFilter.java index 8ebffc1..74bf2aa 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkFilter.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkFilter.java @@ -5,23 +5,22 @@ import org.springframework.data.jpa.domain.Specification; import javax.persistence.criteria.Predicate; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class BulkFilter extends Filter { - private Long id; - private String name; @Override public Specification getSpecification() { return (root, query, criteriaBuilder) -> { final List predicates = new ArrayList<>(); - if (id != null) { - predicates.add(criteriaBuilder.equal(root.get("id"), id)); - } if (name != null) { - predicates.add(criteriaBuilder.like(root.get("name"), "%" + name + "%")); + Arrays.stream(name.split("\\W+")) + .filter(p -> !p.isEmpty()) + .map(name -> criteriaBuilder.like(root.get("name"), "%" + name + "%")) + .forEach(predicates::add); } return criteriaBuilder.and(predicates.toArray(new Predicate[0])); }; diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkMapper.java b/src/main/java/de/ph87/homeautomation/bulk/BulkMapper.java index 854cba2..3283876 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkMapper.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkMapper.java @@ -1,13 +1,15 @@ package de.ph87.homeautomation.bulk; +import de.ph87.homeautomation.bulk.entry.BulkEntry; +import de.ph87.homeautomation.bulk.entry.BulkEntryDto; import de.ph87.homeautomation.property.PropertyDto; import de.ph87.homeautomation.property.PropertyMapper; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; @Service @Transactional @@ -17,15 +19,13 @@ public class BulkMapper { private final PropertyMapper propertyMapper; public BulkDto toDto(final Bulk bulk) { - final List entries = bulk.getEntries().stream().map(this::toDto).collect(Collectors.toList()); + final List entries = new ArrayList<>(); + for (int position = 0; position < bulk.getEntries().size(); position++) { + entries.add(toDto(bulk.getEntries().get(position))); + } return new BulkDto(bulk, entries); } - private BulkEntryDto toDto(final BulkEntry bulkEntry) { - final PropertyDto property = propertyMapper.toDto(bulkEntry.getProperty()); - return new BulkEntryDto(bulkEntry, property); - } - public BulkDto toDtoOrNull(final Bulk bulk) { if (bulk == null) { return null; @@ -33,4 +33,9 @@ public class BulkMapper { return toDto(bulk); } + public BulkEntryDto toDto(final BulkEntry entry) { + final PropertyDto property = propertyMapper.toDto(entry.getProperty()); + return new BulkEntryDto(entry, property); + } + } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkReader.java b/src/main/java/de/ph87/homeautomation/bulk/BulkReader.java index 62ba100..1b827cd 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkReader.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkReader.java @@ -1,5 +1,6 @@ package de.ph87.homeautomation.bulk; +import de.ph87.homeautomation.web.NotFoundException; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -27,14 +28,13 @@ public class BulkReader { return bulkRepository.findAll(filter.getSpecification(), filter.getPageable()).map(bulkMapper::toDto); } - @Deprecated(since = "Use 'filter' instead", forRemoval = true) public BulkDto getDtoById(final long id) { return bulkMapper.toDto(getById(id)); } @Deprecated(since = "Use 'filter' instead", forRemoval = true) public List findAllDtoLike(final String term) { - return bulkRepository.findAllByNameLike(term).stream().map(bulkMapper::toDto).collect(Collectors.toList()); + return bulkRepository.findAllByNameLikeIgnoreCase(term).stream().map(bulkMapper::toDto).collect(Collectors.toList()); } @Deprecated(since = "Use 'filter' instead", forRemoval = true) @@ -42,4 +42,8 @@ public class BulkReader { return bulkRepository.findAll().stream().map(bulkMapper::toDto).collect(Collectors.toList()); } + public Bulk getBulkByEntryId(final long id) { + return bulkRepository.findByEntries_Id(id).orElseThrow(NotFoundException.supply(Bulk.class, "entries_id", id)); + } + } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkRepository.java b/src/main/java/de/ph87/homeautomation/bulk/BulkRepository.java index 49d9e1d..8a84ab4 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkRepository.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkRepository.java @@ -4,10 +4,13 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import java.util.List; +import java.util.Optional; public interface BulkRepository extends JpaRepository, JpaSpecificationExecutor { @Deprecated(since = "Use 'filter' instead", forRemoval = true) - List findAllByNameLike(String term); + List findAllByNameLikeIgnoreCase(String term); + + Optional findByEntries_Id(long id); } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkWriter.java b/src/main/java/de/ph87/homeautomation/bulk/BulkWriter.java index 2072fed..f774fce 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkWriter.java +++ b/src/main/java/de/ph87/homeautomation/bulk/BulkWriter.java @@ -1,14 +1,11 @@ package de.ph87.homeautomation.bulk; -import de.ph87.homeautomation.property.PropertyReadService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; import java.util.function.Consumer; -import java.util.stream.Collectors; @Slf4j @Service @@ -22,11 +19,8 @@ public class BulkWriter { private final BulkMapper bulkMapper; - private final PropertyReadService propertyReadService; - public Bulk create(final BulkCreateDto dto) { - final List entries = dto.getEntries().stream().map(e -> new BulkEntry(e, propertyReadService.getById(e.getPropertyId()))).collect(Collectors.toList()); - final Bulk bulk = bulkRepository.save(new Bulk(dto, entries)); + final Bulk bulk = bulkRepository.save(new Bulk(dto)); log.info("Bulk created: {}", bulk); return bulk; } diff --git a/src/main/java/de/ph87/homeautomation/bulk/BulkEntry.java b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntry.java similarity index 59% rename from src/main/java/de/ph87/homeautomation/bulk/BulkEntry.java rename to src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntry.java index 532c1ac..1ddb9c4 100644 --- a/src/main/java/de/ph87/homeautomation/bulk/BulkEntry.java +++ b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntry.java @@ -1,27 +1,42 @@ -package de.ph87.homeautomation.bulk; +package de.ph87.homeautomation.bulk.entry; import de.ph87.homeautomation.property.Property; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; import lombok.ToString; -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.ManyToOne; +import javax.persistence.*; -@Embeddable +@Entity @Getter @ToString @NoArgsConstructor public class BulkEntry { + @Id + @GeneratedValue + private long id; + + @Version + private long version; + + @Setter + private boolean enabled; + + @Setter + private int position; + + @Setter @ManyToOne(optional = false) private Property property; + @Setter @Column(name = "value_") private double value; public BulkEntry(final BulkEntryCreateDto dto, final Property property) { + this.position = dto.getPosition(); this.property = property; this.value = dto.getValue(); } diff --git a/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryController.java b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryController.java new file mode 100644 index 0000000..17fbc67 --- /dev/null +++ b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryController.java @@ -0,0 +1,44 @@ +package de.ph87.homeautomation.bulk.entry; + +import de.ph87.homeautomation.bulk.BulkMapper; +import de.ph87.homeautomation.property.PropertyReader; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("BulkEntry") +@RequiredArgsConstructor +public class BulkEntryController { + + private final BulkEntryWriter bulkEntryWriter; + + private final BulkMapper bulkMapper; + + private final PropertyReader propertyReader; + + @PostMapping("create") + public BulkEntryDto create(@RequestBody final BulkEntryCreateDto dto) { + return bulkMapper.toDto(bulkEntryWriter.create(dto)); + } + + @PutMapping("{id}/set/property") + public BulkEntryDto setValue(@PathVariable final long id, @RequestBody final long propertyId) { + return bulkMapper.toDto(bulkEntryWriter.set(id, entry -> entry.setProperty(propertyReader.getById(propertyId)))); + } + + @PutMapping("{id}/set/value") + public BulkEntryDto setValue(@PathVariable final long id, @RequestBody final double value) { + return bulkMapper.toDto(bulkEntryWriter.set(id, entry -> entry.setValue(value))); + } + + @GetMapping("move/{id}/{indexFrom}/{indexTo}") + public BulkEntryDto move(@PathVariable final long id, @PathVariable final int indexTo) { + return bulkEntryWriter.move(id, indexTo); + } + + @DeleteMapping("{id}") + public void remove(@PathVariable final long id) { + bulkEntryWriter.remove(id); + } + +} diff --git a/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryCreateDto.java b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryCreateDto.java new file mode 100644 index 0000000..b6e1de5 --- /dev/null +++ b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryCreateDto.java @@ -0,0 +1,16 @@ +package de.ph87.homeautomation.bulk.entry; + +import lombok.Data; + +@Data +public class BulkEntryCreateDto { + + private final long bulkId; + + private final Long propertyId; + + private final double value; + + private final int position; + +} diff --git a/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryDto.java b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryDto.java new file mode 100644 index 0000000..90376e5 --- /dev/null +++ b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryDto.java @@ -0,0 +1,30 @@ +package de.ph87.homeautomation.bulk.entry; + +import de.ph87.homeautomation.property.PropertyDto; +import lombok.Data; + +@Data +public class BulkEntryDto { + + private final long id; + + private final long version; + + private final int position; + + private final boolean enabled; + + private final PropertyDto property; + + private final double value; + + public BulkEntryDto(final BulkEntry entry, final PropertyDto propertyDto) { + this.id = entry.getId(); + this.version = entry.getVersion(); + this.enabled = entry.isEnabled(); + this.position = entry.getPosition(); + this.property = propertyDto; + this.value = entry.getValue(); + } + +} diff --git a/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryMapper.java b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryMapper.java new file mode 100644 index 0000000..96dee41 --- /dev/null +++ b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryMapper.java @@ -0,0 +1,23 @@ +package de.ph87.homeautomation.bulk.entry; + +import de.ph87.homeautomation.property.PropertyDto; +import de.ph87.homeautomation.property.PropertyMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Slf4j +@Service +@Transactional +@RequiredArgsConstructor +public class BulkEntryMapper { + + private final PropertyMapper propertyMapper; + + public BulkEntryDto toDto(final BulkEntry entry) { + final PropertyDto property = propertyMapper.toDto(entry.getProperty()); + return new BulkEntryDto(entry, property); + } + +} diff --git a/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryWriter.java b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryWriter.java new file mode 100644 index 0000000..c80cfe0 --- /dev/null +++ b/src/main/java/de/ph87/homeautomation/bulk/entry/BulkEntryWriter.java @@ -0,0 +1,77 @@ +package de.ph87.homeautomation.bulk.entry; + +import de.ph87.homeautomation.bulk.Bulk; +import de.ph87.homeautomation.bulk.BulkReader; +import de.ph87.homeautomation.bulk.BulkWriter; +import de.ph87.homeautomation.property.Property; +import de.ph87.homeautomation.property.PropertyReader; +import de.ph87.homeautomation.web.NotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.function.Consumer; + +@Slf4j +@Service +@Transactional +@RequiredArgsConstructor +public class BulkEntryWriter { + + private final PropertyReader propertyReader; + + private final BulkWriter bulkWriter; + + private final BulkReader bulkReader; + + private final BulkEntryMapper bulkEntryMapper; + + public BulkEntry create(final BulkEntryCreateDto dto) { + final Property property = dto.getPropertyId() == null ? null : propertyReader.getById(dto.getPropertyId()); + final BulkEntry entry = new BulkEntry(dto, property); + bulkWriter.set(dto.getBulkId(), bulk -> { + bulk.getEntries().add(dto.getPosition(), entry); + updatePositions(bulk); + }); + log.info("BulkEntry created: {}", entry); + return entry; + } + + public BulkEntryDto move(final long id, final int position) { + final Bulk bulk = bulkReader.getBulkByEntryId(id); + final BulkEntry entry = getEntryById(bulk, id); + final int oldIndex = bulk.getEntries().indexOf(entry); + bulk.getEntries().remove(entry); + bulk.getEntries().add(position, entry); + updatePositions(bulk); + log.info("BulkEntry moved from {} to {}: {}", oldIndex, position, entry); + return bulkEntryMapper.toDto(entry); + } + + private static void updatePositions(final Bulk bulk) { + for (int p = 0; p < bulk.getEntries().size(); p++) { + bulk.getEntries().get(p).setPosition(p); + } + } + + public void remove(final long id) { + getEntryById(id); + } + + private BulkEntry getEntryById(final long id) { + final Bulk bulk = bulkReader.getBulkByEntryId(id); + return getEntryById(bulk, id); + } + + private static BulkEntry getEntryById(final Bulk bulk, final long id) { + return bulk.getEntries().stream().filter(e -> e.getId() == id).findFirst().orElseThrow(NotFoundException.supply(BulkEntry.class, "Bulk#" + bulk.getId() + ".entries.id", id)); + } + + public BulkEntry set(final long id, final Consumer consumer) { + final BulkEntry entry = getEntryById(id); + consumer.accept(entry); + return entry; + } + +} diff --git a/src/main/java/de/ph87/homeautomation/channel/ChannelController.java b/src/main/java/de/ph87/homeautomation/channel/ChannelController.java index 3aca91f..e92aa68 100644 --- a/src/main/java/de/ph87/homeautomation/channel/ChannelController.java +++ b/src/main/java/de/ph87/homeautomation/channel/ChannelController.java @@ -22,8 +22,8 @@ public class ChannelController implements ISearchController { } @Override - @GetMapping("getById/{id}") - public SearchResult getById(@PathVariable final long id) { + @GetMapping("searchById/{id}") + public SearchResult searchById(@PathVariable final long id) { return channelService.findDtoById(id).map(this::toSearchResult).orElseThrow(() -> new NotFoundException("Channel.id=" + id)); } diff --git a/src/main/java/de/ph87/homeautomation/channel/ChannelService.java b/src/main/java/de/ph87/homeautomation/channel/ChannelService.java index ad6d468..24f1324 100644 --- a/src/main/java/de/ph87/homeautomation/channel/ChannelService.java +++ b/src/main/java/de/ph87/homeautomation/channel/ChannelService.java @@ -53,7 +53,7 @@ public class ChannelService { } public List findAllDtoLike(final String term) { - return channelOwners.stream().map(owner -> owner.findAllDtoLike(term)).reduce(new ArrayList<>(), Helpers::merge); + return channelOwners.stream().map(owner -> owner.findAllDtoLikeIgnoreCase(term)).reduce(new ArrayList<>(), Helpers::merge); } public Optional findDtoById(final long id) { diff --git a/src/main/java/de/ph87/homeautomation/channel/IChannelOwner.java b/src/main/java/de/ph87/homeautomation/channel/IChannelOwner.java index ca9c89e..f8d36fa 100644 --- a/src/main/java/de/ph87/homeautomation/channel/IChannelOwner.java +++ b/src/main/java/de/ph87/homeautomation/channel/IChannelOwner.java @@ -12,6 +12,6 @@ public interface IChannelOwner { List findAllDto(); - List findAllDtoLike(final String like); + List findAllDtoLikeIgnoreCase(final String like); } diff --git a/src/main/java/de/ph87/homeautomation/device/DeviceController.java b/src/main/java/de/ph87/homeautomation/device/DeviceController.java index 81d2d63..37f322e 100644 --- a/src/main/java/de/ph87/homeautomation/device/DeviceController.java +++ b/src/main/java/de/ph87/homeautomation/device/DeviceController.java @@ -2,7 +2,7 @@ package de.ph87.homeautomation.device; import de.ph87.homeautomation.device.devices.Device; import de.ph87.homeautomation.device.devices.DeviceDto; -import de.ph87.homeautomation.property.PropertyReadService; +import de.ph87.homeautomation.property.PropertyReader; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -19,14 +19,14 @@ public class DeviceController { private final DeviceWriteService deviceWriteService; - private final PropertyReadService propertyReadService; + private final PropertyReader propertyReader; @GetMapping("findAll") public List findAll() { return deviceReadService.findAll(); } - @GetMapping("getById/{id}") + @GetMapping("searchById/{id}") public DeviceDto getById(@PathVariable final long id) { return deviceReadService.getDtoById(id); } @@ -53,22 +53,22 @@ public class DeviceController { @PostMapping("set/{id}/DeviceSwitch/stateProperty") public DeviceDto setDeviceSwitchStateProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) { - return deviceWriteService.setDeviceSwitch(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReadService::getById)), propertyId); + return deviceWriteService.setDeviceSwitch(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReader::getById)), propertyId); } @PostMapping("set/{id}/DeviceStateScene/stateProperty") public DeviceDto setDeviceStateSceneStateProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) { - return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReadService::getById)), propertyId); + return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReader::getById)), propertyId); } @PostMapping("set/{id}/DeviceStateScene/sceneProperty") public DeviceDto setDeviceStateSceneSceneProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) { - return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setSceneProperty(mapOrNull(v, propertyReadService::getById)), propertyId); + return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setSceneProperty(mapOrNull(v, propertyReader::getById)), propertyId); } @PostMapping("set/{id}/DeviceShutter/positionProperty") public DeviceDto setDeviceShutterPositionProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) { - return deviceWriteService.setDeviceShutter(id, (device, v) -> device.setPositionProperty(mapOrNull(v, propertyReadService::getById)), propertyId); + return deviceWriteService.setDeviceShutter(id, (device, v) -> device.setPositionProperty(mapOrNull(v, propertyReader::getById)), propertyId); } } diff --git a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupChannelOwnerService.java b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupChannelOwnerService.java index 4bafc13..a225d84 100644 --- a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupChannelOwnerService.java +++ b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupChannelOwnerService.java @@ -41,7 +41,7 @@ public class KnxGroupChannelOwnerService implements IChannelOwner { } @Override - public List findAllDtoLike(final String like) { + public List findAllDtoLikeIgnoreCase(final String like) { return knxGroupReadService.findAllLike(like).stream().map(this::toDto).collect(Collectors.toList()); } diff --git a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java index ba610ec..9380079 100644 --- a/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java +++ b/src/main/java/de/ph87/homeautomation/knx/group/KnxGroupImportService.java @@ -19,17 +19,41 @@ import java.util.regex.Pattern; @RequiredArgsConstructor public class KnxGroupImportService { + private static final File ETS_HOME = new File("./data/Zuhause-ETS5"); + private final KnxGroupRepository knxGroupRepository; public void importGroups() { + try { + execute("/usr/bin/git", "fetch", "--all"); + execute("/usr/bin/git", "checkout", "master", "--force"); + execute("/usr/bin/git", "reset", "--hard", "origin/master"); + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } knxGroupRepository.findAll().forEach(knxGroup -> knxGroup.setEts(false)); try { - Jsoup.parse(new File("./data/Zuhause-ETS5/G"), "UTF-8").select("GA").forEach(this::importGroup); + Jsoup.parse(new File(ETS_HOME, "G"), "UTF-8").select("GA").forEach(this::importGroup); } catch (IOException e) { log.error("Failed to import KnxGroups: {}", e.toString()); } } + private static void execute(final String... command) throws IOException, InterruptedException { + log.info("{}", (Object) command); + final ProcessBuilder fetchBuilder = new ProcessBuilder(command); + fetchBuilder.directory(ETS_HOME); + fetchBuilder.redirectErrorStream(true); + final Process fetch = fetchBuilder.start(); + fetch.waitFor(); + final String output = new String(fetch.getInputStream().readAllBytes()); + if (!output.matches("^\\s*$")) { + for (final String line : output.split("[\n\r]+")) { + log.info("GIT: {}", line); + } + } + } + private void importGroup(final Element ga) { final GroupAddress address = new GroupAddress(Integer.parseInt(ga.attr("Address"))); final String name = ga.attr("Name"); @@ -47,12 +71,18 @@ public class KnxGroupImportService { } private void setDpt(final KnxGroup knxGroup, final String dptString) { - final Matcher matcher = Pattern.compile("^DPST-(?
\\d+)-(?\\d+)$").matcher(dptString); - if (!matcher.matches()) { - throw new RuntimeException(); + final Matcher mainSub = Pattern.compile("^DPST-(?
\\d+)-(?\\d+)$").matcher(dptString); + if (mainSub.matches()) { + knxGroup.setDptMain(Integer.parseInt(mainSub.group("main"))); + knxGroup.setDptSub(Integer.parseInt(mainSub.group("sub"))); + return; + } + + final Matcher main = Pattern.compile("^DPT-(?
\\d+)$").matcher(dptString); + if (main.matches()) { + knxGroup.setDptMain(Integer.parseInt(main.group("main"))); + knxGroup.setDptSub(0); } - knxGroup.setDptMain(Integer.parseInt(matcher.group("main"))); - knxGroup.setDptSub(Integer.parseInt(matcher.group("sub"))); } } diff --git a/src/main/java/de/ph87/homeautomation/logic/LogicChannelOwner.java b/src/main/java/de/ph87/homeautomation/logic/LogicChannelOwner.java index 91aa627..c70d0f0 100644 --- a/src/main/java/de/ph87/homeautomation/logic/LogicChannelOwner.java +++ b/src/main/java/de/ph87/homeautomation/logic/LogicChannelOwner.java @@ -40,7 +40,7 @@ public class LogicChannelOwner implements IChannelOwner { } @Override - public List findAllDtoLike(final String like) { + public List findAllDtoLikeIgnoreCase(final String like) { return logicReader.findAllDtoLike(like); } diff --git a/src/main/java/de/ph87/homeautomation/logic/LogicWriter.java b/src/main/java/de/ph87/homeautomation/logic/LogicWriter.java index 36c0504..4a14840 100644 --- a/src/main/java/de/ph87/homeautomation/logic/LogicWriter.java +++ b/src/main/java/de/ph87/homeautomation/logic/LogicWriter.java @@ -30,7 +30,6 @@ public class LogicWriter { private final WebSocketService webSocketService; @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) -// @Transactional(propagation = Propagation.REQUIRES_NEW) public void onPropertyChanged(final PropertyDto dto) { log.debug("Listen [{}]: {}", getCurrentTransactionName(), dto.getTitle()); logicReader.findAllByPropertyId(dto.getId()).forEach(this::update); diff --git a/src/main/java/de/ph87/homeautomation/property/PropertyController.java b/src/main/java/de/ph87/homeautomation/property/PropertyController.java index e908aa8..33c44af 100644 --- a/src/main/java/de/ph87/homeautomation/property/PropertyController.java +++ b/src/main/java/de/ph87/homeautomation/property/PropertyController.java @@ -16,7 +16,7 @@ public class PropertyController implements ISearchController { private final PropertyWriteService propertyWriteService; - private final PropertyReadService propertyReadService; + private final PropertyReader propertyReader; private final ChannelService channelService; @@ -27,7 +27,7 @@ public class PropertyController implements ISearchController { @GetMapping("findAll") public List findAll() { - return propertyReadService.findAllDto(); + return propertyReader.findAllDto(); } @PostMapping("set/{id}/type") @@ -47,12 +47,17 @@ public class PropertyController implements ISearchController { @PostMapping("set/{id}/readChannel") public PropertyDto setReadChannel(@PathVariable final long id, @RequestBody(required = false) final Long channelId) { - return propertyWriteService.set(id, (p, v) -> p.setReadChannel(channelService.getById(v)), channelId); + return propertyWriteService.set(id, (p, v) -> p.setReadChannel(channelId == null ? null : channelService.getById(v)), channelId); } @PostMapping("set/{id}/writeChannel") public PropertyDto setWriteChannel(@PathVariable final long id, @RequestBody(required = false) final Long channelId) { - return propertyWriteService.set(id, (p, v) -> p.setWriteChannel(channelService.getById(v)), channelId); + return propertyWriteService.set(id, (p, v) -> p.setWriteChannel(channelId == null ? null : channelService.getById(v)), channelId); + } + + @DeleteMapping("{id}") + public void delete(@PathVariable final long id) { + propertyWriteService.delete(id); } @PostMapping("toggle/{id}") @@ -62,7 +67,7 @@ public class PropertyController implements ISearchController { } private boolean getOldStateBoolean(final long id, final boolean orElse) { - final Double oldValue = propertyReadService.getDtoById(id).getValue(); + final Double oldValue = propertyReader.getDtoById(id).getValue(); if (oldValue == null || oldValue.isNaN()) { return orElse; } @@ -70,15 +75,15 @@ public class PropertyController implements ISearchController { } @Override - @GetMapping("getById/{id}") - public SearchResult getById(@PathVariable final long id) { - return toSearchResult(propertyReadService.getDtoById(id)); + @GetMapping("searchById/{id}") + public SearchResult searchById(@PathVariable final long id) { + return toSearchResult(propertyReader.getDtoById(id)); } @Override @PostMapping("searchLike") public List searchLike(@RequestBody final String term) { - return propertyReadService.findAllDtoLike("%" + term + "%").stream().map(this::toSearchResult).collect(Collectors.toList()); + return propertyReader.findAllDtoLike("%" + term + "%").stream().map(this::toSearchResult).collect(Collectors.toList()); } private SearchResult toSearchResult(final PropertyDto propertyDto) { diff --git a/src/main/java/de/ph87/homeautomation/property/PropertyReadService.java b/src/main/java/de/ph87/homeautomation/property/PropertyReader.java similarity index 87% rename from src/main/java/de/ph87/homeautomation/property/PropertyReadService.java rename to src/main/java/de/ph87/homeautomation/property/PropertyReader.java index 87223db..f01af5b 100644 --- a/src/main/java/de/ph87/homeautomation/property/PropertyReadService.java +++ b/src/main/java/de/ph87/homeautomation/property/PropertyReader.java @@ -12,7 +12,7 @@ import java.util.stream.Collectors; @Service @Transactional @RequiredArgsConstructor -public class PropertyReadService { +public class PropertyReader { private final PropertyRepository propertyRepository; @@ -23,7 +23,7 @@ public class PropertyReadService { } public List findAllDtoLike(final String like) { - return propertyRepository.findAllByTitleLike(like).stream().map(propertyMapper::toDto).collect(Collectors.toList()); + return propertyRepository.findAllByTitleLikeIgnoreCase(like).stream().map(propertyMapper::toDto).collect(Collectors.toList()); } public PropertyDto getDtoById(final long id) { diff --git a/src/main/java/de/ph87/homeautomation/property/PropertyRepository.java b/src/main/java/de/ph87/homeautomation/property/PropertyRepository.java index 16d39ad..90bf1ee 100644 --- a/src/main/java/de/ph87/homeautomation/property/PropertyRepository.java +++ b/src/main/java/de/ph87/homeautomation/property/PropertyRepository.java @@ -1,19 +1,17 @@ package de.ph87.homeautomation.property; -import org.springframework.data.repository.CrudRepository; +import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; import java.util.Optional; -public interface PropertyRepository extends CrudRepository { +public interface PropertyRepository extends JpaRepository { Optional findByTitle(String title); List findAllByReadChannel_Id(long readChannelId); - List findAll(); - - List findAllByTitleLike(final String like); + List findAllByTitleLikeIgnoreCase(final String like); boolean existsByTitle(String title); diff --git a/src/main/java/de/ph87/homeautomation/property/PropertyWriteService.java b/src/main/java/de/ph87/homeautomation/property/PropertyWriteService.java index 3d8fbc7..56fea33 100644 --- a/src/main/java/de/ph87/homeautomation/property/PropertyWriteService.java +++ b/src/main/java/de/ph87/homeautomation/property/PropertyWriteService.java @@ -26,7 +26,7 @@ public class PropertyWriteService { private static final String TITLE_PREFIX = "NEU "; - private final PropertyReadService propertyReadService; + private final PropertyReader propertyReader; private final ChannelService channelService; @@ -39,7 +39,7 @@ public class PropertyWriteService { private final ApplicationEventPublisher applicationEventPublisher; public void updateAllProperties() { - propertyReadService.findAllByReadChannelNotNull().forEach(property -> { + propertyReader.findAllByReadChannelNotNull().forEach(property -> { final Optional ownerOptional = channelService.findByChannel(property.getReadChannel()); if (ownerOptional.isPresent()) { ownerOptional.get().requestUpdate(property.getReadChannel()); @@ -50,10 +50,9 @@ public class PropertyWriteService { } @TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION) -// @Transactional(propagation = Propagation.REQUIRES_NEW) public void onChannelChanged(final ChannelDto dto) { log.debug("onChannelChanged [{}]: {}", getCurrentTransactionName(), dto.getTitle()); - final List properties = propertyReadService.findAllByReadChannel_Id(dto.getId()); + final List properties = propertyReader.findAllByReadChannel_Id(dto.getId()); if (!properties.isEmpty()) { properties.forEach(property -> { property.setValue(property.getReadChannel().getValue()); @@ -86,13 +85,13 @@ public class PropertyWriteService { } public PropertyDto set(final long id, final BiConsumer setter, final T value) { - final Property property = propertyReadService.getById(id); + final Property property = propertyReader.getById(id); setter.accept(property, value); return publish(property, true); } public void delete(final long id) { - final Property property = propertyReadService.getById(id); + final Property property = propertyReader.getById(id); propertyRepository.delete(property); publish(property, false); } diff --git a/src/main/java/de/ph87/homeautomation/scene/SceneController.java b/src/main/java/de/ph87/homeautomation/scene/SceneController.java index e541c55..2013950 100644 --- a/src/main/java/de/ph87/homeautomation/scene/SceneController.java +++ b/src/main/java/de/ph87/homeautomation/scene/SceneController.java @@ -19,7 +19,7 @@ public class SceneController { return sceneReadService.findAll(); } - @GetMapping("getById/{id}") + @GetMapping("searchById/{id}") public SceneDto getById(@PathVariable final long id) { return sceneReadService.getDtoById(id); } diff --git a/src/main/java/de/ph87/homeautomation/schedule/ScheduleController.java b/src/main/java/de/ph87/homeautomation/schedule/ScheduleController.java index b04d14d..669d83b 100644 --- a/src/main/java/de/ph87/homeautomation/schedule/ScheduleController.java +++ b/src/main/java/de/ph87/homeautomation/schedule/ScheduleController.java @@ -1,6 +1,6 @@ package de.ph87.homeautomation.schedule; -import de.ph87.homeautomation.property.PropertyReadService; +import de.ph87.homeautomation.property.PropertyReader; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -15,14 +15,14 @@ public class ScheduleController { private final ScheduleWriteService scheduleWriteService; - private final PropertyReadService propertyReadService; + private final PropertyReader propertyReader; @GetMapping("findAll") public List findAll() { return scheduleReadService.findAllDtos(); } - @GetMapping("getById/{id}") + @GetMapping("searchById/{id}") public ScheduleDto getById(@PathVariable final long id) { return scheduleReadService.getDtoById(id); } diff --git a/src/main/java/de/ph87/homeautomation/schedule/entry/ScheduleEntryController.java b/src/main/java/de/ph87/homeautomation/schedule/entry/ScheduleEntryController.java index d6a5752..a00771a 100644 --- a/src/main/java/de/ph87/homeautomation/schedule/entry/ScheduleEntryController.java +++ b/src/main/java/de/ph87/homeautomation/schedule/entry/ScheduleEntryController.java @@ -1,7 +1,7 @@ package de.ph87.homeautomation.schedule.entry; import de.ph87.homeautomation.bulk.BulkReader; -import de.ph87.homeautomation.property.PropertyReadService; +import de.ph87.homeautomation.property.PropertyReader; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -14,7 +14,7 @@ public class ScheduleEntryController { private final BulkReader bulkReader; - private final PropertyReadService propertyReadService; + private final PropertyReader propertyReader; @GetMapping("create/{scheduleId}") public ScheduleEntryDto create(@PathVariable final long scheduleId) { @@ -72,8 +72,8 @@ public class ScheduleEntryController { } @PostMapping("set/{id}/zenith") - public ScheduleEntryDto setZenith(@PathVariable final long id, @RequestBody final String value) { - return scheduleEntryWriteService.set(id, ScheduleEntry::setZenith, Double.parseDouble(value)); + public ScheduleEntryDto setZenith(@PathVariable final long id, @RequestBody final double value) { + return scheduleEntryWriteService.set(id, ScheduleEntry::setZenith, value); } @PostMapping("set/{id}/hour") @@ -97,8 +97,8 @@ public class ScheduleEntryController { } @PostMapping("set/{id}/property") - public ScheduleEntryDto property(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) { - return scheduleEntryWriteService.set(id, entry -> entry.setProperty(propertyId == null ? null : propertyReadService.getById(propertyId))); + public ScheduleEntryDto setProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) { + return scheduleEntryWriteService.set(id, entry -> entry.setProperty(propertyId == null ? null : propertyReader.getById(propertyId))); } @PostMapping("set/{id}/value") @@ -107,7 +107,7 @@ public class ScheduleEntryController { } @PostMapping("set/{id}/bulk") - public ScheduleEntryDto bulk(@PathVariable final long id, @RequestBody(required = false) final Long bulkId) { + public ScheduleEntryDto setBulk(@PathVariable final long id, @RequestBody(required = false) final Long bulkId) { return scheduleEntryWriteService.set(id, entry -> entry.setBulk(bulkId == null ? null : bulkReader.getById(bulkId))); } diff --git a/src/main/java/de/ph87/homeautomation/shared/ISearchController.java b/src/main/java/de/ph87/homeautomation/shared/ISearchController.java index 890cd14..6d11e1e 100644 --- a/src/main/java/de/ph87/homeautomation/shared/ISearchController.java +++ b/src/main/java/de/ph87/homeautomation/shared/ISearchController.java @@ -4,7 +4,7 @@ import java.util.List; public interface ISearchController { - SearchResult getById(final long id); + SearchResult searchById(final long id); List searchLike(final String term); diff --git a/src/main/java/de/ph87/homeautomation/web/NotFoundException.java b/src/main/java/de/ph87/homeautomation/web/NotFoundException.java index 28781cc..c5c93ad 100644 --- a/src/main/java/de/ph87/homeautomation/web/NotFoundException.java +++ b/src/main/java/de/ph87/homeautomation/web/NotFoundException.java @@ -3,14 +3,20 @@ package de.ph87.homeautomation.web; import org.springframework.http.HttpStatus; import org.springframework.web.server.ResponseStatusException; +import java.util.function.Supplier; + public class NotFoundException extends ResponseStatusException { - public NotFoundException(final String message) { - super(HttpStatus.NOT_FOUND, message); + public NotFoundException(final String format, final Object... args) { + super(HttpStatus.NOT_FOUND, String.format(format, args)); } - public NotFoundException(final String format, final Object... args) { - this(String.format(format, args)); + public NotFoundException(final Class clazz, final String key, final Object value) { + this("Entity not found: %s.%s = %s", clazz.getSimpleName(), key, value == null ? null : "\"" + value + "\""); + } + + public static Supplier supply(final Class clazz, final String key, final Object value) { + return () -> new NotFoundException(clazz, key, value); } }