[Gradle] custom serialization for Gradle extensions model IDEA-216902

GitOrigin-RevId: fc22065b3d5e546ba419a4a51df1416616da2a6f
This commit is contained in:
Vladislav.Soroka
2019-07-24 15:35:58 +03:00
committed by intellij-monorepo-bot
parent 649d24b4c0
commit ddb6d39410
11 changed files with 399 additions and 24 deletions
@@ -16,7 +16,6 @@
package org.jetbrains.plugins.gradle.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
@@ -29,7 +28,4 @@ public interface GradleProperty extends Serializable {
@NotNull
String getTypeFqn();
@Nullable
Serializable getValue();
}
@@ -16,4 +16,5 @@
#
org.jetbrains.plugins.gradle.tooling.serialization.ExternalProjectSerializationService
org.jetbrains.plugins.gradle.tooling.serialization.BuildScriptClasspathModelSerializationService
org.jetbrains.plugins.gradle.tooling.serialization.RepositoriesModelSerializationService
org.jetbrains.plugins.gradle.tooling.serialization.RepositoriesModelSerializationService
org.jetbrains.plugins.gradle.tooling.serialization.GradleExtensionsSerializationService
@@ -51,4 +51,28 @@ public final class DefaultGradleConfiguration implements GradleConfiguration {
public boolean isScriptClasspathConfiguration() {
return scriptClasspathConfiguration;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DefaultGradleConfiguration that = (DefaultGradleConfiguration)o;
if (visible != that.visible) return false;
if (scriptClasspathConfiguration != that.scriptClasspathConfiguration) return false;
if (name != null ? !name.equals(that.name) : that.name != null) return false;
if (description != null ? !description.equals(that.description) : that.description != null) return false;
return true;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (visible ? 1 : 0);
result = 31 * result + (scriptClasspathConfiguration ? 1 : 0);
return result;
}
}
@@ -10,7 +10,7 @@ public final class DefaultGradleConvention extends DefaultGradleProperty impleme
@PropertyMapping({"name", "typeFqn"})
public DefaultGradleConvention(@NotNull String name, @Nullable String typeFqn) {
super(name, typeFqn, null);
super(name, typeFqn);
}
public DefaultGradleConvention(GradleConvention convention) {
@@ -10,7 +10,7 @@ public final class DefaultGradleExtension extends DefaultGradleProperty implemen
@PropertyMapping({"name", "typeFqn"})
public DefaultGradleExtension(@NotNull String name, @Nullable String typeFqn) {
super(name, typeFqn, null);
super(name, typeFqn);
}
public DefaultGradleExtension(GradleExtension extension) {
@@ -110,4 +110,32 @@ public class DefaultGradleExtensions implements GradleExtensions {
public List<DefaultGradleConfiguration> getConfigurations() {
return configurations == null ? Collections.<DefaultGradleConfiguration>emptyList() : configurations;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DefaultGradleExtensions that = (DefaultGradleExtensions)o;
if (extensions != null ? !extensions.equals(that.extensions) : that.extensions != null) return false;
if (conventions != null ? !conventions.equals(that.conventions) : that.conventions != null) return false;
if (gradleProperties != null ? !gradleProperties.equals(that.gradleProperties) : that.gradleProperties != null) return false;
if (tasks != null ? !tasks.equals(that.tasks) : that.tasks != null) return false;
if (configurations != null ? !configurations.equals(that.configurations) : that.configurations != null) return false;
if (parentProjectPath != null ? !parentProjectPath.equals(that.parentProjectPath) : that.parentProjectPath != null) return false;
return true;
}
@Override
public int hashCode() {
int result = extensions != null ? extensions.hashCode() : 0;
result = 31 * result + (conventions != null ? conventions.hashCode() : 0);
result = 31 * result + (gradleProperties != null ? gradleProperties.hashCode() : 0);
result = 31 * result + (tasks != null ? tasks.hashCode() : 0);
result = 31 * result + (configurations != null ? configurations.hashCode() : 0);
result = 31 * result + (parentProjectPath != null ? parentProjectPath.hashCode() : 0);
return result;
}
}
@@ -5,8 +5,6 @@ import com.intellij.serialization.PropertyMapping;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
/**
* @author Vladislav.Soroka
*/
@@ -15,18 +13,15 @@ public class DefaultGradleProperty implements GradleProperty {
private final String name;
@NotNull
private final String rootTypeFqn;
@Nullable
private final Serializable value;
@PropertyMapping({"name", "typeFqn", "value"})
public DefaultGradleProperty(@NotNull String name, @Nullable String typeFqn, @Nullable Serializable value) {
@PropertyMapping({"name", "typeFqn"})
public DefaultGradleProperty(@NotNull String name, @Nullable String typeFqn) {
this.name = name;
rootTypeFqn = typeFqn == null ? "Object" : typeFqn;
this.value = value;
}
public DefaultGradleProperty(GradleProperty property) {
this(property.getName(), property.getTypeFqn(), property.getValue());
this(property.getName(), property.getTypeFqn());
}
@NotNull
@@ -41,9 +36,23 @@ public class DefaultGradleProperty implements GradleProperty {
return rootTypeFqn;
}
@Nullable
@Override
public Serializable getValue() {
return value;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DefaultGradleProperty property = (DefaultGradleProperty)o;
if (!name.equals(property.name)) return false;
if (!rootTypeFqn.equals(property.rootTypeFqn)) return false;
return true;
}
@Override
public int hashCode() {
int result = name.hashCode();
result = 31 * result + rootTypeFqn.hashCode();
return result;
}
}
@@ -43,7 +43,7 @@ class ProjectExtensionsDataBuilderImpl implements ModelBuilderService {
extensions.extraProperties.properties.each { name, value ->
if(name == 'extraModelBuilder' || name.contains('.')) return
String typeFqn = getType(value)
result.gradleProperties.add(new DefaultGradleProperty(name, typeFqn, value.toString()))
result.gradleProperties.add(new DefaultGradleProperty(name, typeFqn))
}
for (it in extensions.findAll()) {
@@ -66,7 +66,7 @@ class ProjectExtensionsDataBuilderImpl implements ModelBuilderService {
return result
}
private List<String> extractKeysViaReflection(ExtensionContainer convention) {
private static List<String> extractKeysViaReflection(ExtensionContainer convention) {
def m = convention.class.getMethod("getAsMap")
return (m.invoke(convention) as Map<String, Object>).keySet().asList() as List<String>
}
@@ -0,0 +1,312 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.tooling.serialization;
import com.amazon.ion.IonReader;
import com.amazon.ion.IonType;
import com.amazon.ion.IonWriter;
import com.amazon.ion.system.IonBinaryWriterBuilder;
import com.amazon.ion.system.IonReaderBuilder;
import com.intellij.openapi.util.Getter;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.*;
import org.jetbrains.plugins.gradle.tooling.util.IntObjectMap;
import org.jetbrains.plugins.gradle.tooling.util.ObjectCollector;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.plugins.gradle.tooling.serialization.ToolingStreamUtils.*;
/**
* @author Vladislav.Soroka
*/
public class GradleExtensionsSerializationService implements SerializationService<GradleExtensions> {
private final WriteContext myWriteContext = new WriteContext();
private final ReadContext myReadContext = new ReadContext();
@Override
public byte[] write(GradleExtensions gradleExtensions, Class<? extends GradleExtensions> modelClazz) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IonWriter writer = IonBinaryWriterBuilder.standard().build(out);
try {
write(writer, myWriteContext, gradleExtensions);
}
finally {
writer.close();
}
return out.toByteArray();
}
@Override
public GradleExtensions read(byte[] object, Class<? extends GradleExtensions> modelClazz) throws IOException {
IonReader reader = IonReaderBuilder.standard().build(object);
try {
return read(reader, myReadContext);
}
finally {
reader.close();
}
}
@Override
public Class<? extends GradleExtensions> getModelClass() {
return GradleExtensions.class;
}
private static void write(final IonWriter writer, final WriteContext context, final GradleExtensions model) throws IOException {
context.objectCollector.add(model, new ObjectCollector.Processor<IOException>() {
@Override
public void process(boolean isAdded, int objectId) throws IOException {
writer.stepIn(IonType.STRUCT);
writer.setFieldName(OBJECT_ID_FIELD);
writer.writeInt(objectId);
if (isAdded) {
writeString(writer, "parentProjectPath", model.getParentProjectPath());
writeConfigurations(writer, context, model.getConfigurations());
writeConventions(writer, context, model.getConventions());
writeExtensions(writer, context, model.getExtensions());
writeGradleProperties(writer, context, model.getGradleProperties());
// do not write tasks, as it will be added from ExternalProject model at BaseGradleProjectResolverExtension.populateModuleExtraModels
}
writer.stepOut();
}
});
}
private static void writeConfigurations(IonWriter writer,
WriteContext context,
List<? extends GradleConfiguration> configurations) throws IOException {
writer.setFieldName("configurations");
writer.stepIn(IonType.LIST);
for (GradleConfiguration configuration : configurations) {
writeConfiguration(writer, context, configuration);
}
writer.stepOut();
}
static void writeConfiguration(final IonWriter writer,
final WriteContext context,
final GradleConfiguration configuration) throws IOException {
context.configurationsCollector.add(configuration, new ObjectCollector.Processor<IOException>() {
@Override
public void process(boolean isAdded, int objectId) throws IOException {
writer.stepIn(IonType.STRUCT);
writer.setFieldName(OBJECT_ID_FIELD);
writer.writeInt(objectId);
if (isAdded) {
writeString(writer, "name", configuration.getName());
writeString(writer, "description", configuration.getDescription());
writeBoolean(writer, "visible", configuration.isVisible());
writeBoolean(writer, "scriptClasspathConfiguration", configuration.isScriptClasspathConfiguration());
}
writer.stepOut();
}
});
}
private static void writeConventions(IonWriter writer,
WriteContext context,
List<? extends GradleConvention> conventions) throws IOException {
writer.setFieldName("conventions");
writer.stepIn(IonType.LIST);
for (GradleConvention convention : conventions) {
write(writer, context, convention);
}
writer.stepOut();
}
private static void writeExtensions(IonWriter writer,
WriteContext context,
List<? extends GradleExtension> extensions) throws IOException {
writer.setFieldName("extensions");
writer.stepIn(IonType.LIST);
for (GradleExtension extension : extensions) {
write(writer, context, extension);
}
writer.stepOut();
}
private static void writeGradleProperties(IonWriter writer,
WriteContext context,
List<? extends GradleProperty> properties) throws IOException {
writer.setFieldName("properties");
writer.stepIn(IonType.LIST);
for (GradleProperty property : properties) {
write(writer, context, property);
}
writer.stepOut();
}
static void write(final IonWriter writer,
final WriteContext context,
final GradleProperty property) throws IOException {
context.propertiesCollector.add(property, new ObjectCollector.Processor<IOException>() {
@Override
public void process(boolean isAdded, int objectId) throws IOException {
writer.stepIn(IonType.STRUCT);
writer.setFieldName(OBJECT_ID_FIELD);
writer.writeInt(objectId);
if (isAdded) {
writeString(writer, "name", property.getName());
writeString(writer, "typeFqn", property.getTypeFqn());
}
writer.stepOut();
}
});
}
@Nullable
private static GradleExtensions read(final IonReader reader, final ReadContext context) {
if (reader.next() == null) return null;
reader.stepIn();
GradleExtensions extensions =
context.objectMap.computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new Getter<DefaultGradleExtensions>() {
@Override
public DefaultGradleExtensions get() {
DefaultGradleExtensions gradleExtensions = new DefaultGradleExtensions();
gradleExtensions.setParentProjectPath(readString(reader, "parentProjectPath"));
gradleExtensions.getConfigurations().addAll(readConfigurations(reader, context));
gradleExtensions.getConventions().addAll(readConventions(reader, context));
gradleExtensions.getExtensions().addAll(readExtensions(reader, context));
gradleExtensions.getGradleProperties().addAll(readGradleProperties(reader, context));
// do not read tasks, as it will be added from ExternalProject model at BaseGradleProjectResolverExtension.populateModuleExtraModels
return gradleExtensions;
}
});
reader.stepOut();
return extensions;
}
private static List<DefaultGradleConfiguration> readConfigurations(IonReader reader, ReadContext context) {
List<DefaultGradleConfiguration> list = new ArrayList<DefaultGradleConfiguration>();
reader.next();
reader.stepIn();
DefaultGradleConfiguration configuration;
while ((configuration = readConfiguration(reader, context)) != null) {
list.add(configuration);
}
reader.stepOut();
return list;
}
@Nullable
private static DefaultGradleConfiguration readConfiguration(final IonReader reader, ReadContext context) {
if (reader.next() == null) return null;
reader.stepIn();
DefaultGradleConfiguration configuration =
context.configurationsMap.computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new Getter<DefaultGradleConfiguration>() {
@Override
public DefaultGradleConfiguration get() {
return new DefaultGradleConfiguration(
assertNotNull(readString(reader, "name")),
readString(reader, "description"),
readBoolean(reader, "visible"),
readBoolean(reader, "scriptClasspathConfiguration"));
}
});
reader.stepOut();
return configuration;
}
private static List<DefaultGradleConvention> readConventions(IonReader reader, ReadContext context) {
List<DefaultGradleConvention> list = new ArrayList<DefaultGradleConvention>();
reader.next();
reader.stepIn();
DefaultGradleConvention entry;
while ((entry = readConvention(reader, context)) != null) {
list.add(entry);
}
reader.stepOut();
return list;
}
@Nullable
private static DefaultGradleConvention readConvention(final IonReader reader, ReadContext context) {
if (reader.next() == null) return null;
reader.stepIn();
DefaultGradleConvention convention =
context.conventionsMap.computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new Getter<DefaultGradleConvention>() {
@Override
public DefaultGradleConvention get() {
return new DefaultGradleConvention(assertNotNull(readString(reader, "name")), readString(reader, "typeFqn"));
}
});
reader.stepOut();
return convention;
}
private static List<DefaultGradleExtension> readExtensions(IonReader reader, ReadContext context) {
List<DefaultGradleExtension> list = new ArrayList<DefaultGradleExtension>();
reader.next();
reader.stepIn();
DefaultGradleExtension entry;
while ((entry = readExtension(reader, context)) != null) {
list.add(entry);
}
reader.stepOut();
return list;
}
@Nullable
private static DefaultGradleExtension readExtension(final IonReader reader, ReadContext context) {
if (reader.next() == null) return null;
reader.stepIn();
DefaultGradleExtension convention =
context.extensionsMap.computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new Getter<DefaultGradleExtension>() {
@Override
public DefaultGradleExtension get() {
return new DefaultGradleExtension(assertNotNull(readString(reader, "name")), readString(reader, "typeFqn"));
}
});
reader.stepOut();
return convention;
}
private static List<DefaultGradleProperty> readGradleProperties(IonReader reader, ReadContext context) {
List<DefaultGradleProperty> list = new ArrayList<DefaultGradleProperty>();
reader.next();
reader.stepIn();
DefaultGradleProperty entry;
while ((entry = readGradleProperty(reader, context)) != null) {
list.add(entry);
}
reader.stepOut();
return list;
}
@Nullable
private static DefaultGradleProperty readGradleProperty(final IonReader reader, ReadContext context) {
if (reader.next() == null) return null;
reader.stepIn();
DefaultGradleProperty convention =
context.propertiesMap.computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new Getter<DefaultGradleProperty>() {
@Override
public DefaultGradleProperty get() {
return new DefaultGradleProperty(assertNotNull(readString(reader, "name")), readString(reader, "typeFqn"));
}
});
reader.stepOut();
return convention;
}
private static class ReadContext {
private final IntObjectMap<GradleExtensions> objectMap = new IntObjectMap<GradleExtensions>();
private final IntObjectMap<DefaultGradleConfiguration> configurationsMap = new IntObjectMap<DefaultGradleConfiguration>();
private final IntObjectMap<DefaultGradleConvention> conventionsMap = new IntObjectMap<DefaultGradleConvention>();
private final IntObjectMap<DefaultGradleExtension> extensionsMap = new IntObjectMap<DefaultGradleExtension>();
private final IntObjectMap<DefaultGradleProperty> propertiesMap = new IntObjectMap<DefaultGradleProperty>();
}
private static class WriteContext {
private final ObjectCollector<GradleExtensions, IOException> objectCollector = new ObjectCollector<GradleExtensions, IOException>();
private final ObjectCollector<GradleConfiguration, IOException> configurationsCollector =
new ObjectCollector<GradleConfiguration, IOException>();
private final ObjectCollector<GradleProperty, IOException> propertiesCollector =
new ObjectCollector<GradleProperty, IOException>();
}
}
@@ -31,11 +31,11 @@ public class RepositoriesModelSerializationService implements SerializationServi
private final ReadContext myReadContext = new ReadContext();
@Override
public byte[] write(RepositoriesModel classpathModel, Class<? extends RepositoriesModel> modelClazz) throws IOException {
public byte[] write(RepositoriesModel repositoriesModel, Class<? extends RepositoriesModel> modelClazz) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IonWriter writer = IonBinaryWriterBuilder.standard().build(out);
try {
write(writer, myWriteContext, classpathModel);
write(writer, myWriteContext, repositoriesModel);
}
finally {
writer.close();
@@ -109,7 +109,7 @@ public class RepositoriesModelSerializationService implements SerializationServi
if (reader.next() == null) return null;
reader.stepIn();
RepositoriesModel project =
RepositoriesModel model =
context.objectMap.computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new Getter<RepositoriesModelImpl>() {
@Override
public RepositoriesModelImpl get() {
@@ -122,7 +122,7 @@ public class RepositoriesModelSerializationService implements SerializationServi
}
});
reader.stepOut();
return project;
return model;
}
private static List<MavenRepositoryModel> readRepositories(IonReader reader, ReadContext context) {
@@ -109,6 +109,11 @@ public class ToolingStreamUtils {
writer.writeString(value);
}
public static void writeBoolean(@NotNull IonWriter writer, @NotNull String fieldName, boolean value) throws IOException {
writer.setFieldName(fieldName);
writer.writeBool(value);
}
public static void writeFile(@NotNull IonWriter writer, @NotNull String fieldName, @Nullable File file) throws IOException {
writeString(writer, fieldName, file == null ? null : file.getPath());
}