Skip to content

Commit 5b7452d

Browse files
Merge pull request #28 from Preponderous-Software/feat/persist-with-json
Feat/persist with json
2 parents 0a6a104 + 4a2275a commit 5b7452d

File tree

9 files changed

+313
-27
lines changed

9 files changed

+313
-27
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ out/
3535

3636
### VS Code ###
3737
.vscode/
38+
39+
*.log
40+
*.json

build.gradle

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1-
21
plugins {
3-
id 'java'
4-
id 'org.springframework.boot' version '3.5.3'
5-
id 'io.spring.dependency-management' version '1.1.7'
2+
id 'java'
3+
id 'org.springframework.boot' version '3.5.3'
4+
id 'io.spring.dependency-management' version '1.1.7'
65
}
76

87
group = 'com.preponderous'
98
version = '0.1.0-SNAPSHOT'
109

1110
java {
12-
toolchain {
13-
languageVersion = JavaLanguageVersion.of(21)
14-
}
11+
toolchain {
12+
languageVersion = JavaLanguageVersion.of(21)
13+
}
1514
}
1615

1716
configurations {
18-
compileOnly {
19-
extendsFrom annotationProcessor
20-
}
17+
compileOnly {
18+
extendsFrom annotationProcessor
19+
}
2120
}
2221

2322
repositories {
24-
mavenCentral()
23+
mavenCentral()
2524
}
2625

2726
dependencies {
28-
implementation 'org.springframework.boot:spring-boot-starter'
29-
implementation 'org.springframework.shell:spring-shell-starter:3.3.0'
30-
implementation 'org.jline:jline-terminal-jansi:3.23.0'
31-
implementation 'org.jline:jline-terminal-jna:3.23.0'
32-
compileOnly 'org.projectlombok:lombok'
33-
developmentOnly 'org.springframework.boot:spring-boot-devtools'
34-
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
35-
annotationProcessor 'org.projectlombok:lombok'
36-
testImplementation 'org.springframework.boot:spring-boot-starter-test'
37-
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
27+
implementation 'org.springframework.boot:spring-boot-starter'
28+
implementation 'org.springframework.shell:spring-shell-starter:3.3.0'
29+
implementation 'org.jline:jline-terminal-jansi:3.23.0'
30+
implementation 'org.jline:jline-terminal-jna:3.23.0'
31+
implementation 'com.fasterxml.jackson.core:jackson-databind' // Added this line
32+
compileOnly 'org.projectlombok:lombok'
33+
developmentOnly 'org.springframework.boot:spring-boot-devtools'
34+
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
35+
annotationProcessor 'org.projectlombok:lombok'
36+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
37+
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
3838
}
3939

4040
tasks.named('test') {
41-
useJUnitPlatform()
41+
useJUnitPlatform()
4242
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.preponderous.parpt.config;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
7+
@Configuration
8+
public class JsonConfig {
9+
10+
@Bean
11+
public ObjectMapper objectMapper() {
12+
return new ObjectMapper();
13+
}
14+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
package com.preponderous.parpt.repo;
3+
4+
import com.preponderous.parpt.domain.Project;
5+
6+
import java.util.List;
7+
8+
/**
9+
* Interface for reading and writing project data to/from JSON format.
10+
* This interface provides methods to persist and retrieve project data
11+
* using JSON serialization.
12+
*/
13+
public interface ProjectJsonReaderWriter {
14+
/**
15+
* Writes a list of projects to JSON format.
16+
*
17+
* @param projects the list of projects to be written to JSON
18+
*/
19+
void writeJson(List<Project> projects);
20+
21+
/**
22+
* Reads and deserializes projects from JSON format.
23+
*
24+
* @return a list of projects read from JSON
25+
*/
26+
List<Project> readJson();
27+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
package com.preponderous.parpt.repo;
3+
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.preponderous.parpt.domain.Project;
6+
import org.springframework.beans.factory.annotation.Value;
7+
import org.springframework.stereotype.Component;
8+
9+
import java.io.File;
10+
import java.io.IOException;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
@Component
15+
public class ProjectJsonReaderWriterImpl implements ProjectJsonReaderWriter {
16+
17+
private final String projectsFilePath;
18+
private final ObjectMapper objectMapper;
19+
20+
public ProjectJsonReaderWriterImpl(
21+
@Value("${app.projects.file}") String projectsFilePath,
22+
ObjectMapper objectMapper) {
23+
this.projectsFilePath = projectsFilePath;
24+
this.objectMapper = objectMapper;
25+
}
26+
27+
@Override
28+
public void writeJson(List<Project> projects) {
29+
if (projects == null) {
30+
throw new IllegalArgumentException("Projects list cannot be null");
31+
}
32+
33+
try {
34+
objectMapper.writeValue(new File(projectsFilePath), projects);
35+
} catch (IOException e) {
36+
throw new RuntimeException("Failed to write projects to JSON file", e);
37+
}
38+
}
39+
40+
@Override
41+
public List<Project> readJson() {
42+
File file = new File(projectsFilePath);
43+
44+
if (!file.exists() || file.length() == 0) {
45+
return new ArrayList<>();
46+
}
47+
48+
try {
49+
return objectMapper.readValue(file,
50+
objectMapper.getTypeFactory().constructCollectionType(List.class, Project.class));
51+
} catch (IOException e) {
52+
throw new RuntimeException("Failed to read projects from JSON file", e);
53+
}
54+
}
55+
}

src/main/java/com/preponderous/parpt/repo/ProjectRepository.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,33 @@
88

99
@Repository
1010
public class ProjectRepository {
11-
private final List<Project> projects = new ArrayList<>();
11+
private final List<Project> projects;
12+
private final ProjectJsonReaderWriter projectJsonReaderWriter;
13+
14+
public ProjectRepository(ProjectJsonReaderWriter projectJsonReaderWriter) {
15+
this.projectJsonReaderWriter = projectJsonReaderWriter;
16+
this.projects = projectJsonReaderWriter.readJson();
17+
}
1218

1319
public List<Project> findAll() {
1420
return new ArrayList<>(projects);
1521
}
1622

1723
public void clear() {
1824
projects.clear();
25+
projectJsonReaderWriter.writeJson(projects);
1926
}
2027

2128
public void add(Project project) throws NameTakenException {
2229
if (projects.stream().anyMatch(p -> p.getName().equals(project.getName()))) {
2330
throw new NameTakenException("Project with the same name already exists");
2431
}
2532
projects.add(project);
33+
projectJsonReaderWriter.writeJson(projects);
2634
}
2735

2836
public Project findByName(String projectName) throws ProjectNotFoundException {
29-
Project retrievedProject = projects.stream()
37+
Project retrievedProject = projects.stream()
3038
.filter(project -> project.getName().equals(projectName))
3139
.findFirst()
3240
.orElse(null);
@@ -47,4 +55,4 @@ public ProjectNotFoundException(String message) {
4755
super(message);
4856
}
4957
}
50-
}
58+
}

src/main/resources/application.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ parpt:
3434
- "How long will this take to build? (1=very quick, 5=very long) "
3535
- "How many people need to be involved? (1=just a few people, 5=many teams) "
3636
- "Will this be hard to maintain? (1=very easy, 5=very difficult) "
37-
- "Does this need ongoing work? (1=set and forget, 5=lots of upkeep) "
37+
- "Does this need ongoing work? (1=set and forget, 5=lots of upkeep) "
38+
app:
39+
projects:
40+
file: projects.json

0 commit comments

Comments
 (0)