From 0b9c56ddf2fcc5bd5953f4d4e36b0eaac6b853f8 Mon Sep 17 00:00:00 2001 From: bageshwar <2353296+bageshwar@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:48:10 +0530 Subject: [PATCH] Date Handlers (#11) --- Handlers.md | 49 ++++++++++++++ README.md | 4 +- .../stub/AbstractPibifyHandlerCache.java | 2 + .../pibify/codegen/stub/DateHandler.java | 66 +++++++++++++++++++ ...trospectorBasedCodeGenSpecCreatorTest.java | 14 +++- .../pibify/codegen/CodeGeneratorImplTest.java | 6 +- .../pibify/test/data/ClassWithReferences.java | 23 +++++-- 7 files changed, 149 insertions(+), 15 deletions(-) create mode 100644 Handlers.md create mode 100644 pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/DateHandler.java diff --git a/Handlers.md b/Handlers.md new file mode 100644 index 0000000..10fb54a --- /dev/null +++ b/Handlers.md @@ -0,0 +1,49 @@ +### Concept + +A Handler is an implementation of the `PibifyGenerated` abstract class. It primarily has 2 methods + +```java +public abstract T deserialize(IDeserializer deserializer, Class type, SerializationContext context) + throws PibifyCodeExecException; + +public abstract void serialize(T object, ISerializer serializer, SerializationContext context) + throws PibifyCodeExecException; +``` + +The Pibify Maven plugin generates a concrete implementation of this abstract class. + +For every class in the maven module annotated with `@Pibify`, a handler is generated. The handler is named as +`Handler`. + +### Out of the Box Handlers + +Few handlers are provided out of the box. They are: + +1. PibifyObjectHandler - for cases where the reference type is `java.lang.Object` +2. PibifyMapHandler - for cases where the reference type is `java.util.Map` with missing type parameters +3. PibifyCollectionHandler - for cases where the reference type is `java.util.Collection` with missing type parameters +4. BigDecimalHandler - for cases where the reference type is `java.math.BigDecimal` +5. DateHandler - for cases where the reference type is `java.util.Date` + +This well-known handlers are registered in `AbstractPibifyHandlerCache`'s protected constructor. + +#### Adding custom hand-written handlers + +If you want to add custom handlers, you can do so by extending the `AbstractPibifyHandlerCache` class and registering +your custom handlers in the constructor. + +```java +public class CustomHandlerCache extends AbstractPibifyHandlerCache { + public CustomHandlerCache() { + super(); + // Type is the class type of the object + super.mapBuilder.put(type, new CustomHandler()); + } +} +``` + +Then merge `CustomHandlerCache` with the generated `PibifyHandlerCache` using `MultiModuleHandlerCache`: + +```java +new MultiModulePibifyHandlerCache(new CustomHandlerCache(), new PibifyHandlerCache()); +``` \ No newline at end of file diff --git a/README.md b/README.md index 94d9575..057dca2 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,9 @@ private int anIntegerVariable; ``` #### Handler -This is the generated source corresponding to the Pojo where a `@Pibify` annotation is present. + +This is the generated source corresponding to the Pojo where a `@Pibify` annotation is present. More +details [here](Handlers.md) ```java public abstract class PibifyGenerated { diff --git a/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/AbstractPibifyHandlerCache.java b/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/AbstractPibifyHandlerCache.java index 29c88dd..dca00c8 100644 --- a/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/AbstractPibifyHandlerCache.java +++ b/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/AbstractPibifyHandlerCache.java @@ -24,6 +24,7 @@ import java.math.BigDecimal; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -75,6 +76,7 @@ protected AbstractPibifyHandlerCache() { mapBuilder.put(LinkedHashSet.class, collectionHandler); mapBuilder.put(BigDecimal.class, new BigDecimalHandler()); + mapBuilder.put(Date.class, new DateHandler()); mapBuilder.put(SerializationContext.class, new SerializationContextHandler()); } diff --git a/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/DateHandler.java b/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/DateHandler.java new file mode 100644 index 0000000..b24ec95 --- /dev/null +++ b/pibify-core/src/main/java/com/flipkart/pibify/codegen/stub/DateHandler.java @@ -0,0 +1,66 @@ +/* + * + * *Copyright [2025] [Original Author] + * * + * * 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 com.flipkart.pibify.codegen.stub; + +import com.flipkart.pibify.codegen.PibifyCodeExecException; +import com.flipkart.pibify.serde.IDeserializer; +import com.flipkart.pibify.serde.ISerializer; + +import java.io.IOException; +import java.util.Date; + +/** + * This class is used for serde of Date + * Author bageshwar.pn + * Date 15/01/25 + */ +public class DateHandler extends PibifyGenerated { + + @Override + public void serialize(Date object, ISerializer serializer, SerializationContext context) throws PibifyCodeExecException { + if (object != null) { + try { + serializer.writeLong(1, object.getTime()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + + @Override + public Date deserialize(IDeserializer deserializer, Class type, SerializationContext context) throws PibifyCodeExecException { + try { + int tag = deserializer.getNextTag(); + Date date = null; + while (tag != 0 && tag != PibifyGenerated.getEndObjectTag()) { + switch (tag) { + case 8: + date = new Date(deserializer.readLong()); + break; + default: + break; + } + tag = deserializer.getNextTag(); + } + return date; + } catch (IOException e) { + throw new PibifyCodeExecException(e); + } + } +} diff --git a/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/BeanIntrospectorBasedCodeGenSpecCreatorTest.java b/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/BeanIntrospectorBasedCodeGenSpecCreatorTest.java index dbeb92c..3dbd07d 100644 --- a/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/BeanIntrospectorBasedCodeGenSpecCreatorTest.java +++ b/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/BeanIntrospectorBasedCodeGenSpecCreatorTest.java @@ -324,12 +324,22 @@ public void createClassWithReference() throws CodeGenException { BeanIntrospectorBasedCodeGenSpecCreator creator = new BeanIntrospectorBasedCodeGenSpecCreator(); CodeGenSpec codeGenSpec = creator.create(ClassWithReferences.class); assertNotNull(codeGenSpec); - assertEquals(2, codeGenSpec.getFields().size()); + assertEquals(3, codeGenSpec.getFields().size()); Map nameToFields = codeGenSpec.getFields().stream() .collect(Collectors.toMap(CodeGenSpec.FieldSpec::getName, f -> f)); - CodeGenSpec.FieldSpec field = nameToFields.get("aString"); + CodeGenSpec.FieldSpec field = nameToFields.get("date"); + assertEquals("date", field.getName()); + assertEquals("getDate", field.getGetter()); + assertEquals("setDate", field.getSetter()); + assertEquals(3, field.getIndex()); + assertEquals(CodeGenSpec.DataType.OBJECT, field.getType().getNativeType()); + assertNull(field.getType().getContainerTypes()); + assertNotNull(field.getType().getReferenceType()); + assertEquals("java.util.Date", field.getType().getReferenceType().getJpClassName().toString()); + + field = nameToFields.get("aString"); assertEquals("aString", field.getName()); assertEquals("getaString", field.getGetter()); assertEquals("setaString", field.getSetter()); diff --git a/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/CodeGeneratorImplTest.java b/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/CodeGeneratorImplTest.java index 703079a..61dec69 100644 --- a/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/CodeGeneratorImplTest.java +++ b/pibify-maven-plugin/src/test/java/com/flipkart/pibify/codegen/CodeGeneratorImplTest.java @@ -313,11 +313,7 @@ public void testClassWithReferences() throws Exception { AnotherClassWithNativeCollections.class.getCanonicalName() + "Handler"); ClassWithReferences deserialized = invokeGeneratedCode(compiler, javaFile, testPayload); - - assertEquals(testPayload.getaString(), deserialized.getaString()); - assertEquals(testPayload.getReference().getaString(), deserialized.getReference().getaString()); - assertEquals(testPayload.getReference().getAnInt(), deserialized.getReference().getAnInt()); - assertEquals(testPayload.getReference().getaMap(), deserialized.getReference().getaMap()); + assertEquals(testPayload, deserialized); } @Test diff --git a/pibify-maven-plugin/src/test/java/com/flipkart/pibify/test/data/ClassWithReferences.java b/pibify-maven-plugin/src/test/java/com/flipkart/pibify/test/data/ClassWithReferences.java index 12b6306..080d992 100644 --- a/pibify-maven-plugin/src/test/java/com/flipkart/pibify/test/data/ClassWithReferences.java +++ b/pibify-maven-plugin/src/test/java/com/flipkart/pibify/test/data/ClassWithReferences.java @@ -21,6 +21,7 @@ import com.flipkart.pibify.core.Pibify; import com.flipkart.pibify.test.data.another.AnotherClassWithNativeCollections; +import java.util.Date; import java.util.Objects; /** @@ -36,8 +37,12 @@ public class ClassWithReferences { @Pibify(2) private String aString; + @Pibify(3) + private Date date; + public ClassWithReferences randomize() { aString = "str" + Math.random(); + date = new Date(System.currentTimeMillis()); reference = new AnotherClassWithNativeCollections(); reference.randomize(); return this; @@ -59,19 +64,23 @@ public void setaString(String aString) { this.aString = aString; } + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - + if (!(o instanceof ClassWithReferences)) return false; ClassWithReferences that = (ClassWithReferences) o; - return Objects.equals(reference, that.reference) && Objects.equals(aString, that.aString); + return Objects.equals(reference, that.reference) && Objects.equals(aString, that.aString) && Objects.equals(date, that.date); } @Override public int hashCode() { - int result = Objects.hashCode(reference); - result = 31 * result + Objects.hashCode(aString); - return result; + return Objects.hash(reference, aString, date); } }