diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/ConstructorSignatures.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/ConstructorSignatures.java index 42d24f93b..17729915a 100644 --- a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/ConstructorSignatures.java +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/ConstructorSignatures.java @@ -21,6 +21,9 @@ import io.hotmoka.beans.api.signatures.ConstructorSignature; import io.hotmoka.beans.api.types.ClassType; import io.hotmoka.beans.api.types.StorageType; +import io.hotmoka.beans.internal.gson.ConstructorSignatureDecoder; +import io.hotmoka.beans.internal.gson.ConstructorSignatureEncoder; +import io.hotmoka.beans.internal.gson.ConstructorSignatureJson; import io.hotmoka.beans.internal.signatures.ConstructorSignatureImpl; import io.hotmoka.marshalling.api.UnmarshallingContext; @@ -65,6 +68,43 @@ public static ConstructorSignature from(UnmarshallingContext context) throws IOE } /** + * Gson encoder. + */ + public static class Encoder extends ConstructorSignatureEncoder { + + /** + * Creates a new encoder. + */ + public Encoder() {} + } + + /** + * Gson decoder. + */ + public static class Decoder extends ConstructorSignatureDecoder { + + /** + * Creates a new decoder. + */ + public Decoder() {} + } + + /** + * Json representation. + */ + public static class Json extends ConstructorSignatureJson { + + /** + * Creates the Json representation for the given constructor signature. + * + * @param constructor the constructor signature + */ + public Json(ConstructorSignature constructor) { + super(constructor); + } + } + + /** * The constructor of an externally owned account. */ public final static ConstructorSignature EOA_CONSTRUCTOR = ConstructorSignatureImpl.EOA_CONSTRUCTOR; diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/MethodSignatures.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/MethodSignatures.java index 63324157a..e1ec9bcbc 100644 --- a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/MethodSignatures.java +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/MethodSignatures.java @@ -214,7 +214,7 @@ public static MethodSignature from(UnmarshallingContext context) throws IOExcept /** * The method {@code get} of the account ledger. */ - public final static NonVoidMethodSignature GET_FROM_ACCOUNTS_LEDGER = AbstractMethodSignature.GET_FROM_ACCOUNTS_LEDGER; // TODO: check name + public final static NonVoidMethodSignature GET_FROM_ACCOUNTS_LEDGER = AbstractMethodSignature.GET_FROM_ACCOUNTS_LEDGER; /** * The method {@code getGasPrice} of the gas station. diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureDecoder.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureDecoder.java new file mode 100644 index 000000000..ed427aa71 --- /dev/null +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureDecoder.java @@ -0,0 +1,31 @@ +/* +Copyright 2024 Fausto Spoto + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.hotmoka.beans.internal.gson; + +import io.hotmoka.beans.ConstructorSignatures; +import io.hotmoka.beans.api.signatures.ConstructorSignature; +import io.hotmoka.websockets.beans.MappedDecoder; + +/** + * A decoder for {@link ConstructorSignature}. + */ +public class ConstructorSignatureDecoder extends MappedDecoder { + + public ConstructorSignatureDecoder() { + super(ConstructorSignatures.Json.class); + } +} \ No newline at end of file diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureEncoder.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureEncoder.java new file mode 100644 index 000000000..63d8331eb --- /dev/null +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureEncoder.java @@ -0,0 +1,31 @@ +/* +Copyright 2024 Fausto Spoto + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.hotmoka.beans.internal.gson; + +import io.hotmoka.beans.ConstructorSignatures; +import io.hotmoka.beans.api.signatures.ConstructorSignature; +import io.hotmoka.websockets.beans.MappedEncoder; + +/** + * An encoder for {@link ConstructorSignature}. + */ +public class ConstructorSignatureEncoder extends MappedEncoder { + + public ConstructorSignatureEncoder() { + super(ConstructorSignatures.Json::new); + } +} \ No newline at end of file diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureJson.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureJson.java new file mode 100644 index 000000000..fd761a508 --- /dev/null +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/ConstructorSignatureJson.java @@ -0,0 +1,43 @@ +/* +Copyright 2024 Fausto Spoto + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.hotmoka.beans.internal.gson; + +import java.util.stream.Stream; + +import io.hotmoka.beans.ConstructorSignatures; +import io.hotmoka.beans.StorageTypes; +import io.hotmoka.beans.api.signatures.ConstructorSignature; +import io.hotmoka.beans.api.types.StorageType; +import io.hotmoka.websockets.beans.api.JsonRepresentation; + +/** + * The JSON representation of a {@link ConstructorSignature}. + */ +public abstract class ConstructorSignatureJson implements JsonRepresentation { + private final String definingClass; + private final String[] formals; + + protected ConstructorSignatureJson(ConstructorSignature constructor) { + this.definingClass = constructor.getDefiningClass().getName(); + this.formals = constructor.getFormals().map(StorageType::getName).toArray(String[]::new); + } + + @Override + public ConstructorSignature unmap() { + return ConstructorSignatures.of(StorageTypes.classNamed(definingClass), Stream.of(formals).map(StorageTypes::named).toArray(StorageType[]::new)); + } +} \ No newline at end of file diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/FieldSignatureJson.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/FieldSignatureJson.java index bb256c9fa..31041e2f1 100644 --- a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/FieldSignatureJson.java +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/gson/FieldSignatureJson.java @@ -19,7 +19,6 @@ import io.hotmoka.beans.FieldSignatures; import io.hotmoka.beans.StorageTypes; import io.hotmoka.beans.api.signatures.FieldSignature; -import io.hotmoka.beans.api.types.ClassType; import io.hotmoka.websockets.beans.api.JsonRepresentation; /** @@ -38,7 +37,6 @@ protected FieldSignatureJson(FieldSignature field) { @Override public FieldSignature unmap() { - // this cast might actually fail if the JSON is inconsistent - return FieldSignatures.of((ClassType) StorageTypes.named(definingClass), name, StorageTypes.named(type)); + return FieldSignatures.of(StorageTypes.classNamed(definingClass), name, StorageTypes.named(type)); } } \ No newline at end of file diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/signatures/AbstractCodeSignature.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/signatures/AbstractCodeSignature.java index 66ca36bec..27c643f05 100644 --- a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/signatures/AbstractCodeSignature.java +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/internal/signatures/AbstractCodeSignature.java @@ -97,7 +97,10 @@ protected final String commaSeparatedFormals() { @Override public boolean equals(Object other) { - return other instanceof CodeSignature cs && cs.getDefiningClass().equals(definingClass) && Arrays.equals(cs.getFormals().toArray(StorageType[]::new), formals); // TODO: optimize + if (other instanceof AbstractCodeSignature acs) + return acs.definingClass.equals(definingClass) && Arrays.equals(acs.formals, formals); // optimization + else + return other instanceof CodeSignature cs && cs.getDefiningClass().equals(definingClass) && Arrays.equals(cs.getFormals().toArray(StorageType[]::new), formals); } @Override diff --git a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/updates/Update.java b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/updates/Update.java index f1d27bf5c..0b426954b 100644 --- a/io-hotmoka-beans/src/main/java/io/hotmoka/beans/updates/Update.java +++ b/io-hotmoka-beans/src/main/java/io/hotmoka/beans/updates/Update.java @@ -119,8 +119,14 @@ public void into(MarshallingContext context) throws IOException { public static Update from(UnmarshallingContext context) throws IOException { var selector = context.readByte(); switch (selector) { - // TODO: cast -> IOException - case ClassTag.SELECTOR: return new ClassTag(StorageReferenceImpl.fromWithoutSelector(context), (ClassType) StorageTypes.from(context), TransactionReferences.from(context)); + case ClassTag.SELECTOR: { + try { + return new ClassTag(StorageReferenceImpl.fromWithoutSelector(context), (ClassType) StorageTypes.from(context), TransactionReferences.from(context)); + } + catch (ClassCastException e) { + throw new IOException("Failed unmrshalling a class tag", e); + } + } case UpdateOfBigInteger.SELECTOR_BALANCE: return new UpdateOfBigInteger(StorageReferenceImpl.fromWithoutSelector(context), FieldSignatures.BALANCE_FIELD, context.readBigInteger()); case UpdateOfBigInteger.SELECTOR_GAS_PRICE: return new UpdateOfBigInteger(StorageReferenceImpl.fromWithoutSelector(context), FieldSignatures.GENERIC_GAS_STATION_GAS_PRICE_FIELD, context.readBigInteger()); case UpdateOfBigInteger.SELECTOR_UBI_VALUE: return new UpdateOfBigInteger(StorageReferenceImpl.fromWithoutSelector(context), FieldSignatures.UNSIGNED_BIG_INTEGER_VALUE_FIELD, context.readBigInteger()); diff --git a/io-hotmoka-beans/src/test/java/io/hotmoka/beans/tests/ConstructorSignatureTests.java b/io-hotmoka-beans/src/test/java/io/hotmoka/beans/tests/ConstructorSignatureTests.java new file mode 100644 index 000000000..d49d064c4 --- /dev/null +++ b/io-hotmoka-beans/src/test/java/io/hotmoka/beans/tests/ConstructorSignatureTests.java @@ -0,0 +1,40 @@ +/* +Copyright 2024 Fausto Spoto + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.hotmoka.beans.tests; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import io.hotmoka.beans.ConstructorSignatures; +import io.hotmoka.beans.StorageTypes; +import io.hotmoka.testing.AbstractLoggedTests; +import jakarta.websocket.DecodeException; +import jakarta.websocket.EncodeException; + +public class ConstructorSignatureTests extends AbstractLoggedTests { + + @Test + @DisplayName("constructor signatures are correctly encoded into Json and decoded from Json") + public void encodeDecodeWorksForConstructorSignature() throws EncodeException, DecodeException { + var constructor1 = ConstructorSignatures.of("io.hotmoka.MyClass", StorageTypes.named("io.hotmoka.OtherClass"), StorageTypes.CHAR, StorageTypes.DOUBLE, StorageTypes.named("io.hotmoka.Something")); + String encoded = new ConstructorSignatures.Encoder().encode(constructor1); + var constructor2 = new ConstructorSignatures.Decoder().decode(encoded); + assertEquals(constructor1, constructor2); + } +} \ No newline at end of file