Skip to content

Commit

Permalink
Add more Serializers/Deserializers and lots of fixed to support Jakar…
Browse files Browse the repository at this point in the history
…ta annotations. Added more Tests.
  • Loading branch information
BidyadharM committed Dec 6, 2024
1 parent 158d73b commit 4adcef6
Show file tree
Hide file tree
Showing 31 changed files with 1,726 additions and 55 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
** Copyright (c) 2024 Oracle and/or its affiliates.
**
** The Universal Permissive License (UPL), Version 1.0
**
** Subject to the condition set forth below, permission is hereby granted to any
** person obtaining a copy of this software, associated documentation and/or data
** (collectively the "Software"), free of charge and under any and all copyright
** rights in the Software, and any and all patent rights owned or freely
** licensable by each licensor hereunder covering either (i) the unmodified
** Software as contributed to or provided by such licensor, or (ii) the Larger
** Works (as defined below), to deal in both
**
** (a) the Software, and
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
** one is included with the Software (each a "Larger Work" to which the Software
** is contributed by such licensors),
**
** without restriction, including without limitation the rights to copy, create
** derivative works of, display, perform, and distribute the Software and make,
** use, sell, offer for sale, import, export, have made, and have sold the
** Software and the Larger Work(s), and to sublicense the foregoing rights on
** either these or other terms.
**
** This license is subject to the following condition:
** The above copyright notice and either this complete permission notice or at
** a minimum a reference to the UPL must be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/

package oracle.jdbc.provider.oson;

import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import jakarta.persistence.Column;


public class AnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public PropertyName findNameForSerialization(Annotated a) {
Column column = _findAnnotation(a, Column.class);
if (column != null && !column.name().isEmpty()) {
return PropertyName.construct(column.name());
}
return super.findNameForSerialization(a);
}

