Improve schema definition
This commit is contained in:
parent
b48f4eb43d
commit
6e08ed39ed
@ -3,7 +3,7 @@ package it.cavallium.data.generator;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ClassConfiguration {
|
public final class ClassConfiguration {
|
||||||
|
|
||||||
public String stringRepresenter;
|
public String stringRepresenter;
|
||||||
|
|
||||||
@ -36,4 +36,13 @@ public class ClassConfiguration {
|
|||||||
hash += ConfigUtils.hashCode(data);
|
hash += ConfigUtils.hashCode(data);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public ClassConfiguration clone() {
|
||||||
|
var cc = new ClassConfiguration();
|
||||||
|
cc.stringRepresenter = stringRepresenter;
|
||||||
|
cc.data = new LinkedHashMap<>(data);
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
package it.cavallium.data.generator;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ComputedVersion {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Map<String, ParsedClass> classMap;
|
||||||
|
private final int version;
|
||||||
|
private final boolean current;
|
||||||
|
public DetailsConfiguration details;
|
||||||
|
public List<VersionTransformation> transformations;
|
||||||
|
|
||||||
|
public ComputedVersion(ParsedVersion value, int version, boolean current, String versionName, Map<String, ParsedClass> classMap) {
|
||||||
|
this.details = value.details;
|
||||||
|
this.transformations = value.transformations;
|
||||||
|
this.version = version;
|
||||||
|
this.current = current;
|
||||||
|
this.name = versionName;
|
||||||
|
this.classMap = classMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ParsedClass> getClassMap() {
|
||||||
|
return classMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ComputedVersion that = (ComputedVersion) o;
|
||||||
|
return Objects.equals(details, that.details)
|
||||||
|
&& Objects.equals(transformations, that.transformations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
hash += ConfigUtils.hashCode(details);
|
||||||
|
hash += ConfigUtils.hashCode(transformations);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPackage(String basePackageName) {
|
||||||
|
if (current) {
|
||||||
|
return joinPackage(basePackageName, "current");
|
||||||
|
} else {
|
||||||
|
return joinPackage(basePackageName, "v" + getVersionCompleteInt());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersionVarName() {
|
||||||
|
return "V" + version;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getVersionCompleteInt() {
|
||||||
|
return Integer.toString(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String joinPackage(String basePackageName, String packageName) {
|
||||||
|
if (basePackageName.isBlank()) {
|
||||||
|
basePackageName = "org.generated";
|
||||||
|
}
|
||||||
|
if (packageName.isBlank()) {
|
||||||
|
return basePackageName;
|
||||||
|
} else {
|
||||||
|
return basePackageName + "." + packageName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCurrent() {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import com.squareup.javapoet.ParameterizedTypeName;
|
|||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.TypeName;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class CustomTypesConfiguration {
|
public final class CustomTypesConfiguration {
|
||||||
|
|
||||||
private String javaClass;
|
private String javaClass;
|
||||||
public String serializer;
|
public String serializer;
|
||||||
@ -50,4 +50,13 @@ public class CustomTypesConfiguration {
|
|||||||
hash += ConfigUtils.hashCode(serializer);
|
hash += ConfigUtils.hashCode(serializer);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public CustomTypesConfiguration clone() {
|
||||||
|
var c = new CustomTypesConfiguration();
|
||||||
|
c.javaClass = this.javaClass;
|
||||||
|
c.serializer = this.serializer;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,399 @@
|
|||||||
|
package it.cavallium.data.generator;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectCollection;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collector;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class DataModel {
|
||||||
|
|
||||||
|
private static final List<String> NATIVE_TYPES = List.of("String",
|
||||||
|
"boolean",
|
||||||
|
"short",
|
||||||
|
"char",
|
||||||
|
"int",
|
||||||
|
"long",
|
||||||
|
"float",
|
||||||
|
"double",
|
||||||
|
"byte",
|
||||||
|
"Int52"
|
||||||
|
);
|
||||||
|
|
||||||
|
private final int currentVersion;
|
||||||
|
private final Int2ObjectMap<Map<String, ParsedClass>> classConfig;
|
||||||
|
private final int hash;
|
||||||
|
private final Map<String, ParsedInterface> interfacesData;
|
||||||
|
private final Int2ObjectMap<ComputedVersion> versions;
|
||||||
|
private final Map<String, Set<String>> superTypes;
|
||||||
|
private final Map<String, CustomTypesConfiguration> customTypes;
|
||||||
|
|
||||||
|
public DataModel(int hash,
|
||||||
|
String currentVersionKey,
|
||||||
|
Map<String, InterfaceDataConfiguration> interfacesData,
|
||||||
|
Map<String, ClassConfiguration> baseTypesData,
|
||||||
|
Map<String, Set<String>> superTypesData,
|
||||||
|
Map<String, CustomTypesConfiguration> customTypesData,
|
||||||
|
Map<String, VersionConfiguration> rawVersions) {
|
||||||
|
|
||||||
|
this.hash = hash;
|
||||||
|
|
||||||
|
if (rawVersions.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("No defined versions");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rawVersions.containsKey(currentVersionKey)) {
|
||||||
|
throw new IllegalArgumentException("Current version " + currentVersionKey + " is not defined in versions!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are multiple root versions
|
||||||
|
String rootVersion = rawVersions.entrySet().stream()
|
||||||
|
.filter(e -> e.getValue().previousVersion == null)
|
||||||
|
.map(Entry::getKey)
|
||||||
|
.collect(toSingleton(DataModel::throwMultiRootVersions));
|
||||||
|
|
||||||
|
// Check if multiple versions depend on the same version
|
||||||
|
rawVersions.entrySet().stream()
|
||||||
|
.filter(v -> v.getValue().previousVersion != null)
|
||||||
|
.collect(Collectors.groupingBy(v -> v.getValue().previousVersion))
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(x -> x.getValue().size() > 1)
|
||||||
|
.forEach(x -> {
|
||||||
|
throw new IllegalArgumentException("Multiple versions depend on version " + x.getKey() + ": " + x.getValue()
|
||||||
|
.stream().map(Entry::getKey).collect(Collectors.joining(", ")));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the next versions map
|
||||||
|
Map<String, String> nextVersionMap = rawVersions.keySet().stream()
|
||||||
|
.map(version -> Map.entry(version, rawVersions
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(x -> Objects.equals(version, x.getValue().previousVersion))
|
||||||
|
.map(Entry::getKey)
|
||||||
|
.collect(toOptional(nextVersions -> throwMultiNextVersions(version, nextVersions))))
|
||||||
|
)
|
||||||
|
.filter(x -> x.getValue().isPresent())
|
||||||
|
.map(x -> Map.entry(x.getKey(), x.getValue().get()))
|
||||||
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
||||||
|
|
||||||
|
// Build versions sequence
|
||||||
|
List<String> rawVersionsSequence = new ArrayList<>();
|
||||||
|
int versionsCount = 0;
|
||||||
|
IntList versionsSequence = IntStream.range(0, versionsCount).boxed().collect(Collectors.toCollection(IntArrayList::new));
|
||||||
|
Int2ObjectMap<String> versionToName = new Int2ObjectOpenHashMap<>();
|
||||||
|
Object2IntMap<String> nameToVersion = new Object2IntOpenHashMap<>();
|
||||||
|
{
|
||||||
|
String lastVersion = null;
|
||||||
|
String nextVersion = rootVersion;
|
||||||
|
while (nextVersion != null) {
|
||||||
|
rawVersionsSequence.add(nextVersion);
|
||||||
|
lastVersion = nextVersion;
|
||||||
|
versionToName.put(versionsCount, nextVersion);
|
||||||
|
nameToVersion.put(nextVersion, versionsCount);
|
||||||
|
nextVersion = getNextVersion(nextVersionMap, nextVersion);
|
||||||
|
versionsCount++;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(lastVersion, currentVersionKey)) {
|
||||||
|
throw new IllegalArgumentException("Last version " + lastVersion
|
||||||
|
+ " is different than the defined current version: " + currentVersionKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int latestVersion = versionsCount - 1;
|
||||||
|
|
||||||
|
// Collect all existing base types
|
||||||
|
List<String> baseTypes = new ArrayList<>(baseTypesData.keySet());
|
||||||
|
|
||||||
|
// Collect all existing super types
|
||||||
|
List<String> superTypes = new ArrayList<>(superTypesData.keySet());
|
||||||
|
|
||||||
|
// Collect all custom types
|
||||||
|
List<String> customTypes = new ArrayList<>(customTypesData.keySet());
|
||||||
|
|
||||||
|
List<String> allTypes = Stream.concat(Stream.concat(Stream.concat(baseTypes.stream(), superTypes.stream()),
|
||||||
|
customTypes.stream()), NATIVE_TYPES.stream())
|
||||||
|
.distinct()
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Stream.concat(Stream.concat(Stream.concat(baseTypes.stream(), superTypes.stream()),
|
||||||
|
customTypes.stream()), NATIVE_TYPES.stream())
|
||||||
|
.collect(Collectors.groupingBy(Function.identity()))
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.filter(x -> x.size() > 1)
|
||||||
|
.forEach(x -> {
|
||||||
|
var type = x.get(0);
|
||||||
|
throw new IllegalArgumentException("Type " + type + " has been defined more than once (check base, super, and custom types)!");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compute the numeric versions map
|
||||||
|
Int2ObjectMap<ParsedVersion> versions = new Int2ObjectOpenHashMap<>();
|
||||||
|
rawVersions.forEach((k, v) -> versions.put(nameToVersion.getInt(k), new ParsedVersion(v)));
|
||||||
|
|
||||||
|
// Compute the cartesian product of version * base type
|
||||||
|
record VersionAndType(int version, String type) {}
|
||||||
|
List<VersionAndType> versionAndBaseType = Lists.<Object>cartesianProduct(versionsSequence, baseTypes).stream()
|
||||||
|
.map(tuple -> new VersionAndType((Integer) tuple.get(0), (String) tuple.get(1)))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Int2ObjectMap<Map<String, ParsedClass>> computedClassConfig = new Int2ObjectOpenHashMap<>();
|
||||||
|
for (int versionIndex = 0; versionIndex < versionsCount; versionIndex++) {
|
||||||
|
if (versionIndex == 0) {
|
||||||
|
computedClassConfig.put(0, baseTypesData.entrySet().stream()
|
||||||
|
.map(e -> Map.entry(e.getKey(), new ParsedClass(e.getValue())))
|
||||||
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue))
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var version = versions.get(versionIndex);
|
||||||
|
Map<String, ParsedClass> prevVersionConfiguration
|
||||||
|
= requireNonNull(computedClassConfig.get(versionIndex - 1));
|
||||||
|
Map<String, ParsedClass> newVersionConfiguration = prevVersionConfiguration.entrySet().stream()
|
||||||
|
.map(entry -> Map.entry(entry.getKey(), entry.getValue().clone()))
|
||||||
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
||||||
|
|
||||||
|
for (VersionTransformation rawTransformation : version.transformations) {
|
||||||
|
TransformationConfiguration transformation;
|
||||||
|
var transformCoordinate = "Transformation at index "
|
||||||
|
+ version.transformations.indexOf(rawTransformation) + " in version "
|
||||||
|
+ versionToName.get(versionIndex);
|
||||||
|
try {
|
||||||
|
transformation = rawTransformation.getTransformation();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " is not consistent", ex);
|
||||||
|
}
|
||||||
|
final String transformName = transformation.getTransformName();
|
||||||
|
switch (transformName) {
|
||||||
|
case "move-data" -> {
|
||||||
|
var t = (MoveDataConfiguration) transformation;
|
||||||
|
var transformClass = newVersionConfiguration.get(t.transformClass);
|
||||||
|
if (transformClass == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||||
|
+ t.transformClass);
|
||||||
|
}
|
||||||
|
String definition = transformClass.data.remove(t.from);
|
||||||
|
if (definition == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||||
|
}
|
||||||
|
var prevDef = transformClass.data.put(t.to, definition);
|
||||||
|
if (prevDef != null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
transformCoordinate + " tries to overwrite the existing field \"" + t.to + "\" of value \""
|
||||||
|
+ prevDef + "\" with the field \"" + t.from + "\" of type \"" + definition + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "new-data" -> {
|
||||||
|
var t = (NewDataConfiguration) transformation;
|
||||||
|
var transformClass = newVersionConfiguration.get(t.transformClass);
|
||||||
|
if (transformClass == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||||
|
+ t.transformClass);
|
||||||
|
}
|
||||||
|
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||||
|
}
|
||||||
|
var prevDef = transformClass.data.put(t.to, fixType(t.type));
|
||||||
|
if (prevDef != null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " tries to overwrite the existing field \""
|
||||||
|
+ t.to + "\" of value \"" + prevDef
|
||||||
|
+ "\" with the new type \"" + t.type + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "remove-data" -> {
|
||||||
|
var t = (RemoveDataConfiguration) transformation;
|
||||||
|
var transformClass = newVersionConfiguration.get(t.transformClass);
|
||||||
|
if (transformClass == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||||
|
+ t.transformClass);
|
||||||
|
}
|
||||||
|
var prevDef = transformClass.data.remove(t.from);
|
||||||
|
if (prevDef == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " tries to remove the nonexistent field \""
|
||||||
|
+ t.from + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "upgrade-data" -> {
|
||||||
|
var t = (UpgradeDataConfiguration) transformation;
|
||||||
|
var transformClass = newVersionConfiguration.get(t.transformClass);
|
||||||
|
if (transformClass == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||||
|
+ t.transformClass);
|
||||||
|
}
|
||||||
|
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||||
|
}
|
||||||
|
String prevDefinition = transformClass.data.put(t.from, fixType(t.type));
|
||||||
|
if (prevDefinition == null) {
|
||||||
|
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> throw new IllegalArgumentException("Unknown transform name: "+ transformName);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
computedClassConfig.put(versionIndex, newVersionConfiguration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.classConfig = computedClassConfig;
|
||||||
|
this.interfacesData = interfacesData.entrySet().stream()
|
||||||
|
.map(e -> Map.entry(e.getKey(), new ParsedInterface(e.getValue())))
|
||||||
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
|
||||||
|
this.versions = versions
|
||||||
|
.int2ObjectEntrySet()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(Int2ObjectMap.Entry::getIntKey,
|
||||||
|
e -> new ComputedVersion(e.getValue(),
|
||||||
|
e.getIntKey(),
|
||||||
|
e.getIntKey() == latestVersion,
|
||||||
|
versionToName.get(e.getIntKey()),
|
||||||
|
computedClassConfig.get(e.getIntKey())
|
||||||
|
),
|
||||||
|
(a, b) -> {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
},
|
||||||
|
Int2ObjectOpenHashMap::new
|
||||||
|
));
|
||||||
|
this.currentVersion = versionsCount - 1;
|
||||||
|
this.superTypes = superTypesData;
|
||||||
|
this.customTypes = customTypesData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static String getNextVersion(Map<String, String> versionsSequence, String version) {
|
||||||
|
return versionsSequence.get(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuntimeException throwMultiNextVersions(String version, List<String> nextVersions) {
|
||||||
|
return new IllegalArgumentException("Found many next versions of version " + version + ":"
|
||||||
|
+ String.join(", ", nextVersions));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuntimeException throwMultiRootVersions(List<String> rootVersions) {
|
||||||
|
return new IllegalArgumentException("Found many root versions: " + String.join(", ", rootVersions));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Collector<T, ?, T> toSingleton() {
|
||||||
|
return toSingleton(x -> new IllegalStateException());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Collector<T, ?, T> toSingleton(Function<List<T>, RuntimeException> exceptionGenerator) {
|
||||||
|
return Collectors.collectingAndThen(
|
||||||
|
Collectors.toList(),
|
||||||
|
list -> {
|
||||||
|
if (list.size() != 1) {
|
||||||
|
throw exceptionGenerator.apply(list);
|
||||||
|
}
|
||||||
|
return list.get(0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Collector<T, ?, Optional<T>> toOptional() {
|
||||||
|
return toOptional(x -> new IllegalStateException());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Collector<T, ?, Optional<T>> toOptional(Function<List<T>, RuntimeException> exceptionGenerator) {
|
||||||
|
return Collectors.collectingAndThen(
|
||||||
|
Collectors.toList(),
|
||||||
|
list -> {
|
||||||
|
if (list.size() > 1) {
|
||||||
|
throw exceptionGenerator.apply(list);
|
||||||
|
}
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(list.get(0));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int computeHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Entry<String, ParsedInterface>> getInterfacesSet() {
|
||||||
|
return interfacesData.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String fixType(String fieldType) {
|
||||||
|
if (fieldType.endsWith("[]") && fieldType.startsWith("-")) {
|
||||||
|
throw new UnsupportedOperationException("Arrays cannot be null");
|
||||||
|
}
|
||||||
|
if (fieldType.endsWith("[]")) {
|
||||||
|
return "§" + fieldType.substring(0, fieldType.length() - 2);
|
||||||
|
} else {
|
||||||
|
return fieldType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the base type
|
||||||
|
* X --> X
|
||||||
|
* -X --> X
|
||||||
|
* X[] --> X
|
||||||
|
*/
|
||||||
|
public static String extractTypeName(String fieldType) {
|
||||||
|
if (fieldType.endsWith("[]") && fieldType.startsWith("-")) {
|
||||||
|
throw new UnsupportedOperationException("Arrays cannot be null");
|
||||||
|
}
|
||||||
|
if (fieldType.endsWith("[]")) {
|
||||||
|
return fieldType.substring(0, fieldType.length() - 2);
|
||||||
|
} else if (fieldType.startsWith("-")) {
|
||||||
|
return fieldType.substring(1);
|
||||||
|
} else {
|
||||||
|
return fieldType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectCollection<ComputedVersion> getVersionsSet() {
|
||||||
|
return this.versions.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentVersionNumber() {
|
||||||
|
return currentVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComputedVersion getCurrentVersion() {
|
||||||
|
return versions.get(currentVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Set<String>> getSuperTypes() {
|
||||||
|
return this.superTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<ComputedVersion> getNextVersion(ComputedVersion versionConfiguration) {
|
||||||
|
var nextVersion = versions.get(versionConfiguration.getVersion() + 1);
|
||||||
|
return Optional.ofNullable(nextVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComputedVersion getNextVersionOrThrow(ComputedVersion versionConfiguration) {
|
||||||
|
return Objects.requireNonNull(versions.get(versionConfiguration.getVersion() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ParsedInterface> getInterfaces() {
|
||||||
|
return interfacesData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, CustomTypesConfiguration> getCustomTypes() {
|
||||||
|
return customTypes;
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ package it.cavallium.data.generator;
|
|||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class MoveDataConfiguration implements TransformationConfiguration {
|
public final class MoveDataConfiguration implements TransformationConfiguration {
|
||||||
|
|
||||||
public String transformClass;
|
public String transformClass;
|
||||||
public String from;
|
public String from;
|
||||||
@ -40,4 +40,14 @@ public class MoveDataConfiguration implements TransformationConfiguration {
|
|||||||
hash += ConfigUtils.hashCode(to);
|
hash += ConfigUtils.hashCode(to);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public MoveDataConfiguration clone() {
|
||||||
|
var c = new MoveDataConfiguration();
|
||||||
|
if (this.transformClass != null) c.transformClass = this.transformClass;
|
||||||
|
if (this.from != null) c.from = this.from;
|
||||||
|
if (this.to != null) c.to = this.to;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
|
|
||||||
public String transformClass;
|
public String transformClass;
|
||||||
public String to;
|
public String to;
|
||||||
|
public String type;
|
||||||
public String initializer;
|
public String initializer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,10 +28,8 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
NewDataConfiguration that = (NewDataConfiguration) o;
|
NewDataConfiguration that = (NewDataConfiguration) o;
|
||||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to) && Objects.equals(
|
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to)
|
||||||
initializer,
|
&& Objects.equals(type, that.type) && Objects.equals(initializer, that.initializer);
|
||||||
that.initializer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,7 +37,19 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
|||||||
int hash = 0;
|
int hash = 0;
|
||||||
hash += ConfigUtils.hashCode(transformClass);
|
hash += ConfigUtils.hashCode(transformClass);
|
||||||
hash += ConfigUtils.hashCode(to);
|
hash += ConfigUtils.hashCode(to);
|
||||||
|
hash += ConfigUtils.hashCode(type);
|
||||||
hash += ConfigUtils.hashCode(initializer);
|
hash += ConfigUtils.hashCode(initializer);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public NewDataConfiguration clone() {
|
||||||
|
var c = new NewDataConfiguration();
|
||||||
|
if (this.transformClass != null) c.transformClass = this.transformClass;
|
||||||
|
if (this.initializer != null) c.initializer = this.initializer;
|
||||||
|
if (this.to != null) c.to = this.to;
|
||||||
|
if (this.type != null) c.type = this.type;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
package it.cavallium.data.generator;
|
||||||
|
|
||||||
|
import static it.cavallium.data.generator.DataModel.fixType;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public final class ParsedClass {
|
||||||
|
|
||||||
|
public String stringRepresenter;
|
||||||
|
|
||||||
|
public LinkedHashMap<String, String> data;
|
||||||
|
|
||||||
|
public ParsedClass(ClassConfiguration baseTypesData) {
|
||||||
|
this.stringRepresenter = baseTypesData.stringRepresenter;
|
||||||
|
if (baseTypesData.data != null) {
|
||||||
|
this.data = baseTypesData.data.entrySet().stream()
|
||||||
|
.map(e -> Map.entry(e.getKey(), fixType(e.getValue())))
|
||||||
|
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}, LinkedHashMap::new));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParsedClass() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringRepresenter() {
|
||||||
|
return stringRepresenter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LinkedHashMap<String, String> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParsedClass that = (ParsedClass) o;
|
||||||
|
return Objects.equals(stringRepresenter, that.stringRepresenter) && Objects.equals(data, that.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
hash += ConfigUtils.hashCode(stringRepresenter);
|
||||||
|
hash += ConfigUtils.hashCode(data);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public ParsedClass clone() {
|
||||||
|
var cc = new ParsedClass();
|
||||||
|
if (this.stringRepresenter != null) cc.stringRepresenter = this.stringRepresenter;
|
||||||
|
cc.data = new LinkedHashMap<>(data);
|
||||||
|
return cc;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package it.cavallium.data.generator;
|
||||||
|
|
||||||
|
import static it.cavallium.data.generator.DataModel.fixType;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ParsedInterface {
|
||||||
|
|
||||||
|
public Set<String> extendInterfaces = new HashSet<>();
|
||||||
|
public Map<String, String> commonData = new HashMap<>();
|
||||||
|
public Map<String, String> commonGetters = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParsedInterface that = (ParsedInterface) o;
|
||||||
|
return Objects.equals(extendInterfaces, that.extendInterfaces) && Objects.equals(commonData, that.commonData)
|
||||||
|
&& Objects.equals(commonGetters, that.commonGetters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
hash += ConfigUtils.hashCode(extendInterfaces);
|
||||||
|
hash += ConfigUtils.hashCode(commonData);
|
||||||
|
hash += ConfigUtils.hashCode(commonGetters);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParsedInterface(InterfaceDataConfiguration value) {
|
||||||
|
if (value.extendInterfaces != null) this.extendInterfaces = value.extendInterfaces;
|
||||||
|
if (value.commonData != null) {
|
||||||
|
this.commonData = value.commonData;
|
||||||
|
this.commonData.replaceAll((k, v) -> fixType(v));
|
||||||
|
}
|
||||||
|
if (value.commonGetters != null) {
|
||||||
|
this.commonGetters = value.commonGetters;
|
||||||
|
this.commonGetters.replaceAll((k, v) -> fixType(v));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package it.cavallium.data.generator;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class ParsedVersion {
|
||||||
|
|
||||||
|
public DetailsConfiguration details;
|
||||||
|
public List<VersionTransformation> transformations;
|
||||||
|
|
||||||
|
public ParsedVersion(VersionConfiguration versionConfiguration) {
|
||||||
|
this.details = versionConfiguration.details;
|
||||||
|
if (versionConfiguration.transformations != null) {
|
||||||
|
this.transformations = versionConfiguration.transformations.stream().map(VersionTransformation::clone).toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ParsedVersion() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParsedVersion that = (ParsedVersion) o;
|
||||||
|
return Objects.equals(details, that.details) && Objects.equals(transformations, that.transformations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 0;
|
||||||
|
hash += ConfigUtils.hashCode(details);
|
||||||
|
hash += ConfigUtils.hashCode(transformations);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
@ -36,4 +36,13 @@ public class RemoveDataConfiguration implements TransformationConfiguration {
|
|||||||
hash += ConfigUtils.hashCode(from);
|
hash += ConfigUtils.hashCode(from);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public RemoveDataConfiguration clone() {
|
||||||
|
var c = new RemoveDataConfiguration();
|
||||||
|
if (this.transformClass != null) c.transformClass = this.transformClass;
|
||||||
|
if (this.from != null) c.from = this.from;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,11 +73,12 @@ public class SourcesGenerator {
|
|||||||
private static final Logger logger = LoggerFactory.getLogger(SourcesGenerator.class);
|
private static final Logger logger = LoggerFactory.getLogger(SourcesGenerator.class);
|
||||||
private static final boolean OVERRIDE_ALL_NULLABLE_METHODS = false;
|
private static final boolean OVERRIDE_ALL_NULLABLE_METHODS = false;
|
||||||
|
|
||||||
private final SourcesGeneratorConfiguration configuration;
|
private final DataModel dataModel;
|
||||||
|
|
||||||
private SourcesGenerator(InputStream yamlDataStream) {
|
private SourcesGenerator(InputStream yamlDataStream) {
|
||||||
Yaml yaml = new Yaml();
|
Yaml yaml = new Yaml();
|
||||||
this.configuration = yaml.loadAs(yamlDataStream, SourcesGeneratorConfiguration.class);
|
var configuration = yaml.loadAs(yamlDataStream, SourcesGeneratorConfiguration.class);
|
||||||
|
this.dataModel = configuration.buildDataModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SourcesGenerator load(InputStream yamlData) {
|
public static SourcesGenerator load(InputStream yamlData) {
|
||||||
@ -111,7 +112,7 @@ public class SourcesGenerator {
|
|||||||
basePackageNamePath = basePackageNamePathPartial;
|
basePackageNamePath = basePackageNamePathPartial;
|
||||||
}
|
}
|
||||||
var hashPath = basePackageNamePath.resolve(".hash");
|
var hashPath = basePackageNamePath.resolve(".hash");
|
||||||
var curHash = computeHash(this.configuration);
|
var curHash = dataModel.computeHash();
|
||||||
if (Files.isRegularFile(hashPath) && Files.isReadable(hashPath)) {
|
if (Files.isRegularFile(hashPath) && Files.isReadable(hashPath)) {
|
||||||
var lines = Files.readAllLines(hashPath, StandardCharsets.UTF_8);
|
var lines = Files.readAllLines(hashPath, StandardCharsets.UTF_8);
|
||||||
if (lines.size() >= 3) {
|
if (lines.size() >= 3) {
|
||||||
@ -150,27 +151,6 @@ public class SourcesGenerator {
|
|||||||
StandardCharsets.UTF_8, TRUNCATE_EXISTING, WRITE, CREATE);
|
StandardCharsets.UTF_8, TRUNCATE_EXISTING, WRITE, CREATE);
|
||||||
markFileAsCreated(generatedFilesToDelete, outPath, hashPath);
|
markFileAsCreated(generatedFilesToDelete, outPath, hashPath);
|
||||||
|
|
||||||
// Fix the configuration
|
|
||||||
for (Entry<String, InterfaceDataConfiguration> interfacesDatum : configuration.interfacesData.entrySet()) {
|
|
||||||
String k = interfacesDatum.getKey();
|
|
||||||
InterfaceDataConfiguration value = interfacesDatum.getValue();
|
|
||||||
value.commonData.replaceAll((field, fieldType) -> fixType(fieldType));
|
|
||||||
}
|
|
||||||
for (Entry<String, InterfaceDataConfiguration> interfacesDatum : configuration.interfacesData.entrySet()) {
|
|
||||||
String name = interfacesDatum.getKey();
|
|
||||||
InterfaceDataConfiguration value = interfacesDatum.getValue();
|
|
||||||
value.commonGetters.replaceAll((field, fieldType) -> fixType(fieldType));
|
|
||||||
}
|
|
||||||
for (Entry<String, VersionConfiguration> stringVersionConfigurationEntry : configuration.versions.entrySet()) {
|
|
||||||
String k = stringVersionConfigurationEntry.getKey();
|
|
||||||
VersionConfiguration config = stringVersionConfigurationEntry.getValue();
|
|
||||||
for (Entry<String, ClassConfiguration> entry : config.classes.entrySet()) {
|
|
||||||
String clazz = entry.getKey();
|
|
||||||
ClassConfiguration classConfiguration = entry.getValue();
|
|
||||||
classConfiguration.getData().replaceAll((field, fieldType) -> fixType(fieldType));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the Versions class
|
// Create the Versions class
|
||||||
var versionsClass = TypeSpec.classBuilder("Versions");
|
var versionsClass = TypeSpec.classBuilder("Versions");
|
||||||
versionsClass.addModifiers(Modifier.PUBLIC);
|
versionsClass.addModifiers(Modifier.PUBLIC);
|
||||||
@ -182,21 +162,19 @@ public class SourcesGenerator {
|
|||||||
Modifier.FINAL
|
Modifier.FINAL
|
||||||
);
|
);
|
||||||
List<CodeBlock> versionsInstancesValue = new ArrayList<>();
|
List<CodeBlock> versionsInstancesValue = new ArrayList<>();
|
||||||
for (Entry<String, VersionConfiguration> stringVersionConfigurationEntry : configuration.versions.entrySet()) {
|
for (ComputedVersion value : dataModel.getVersionsSet()) {
|
||||||
String version = stringVersionConfigurationEntry.getKey();
|
|
||||||
VersionConfiguration value = stringVersionConfigurationEntry.getValue();
|
|
||||||
// Add a static variable for this version, containing the normalized version number
|
// Add a static variable for this version, containing the normalized version number
|
||||||
var versionNumberField = FieldSpec
|
var versionNumberField = FieldSpec
|
||||||
.builder(TypeName.INT, getVersionVarName(version))
|
.builder(TypeName.INT, getVersionVarName(value))
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addModifiers(Modifier.STATIC)
|
.addModifiers(Modifier.STATIC)
|
||||||
.addModifiers(Modifier.FINAL)
|
.addModifiers(Modifier.FINAL)
|
||||||
.initializer(getVersionShortInt(version))
|
.initializer(getVersionShortInt(value))
|
||||||
.build();
|
.build();
|
||||||
// Add the fields to the class
|
// Add the fields to the class
|
||||||
versionsClass.addField(versionNumberField);
|
versionsClass.addField(versionNumberField);
|
||||||
|
|
||||||
var versionPackage = getVersionPackage(configuration.currentVersion, basePackageName, version);
|
var versionPackage = value.getPackage(basePackageName);
|
||||||
var versionClassType = ClassName.get(joinPackage(versionPackage, ""), "Version");
|
var versionClassType = ClassName.get(joinPackage(versionPackage, ""), "Version");
|
||||||
|
|
||||||
versionsInstancesValue.add(CodeBlock.builder().add("$T.INSTANCE", versionClassType).build());
|
versionsInstancesValue.add(CodeBlock.builder().add("$T.INSTANCE", versionClassType).build());
|
||||||
@ -215,10 +193,8 @@ public class SourcesGenerator {
|
|||||||
{
|
{
|
||||||
var basicTypeClass = TypeSpec.enumBuilder("BasicType");
|
var basicTypeClass = TypeSpec.enumBuilder("BasicType");
|
||||||
basicTypeClass.addModifiers(Modifier.PUBLIC);
|
basicTypeClass.addModifiers(Modifier.PUBLIC);
|
||||||
for (Entry<String, VersionConfiguration> stringVersionConfigurationEntry : configuration.versions.entrySet()) {
|
for (var value : dataModel.getVersionsSet()) {
|
||||||
String k = stringVersionConfigurationEntry.getKey();
|
for (String basicTypeName : value.getClassMap().keySet()) {
|
||||||
VersionConfiguration value = stringVersionConfigurationEntry.getValue();
|
|
||||||
for (String basicTypeName : value.classes.keySet()) {
|
|
||||||
if (!basicTypeClass.enumConstants.containsKey(basicTypeName)) {
|
if (!basicTypeClass.enumConstants.containsKey(basicTypeName)) {
|
||||||
basicTypeClass.addEnumConstant(basicTypeName);
|
basicTypeClass.addEnumConstant(basicTypeName);
|
||||||
}
|
}
|
||||||
@ -232,10 +208,8 @@ public class SourcesGenerator {
|
|||||||
{
|
{
|
||||||
var genericTypeClass = TypeSpec.enumBuilder("GenericType");
|
var genericTypeClass = TypeSpec.enumBuilder("GenericType");
|
||||||
genericTypeClass.addModifiers(Modifier.PUBLIC);
|
genericTypeClass.addModifiers(Modifier.PUBLIC);
|
||||||
for (Entry<String, VersionConfiguration> stringVersionConfigurationEntry : configuration.versions.entrySet()) {
|
for (var value : dataModel.getVersionsSet()) {
|
||||||
String k = stringVersionConfigurationEntry.getKey();
|
for (String superTypeName : dataModel.getSuperTypes().keySet()) {
|
||||||
VersionConfiguration value = stringVersionConfigurationEntry.getValue();
|
|
||||||
for (String superTypeName : value.superTypes.keySet()) {
|
|
||||||
if (!genericTypeClass.enumConstants.containsKey(superTypeName)) {
|
if (!genericTypeClass.enumConstants.containsKey(superTypeName)) {
|
||||||
genericTypeClass.addEnumConstant(superTypeName);
|
genericTypeClass.addEnumConstant(superTypeName);
|
||||||
}
|
}
|
||||||
@ -298,6 +272,8 @@ public class SourcesGenerator {
|
|||||||
writeClass(generatedFilesToDelete, outPath, joinPackage(basePackageName, ""), iVersionClass);
|
writeClass(generatedFilesToDelete, outPath, joinPackage(basePackageName, ""), iVersionClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentVersionPackage = dataModel.getCurrentVersion().getPackage(basePackageName);
|
||||||
|
|
||||||
// Create the CurrentVersion class
|
// Create the CurrentVersion class
|
||||||
{
|
{
|
||||||
var currentVersionClass = TypeSpec.classBuilder("CurrentVersion");
|
var currentVersionClass = TypeSpec.classBuilder("CurrentVersion");
|
||||||
@ -306,10 +282,9 @@ public class SourcesGenerator {
|
|||||||
// Add a static variable for the current version
|
// Add a static variable for the current version
|
||||||
{
|
{
|
||||||
var versionNumberField = FieldSpec.builder(ClassName
|
var versionNumberField = FieldSpec.builder(ClassName
|
||||||
.get(getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion),
|
.get(dataModel.getCurrentVersion().getPackage(basePackageName),
|
||||||
"Version"), "VERSION").addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC)
|
"Version"), "VERSION").addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC)
|
||||||
.addModifiers(Modifier.FINAL).initializer(
|
.addModifiers(Modifier.FINAL).initializer("new " + dataModel.getCurrentVersion().getPackage(basePackageName)
|
||||||
"new " + getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion)
|
|
||||||
+ ".Version()").build();
|
+ ".Version()").build();
|
||||||
currentVersionClass.addField(versionNumberField);
|
currentVersionClass.addField(versionNumberField);
|
||||||
}
|
}
|
||||||
@ -327,21 +302,18 @@ public class SourcesGenerator {
|
|||||||
.addModifiers(Modifier.FINAL).addModifiers(Modifier.STATIC).returns(ParameterizedTypeName.get(
|
.addModifiers(Modifier.FINAL).addModifiers(Modifier.STATIC).returns(ParameterizedTypeName.get(
|
||||||
ClassName.get(Set.class), ParameterizedTypeName.get(
|
ClassName.get(Set.class), ParameterizedTypeName.get(
|
||||||
ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName
|
ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName
|
||||||
.get(joinPackage(getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion), "data"),
|
.get(joinPackage(currentVersionPackage, "data"),
|
||||||
"IType")))))
|
"IType")))))
|
||||||
.addCode("return $T.of(\n", Set.class);
|
.addCode("return $T.of(\n", Set.class);
|
||||||
AtomicBoolean isFirst = new AtomicBoolean(true);
|
AtomicBoolean isFirst = new AtomicBoolean(true);
|
||||||
for (Entry<String, Set<String>> entry : configuration.versions.get(configuration.currentVersion).superTypes.entrySet()) {
|
for (Entry<String, Set<String>> entry : dataModel.getSuperTypes().entrySet()) {
|
||||||
String superTypeName = entry.getKey();
|
String superTypeName = entry.getKey();
|
||||||
Set<String> superTypeConfig = entry.getValue();
|
Set<String> superTypeConfig = entry.getValue();
|
||||||
if (!isFirst.getAndSet(false)) {
|
if (!isFirst.getAndSet(false)) {
|
||||||
getSuperTypeClasses.addCode(",\n");
|
getSuperTypeClasses.addCode(",\n");
|
||||||
}
|
}
|
||||||
getSuperTypeClasses.addCode("$T.class",
|
getSuperTypeClasses.addCode("$T.class",
|
||||||
ClassName.get(joinPackage(getVersionPackage(configuration.currentVersion,
|
ClassName.get(joinPackage(currentVersionPackage, "data"), superTypeName)
|
||||||
basePackageName,
|
|
||||||
configuration.currentVersion
|
|
||||||
), "data"), superTypeName)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
getSuperTypeClasses.addCode("\n);");
|
getSuperTypeClasses.addCode("\n);");
|
||||||
@ -353,20 +325,17 @@ public class SourcesGenerator {
|
|||||||
.addModifiers(Modifier.FINAL).addModifiers(Modifier.STATIC).returns(ParameterizedTypeName.get(
|
.addModifiers(Modifier.FINAL).addModifiers(Modifier.STATIC).returns(ParameterizedTypeName.get(
|
||||||
ClassName.get(Set.class), ParameterizedTypeName.get(
|
ClassName.get(Set.class), ParameterizedTypeName.get(
|
||||||
ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName
|
ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName
|
||||||
.get(joinPackage(getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion), "data"),
|
.get(joinPackage(currentVersionPackage, "data"),
|
||||||
"IBasicType")))));
|
"IBasicType")))));
|
||||||
getSuperTypeSubtypesClasses.addParameter(ParameterSpec.builder(ParameterizedTypeName.get(ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName
|
getSuperTypeSubtypesClasses.addParameter(ParameterSpec.builder(ParameterizedTypeName.get(ClassName.get(Class.class), WildcardTypeName.subtypeOf(ClassName
|
||||||
.get(joinPackage(getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion), "data"),
|
.get(joinPackage(currentVersionPackage, "data"),
|
||||||
"IType"))), "superTypeClass").build());
|
"IType"))), "superTypeClass").build());
|
||||||
getSuperTypeSubtypesClasses.beginControlFlow("switch (superTypeClass.getCanonicalName())");
|
getSuperTypeSubtypesClasses.beginControlFlow("switch (superTypeClass.getCanonicalName())");
|
||||||
for (Entry<String, Set<String>> entry : configuration.versions.get(configuration.currentVersion).superTypes.entrySet()) {
|
for (Entry<String, Set<String>> entry : dataModel.getSuperTypes().entrySet()) {
|
||||||
String superTypeName = entry.getKey();
|
String superTypeName = entry.getKey();
|
||||||
Set<String> subTypes = entry.getValue();
|
Set<String> subTypes = entry.getValue();
|
||||||
getSuperTypeSubtypesClasses.beginControlFlow("case \"" + ClassName
|
getSuperTypeSubtypesClasses.beginControlFlow("case \"" + ClassName
|
||||||
.get(joinPackage(getVersionPackage(configuration.currentVersion,
|
.get(joinPackage(currentVersionPackage, "data"), superTypeName)
|
||||||
basePackageName,
|
|
||||||
configuration.currentVersion
|
|
||||||
), "data"), superTypeName)
|
|
||||||
.canonicalName() + "\":");
|
.canonicalName() + "\":");
|
||||||
getSuperTypeSubtypesClasses.addCode("return $T.of(\n", Set.class);
|
getSuperTypeSubtypesClasses.addCode("return $T.of(\n", Set.class);
|
||||||
AtomicBoolean isFirst = new AtomicBoolean(true);
|
AtomicBoolean isFirst = new AtomicBoolean(true);
|
||||||
@ -375,10 +344,7 @@ public class SourcesGenerator {
|
|||||||
getSuperTypeSubtypesClasses.addCode(",\n");
|
getSuperTypeSubtypesClasses.addCode(",\n");
|
||||||
}
|
}
|
||||||
getSuperTypeSubtypesClasses.addCode("$T.class",
|
getSuperTypeSubtypesClasses.addCode("$T.class",
|
||||||
ClassName.get(joinPackage(getVersionPackage(configuration.currentVersion,
|
ClassName.get(joinPackage(currentVersionPackage, "data"), subTypeName)
|
||||||
basePackageName,
|
|
||||||
configuration.currentVersion
|
|
||||||
), "data"), subTypeName)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
getSuperTypeSubtypesClasses.addCode("\n);\n");
|
getSuperTypeSubtypesClasses.addCode("\n);\n");
|
||||||
@ -393,7 +359,7 @@ public class SourcesGenerator {
|
|||||||
// UpgradeDataToLatestVersion1 Method
|
// UpgradeDataToLatestVersion1 Method
|
||||||
{
|
{
|
||||||
var upgradeDataToLatestVersion1MethodBuilder = MethodSpec.methodBuilder("upgradeDataToLatestVersion").addTypeVariable(TypeVariableName.get("U", ClassName
|
var upgradeDataToLatestVersion1MethodBuilder = MethodSpec.methodBuilder("upgradeDataToLatestVersion").addTypeVariable(TypeVariableName.get("U", ClassName
|
||||||
.get(joinPackage(getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion), "data"),
|
.get(joinPackage(currentVersionPackage, "data"),
|
||||||
"IBasicType")))
|
"IBasicType")))
|
||||||
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).returns(TypeVariableName.get("U"))
|
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).returns(TypeVariableName.get("U"))
|
||||||
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()).addParameter(
|
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()).addParameter(
|
||||||
@ -401,20 +367,16 @@ public class SourcesGenerator {
|
|||||||
.addParameter(ParameterSpec.builder(DataInput.class, "oldDataInput").build())
|
.addParameter(ParameterSpec.builder(DataInput.class, "oldDataInput").build())
|
||||||
.addException(IOException.class).beginControlFlow("switch (oldVersion)");
|
.addException(IOException.class).beginControlFlow("switch (oldVersion)");
|
||||||
AtomicInteger seqNumber = new AtomicInteger(0);
|
AtomicInteger seqNumber = new AtomicInteger(0);
|
||||||
for (Entry<String, VersionConfiguration> entry : configuration.versions.entrySet()) {
|
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
||||||
String version = entry.getKey();
|
|
||||||
VersionConfiguration versionConfiguration = entry.getValue();
|
|
||||||
// Add a case in which the data version deserializes the serialized data and upgrades it
|
// Add a case in which the data version deserializes the serialized data and upgrades it
|
||||||
upgradeDataToLatestVersion1MethodBuilder.beginControlFlow("case $T." + getVersionVarName(version) + ":",
|
upgradeDataToLatestVersion1MethodBuilder.beginControlFlow("case $T." + versionConfiguration.getVersionVarName() + ":",
|
||||||
ClassName.get(joinPackage(basePackageName, ""), "Versions")
|
ClassName.get(joinPackage(basePackageName, ""), "Versions")
|
||||||
);
|
);
|
||||||
|
upgradeDataToLatestVersion1MethodBuilder.addStatement("var deserialized" + seqNumber.incrementAndGet() + " = "
|
||||||
|
+ versionConfiguration.getPackage(basePackageName)
|
||||||
|
+ ".Version.INSTANCE.getSerializer(type).deserialize(oldDataInput)");
|
||||||
upgradeDataToLatestVersion1MethodBuilder.addStatement(
|
upgradeDataToLatestVersion1MethodBuilder.addStatement(
|
||||||
"var deserialized" + seqNumber.incrementAndGet() + " = " + getVersionPackage(configuration.currentVersion,
|
"return upgradeDataToLatestVersion(Versions." + versionConfiguration.getVersionVarName() + ", deserialized"
|
||||||
basePackageName,
|
|
||||||
version
|
|
||||||
) + ".Version.INSTANCE.getSerializer(type).deserialize(oldDataInput)");
|
|
||||||
upgradeDataToLatestVersion1MethodBuilder.addStatement(
|
|
||||||
"return upgradeDataToLatestVersion(Versions." + getVersionVarName(version) + ", deserialized"
|
|
||||||
+ seqNumber.get() + ")");
|
+ seqNumber.get() + ")");
|
||||||
upgradeDataToLatestVersion1MethodBuilder.endControlFlow();
|
upgradeDataToLatestVersion1MethodBuilder.endControlFlow();
|
||||||
}
|
}
|
||||||
@ -429,7 +391,7 @@ public class SourcesGenerator {
|
|||||||
var upgradeDataToLatestVersion2MethodBuilder = MethodSpec.methodBuilder("upgradeDataToLatestVersion")
|
var upgradeDataToLatestVersion2MethodBuilder = MethodSpec.methodBuilder("upgradeDataToLatestVersion")
|
||||||
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).addTypeVariable(TypeVariableName.get("T"))
|
.addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).addTypeVariable(TypeVariableName.get("T"))
|
||||||
.addTypeVariable(TypeVariableName.get("U", ClassName
|
.addTypeVariable(TypeVariableName.get("U", ClassName
|
||||||
.get(joinPackage(getVersionPackage(configuration.currentVersion, basePackageName, configuration.currentVersion), "data"),
|
.get(joinPackage(currentVersionPackage, "data"),
|
||||||
"IBasicType"))).returns(TypeVariableName.get("U"))
|
"IBasicType"))).returns(TypeVariableName.get("U"))
|
||||||
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build())
|
.addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build())
|
||||||
.addParameter(ParameterSpec.builder(TypeVariableName.get("T"), "oldData").build())
|
.addParameter(ParameterSpec.builder(TypeVariableName.get("T"), "oldData").build())
|
||||||
@ -438,28 +400,26 @@ public class SourcesGenerator {
|
|||||||
.addStatement("$T intermediateData = oldData", Object.class)
|
.addStatement("$T intermediateData = oldData", Object.class)
|
||||||
.beginControlFlow("while (true)")
|
.beginControlFlow("while (true)")
|
||||||
.beginControlFlow("switch (intermediateVersion)");
|
.beginControlFlow("switch (intermediateVersion)");
|
||||||
for (Entry<String, VersionConfiguration> entry : configuration.versions.entrySet()) {
|
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
||||||
String version = entry.getKey();
|
|
||||||
VersionConfiguration versionConfiguration = entry.getValue();
|
|
||||||
// Add a case in which the data version deserializes the serialized data and upgrades it
|
// Add a case in which the data version deserializes the serialized data and upgrades it
|
||||||
upgradeDataToLatestVersion2MethodBuilder.beginControlFlow("case $T." + getVersionVarName(version) + ":",
|
upgradeDataToLatestVersion2MethodBuilder.beginControlFlow("case $T." + versionConfiguration.getVersionVarName() + ":",
|
||||||
versionsClassName
|
versionsClassName
|
||||||
);
|
);
|
||||||
if (version.equalsIgnoreCase(configuration.currentVersion)) {
|
if (versionConfiguration.isCurrent()) {
|
||||||
// This is the latest version, don't upgrade.
|
// This is the latest version, don't upgrade.
|
||||||
upgradeDataToLatestVersion2MethodBuilder.addStatement("return ($T) intermediateData", TypeVariableName.get("U"));
|
upgradeDataToLatestVersion2MethodBuilder.addStatement("return ($T) intermediateData", TypeVariableName.get("U"));
|
||||||
} else {
|
} else {
|
||||||
// Upgrade
|
// Upgrade
|
||||||
upgradeDataToLatestVersion2MethodBuilder
|
upgradeDataToLatestVersion2MethodBuilder
|
||||||
.addStatement(
|
.addStatement(
|
||||||
"intermediateData = " + getVersionPackage(configuration.currentVersion, basePackageName, version)
|
"intermediateData = " + versionConfiguration.getPackage(basePackageName)
|
||||||
+ ".Version.upgradeToNextVersion(($T) intermediateData)",
|
+ ".Version.upgradeToNextVersion(($T) intermediateData)",
|
||||||
ClassName.get(joinPackage(getVersionPackage(configuration.currentVersion, basePackageName, version),
|
ClassName.get(joinPackage(versionConfiguration.getPackage (basePackageName),
|
||||||
"data"
|
"data"
|
||||||
), "IBasicType")
|
), "IBasicType")
|
||||||
)
|
)
|
||||||
.addStatement("intermediateVersion = $T."
|
.addStatement("intermediateVersion = $T."
|
||||||
+ getVersionVarName(findNextVersion(configuration, version).orElseThrow()), versionsClassName)
|
+ getVersionVarName(dataModel.getNextVersionOrThrow(versionConfiguration)), versionsClassName)
|
||||||
.addStatement("break");
|
.addStatement("break");
|
||||||
}
|
}
|
||||||
upgradeDataToLatestVersion2MethodBuilder.endControlFlow();
|
upgradeDataToLatestVersion2MethodBuilder.endControlFlow();
|
||||||
@ -475,21 +435,16 @@ public class SourcesGenerator {
|
|||||||
writeClass(generatedFilesToDelete, outPath, joinPackage(basePackageName, "current"), currentVersionClass);
|
writeClass(generatedFilesToDelete, outPath, joinPackage(basePackageName, "current"), currentVersionClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entry<String, VersionConfiguration> mapEntry : configuration.versions.entrySet()) {
|
for (var versionConfiguration : dataModel.getVersionsSet()) {
|
||||||
String version = mapEntry.getKey();
|
var versionPackage = versionConfiguration.getPackage(basePackageName);
|
||||||
VersionConfiguration versionConfiguration = mapEntry.getValue();
|
|
||||||
var versionPackage = getVersionPackage(configuration.currentVersion, basePackageName, version);
|
|
||||||
var versionClassType = ClassName.get(joinPackage(versionPackage, ""), "Version");
|
var versionClassType = ClassName.get(joinPackage(versionPackage, ""), "Version");
|
||||||
var nextVersion = findNextVersion(configuration, version);
|
var nextVersion = dataModel.getNextVersion(versionConfiguration);
|
||||||
var nextVersionPackage = nextVersion.map((nextVersionValue) -> getVersionPackage(configuration.currentVersion,
|
var nextVersionPackage = nextVersion.map((nextVersionValue) -> nextVersionValue.getPackage(basePackageName));
|
||||||
basePackageName,
|
|
||||||
nextVersionValue
|
|
||||||
));
|
|
||||||
|
|
||||||
logger.info(
|
logger.info("Found version configuration:\n{\n\tversion: \"" + versionConfiguration.getName()
|
||||||
"Found version configuration:\n{\n\tversion: \"" + version + "\",\n\tversionPackage: \"" + versionPackage
|
+ "\",\n\tversionPackage: \"" + versionPackage + "\",\n\tnextVersion: \"" + nextVersion
|
||||||
+ "\",\n\tnextVersion: \"" + nextVersion.orElse("unknown") + "\",\n\tnextVersionPackage: \""
|
.map(ComputedVersion::getName)
|
||||||
+ nextVersionPackage.orElse("unknown") + "\"\n}");
|
.orElse("unknown") + "\",\n\tnextVersionPackage: \"" + nextVersionPackage.orElse("unknown") + "\"\n}");
|
||||||
|
|
||||||
HashMap<String, TypeName> typeOptionalSerializers = new LinkedHashMap<>();
|
HashMap<String, TypeName> typeOptionalSerializers = new LinkedHashMap<>();
|
||||||
HashMap<String, TypeName> typeOptionalUpgraders = new LinkedHashMap<>();
|
HashMap<String, TypeName> typeOptionalUpgraders = new LinkedHashMap<>();
|
||||||
@ -702,7 +657,7 @@ public class SourcesGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup only the basic types upgraders variables
|
// Setup only the basic types upgraders variables
|
||||||
for (String s : versionConfiguration.classes.keySet()) {
|
for (String s : versionConfiguration.getClassMap().keySet()) {
|
||||||
if (nextVersion.isPresent()) {
|
if (nextVersion.isPresent()) {
|
||||||
typeOptionalUpgraders.put(s, ClassName.get(joinPackage(versionPackage, "upgraders"), s + "Upgrader"));
|
typeOptionalUpgraders.put(s, ClassName.get(joinPackage(versionPackage, "upgraders"), s + "Upgrader"));
|
||||||
}
|
}
|
||||||
@ -710,9 +665,9 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// Generate the basic and super types
|
// Generate the basic and super types
|
||||||
Stream
|
Stream
|
||||||
.concat(versionConfiguration.classes.keySet().stream(), versionConfiguration.superTypes.keySet().stream())
|
.concat(versionConfiguration.getClassMap().keySet().stream(), dataModel.getSuperTypes().keySet().stream())
|
||||||
.forEach((type) -> {
|
.forEach((type) -> {
|
||||||
boolean isBasic = versionConfiguration.classes.containsKey(type);
|
boolean isBasic = versionConfiguration.getClassMap().containsKey(type);
|
||||||
typeOptionalSerializers.put(type,
|
typeOptionalSerializers.put(type,
|
||||||
ClassName.get(joinPackage(versionPackage, "serializers"), type + "Serializer")
|
ClassName.get(joinPackage(versionPackage, "serializers"), type + "Serializer")
|
||||||
);
|
);
|
||||||
@ -757,11 +712,11 @@ public class SourcesGenerator {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Generate the special types
|
// Generate the special types
|
||||||
for (Entry<String, CustomTypesConfiguration> entry : versionConfiguration.customTypes.entrySet()) {
|
for (Entry<String, CustomTypesConfiguration> entry : dataModel.getCustomTypes().entrySet()) {
|
||||||
String key = entry.getKey();
|
String key = entry.getKey();
|
||||||
CustomTypesConfiguration customTypeConfiguration = entry.getValue();
|
CustomTypesConfiguration customTypeConfiguration = entry.getValue();
|
||||||
Optional<CustomTypesConfiguration> nextVersionCustomTypeConfiguration = nextVersion
|
Optional<CustomTypesConfiguration> nextVersionCustomTypeConfiguration = nextVersion
|
||||||
.map(s -> Objects.requireNonNull(configuration.versions.get(s).customTypes.get(key),
|
.map(s -> Objects.requireNonNull(dataModel.getCustomTypes().get(key),
|
||||||
() -> "Custom type " + key + " not found in version " + s
|
() -> "Custom type " + key + " not found in version " + s
|
||||||
));
|
));
|
||||||
typeOptionalSerializers.put(key, ClassName.bestGuess(customTypeConfiguration.serializer));
|
typeOptionalSerializers.put(key, ClassName.bestGuess(customTypeConfiguration.serializer));
|
||||||
@ -825,16 +780,16 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// Check if all types exist
|
// Check if all types exist
|
||||||
{
|
{
|
||||||
for (Entry<String, ClassConfiguration> e : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> e : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String type = e.getKey();
|
String type = e.getKey();
|
||||||
ClassConfiguration typeConfig = e.getValue();
|
ParsedClass typeConfig = e.getValue();
|
||||||
for (Entry<String, String> entry : typeConfig.data.entrySet()) {
|
for (Entry<String, String> entry : typeConfig.data.entrySet()) {
|
||||||
String field = entry.getKey();
|
String field = entry.getKey();
|
||||||
String fieldType = entry.getValue();
|
String fieldType = entry.getValue();
|
||||||
if (!typeTypes.containsKey(fieldType)) {
|
if (!typeTypes.containsKey(fieldType)) {
|
||||||
throw new UnsupportedOperationException(
|
throw new UnsupportedOperationException(
|
||||||
"Unknown type '" + fieldType + "' of field '" + field + "' in class '" + type + "' in version '"
|
"Unknown type '" + fieldType + "' of field '" + field + "' in class '" + type + "' in version '"
|
||||||
+ version + "'");
|
+ versionConfiguration.getName() + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1187,9 +1142,9 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// Generate the basic types serializers
|
// Generate the basic types serializers
|
||||||
{
|
{
|
||||||
for (Entry<String, ClassConfiguration> classConfigurationEntry : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> classConfigurationEntry : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String type = classConfigurationEntry.getKey();
|
String type = classConfigurationEntry.getKey();
|
||||||
ClassConfiguration basicTypeConfiguration = classConfigurationEntry.getValue();
|
ParsedClass basicTypeConfiguration = classConfigurationEntry.getValue();
|
||||||
var classType = ClassName.get(joinPackage(versionPackage, "data"), type);
|
var classType = ClassName.get(joinPackage(versionPackage, "data"), type);
|
||||||
|
|
||||||
// Create the basic X serializer class
|
// Create the basic X serializer class
|
||||||
@ -1313,7 +1268,7 @@ public class SourcesGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<VersionTransformation> list = new ArrayList<>();
|
List<VersionTransformation> list = new ArrayList<>();
|
||||||
for (VersionTransformation versionTransformation : configuration.versions.get(nextVersion.get()).transformations) {
|
for (VersionTransformation versionTransformation : nextVersion.get().transformations) {
|
||||||
if (versionTransformation.isForClass(type)) {
|
if (versionTransformation.isForClass(type)) {
|
||||||
list.add(versionTransformation);
|
list.add(versionTransformation);
|
||||||
}
|
}
|
||||||
@ -1321,9 +1276,9 @@ public class SourcesGenerator {
|
|||||||
var transformations = Collections.unmodifiableList(list);
|
var transformations = Collections.unmodifiableList(list);
|
||||||
AtomicInteger transformationNumber = new AtomicInteger(0);
|
AtomicInteger transformationNumber = new AtomicInteger(0);
|
||||||
HashMap<String, TypeName> currentTransformedFieldTypes = new HashMap<>();
|
HashMap<String, TypeName> currentTransformedFieldTypes = new HashMap<>();
|
||||||
for (Entry<String, ClassConfiguration> stringClassConfigurationEntry : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> stringClassConfigurationEntry : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String className = stringClassConfigurationEntry.getKey();
|
String className = stringClassConfigurationEntry.getKey();
|
||||||
ClassConfiguration classConfiguration = stringClassConfigurationEntry.getValue();
|
ParsedClass classConfiguration = stringClassConfigurationEntry.getValue();
|
||||||
for (Entry<String, String> entry : classConfiguration.getData().entrySet()) {
|
for (Entry<String, String> entry : classConfiguration.getData().entrySet()) {
|
||||||
String fieldName = entry.getKey();
|
String fieldName = entry.getKey();
|
||||||
String fieldType = entry.getValue();
|
String fieldType = entry.getValue();
|
||||||
@ -1400,11 +1355,17 @@ public class SourcesGenerator {
|
|||||||
TypeName fromType = currentTransformedFieldTypes.get(
|
TypeName fromType = currentTransformedFieldTypes.get(
|
||||||
upgradeDataTransformation.transformClass + "." + upgradeDataTransformation.from);
|
upgradeDataTransformation.transformClass + "." + upgradeDataTransformation.from);
|
||||||
TypeName fromTypeBoxed = fromType.isPrimitive() ? fromType.box() : fromType;
|
TypeName fromTypeBoxed = fromType.isPrimitive() ? fromType.box() : fromType;
|
||||||
String toTypeName = configuration.versions.get(nextVersion.get()).classes
|
String toTypeName = nextVersion.get().getClassMap()
|
||||||
.get(upgradeDataTransformation.transformClass)
|
.get(upgradeDataTransformation.transformClass)
|
||||||
.getData()
|
.getData()
|
||||||
.get(upgradeDataTransformation.from);
|
.get(upgradeDataTransformation.from);
|
||||||
TypeName toType = nextVersionTypeTypes.get(toTypeName);
|
TypeName toType = nextVersionTypeTypes.get(toTypeName);
|
||||||
|
if (toType == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Type " + toTypeName + " does not exist in version " + nextVersion
|
||||||
|
.map(ComputedVersion::getName)
|
||||||
|
.orElse("---"));
|
||||||
|
}
|
||||||
TypeName toTypeBoxed = toType.isPrimitive() ? toType.box() : toType;
|
TypeName toTypeBoxed = toType.isPrimitive() ? toType.box() : toType;
|
||||||
deserializeMethod.addStatement(
|
deserializeMethod.addStatement(
|
||||||
"$T $$field$$" + (currentVarNumber.getInt(upgradeDataTransformation.from) + 1) + "$$"
|
"$T $$field$$" + (currentVarNumber.getInt(upgradeDataTransformation.from) + 1) + "$$"
|
||||||
@ -1454,13 +1415,13 @@ public class SourcesGenerator {
|
|||||||
}
|
}
|
||||||
case "new-data" -> {
|
case "new-data" -> {
|
||||||
var newDataTransformation = (NewDataConfiguration) transformation;
|
var newDataTransformation = (NewDataConfiguration) transformation;
|
||||||
String newTypeName = configuration.versions.get(nextVersion.get()).classes
|
String newTypeName = nextVersion.get().getClassMap()
|
||||||
.get(newDataTransformation.transformClass)
|
.get(newDataTransformation.transformClass)
|
||||||
.getData()
|
.getData()
|
||||||
.get(newDataTransformation.to);
|
.get(newDataTransformation.to);
|
||||||
TypeName newType = nextVersionTypeTypes.get(newTypeName);
|
TypeName newType = nextVersionTypeTypes.get(newTypeName);
|
||||||
Objects.requireNonNull(newType,
|
Objects.requireNonNull(newType,
|
||||||
() -> "Type \"" + newTypeName + "\" is not present from next version " + version
|
() -> "Type \"" + newTypeName + "\" is not present from next version " + versionConfiguration.getName()
|
||||||
+ " to version " + nextVersion.get() + " in upgrader "
|
+ " to version " + nextVersion.get() + " in upgrader "
|
||||||
+ newDataTransformation.transformClass + "." + newDataTransformation.to
|
+ newDataTransformation.transformClass + "." + newDataTransformation.to
|
||||||
);
|
);
|
||||||
@ -1515,7 +1476,7 @@ public class SourcesGenerator {
|
|||||||
deserializeMethod.addComment(
|
deserializeMethod.addComment(
|
||||||
"Upgrade the remaining untouched values to the new version before returning");
|
"Upgrade the remaining untouched values to the new version before returning");
|
||||||
|
|
||||||
var nextVersionFieldTypes = configuration.versions.get(nextVersion.get()).classes.get(type).getData();
|
var nextVersionFieldTypes = nextVersion.get().getClassMap().get(type).getData();
|
||||||
for (var e : currentVarNumber.object2IntEntrySet()) {
|
for (var e : currentVarNumber.object2IntEntrySet()) {
|
||||||
String key = e.getKey();
|
String key = e.getKey();
|
||||||
int number = e.getIntValue();
|
int number = e.getIntValue();
|
||||||
@ -1611,8 +1572,8 @@ public class SourcesGenerator {
|
|||||||
if (currentVarNumber.getInt(field) < 0) {
|
if (currentVarNumber.getInt(field) < 0) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Field " + field + " in class " + type + " has an invalid var number ("
|
"Field " + field + " in class " + type + " has an invalid var number ("
|
||||||
+ currentVarNumber.getInt(field) + ") after upgrading from version " + version
|
+ currentVarNumber.getInt(field) + ") after upgrading from version " + versionConfiguration.getName()
|
||||||
+ " to version " + nextVersion.orElse("---"));
|
+ " to version " + nextVersion.map(ComputedVersion::getName).orElse("---"));
|
||||||
}
|
}
|
||||||
deserializeMethod.addCode("$$field$$" + currentVarNumber.getInt(field) + "$$" + field);
|
deserializeMethod.addCode("$$field$$" + currentVarNumber.getInt(field) + "$$" + field);
|
||||||
}
|
}
|
||||||
@ -1633,7 +1594,7 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// Generate the super types serializers
|
// Generate the super types serializers
|
||||||
{
|
{
|
||||||
for (Entry<String, Set<String>> entry : versionConfiguration.superTypes.entrySet()) {
|
for (Entry<String, Set<String>> entry : dataModel.getSuperTypes().entrySet()) {
|
||||||
String type = entry.getKey();
|
String type = entry.getKey();
|
||||||
Set<String> superTypeConfiguration = entry.getValue();
|
Set<String> superTypeConfiguration = entry.getValue();
|
||||||
var classType = ClassName.get(joinPackage(versionPackage, "data"), type);
|
var classType = ClassName.get(joinPackage(versionPackage, "data"), type);
|
||||||
@ -1753,7 +1714,7 @@ public class SourcesGenerator {
|
|||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addModifiers(Modifier.STATIC)
|
.addModifiers(Modifier.STATIC)
|
||||||
.addModifiers(Modifier.FINAL)
|
.addModifiers(Modifier.FINAL)
|
||||||
.initializer("$T." + getVersionVarName(version),
|
.initializer("$T." + versionConfiguration.getVersionVarName(),
|
||||||
ClassName.get(joinPackage(basePackageName, ""), "Versions")
|
ClassName.get(joinPackage(basePackageName, ""), "Versions")
|
||||||
)
|
)
|
||||||
.build();
|
.build();
|
||||||
@ -1826,9 +1787,9 @@ public class SourcesGenerator {
|
|||||||
.builder(ClassName.get(joinPackage(versionPackage, "data"), "IBasicType"), "oldData")
|
.builder(ClassName.get(joinPackage(versionPackage, "data"), "IBasicType"), "oldData")
|
||||||
.build())
|
.build())
|
||||||
.beginControlFlow("switch (oldData.getBasicType$$()) ");
|
.beginControlFlow("switch (oldData.getBasicType$$()) ");
|
||||||
for (Entry<String, ClassConfiguration> entry : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> entry : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String type = entry.getKey();
|
String type = entry.getKey();
|
||||||
ClassConfiguration typeConfiguration = entry.getValue();
|
ParsedClass typeConfiguration = entry.getValue();
|
||||||
var data = typeConfiguration.data;
|
var data = typeConfiguration.data;
|
||||||
upgradeToNextVersionMethodBuilder.addStatement(
|
upgradeToNextVersionMethodBuilder.addStatement(
|
||||||
"case " + type + ": return $T." + type + "UpgraderInstance.upgrade(($T) oldData)",
|
"case " + type + ": return $T." + type + "UpgraderInstance.upgrade(($T) oldData)",
|
||||||
@ -1858,9 +1819,9 @@ public class SourcesGenerator {
|
|||||||
.builder(ClassName.get(joinPackage(basePackageName, ""), "BasicType"), "type")
|
.builder(ClassName.get(joinPackage(basePackageName, ""), "BasicType"), "type")
|
||||||
.build())
|
.build())
|
||||||
.beginControlFlow("switch (type)");
|
.beginControlFlow("switch (type)");
|
||||||
for (Entry<String, ClassConfiguration> entry : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> entry : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String type = entry.getKey();
|
String type = entry.getKey();
|
||||||
ClassConfiguration typeConfiguration = entry.getValue();
|
ParsedClass typeConfiguration = entry.getValue();
|
||||||
var data = typeConfiguration.data;
|
var data = typeConfiguration.data;
|
||||||
|
|
||||||
getClassMethodBuilder.addStatement("case " + type + ": return $T.class",
|
getClassMethodBuilder.addStatement("case " + type + ": return $T.class",
|
||||||
@ -1889,9 +1850,9 @@ public class SourcesGenerator {
|
|||||||
.builder(ClassName.get(joinPackage(basePackageName, ""), "BasicType"), "type")
|
.builder(ClassName.get(joinPackage(basePackageName, ""), "BasicType"), "type")
|
||||||
.build())
|
.build())
|
||||||
.beginControlFlow("switch (type)");
|
.beginControlFlow("switch (type)");
|
||||||
for (Entry<String, ClassConfiguration> entry : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> entry : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String type = entry.getKey();
|
String type = entry.getKey();
|
||||||
ClassConfiguration typeConfiguration = entry.getValue();
|
ParsedClass typeConfiguration = entry.getValue();
|
||||||
var data = typeConfiguration.data;
|
var data = typeConfiguration.data;
|
||||||
getSerializerMethodBuilder.addStatement("case " + type + ": return ($T) $T." + type + "SerializerInstance",
|
getSerializerMethodBuilder.addStatement("case " + type + ": return ($T) $T." + type + "SerializerInstance",
|
||||||
ParameterizedTypeName.get(ClassName.get(DataSerializer.class), TypeVariableName.get("T")),
|
ParameterizedTypeName.get(ClassName.get(DataSerializer.class), TypeVariableName.get("T")),
|
||||||
@ -2131,7 +2092,7 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// Create the interfaces
|
// Create the interfaces
|
||||||
{
|
{
|
||||||
for (Entry<String, Set<String>> superType : versionConfiguration.superTypes.entrySet()) {
|
for (Entry<String, Set<String>> superType : dataModel.getSuperTypes().entrySet()) {
|
||||||
String type = superType.getKey();
|
String type = superType.getKey();
|
||||||
Set<String> superTypeConfiguration = superType.getValue();
|
Set<String> superTypeConfiguration = superType.getValue();
|
||||||
var iBasicTypeInterfaceType = ClassName.get(joinPackage(versionPackage, "data"), "IBasicType");
|
var iBasicTypeInterfaceType = ClassName.get(joinPackage(versionPackage, "data"), "IBasicType");
|
||||||
@ -2154,7 +2115,7 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// If it's the latest version, add the common methods
|
// If it's the latest version, add the common methods
|
||||||
if (nextVersion.isEmpty()) {
|
if (nextVersion.isEmpty()) {
|
||||||
var interfaceDataConfiguration = configuration.interfacesData.get(type);
|
var interfaceDataConfiguration = dataModel.getInterfaces().get(type);
|
||||||
if (interfaceDataConfiguration != null) {
|
if (interfaceDataConfiguration != null) {
|
||||||
// Extend this interface
|
// Extend this interface
|
||||||
for (String extendedInterface : interfaceDataConfiguration.extendInterfaces) {
|
for (String extendedInterface : interfaceDataConfiguration.extendInterfaces) {
|
||||||
@ -2218,9 +2179,9 @@ public class SourcesGenerator {
|
|||||||
|
|
||||||
// Create the basic types classes
|
// Create the basic types classes
|
||||||
{
|
{
|
||||||
for (Entry<String, ClassConfiguration> stringClassConfigurationEntry : versionConfiguration.classes.entrySet()) {
|
for (Entry<String, ParsedClass> stringClassConfigurationEntry : versionConfiguration.getClassMap().entrySet()) {
|
||||||
String type = stringClassConfigurationEntry.getKey();
|
String type = stringClassConfigurationEntry.getKey();
|
||||||
ClassConfiguration classConfiguration = stringClassConfigurationEntry.getValue();
|
ParsedClass classConfiguration = stringClassConfigurationEntry.getValue();
|
||||||
var typeClass = TypeSpec.recordBuilder(type);
|
var typeClass = TypeSpec.recordBuilder(type);
|
||||||
typeClass.addModifiers(Modifier.PUBLIC);
|
typeClass.addModifiers(Modifier.PUBLIC);
|
||||||
typeClass.addModifiers(Modifier.STATIC);
|
typeClass.addModifiers(Modifier.STATIC);
|
||||||
@ -2237,7 +2198,7 @@ public class SourcesGenerator {
|
|||||||
.returns(ClassName.get(joinPackage(basePackageName, ""), "BasicType"))
|
.returns(ClassName.get(joinPackage(basePackageName, ""), "BasicType"))
|
||||||
.addStatement("return $T." + type, ClassName.get(joinPackage(basePackageName, ""), "BasicType"));
|
.addStatement("return $T." + type, ClassName.get(joinPackage(basePackageName, ""), "BasicType"));
|
||||||
typeClass.addMethod(getBasicTypeMethod.build());
|
typeClass.addMethod(getBasicTypeMethod.build());
|
||||||
var superTypes = versionConfiguration.superTypes
|
var superTypes = dataModel.getSuperTypes()
|
||||||
.entrySet()
|
.entrySet()
|
||||||
.parallelStream()
|
.parallelStream()
|
||||||
.filter(((entry) -> entry.getValue().contains(type)))
|
.filter(((entry) -> entry.getValue().contains(type)))
|
||||||
@ -2271,7 +2232,7 @@ public class SourcesGenerator {
|
|||||||
if (nextVersion.isEmpty()) {
|
if (nextVersion.isEmpty()) {
|
||||||
for (Entry<String, Integer> superType : superTypes) {
|
for (Entry<String, Integer> superType : superTypes) {
|
||||||
if (superType != null) {
|
if (superType != null) {
|
||||||
var interfaceCommonDataConfiguration = configuration.interfacesData.getOrDefault(superType.getKey(),
|
var interfaceCommonDataConfiguration = dataModel.getInterfaces().getOrDefault(superType.getKey(),
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
if (interfaceCommonDataConfiguration != null
|
if (interfaceCommonDataConfiguration != null
|
||||||
@ -2396,10 +2357,6 @@ public class SourcesGenerator {
|
|||||||
generatedFilesToDelete.remove(basePath.relativize(filePath));
|
generatedFilesToDelete.remove(basePath.relativize(filePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String computeHash(SourcesGeneratorConfiguration configuration) {
|
|
||||||
return Integer.toString(configuration.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
private TypeName getImmutableArrayType(HashMap<String, TypeName> typeTypes, String typeString) {
|
private TypeName getImmutableArrayType(HashMap<String, TypeName> typeTypes, String typeString) {
|
||||||
var type = typeTypes.get(typeString);
|
var type = typeTypes.get(typeString);
|
||||||
return getImmutableArrayType(type);
|
return getImmutableArrayType(type);
|
||||||
@ -2694,10 +2651,10 @@ public class SourcesGenerator {
|
|||||||
boolean nextVersionArrayTypeNeeded){}
|
boolean nextVersionArrayTypeNeeded){}
|
||||||
|
|
||||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||||
public NeededTypes registerNeededTypes(VersionConfiguration versionConfiguration,
|
public NeededTypes registerNeededTypes(ComputedVersion versionConfiguration,
|
||||||
Family family,
|
Family family,
|
||||||
String type,
|
String type,
|
||||||
Optional<String> nextVersion,
|
Optional<ComputedVersion> nextVersion,
|
||||||
Optional<String> nextVersionPackage,
|
Optional<String> nextVersionPackage,
|
||||||
ClassName versionClassType,
|
ClassName versionClassType,
|
||||||
String versionPackage,
|
String versionPackage,
|
||||||
@ -2712,10 +2669,10 @@ public class SourcesGenerator {
|
|||||||
Supplier<TypeName> arrayClassName,
|
Supplier<TypeName> arrayClassName,
|
||||||
Supplier<TypeName> nextArrayClassName) {
|
Supplier<TypeName> nextArrayClassName) {
|
||||||
// Check if the nullable type is needed
|
// Check if the nullable type is needed
|
||||||
boolean nullableTypeNeeded = versionConfiguration.classes
|
boolean nullableTypeNeeded = versionConfiguration.getClassMap()
|
||||||
.values()
|
.values()
|
||||||
.parallelStream()
|
.parallelStream()
|
||||||
.map(ClassConfiguration::getData)
|
.map(ParsedClass::getData)
|
||||||
.map(Map::values)
|
.map(Map::values)
|
||||||
.flatMap(Collection::parallelStream)
|
.flatMap(Collection::parallelStream)
|
||||||
.filter((typeZ) -> typeZ.startsWith("-"))
|
.filter((typeZ) -> typeZ.startsWith("-"))
|
||||||
@ -2723,10 +2680,10 @@ public class SourcesGenerator {
|
|||||||
.anyMatch((typeZ) -> typeZ.equals(type));
|
.anyMatch((typeZ) -> typeZ.equals(type));
|
||||||
|
|
||||||
boolean nextVersionNullableTypeNeeded = nextVersion
|
boolean nextVersionNullableTypeNeeded = nextVersion
|
||||||
.filter(s -> configuration.versions.get(s).classes
|
.filter(s -> s.getClassMap()
|
||||||
.values()
|
.values()
|
||||||
.parallelStream()
|
.parallelStream()
|
||||||
.map(ClassConfiguration::getData)
|
.map(ParsedClass::getData)
|
||||||
.map(Map::values)
|
.map(Map::values)
|
||||||
.flatMap(Collection::parallelStream)
|
.flatMap(Collection::parallelStream)
|
||||||
.filter((typeZ) -> typeZ.startsWith("-"))
|
.filter((typeZ) -> typeZ.startsWith("-"))
|
||||||
@ -2766,20 +2723,20 @@ public class SourcesGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the array type is needed
|
// Check if the array type is needed
|
||||||
boolean arrayTypeNeeded = versionConfiguration.classes
|
boolean arrayTypeNeeded = versionConfiguration.getClassMap()
|
||||||
.values()
|
.values()
|
||||||
.parallelStream()
|
.parallelStream()
|
||||||
.map(ClassConfiguration::getData)
|
.map(ParsedClass::getData)
|
||||||
.map(Map::values)
|
.map(Map::values)
|
||||||
.flatMap(Collection::parallelStream)
|
.flatMap(Collection::parallelStream)
|
||||||
.filter((typeZ) -> typeZ.startsWith("§"))
|
.filter((typeZ) -> typeZ.startsWith("§"))
|
||||||
.map((typeZ) -> typeZ.substring(1))
|
.map((typeZ) -> typeZ.substring(1))
|
||||||
.anyMatch((typeZ) -> typeZ.equals(type));
|
.anyMatch((typeZ) -> typeZ.equals(type));
|
||||||
|
|
||||||
boolean nextVersionArrayTypeNeeded = nextVersion.filter(s -> configuration.versions.get(s).classes
|
boolean nextVersionArrayTypeNeeded = nextVersion.filter(s -> s.getClassMap()
|
||||||
.values()
|
.values()
|
||||||
.parallelStream()
|
.parallelStream()
|
||||||
.map(ClassConfiguration::getData)
|
.map(ParsedClass::getData)
|
||||||
.map(Map::values)
|
.map(Map::values)
|
||||||
.flatMap(Collection::parallelStream)
|
.flatMap(Collection::parallelStream)
|
||||||
.filter((typeZ) -> typeZ.startsWith("§"))
|
.filter((typeZ) -> typeZ.startsWith("§"))
|
||||||
@ -2833,17 +2790,6 @@ public class SourcesGenerator {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String fixType(String fieldType) {
|
|
||||||
if (fieldType.endsWith("[]") && fieldType.startsWith("-")) {
|
|
||||||
throw new UnsupportedOperationException("Arrays cannot be null");
|
|
||||||
}
|
|
||||||
if (fieldType.endsWith("[]")) {
|
|
||||||
return "§" + fieldType.substring(0, fieldType.length() - 2);
|
|
||||||
} else {
|
|
||||||
return fieldType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addImmutableSetter(Builder classBuilder, TypeName classType, Collection<String> fieldNames,
|
private void addImmutableSetter(Builder classBuilder, TypeName classType, Collection<String> fieldNames,
|
||||||
String fieldName, TypeName fieldType, boolean isOverride) {
|
String fieldName, TypeName fieldType, boolean isOverride) {
|
||||||
var setterMethod = MethodSpec.methodBuilder("set" + capitalize(fieldName));
|
var setterMethod = MethodSpec.methodBuilder("set" + capitalize(fieldName));
|
||||||
@ -2929,36 +2875,9 @@ public class SourcesGenerator {
|
|||||||
return Character.toUpperCase(field.charAt(0)) + field.substring(1);
|
return Character.toUpperCase(field.charAt(0)) + field.substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<String> findNextVersion(SourcesGeneratorConfiguration config, String version) {
|
@Deprecated
|
||||||
int currentVersion = Integer.parseInt(getVersionShortInt(version));
|
private String getVersionPackage(String basePackageName, ComputedVersion version) {
|
||||||
int maxVersion = Integer.parseInt(getVersionShortInt(config.currentVersion));
|
return version.getPackage(basePackageName);
|
||||||
if (currentVersion >= maxVersion) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
AtomicInteger smallestNextVersion = new AtomicInteger(Integer.MAX_VALUE);
|
|
||||||
AtomicReference<String> smallestNextVersionString = new AtomicReference<>(null);
|
|
||||||
for (Entry<String, VersionConfiguration> entry : config.versions.entrySet()) {
|
|
||||||
String possibleNextVersionString = entry.getKey();
|
|
||||||
VersionConfiguration conf = entry.getValue();
|
|
||||||
int possibleNextVersion = Integer.parseInt(getVersionShortInt(possibleNextVersionString));
|
|
||||||
if (possibleNextVersion <= maxVersion && possibleNextVersion > currentVersion
|
|
||||||
&& possibleNextVersion <= smallestNextVersion.get()) {
|
|
||||||
smallestNextVersion.set(possibleNextVersion);
|
|
||||||
smallestNextVersionString.set(possibleNextVersionString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String value = smallestNextVersionString.get();
|
|
||||||
return Optional.ofNullable(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVersionPackage(String latestVersion, String basePackageName, String version) {
|
|
||||||
if (latestVersion.equals(version)) {
|
|
||||||
return joinPackage(basePackageName, "current");
|
|
||||||
} else {
|
|
||||||
return joinPackage(basePackageName, "v" + getVersionCompleteInt(version));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String joinPackage(String basePackageName, String packageName) {
|
private String joinPackage(String basePackageName, String packageName) {
|
||||||
@ -3004,33 +2923,13 @@ public class SourcesGenerator {
|
|||||||
markFileAsCreated(generatedFilesToDelete, outPath, outJavaFile);
|
markFileAsCreated(generatedFilesToDelete, outPath, outJavaFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getVersionVarName(String version) {
|
@Deprecated
|
||||||
return "V" + version.replace('-', '_').replace('.', '_');
|
private String getVersionVarName(ComputedVersion computedVersion) {
|
||||||
|
return computedVersion.getVersionVarName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getVersionCompleteInt(String version) {
|
private String getVersionShortInt(ComputedVersion version) {
|
||||||
String[] parts = version.split("\\.");
|
return Integer.toString(version.getVersion());
|
||||||
while (parts[0].length() < 2) {
|
|
||||||
parts[0] = "0" + parts[0];
|
|
||||||
}
|
|
||||||
while (parts[1].length() < 3) {
|
|
||||||
parts[1] = "0" + parts[1];
|
|
||||||
}
|
|
||||||
while (parts[2].length() < 4) {
|
|
||||||
parts[2] = "0" + parts[2];
|
|
||||||
}
|
|
||||||
return parts[0] + parts[1] + parts[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getVersionShortInt(String version) {
|
|
||||||
version = getVersionCompleteInt(version);
|
|
||||||
while (version.startsWith("0")) {
|
|
||||||
version = version.substring(1);
|
|
||||||
}
|
|
||||||
if (version.isBlank()) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
return version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Family {
|
private enum Family {
|
||||||
|
@ -2,12 +2,15 @@ package it.cavallium.data.generator;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class SourcesGeneratorConfiguration {
|
public class SourcesGeneratorConfiguration {
|
||||||
public String currentVersion;
|
public String currentVersion;
|
||||||
public Map<String, InterfaceDataConfiguration> interfacesData;
|
public Map<String, InterfaceDataConfiguration> interfacesData;
|
||||||
|
public Map<String, ClassConfiguration> baseTypesData;
|
||||||
|
public Map<String, Set<String>> superTypesData;
|
||||||
|
public Map<String, CustomTypesConfiguration> customTypesData;
|
||||||
public Map<String, VersionConfiguration> versions;
|
public Map<String, VersionConfiguration> versions;
|
||||||
public SourcesGeneratorConfigurationRefs refs;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
@ -19,7 +22,8 @@ public class SourcesGeneratorConfiguration {
|
|||||||
}
|
}
|
||||||
SourcesGeneratorConfiguration that = (SourcesGeneratorConfiguration) o;
|
SourcesGeneratorConfiguration that = (SourcesGeneratorConfiguration) o;
|
||||||
return Objects.equals(currentVersion, that.currentVersion) && Objects.equals(interfacesData, that.interfacesData)
|
return Objects.equals(currentVersion, that.currentVersion) && Objects.equals(interfacesData, that.interfacesData)
|
||||||
&& Objects.equals(versions, that.versions) && Objects.equals(refs, that.refs);
|
&& Objects.equals(baseTypesData, that.baseTypesData) && Objects.equals(superTypesData, that.superTypesData)
|
||||||
|
&& Objects.equals(customTypesData, that.customTypesData) && Objects.equals(versions, that.versions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,8 +31,20 @@ public class SourcesGeneratorConfiguration {
|
|||||||
int hash = 0;
|
int hash = 0;
|
||||||
hash += ConfigUtils.hashCode(currentVersion);
|
hash += ConfigUtils.hashCode(currentVersion);
|
||||||
hash += ConfigUtils.hashCode(interfacesData);
|
hash += ConfigUtils.hashCode(interfacesData);
|
||||||
|
hash += ConfigUtils.hashCode(superTypesData);
|
||||||
|
hash += ConfigUtils.hashCode(customTypesData);
|
||||||
hash += ConfigUtils.hashCode(versions);
|
hash += ConfigUtils.hashCode(versions);
|
||||||
hash += ConfigUtils.hashCode(refs);
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataModel buildDataModel() {
|
||||||
|
return new DataModel(hashCode(),
|
||||||
|
currentVersion,
|
||||||
|
Objects.requireNonNullElse(interfacesData, Map.of()),
|
||||||
|
Objects.requireNonNullElse(baseTypesData, Map.of()),
|
||||||
|
Objects.requireNonNullElse(superTypesData, Map.of()),
|
||||||
|
Objects.requireNonNullElse(customTypesData, Map.of()),
|
||||||
|
Objects.requireNonNullElse(versions, Map.of())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package it.cavallium.data.generator;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class SourcesGeneratorConfigurationRefs {
|
|
||||||
public Map<String, Map<String, Set<String>>> superTypes;
|
|
||||||
public Map<String, Map<String, CustomTypesConfiguration>> customTypes;
|
|
||||||
public Map<String, Map<String, ClassConfiguration>> classes;
|
|
||||||
public Map<String, List<VersionTransformation>> transformations;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (o == null || getClass() != o.getClass()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SourcesGeneratorConfigurationRefs that = (SourcesGeneratorConfigurationRefs) o;
|
|
||||||
return Objects.equals(superTypes, that.superTypes) && Objects.equals(customTypes, that.customTypes)
|
|
||||||
&& Objects.equals(classes, that.classes) && Objects.equals(transformations, that.transformations);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 0;
|
|
||||||
hash += ConfigUtils.hashCode(superTypes);
|
|
||||||
hash += ConfigUtils.hashCode(customTypes);
|
|
||||||
hash += ConfigUtils.hashCode(classes);
|
|
||||||
hash += ConfigUtils.hashCode(transformations);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
|
|
||||||
public String transformClass;
|
public String transformClass;
|
||||||
public String from;
|
public String from;
|
||||||
|
public String type;
|
||||||
public String upgrader;
|
public String upgrader;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -27,10 +28,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
|
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
|
||||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from) && Objects.equals(
|
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
|
||||||
upgrader,
|
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader);
|
||||||
that.upgrader
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,7 +37,19 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
|||||||
int hash = 0;
|
int hash = 0;
|
||||||
hash += ConfigUtils.hashCode(transformClass);
|
hash += ConfigUtils.hashCode(transformClass);
|
||||||
hash += ConfigUtils.hashCode(from);
|
hash += ConfigUtils.hashCode(from);
|
||||||
|
hash += ConfigUtils.hashCode(type);
|
||||||
hash += ConfigUtils.hashCode(upgrader);
|
hash += ConfigUtils.hashCode(upgrader);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public UpgradeDataConfiguration clone() {
|
||||||
|
var c = new UpgradeDataConfiguration();
|
||||||
|
if (this.transformClass != null) c.transformClass = this.transformClass;
|
||||||
|
if (this.from != null) c.from = this.from;
|
||||||
|
if (this.type != null) c.type = this.type;
|
||||||
|
if (this.upgrader != null) c.upgrader = this.upgrader;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,8 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class VersionConfiguration {
|
public class VersionConfiguration {
|
||||||
|
|
||||||
|
public String previousVersion;
|
||||||
public DetailsConfiguration details;
|
public DetailsConfiguration details;
|
||||||
public Map<String, Set<String>> superTypes;
|
|
||||||
public Map<String, CustomTypesConfiguration> customTypes;
|
|
||||||
public Map<String, ClassConfiguration> classes;
|
|
||||||
public List<VersionTransformation> transformations;
|
public List<VersionTransformation> transformations;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -22,19 +20,15 @@ public class VersionConfiguration {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
VersionConfiguration that = (VersionConfiguration) o;
|
VersionConfiguration that = (VersionConfiguration) o;
|
||||||
return Objects.equals(details, that.details) && Objects.equals(superTypes, that.superTypes) && Objects.equals(
|
return Objects.equals(previousVersion, that.previousVersion) && Objects.equals(details, that.details)
|
||||||
customTypes,
|
&& Objects.equals(transformations, that.transformations);
|
||||||
that.customTypes
|
|
||||||
) && Objects.equals(classes, that.classes) && Objects.equals(transformations, that.transformations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 0;
|
int hash = 0;
|
||||||
|
hash += ConfigUtils.hashCode(previousVersion);
|
||||||
hash += ConfigUtils.hashCode(details);
|
hash += ConfigUtils.hashCode(details);
|
||||||
hash += ConfigUtils.hashCode(superTypes);
|
|
||||||
hash += ConfigUtils.hashCode(customTypes);
|
|
||||||
hash += ConfigUtils.hashCode(classes);
|
|
||||||
hash += ConfigUtils.hashCode(transformations);
|
hash += ConfigUtils.hashCode(transformations);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package it.cavallium.data.generator;
|
|||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class VersionTransformation {
|
public final class VersionTransformation {
|
||||||
|
|
||||||
public MoveDataConfiguration moveData = null;
|
public MoveDataConfiguration moveData = null;
|
||||||
public RemoveDataConfiguration removeData = null;
|
public RemoveDataConfiguration removeData = null;
|
||||||
@ -86,4 +86,15 @@ public class VersionTransformation {
|
|||||||
hash += ConfigUtils.hashCode(newData);
|
hash += ConfigUtils.hashCode(newData);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("MethodDoesntCallSuperMethod")
|
||||||
|
@Override
|
||||||
|
public VersionTransformation clone() {
|
||||||
|
var t = new VersionTransformation();
|
||||||
|
if (this.moveData != null) t.moveData = this.moveData.clone();
|
||||||
|
if (this.removeData != null) t.removeData = this.removeData.clone();
|
||||||
|
if (this.upgradeData != null) t.upgradeData = this.upgradeData.clone();
|
||||||
|
if (this.newData != null) t.newData = this.newData.clone();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package it.cavallium.data.generator;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class TestGenerator {
|
||||||
|
|
||||||
|
//@Test
|
||||||
|
public void test() throws IOException {
|
||||||
|
var dir = Files.createTempDirectory("data-generator-test");
|
||||||
|
try {
|
||||||
|
SourcesGenerator.load(this.getClass().getResourceAsStream("/test.yaml")).generateSources("it.test", dir, false);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
FileUtils.deleteDirectory(dir.toFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
0
data-generator-plugin/src/test/resources/test.yaml
Normal file
0
data-generator-plugin/src/test/resources/test.yaml
Normal file
Loading…
Reference in New Issue
Block a user