Skip to content

Commit b8b69eb

Browse files
committed
Add a way to represent ApplicationModel as a Map and serialize it to JSON
1 parent 84414f0 commit b8b69eb

File tree

72 files changed

+2800
-193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2800
-193
lines changed

core/builder/src/main/java/io/quarkus/builder/Json.java

Lines changed: 156 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import java.util.ArrayList;
55
import java.util.Collection;
66
import java.util.HashMap;
7+
import java.util.Iterator;
78
import java.util.List;
89
import java.util.Map;
910
import java.util.Map.Entry;
1011
import java.util.Objects;
12+
import java.util.Set;
1113

1214
import io.quarkus.builder.json.JsonArray;
1315
import io.quarkus.builder.json.JsonBoolean;
@@ -58,6 +60,14 @@ public static JsonArrayBuilder array() {
5860
return new JsonArrayBuilder(false, false);
5961
}
6062

63+
/**
64+
* @param initialCapacity initial underlying array capacity
65+
* @return the new JSON array builder, empty builders are not ignored
66+
*/
67+
public static JsonArrayBuilder array(int initialCapacity) {
68+
return new JsonArrayBuilder(false, false, initialCapacity);
69+
}
70+
6171
/**
6272
* @param ignoreEmptyBuilders
6373
* @return the new JSON array builder
@@ -74,6 +84,14 @@ public static JsonObjectBuilder object() {
7484
return new JsonObjectBuilder(false, false);
7585
}
7686

87+
/**
88+
* @param initialCapacity initial underlying map capacity
89+
* @return the new JSON object builder, empty builders are not ignored
90+
*/
91+
public static JsonObjectBuilder object(int initialCapacity) {
92+
return new JsonObjectBuilder(false, false, initialCapacity);
93+
}
94+
7795
/**
7896
* @param ignoreEmptyBuilders
7997
* @return the new JSON object builder
@@ -162,16 +180,21 @@ public void transform(JsonMultiValue value, JsonTransform transform) {
162180
/**
163181
* JSON array builder.
164182
*/
165-
public static class JsonArrayBuilder extends JsonBuilder<JsonArrayBuilder> {
183+
public static class JsonArrayBuilder extends JsonBuilder<JsonArrayBuilder> implements Collection<Object> {
166184

167185
private final List<Object> values;
168186

169187
private JsonArrayBuilder(boolean ignoreEmptyBuilders, boolean skipEscapeCharacters) {
170188
super(ignoreEmptyBuilders, skipEscapeCharacters);
171-
this.values = new ArrayList<Object>();
189+
this.values = new ArrayList<>();
190+
}
191+
192+
private JsonArrayBuilder(boolean ignoreEmptyBuilders, boolean skipEscapeCharacters, int initialCapacity) {
193+
super(ignoreEmptyBuilders, skipEscapeCharacters);
194+
this.values = new ArrayList<>(initialCapacity);
172195
}
173196

174-
JsonArrayBuilder add(JsonArrayBuilder value) {
197+
public JsonArrayBuilder add(JsonArrayBuilder value) {
175198
addInternal(value);
176199
return this;
177200
}
@@ -214,10 +237,74 @@ void addInternal(Object value) {
214237
}
215238
}
216239

240+
@Override
241+
public int size() {
242+
return values.size();
243+
}
244+
217245
public boolean isEmpty() {
218246
return isValuesEmpty(values);
219247
}
220248

249+
@Override
250+
public boolean contains(Object o) {
251+
return values.contains(o);
252+
}
253+
254+
@Override
255+
public Iterator<Object> iterator() {
256+
return values.iterator();
257+
}
258+
259+
@Override
260+
public Object[] toArray() {
261+
return values.toArray();
262+
}
263+
264+
@Override
265+
public <T> T[] toArray(T[] a) {
266+
return values.toArray(a);
267+
}
268+
269+
@Override
270+
public boolean add(Object o) {
271+
addInternal(o);
272+
return o != null;
273+
}
274+
275+
@Override
276+
public boolean remove(Object o) {
277+
return values.remove(o);
278+
}
279+
280+
@Override
281+
public boolean containsAll(Collection<?> c) {
282+
return values.containsAll(c);
283+
}
284+
285+
@Override
286+
public boolean addAll(Collection<?> c) {
287+
for (Object o : c) {
288+
addInternal(o);
289+
}
290+
return false;
291+
}
292+
293+
@Override
294+
public boolean removeAll(Collection<?> c) {
295+
return values.removeAll(c);
296+
}
297+
298+
@Override
299+
public boolean retainAll(Collection<?> c) {
300+
return values.retainAll(c);
301+
}
302+
303+
@Override
304+
public void clear() {
305+
values.clear();
306+
}
307+
221308
String build() throws IOException {
222309
StringBuilder builder = new StringBuilder();
223310
appendTo(builder);
@@ -276,7 +363,7 @@ void add(JsonValue element) {
276363
/**
277364
* JSON object builder.
278365
*/
279-
public static class JsonObjectBuilder extends JsonBuilder<JsonObjectBuilder> {
366+
public static class JsonObjectBuilder extends JsonBuilder<JsonObjectBuilder> implements Map<String, Object> {
280367

281368
private final Map<String, Object> properties;
282369

@@ -285,6 +372,11 @@ private JsonObjectBuilder(boolean ignoreEmptyBuilders, boolean skipEscapeCharact
285372
this.properties = new HashMap<String, Object>();
286373
}
287374

375+
private JsonObjectBuilder(boolean ignoreEmptyBuilders, boolean skipEscapeCharacters, int initialCapacity) {
376+
super(ignoreEmptyBuilders, skipEscapeCharacters);
377+
this.properties = new HashMap<>(initialCapacity);
378+
}
379+
288380
public JsonObjectBuilder put(String name, String value) {
289381
putInternal(name, value);
290382
return this;
@@ -319,11 +411,17 @@ boolean has(String name) {
319411
return properties.containsKey(name);
320412
}
321413

322-
void putInternal(String name, Object value) {
414+
Object putInternal(String name, Object value) {
323415
Objects.requireNonNull(name);
324416
if (value != null) {
325-
properties.put(name, value);
417+
return properties.put(name, value);
326418
}
419+
return null;
420+
}
421+
422+
@Override
423+
public int size() {
424+
return properties.size();
327425
}
328426

329427
public boolean isEmpty() {
@@ -333,6 +431,58 @@ public boolean isEmpty() {
333431
return isValuesEmpty(properties.values());
334432
}
335433

434+
@Override
435+
public boolean containsKey(Object key) {
436+
return properties.containsKey(key);
437+
}
438+
439+
@Override
440+
public boolean containsValue(Object value) {
441+
return properties.containsValue(value);
442+
}
443+
444+
@Override
445+
public Object get(Object key) {
446+
return properties.get(key);
447+
}
448+
449+
@Override
450+
public Object put(String key, Object value) {
451+
return putInternal(key, value);
452+
}
453+
454+
@Override
455+
public Object remove(Object key) {
456+
return properties.remove(key);
457+
}
458+
459+
@Override
460+
public void putAll(Map<? extends String, ?> m) {
461+
for (Map.Entry<? extends String, ?> entry : m.entrySet()) {
462+
putInternal(entry.getKey(), entry.getValue());
463+
}
464+
}
465+
466+
@Override
467+
public void clear() {
468+
properties.clear();
469+
}
470+
471+
@Override
472+
public Set<String> keySet() {
473+
return properties.keySet();
474+
}
475+
476+
@Override
477+
public Collection<Object> values() {
478+
return properties.values();
479+
}
480+
481+
@Override
482+
public Set<Entry<String, Object>> entrySet() {
483+
return properties.entrySet();
484+
}
485+
336486
String build() throws IOException {
337487
StringBuilder builder = new StringBuilder();
338488
appendTo(builder);

core/builder/src/main/java/io/quarkus/builder/json/JsonArray.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ public <T extends JsonValue> Stream<T> stream() {
2525
public void forEach(JsonTransform transform) {
2626
value.forEach(v -> transform.accept(null, v));
2727
}
28+
29+
public int size() {
30+
return value.size();
31+
}
2832
}

core/builder/src/main/java/io/quarkus/builder/json/JsonInteger.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@ public long longValue() {
1414
public int intValue() {
1515
return (int) value;
1616
}
17+
18+
@Override
19+
public String toString() {
20+
return Long.toString(value);
21+
}
1722
}

core/builder/src/main/java/io/quarkus/builder/json/JsonString.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ public boolean equals(Object o) {
2727
public int hashCode() {
2828
return Objects.hash(value);
2929
}
30+
31+
@Override
32+
public String toString() {
33+
return value;
34+
}
3035
}

core/deployment/src/main/java/io/quarkus/deployment/dev/IDEDevModeMain.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313

1414
import io.quarkus.bootstrap.BootstrapConstants;
1515
import io.quarkus.bootstrap.BootstrapGradleException;
16+
import io.quarkus.bootstrap.app.ApplicationModelSerializer;
1617
import io.quarkus.bootstrap.app.CuratedApplication;
1718
import io.quarkus.bootstrap.devmode.DependenciesFilter;
1819
import io.quarkus.bootstrap.model.ApplicationModel;
19-
import io.quarkus.bootstrap.resolver.AppModelResolverException;
20-
import io.quarkus.bootstrap.util.BootstrapUtils;
2120
import io.quarkus.bootstrap.utils.BuildToolHelper;
2221
import io.quarkus.bootstrap.workspace.ArtifactSources;
2322
import io.quarkus.bootstrap.workspace.SourceDir;
@@ -48,8 +47,8 @@ public void accept(CuratedApplication curatedApplication, Map<String, Object> st
4847
if (BuildToolHelper.isMavenProject(appClasses)) {
4948
appModel = curatedApplication.getApplicationModel();
5049
} else {
51-
appModel = BootstrapUtils
52-
.deserializeQuarkusModel((Path) stringObjectMap.get(BootstrapConstants.SERIALIZED_APP_MODEL));
50+
appModel = ApplicationModelSerializer
51+
.deserialize((Path) stringObjectMap.get(BootstrapConstants.SERIALIZED_APP_MODEL));
5352
}
5453

5554
if (appModel != null) {
@@ -64,7 +63,7 @@ public void accept(CuratedApplication curatedApplication, Map<String, Object> st
6463
}
6564
}
6665
}
67-
} catch (AppModelResolverException e) {
66+
} catch (Exception e) {
6867
log.error("Failed to load workspace, hot reload will not be available", e);
6968
}
7069

devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/GradleApplicationModelBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
import io.quarkus.bootstrap.model.gradle.impl.ModelParameterImpl;
5555
import io.quarkus.bootstrap.workspace.ArtifactSources;
5656
import io.quarkus.bootstrap.workspace.DefaultArtifactSources;
57-
import io.quarkus.bootstrap.workspace.DefaultSourceDir;
5857
import io.quarkus.bootstrap.workspace.DefaultWorkspaceModule;
58+
import io.quarkus.bootstrap.workspace.LazySourceDir;
5959
import io.quarkus.bootstrap.workspace.SourceDir;
6060
import io.quarkus.bootstrap.workspace.WorkspaceModule;
6161
import io.quarkus.bootstrap.workspace.WorkspaceModuleId;
@@ -643,7 +643,7 @@ private static void initProjectModule(Project project, WorkspaceModule.Mutable m
643643
}
644644
final List<SourceDir> resources = new ArrayList<>(resourceDirs.size());
645645
for (Map.Entry<File, Path> e : resourceDirs.entrySet()) {
646-
resources.add(new DefaultSourceDir(e.getKey().toPath(), e.getValue(), null));
646+
resources.add(new LazySourceDir(e.getKey().toPath(), e.getValue(), null));
647647
}
648648
module.addArtifactSources(new DefaultArtifactSources(classifier, sourceDirs, resources));
649649
}
@@ -698,7 +698,7 @@ private static void configureCompileTask(FileTree sources, DirectoryProperty des
698698
// we are looking for the root dirs containing sources
699699
if (visitor.getRelativePath().getSegments().length == 1) {
700700
final File srcDir = visitor.getFile().getParentFile();
701-
sourceDirs.add(new DefaultSourceDir(srcDir.toPath(), destDir.toPath(),
701+
sourceDirs.add(new LazySourceDir(srcDir.toPath(), destDir.toPath(),
702702
findGeneratedSourceDir(destDir, sourceSet),
703703
Map.of("compiler", task.getName())));
704704
}

devtools/gradle/gradle-model/src/main/java/io/quarkus/gradle/tooling/ToolingUtils.java

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import java.io.File;
44
import java.io.IOException;
5-
import java.io.ObjectInputStream;
6-
import java.io.ObjectOutputStream;
7-
import java.nio.file.Files;
85
import java.nio.file.Path;
96
import java.util.Objects;
107
import java.util.concurrent.atomic.AtomicReference;
@@ -21,6 +18,7 @@
2118
import org.gradle.internal.composite.IncludedBuildInternal;
2219
import org.gradle.internal.composite.IncludedRootBuild;
2320

21+
import io.quarkus.bootstrap.app.ApplicationModelSerializer;
2422
import io.quarkus.bootstrap.model.ApplicationModel;
2523
import io.quarkus.bootstrap.model.gradle.ModelParameter;
2624
import io.quarkus.bootstrap.model.gradle.impl.ModelParameterImpl;
@@ -158,24 +156,16 @@ private static Project findIncludedBuildProject(IncludedBuild ib, ExternalModule
158156
public static Path serializeAppModel(ApplicationModel appModel, Task context, boolean test) throws IOException {
159157
final Path serializedModel = context.getTemporaryDir().toPath()
160158
.resolve("quarkus-app" + (test ? "-test" : "") + "-model.dat");
161-
try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModel))) {
162-
out.writeObject(appModel);
163-
}
159+
ApplicationModelSerializer.serialize(appModel, serializedModel);
164160
return serializedModel;
165161
}
166162

167163
public static ApplicationModel deserializeAppModel(Path path) throws IOException {
168-
try (ObjectInputStream out = new ObjectInputStream(Files.newInputStream(path))) {
169-
return (ApplicationModel) out.readObject();
170-
} catch (ClassNotFoundException e) {
171-
throw new RuntimeException(e);
172-
}
164+
return ApplicationModelSerializer.deserialize(path);
173165
}
174166

175167
public static Path serializeAppModel(ApplicationModel appModel, Path serializedModelPath) throws IOException {
176-
try (ObjectOutputStream out = new ObjectOutputStream(Files.newOutputStream(serializedModelPath))) {
177-
out.writeObject(appModel);
178-
}
168+
ApplicationModelSerializer.serialize(appModel, serializedModelPath);
179169
return serializedModelPath;
180170
}
181171

devtools/maven/src/main/java/io/quarkus/maven/DevMojo.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
import org.fusesource.jansi.internal.Kernel32;
9292

9393
import io.quarkus.bootstrap.BootstrapConstants;
94+
import io.quarkus.bootstrap.app.ApplicationModelSerializer;
9495
import io.quarkus.bootstrap.app.ConfiguredClassLoading;
9596
import io.quarkus.bootstrap.app.QuarkusBootstrap;
9697
import io.quarkus.bootstrap.devmode.DependenciesFilter;
@@ -1556,7 +1557,7 @@ private DevModeCommandLine newLauncher(String actualDebugPort, String bootstrapI
15561557
.extensionDevModeJvmOptionFilter(extensionJvmOptions);
15571558

15581559
// serialize the app model to avoid re-resolving it in the dev process
1559-
BootstrapUtils.serializeAppModel(appModel, appModelLocation);
1560+
ApplicationModelSerializer.serialize(appModel, appModelLocation);
15601561
builder.jvmArgs("-D" + BootstrapConstants.SERIALIZED_APP_MODEL + "=" + appModelLocation);
15611562

15621563
if (noDeps) {

0 commit comments

Comments
 (0)