@Override
public PropertyName findNameForDeserialization(Annotated a) {
Column column = _findAnnotation(a, Column.class);
if (column != null && !column.name().isEmpty()) {
return PropertyName.construct(column.name());
}
return super.findNameForDeserialization(a);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import oracle.jdbc.spi.OsonConverter;
import oracle.sql.json.OracleJsonGenerator;
import oracle.sql.json.OracleJsonParser;
Expand Down Expand Up @@ -70,6 +72,8 @@ public class JacksonOsonConverter implements OsonConverter{
static {
om.findAndRegisterModules();
om.registerModule(new OsonModule());
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.setAnnotationIntrospector(new AnnotationIntrospector());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,26 @@
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.base.GeneratorBase;
import com.fasterxml.jackson.core.json.JsonWriteContext;
import oracle.jdbc.driver.json.tree.OracleJsonDateImpl;
import oracle.jdbc.driver.json.tree.OracleJsonTimestampImpl;
import oracle.sql.DATE;
import oracle.sql.TIMESTAMP;
import oracle.sql.json.OracleJsonDate;
import oracle.sql.json.OracleJsonFactory;
import oracle.sql.json.OracleJsonGenerator;
import oracle.sql.json.OracleJsonTimestamp;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.sql.Timestamp;
import java.time.*;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -99,6 +106,7 @@ protected OsonGenerator(int features, ObjectCodec codec, OracleJsonGenerator gen
protected OsonGenerator(int features, ObjectCodec codec, OracleJsonGenerator gen) {
super(features, codec);
this.gen = gen;

}

/**
Expand Down Expand Up @@ -339,7 +347,7 @@ public void writeRaw(char c) throws IOException {
@Override
public void writeBinary(Base64Variant bv, byte[] data, int offset, int len) throws IOException {
_verifyValueWrite("writeBinary");
// gen.write(Base64.getEncoder().encode(Arrays.copyOfRange(data, offset, offset+len)));
// gen.write(bv.encode(Arrays.copyOfRange(data, offset, offset+len)));
gen.write(Arrays.copyOfRange(data, offset, offset+len));
}

Expand Down Expand Up @@ -514,5 +522,26 @@ public void close() throws IOException {
gen.close();
closed = true;
}


public void writeDate(Date value) throws IOException {
_verifyValueWrite("write date");

if(value instanceof java.sql.Date) {
DATE dd = new DATE((java.sql.Date)value);
OracleJsonDate jsonDate = new OracleJsonDateImpl(dd.shareBytes());
gen.write(jsonDate);
}else {
// java.util.Date
DATE dd = new DATE(new java.sql.Date(value.getTime()));
OracleJsonDate jsonDate = new OracleJsonDateImpl(dd.shareBytes());
gen.write(jsonDate);
}
}

public void writeTimeStamp(Timestamp value) throws IOException {
_verifyValueWrite("write TimeStamp");
TIMESTAMP timestamp = new TIMESTAMP(value);
OracleJsonTimestamp writeTimeStamp = new OracleJsonTimestampImpl(timestamp.shareBytes());
gen.write(writeTimeStamp);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,30 @@

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.core.util.VersionUtil;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.deser.SettableBeanProperty;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.SqlTimeSerializer;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import jakarta.persistence.Convert;
import jakarta.persistence.OneToMany;
import oracle.jdbc.provider.oson.deser.*;
import oracle.jdbc.provider.oson.ser.*;

import java.io.InputStream;
import java.io.Serializable;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.*;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.UUID;


/**
Expand Down Expand Up @@ -127,8 +139,76 @@ public OsonModule() {
addDeserializer(byte[].class, OsonByteDeserializer.INSTANCE);
addSerializer(byte[].class, OsonByteSerializer.INSTANCE);

addDeserializer(Date.class, OsonDateDeserializer.INSTANCE);
addSerializer(Date.class, OsonDateSerializer.INSTANCE);

addDeserializer(java.util.Date.class, OsonDateDeserializer.INSTANCE);
addSerializer(java.util.Date.class, OsonDateSerializer.INSTANCE);

addDeserializer(java.sql.Date.class, OsonSqlDateDeserializer.INSTANCE);
addDeserializer(Timestamp.class, OsonTimeStampDeserializer.INSTANCE);

addDeserializer(UUID.class, OsonUUIDDeserializer.INSTANCE);
addDeserializer(Boolean.class, OsonBooleanDeserializer.INSTANCE);


}

@Override
public void setupModule(SetupContext context) {
super.setupModule(context);

context.addBeanSerializerModifier(new BeanSerializerModifier() {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
Iterator<PropertyWriter> properties = serializer.properties();
while (properties.hasNext()) {
BeanPropertyWriter writer = (BeanPropertyWriter) properties.next();
if (writer.getMember().hasAnnotation(Convert.class)) {
Convert annotation = writer.getMember().getAnnotation(Convert.class);
Class<? extends jakarta.persistence.AttributeConverter> converterClass = annotation.converter();
if (writer.getType().isArrayType()) {
JsonSerializer<?> mySerializer = new OsonConverterArraySerializer(converterClass);
writer.assignSerializer((JsonSerializer<Object>) mySerializer);
} else {
JsonSerializer<Object> mySerializer = new OsonConverterSerialiser(converterClass);
writer.assignSerializer(mySerializer);
}


}
}
return serializer;
}

@Override
public JsonSerializer<?> modifyEnumSerializer(SerializationConfig config, JavaType valueType, BeanDescription beanDesc, JsonSerializer<?> serializer) {
return new OsonEnumSerializer(false,false);
}
});

context.addBeanDeserializerModifier(new BeanDeserializerModifier() {

@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if(deserializer instanceof BeanDeserializer){
Iterator<SettableBeanProperty> properties = ((BeanDeserializer) deserializer).properties();
while (properties.hasNext()) {
SettableBeanProperty property = properties.next();
if (property.getMember().hasAnnotation(Convert.class)) {
Convert annotation = property.getMember().getAnnotation(Convert.class);
Class<? extends jakarta.persistence.AttributeConverter> converterClass = annotation.converter();

if(property.getType().isArrayType()){
JsonDeserializer<Object[]> deser = new OsonConverterArrayDeserializer(converterClass);
((BeanDeserializer) deserializer).replaceProperty(property,property.withValueDeserializer(deser));
} else {
JsonDeserializer<Object> deser = new OsonConverterDeserializer(converterClass);
((BeanDeserializer) deserializer).replaceProperty(property,property.withValueDeserializer(deser));
}
}
}
return deserializer;
}
return deserializer;
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ public JsonParser skipChildren() throws IOException {
if(currentEvent == Event.START_OBJECT) {
parser.skipObject();
}

return this;
}
@Override
Expand Down Expand Up @@ -305,6 +306,10 @@ public int currentTokenId() {
return JsonTokenId.ID_NO_TOKEN;
}

public OracleJsonParser.Event currentOsonEvent() {
return currentEvent;
}

/**
* Get the current Token ID.
*/
Expand Down Expand Up @@ -584,4 +589,9 @@ public Period readPeriod() {
return parser.getPeriod();
}
}

public LocalDateTime getLocalDateTime() {
if(DEBUG) logger.log(Level.FINEST, "getLocalDateTime");
return parser.getLocalDateTime();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
** Copyright (c) 2024 Oracle and/or its affiliates.
**
** The Universal Permissive License (UPL), Version 1.0
**
** Subject to the condition set forth below, permission is hereby granted to any
** person obtaining a copy of this software, associated documentation and/or data
** (collectively the "Software"), free of charge and under any and all copyright
** rights in the Software, and any and all patent rights owned or freely
** licensable by each licensor hereunder covering either (i) the unmodified
** Software as contributed to or provided by such licensor, or (ii) the Larger
** Works (as defined below), to deal in both
**
** (a) the Software, and
** (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
** one is included with the Software (each a "Larger Work" to which the Software
** is contributed by such licensors),
**
** without restriction, including without limitation the rights to copy, create
** derivative works of, display, perform, and distribute the Software and make,
** use, sell, offer for sale, import, export, have made, and have sold the
** Software and the Larger Work(s), and to sublicense the foregoing rights on
** either these or other terms.
**
** This license is subject to the following condition:
** The above copyright notice and either this complete permission notice or at
** a minimum a reference to the UPL must be included in all copies or
** substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/

package oracle.jdbc.provider.oson.deser;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers.BooleanDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import oracle.jdbc.provider.oson.OsonParser;

import java.io.IOException;

public class OsonBooleanDeserializer extends StdScalarDeserializer<Boolean> {
public static final OsonBooleanDeserializer INSTANCE = new OsonBooleanDeserializer();
public static final BooleanDeserializer WRAPPER_INSTAMCE = new BooleanDeserializer(Boolean.class,null);

protected OsonBooleanDeserializer() {
super(Boolean.class);
}

@Override
public Boolean deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
if (p instanceof OsonParser) {
switch (p.getCurrentToken()) {
case VALUE_STRING:
{
String str = p.getText();
if (str.equalsIgnoreCase("Y")) {
return Boolean.TRUE;
} else if (str.equalsIgnoreCase("N")) {
return Boolean.FALSE;
}
}
default:
return WRAPPER_INSTAMCE.deserialize(p, ctxt);
}
}
return WRAPPER_INSTAMCE.deserialize(p, ctxt);
}
}
Loading

0 comments on commit 4adcef6

Please sign in to comment.