001/* 002 * SPDX-License-Identifier: Apache-2.0 003 * 004 * Copyright 2025-2026 The Enola <https://enola.dev> Authors 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package dev.enola.tool.todo.yaml; 019 020import dev.enola.common.collect.MoreIterables; 021import dev.enola.common.io.object.ObjectReaderWriter; 022import dev.enola.common.io.object.jackson.JacksonObjectReaderWriterChain; 023import dev.enola.common.io.resource.Resource; 024import dev.enola.tool.todo.ToDo; 025import dev.enola.tool.todo.ToDoRepository; 026import dev.enola.tool.todo.ToDoRepositoryInMemory; 027 028import java.io.IOException; 029import java.net.URI; 030import java.nio.file.NoSuchFileException; 031 032public class ToDoYamlFileRepository implements ToDoRepository { 033 034 private final ToDoRepository delegate = new ToDoRepositoryInMemory(); 035 private final ObjectReaderWriter readerWriter; 036 private final Resource resource; 037 038 public ToDoYamlFileRepository(Resource resource) throws IOException { 039 this.readerWriter = new JacksonObjectReaderWriterChain(); 040 this.resource = resource; 041 042 try { 043 MoreIterables.forEach(readerWriter.readArray(resource, ToDo.class), delegate::store); 044 } catch (NoSuchFileException e) { 045 // That's OK; we will create the file on first write. 046 } 047 } 048 049 private void write() throws IOException { 050 var tasks = delegate.list(); 051 if (!readerWriter.write(tasks, resource)) { 052 throw new IOException("Failed to write ToDos to " + resource); 053 } 054 } 055 056 @Override 057 public ToDo get(URI id) { 058 return delegate.get(id); 059 } 060 061 @Override 062 public Iterable<ToDo> list() { 063 return delegate.list(); 064 } 065 066 @Override 067 public void store(ToDo todo) throws IOException { 068 delegate.store(todo); 069 write(); 070 } 071 072 @Override 073 public void delete(URI id) throws IOException { 074 delegate.delete(id); 075 write(); 076 } 077}