Skip to content

Commit c57ceb6

Browse files
committed
feat: add input parameters parsing with jcommander
1 parent e102a80 commit c57ceb6

File tree

5 files changed

+165
-61
lines changed

5 files changed

+165
-61
lines changed

pom.xml

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3232
<maven.compiler.release>22</maven.compiler.release>
3333
<json-schema-ref-parser-jvm.version>0.8.7</json-schema-ref-parser-jvm.version>
34+
<jcommander.version>2.0</jcommander.version>
3435
</properties>
3536

3637
<dependencyManagement>
@@ -62,6 +63,11 @@
6263
<artifactId>json-schema-ref-parser-jvm</artifactId>
6364
<version>${json-schema-ref-parser-jvm.version}</version>
6465
</dependency>
66+
<dependency>
67+
<groupId>org.jcommander</groupId>
68+
<artifactId>jcommander</artifactId>
69+
<version>${jcommander.version}</version>
70+
</dependency>
6571
</dependencies>
6672

6773
<build>
@@ -126,7 +132,44 @@
126132
<argLine>--enable-preview</argLine>
127133
</configuration>
128134
</plugin>
129-
135+
<plugin>
136+
<!-- Build an executable JAR -->
137+
<groupId>org.apache.maven.plugins</groupId>
138+
<artifactId>maven-jar-plugin</artifactId>
139+
<version>3.4.2</version>
140+
<configuration>
141+
<archive>
142+
<manifest>
143+
<addClasspath>true</addClasspath>
144+
<classpathPrefix>lib/</classpathPrefix>
145+
<mainClass>es.nachobrito.jsonschema.compiler.application.cli.App</mainClass>
146+
</manifest>
147+
</archive>
148+
</configuration>
149+
</plugin>
150+
<plugin>
151+
<artifactId>maven-assembly-plugin</artifactId>
152+
<version>3.7.1</version>
153+
<configuration>
154+
<archive>
155+
<manifest>
156+
<mainClass>es.nachobrito.jsonschema.compiler.application.cli.App</mainClass>
157+
</manifest>
158+
</archive>
159+
<descriptorRefs>
160+
<descriptorRef>jar-with-dependencies</descriptorRef>
161+
</descriptorRefs>
162+
</configuration>
163+
<executions>
164+
<execution>
165+
<id>make-assembly</id> <!-- this is used for inheritance merges -->
166+
<phase>package</phase> <!-- bind to the packaging phase -->
167+
<goals>
168+
<goal>single</goal>
169+
</goals>
170+
</execution>
171+
</executions>
172+
</plugin>
130173
</plugins>
131174
</build>
132175
</project>

src/main/java/es/nachobrito/jsonschema/compiler/application/cli/App.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,23 @@
1616

1717
package es.nachobrito.jsonschema.compiler.application.cli;
1818

19-
/** Hello world! */
19+
import com.beust.jcommander.JCommander;
20+
import es.nachobrito.jsonschema.compiler.application.jcommander.Params;
21+
import es.nachobrito.jsonschema.compiler.domain.Compiler;
22+
import es.nachobrito.jsonschema.compiler.infrastructure.jsonrefparser.JsonSchemaReader;
23+
24+
import java.net.URI;
25+
2026
public class App {
2127
public static void main(String[] args) {
22-
System.out.println("Hello World!");
28+
var params = new Params();
29+
JCommander.newBuilder()
30+
.addObject(params)
31+
.build()
32+
.parse(args);
33+
34+
var compiler = new Compiler(params, new JsonSchemaReader());
35+
var uri = URI.create(params.getSchemaFile());
36+
compiler.compile(uri);
2337
}
2438
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2024 Nacho Brito
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package es.nachobrito.jsonschema.compiler.application.jcommander;
18+
19+
import com.beust.jcommander.Parameter;
20+
import es.nachobrito.jsonschema.compiler.domain.InputParameters;
21+
22+
import java.nio.file.Path;
23+
import java.util.Optional;
24+
25+
public class Params implements InputParameters{
26+
27+
@Parameter(description="The path of the json schema file to compile")
28+
private String schemaFile;
29+
30+
@Parameter(names = {"-p", "--package-name"}, description = "The package name for the generated classes")
31+
private String packageName = "";
32+
33+
@Parameter(names = {"-o", "--output"}, description = "The destination folder")
34+
private String destinationFolder = ".";
35+
36+
@Override
37+
public Optional<String> getPackageName() {
38+
return Optional.ofNullable(packageName);
39+
}
40+
41+
@Override
42+
public Path getOutputFolder() {
43+
return Path.of(destinationFolder);
44+
}
45+
46+
public void setPackageName(String packageName) {
47+
this.packageName = packageName;
48+
}
49+
50+
public String getDestinationFolder() {
51+
return destinationFolder;
52+
}
53+
54+
public void setDestinationFolder(String destinationFolder) {
55+
this.destinationFolder = destinationFolder;
56+
}
57+
58+
public String getSchemaFile() {
59+
return schemaFile;
60+
}
61+
62+
public void setSchemaFile(String schemaFile) {
63+
this.schemaFile = schemaFile;
64+
}
65+
66+
@Override
67+
public String toString() {
68+
return "Params{" +
69+
"schemaFile='" + schemaFile + '\'' +
70+
", packageName='" + packageName + '\'' +
71+
", destinationFolder='" + destinationFolder + '\'' +
72+
'}';
73+
}
74+
}

src/main/java/es/nachobrito/jsonschema/compiler/domain/Compiler.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.lang.classfile.ClassFile;
2727
import java.lang.constant.ClassDesc;
2828
import java.net.URI;
29+
import java.nio.file.Path;
2930
import java.util.SortedMap;
3031

3132
public class Compiler {
@@ -61,7 +62,7 @@ private void compile(Schema schema) {
6162
.getPackageName()
6263
.map(pkg -> "%s.%s".formatted(pkg, schema.className()))
6364
.orElse(schema.className());
64-
var destinationPath = inputParameters.getOutputFolder();
65+
var destinationPath = buildDestinationPath(className);
6566
var properties = schema.properties();
6667

6768
try {
@@ -75,6 +76,13 @@ private void compile(Schema schema) {
7576
}
7677
}
7778

79+
private Path buildDestinationPath(String className) {
80+
var parts = "%s.class".formatted(className.replace('.', '/'));
81+
var path = Path.of(inputParameters.getOutputFolder().toAbsolutePath().toString(), parts);
82+
path.getParent().toFile().mkdirs();
83+
return path;
84+
}
85+
7886
private void writeRecord(
7987
String className, ClassBuilder classBuilder, SortedMap<String, ClassDesc> properties) {
8088
classBuilder.withFlags(ACC_PUBLIC | ACC_FINAL).withSuperclass(of("java.lang.Record"));

src/test/java/es/nachobrito/jsonschema/compiler/CompilerTest.java

Lines changed: 22 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,20 @@
2020
import es.nachobrito.jsonschema.compiler.domain.Compiler;
2121
import es.nachobrito.jsonschema.compiler.domain.InputParametersRecord;
2222
import es.nachobrito.jsonschema.compiler.infrastructure.jsonrefparser.JsonSchemaReader;
23+
import java.io.File;
2324
import java.io.IOException;
2425
import java.lang.reflect.InvocationTargetException;
2526
import java.net.URI;
2627
import java.net.URL;
2728
import java.net.URLClassLoader;
2829
import java.nio.file.Files;
2930
import java.nio.file.Path;
30-
import org.junit.jupiter.api.BeforeAll;
31+
import java.util.Comparator;
32+
import org.junit.jupiter.api.AfterEach;
33+
import org.junit.jupiter.api.BeforeEach;
3134

3235
public class CompilerTest {
33-
/**
34-
* @param filePath
35-
* @param expectedName
36-
* @param initArgs
37-
* @return
38-
* @throws IOException
39-
* @throws ClassNotFoundException
40-
* @throws InvocationTargetException
41-
* @throws InstantiationException
42-
* @throws IllegalAccessException
43-
*/
36+
4437
protected static Object instantiateSampleSchema(
4538
String filePath, String expectedName, Object... initArgs)
4639
throws IOException,
@@ -50,71 +43,43 @@ protected static Object instantiateSampleSchema(
5043
IllegalAccessException {
5144
var cls = compileSampleSchemaFromFile(filePath, expectedName);
5245
var constructors = cls.getDeclaredConstructors();
53-
var person = constructors[0].newInstance(initArgs);
54-
return person;
46+
return constructors[0].newInstance(initArgs);
5547
}
5648

57-
/**
58-
* @param filePath
59-
* @param expectedName
60-
* @return
61-
* @throws IOException
62-
* @throws ClassNotFoundException
63-
*/
6449
protected static Class<?> compileSampleSchemaFromFile(String filePath, String expectedName)
6550
throws IOException, ClassNotFoundException {
6651
var uri = URI.create(filePath);
67-
var destURL =
68-
Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES)
69-
.toAbsolutePath()
70-
.toFile()
71-
.toURI()
72-
.toURL();
73-
var destPath =
74-
Path.of("%s/%s.class".formatted(CompilerSmokeTest.TARGET_GENERATED_CLASSES, expectedName));
52+
Path destPath = Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES);
53+
var destURL = destPath.toAbsolutePath().toFile().toURI().toURL();
7554
var compiler = new Compiler(new InputParametersRecord(destPath, ""), new JsonSchemaReader());
76-
77-
Files.deleteIfExists(destPath);
7855
compiler.compile(uri);
7956
assertTrue(destPath.toFile().exists());
8057

81-
var cls = new URLClassLoader(new URL[] {destURL}).loadClass(expectedName);
82-
return cls;
58+
return new URLClassLoader(new URL[] {destURL}).loadClass(expectedName);
8359
}
8460

85-
/**
86-
* @param jsonSchema
87-
* @param expectedName
88-
* @return
89-
* @throws IOException
90-
* @throws ClassNotFoundException
91-
*/
9261
protected static Class<?> compileSampleSchemaFromString(String jsonSchema, String expectedName)
93-
throws IOException, ClassNotFoundException {
94-
var destURL =
95-
Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES)
96-
.toAbsolutePath()
97-
.toFile()
98-
.toURI()
99-
.toURL();
100-
var destPath =
101-
Path.of("%s/%s.class".formatted(CompilerSmokeTest.TARGET_GENERATED_CLASSES, expectedName));
62+
throws IOException, ClassNotFoundException {
63+
Path destPath = Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES);
64+
var destURL = destPath.toAbsolutePath().toFile().toURI().toURL();
10265
var compiler = new Compiler(new InputParametersRecord(destPath, ""), new JsonSchemaReader());
103-
104-
Files.deleteIfExists(destPath);
10566
compiler.compile(jsonSchema);
10667
assertTrue(destPath.toFile().exists());
10768

108-
var cls = new URLClassLoader(new URL[] {destURL}).loadClass(expectedName);
109-
return cls;
69+
return new URLClassLoader(new URL[] {destURL}).loadClass(expectedName);
11070
}
11171

112-
@BeforeAll
113-
static void beforeAll() throws IOException {
72+
@BeforeEach
73+
void beforeAll() throws IOException {
11474
Files.createDirectories(Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES));
11575
}
11676

117-
static void afterAll() throws IOException {
118-
Files.deleteIfExists(Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES));
77+
@AfterEach
78+
void afterAll() throws IOException {
79+
var pathToBeDeleted = Path.of(CompilerSmokeTest.TARGET_GENERATED_CLASSES);
80+
Files.walk(pathToBeDeleted)
81+
.sorted(Comparator.reverseOrder())
82+
.map(Path::toFile)
83+
.forEach(File::delete);
11984
}
12085
}

0 commit comments

Comments
 (0)