Giter VIP home page Giter VIP logo

gson-fire's People

Contributors

camillem avatar dependabot[bot] avatar joaocpsantos avatar julman99 avatar jwir3 avatar sineaggi avatar swankjesse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gson-fire's Issues

Preventing infinite recursion caused by circular references

Jackson has a solution to serializing classes with bidirection references using @JsonIdentityInfo (For example, see http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion#json-identity-info). This way, you can serialize either object, and rather than causing a stack overflow error, it will just include a reference back to the object already included in the serialization.
It seems like Gson does not have a solution like that. Could that be added to gson-fire?

osgi is not more compatible with new version of gson

In my use case i'm usin gson-fire version 1.8.5 e Gson 2.8.5.

507 | Installed |  80 | 1.8.5                                    | Gson on Fire!
510 | Active    |  80 | 2.8.5                                    | Gson
karaf@root()> start 507
Error executing command: Error executing command on bundles:
        Error starting bundle 507: Unable to resolve io.gsonfire [507](R 507.0): missing requirement [io.gsonfire [507](R 507.0)] osgi.wiring.package; (osgi.wiring.package=com.google.gson.internal.bind) Unresolved requirements: [[io.gsonfire [507](R 507.0)] osgi.wiring.package; (osgi.wiring.package=com.google.gson.internal.bind)]

It’s probably due to the Gson upgrade. The new bundle no longer exports the com.google.gson.internal package. That package is considered internal, i.e. not part of the API so it should never have been exported by the bundle or used by any add-on. The classes in this package can have breaking changes with any release.

The solution is probably to removed the import com.google.gson.internal from the bnd manifest.

I see the solution is already done here:
escv@bf14654

recurcive deserialisation hooks

Threre is problem with recursive pre/post deserialization processing.

If I have class:

class Node {
int i;
Node n;
}

and I want deserialize following json:
{i:1,n:{i:2,n:{i:3}}}

so post deserialisation hook will be called once

Preprocessor for Array Insertion

May it possible adding a preprocessor/postprocessor to make some changes before/after inserting an array of objects?

I mean, something like this:

public class ArrayPreProcessor implements PreProcessor<List<MyClass>> {

    @Override
    public void preDeserialize(Class<? extends List<MyClass>> clazz, JsonElement src, Gson gson) {
         // whatever
    }

Any chance to be added in the future?

DateRFC3339TypeAdapter is not thread-safe

Weird bugs appeared in my application when DateRFC3339TypeAdapter was called simultaneously from different Threads. The RFC3339DateFormat seems to cause the problem.

Crash on old HTC devices

Some HTC devices with Android 2.3 contain pre-installed old version of gson library.
Creating GsonFireBuilder on them causes a crash:
Crash Reason:
java.lang.NoSuchMethodError:com.google.gson.GsonBuilder.registerTypeAdapterFactory

Exception Backtrace:
com.github.julman99.gsonfire.GsonFireBuilder.createGsonBuilder GsonFireBuilder.java, line 114

Related stackoverflow topic:
http://stackoverflow.com/questions/15609565/application-crashing-htc-explorer-a310e-when-using-gson

Support "Hooks" as annotations

We should have annotations called

@PreFromJson
@PostFromJson
@PreToJson
@PostToJson

That annotate methods and are triggered when a object is going to be converted from/to json

Serialize complex map keys to strings and back

Currently, when serializing maps, there are only two options for non-primitive keys:

  • Either don't do anything and it will be serialized with toString with no way back,
  • or enable complex key serialization and it will serialize the entrySet as list instead of the map.

The first one is bad because it doesn't allow deserialization, while I don't like the second one either because it reduces readability and it is overkill for less complex primitive keys.

My idea is to register a special type adapter to serialize objects of certain classes if they are found as map keys, but to and from Strings instead of JSON. For example, if you want to serialize a BitSet as key, it could look like this:

builder.registerMapKeyTypeAdapter(BitSet.class, new MapKeyTypeAdapter() {
	@Override
	public BitSet deserializeKey(String key) {
		return BitSet.valueOf(Base64.getDecoder().decode(key));
	}

	@Override
	public String serializeKey(BitSet key) {
		return Base64.getEncoder().encodeToString(key.toByteArray());
	}
});

My current workaround is to put the functionality into the serialization hooks while hiding the complex map from GSON and using a String-key copy.

Null pointer exception when serializing object with null field AND while using hooks and type selectors

I've mostly been using GSON and gson-fire for deserialization, and I've had no problems with that. However, I've been having a following problem when trying to serialize data. I've tried using the same GSON instance I use for deseriailzation, and this istance has hooks and a type selector enabled. When trying to serialize object that has a null value in one of his variables (both the object and the null attribute being of types covered by my custom type selector), I get a null pointer exception at HooksInvoker class, line 47. When I disable hooks, I get an exception at TypeSelectorTypeAdapterFactory, line 48. In both cases value/object variables are null when processing reaches the null object which is a part of the object being seriailzed.

I've momentarily solved this by using a different GSON instance for serialization, which doesn't use hooks nor type selection but that might not work for me in the future, and this seems to be a bug of some kind. At the very least, I think that hooks should totaly be ignored if object is null. Probably something similar should be done with the type selection.

Your library was otherwise very helpful to me, and I'm hoping you'll take a look at this. Thanks!

TypeAdapter does not respect `lenient` value

When using a preprocessor with a lenient gson instance, the FireTypeAdapter.deserialize call fails to propagate the reader's lenient setting through to the TypeAdapter's next read() call.

The result is the below failing test:

class GsonFireFixture {

    data class SimpleThingy(val name: String, val value: Double)

    @Test fun `when deserializing nan with lenient gson should properly deserialize`(){
        val gson = GsonFireBuilder()
                .registerPreProcessor(SimpleThingy::class.java, PreProcessor { _, _, _ -> /*noop*/ })
                .createGsonBuilder()
                .setLenient() //!!!
                .create()

        val json = """{"name":"bob","value":"NaN"}"""
        val result = gson.fromJson(json, SimpleThingy::class.java) //raises exception: 
        //java.lang.NumberFormatException: JSON forbids NaN and infinities: NaN
        //	at com.google.gson.internal.bind.JsonTreeReader.nextDouble(JsonTreeReader.java:214)

        assertThat(result.value).isEqualTo(Double.NaN)
    }
}

edit: the above code is kotlin, corresponding java can be supplied on request

I'm not familiar enogh with gson to know what the correct way to do this is.

Reuse Objects

I have an issue with the Gson library, and I found your library, which looks that can suit almost all my needs, except for this one, the possibility to reuse already parsed objects, for example, lets say you have this json:

{
    "data" : [
        {
            "id" : 1
            "type" : "student"
            "name" : "Student 1",
            "subjects" : [
                 {
                     "id": 1,
                     "type" : "subject"
                  }
             ]
        },
        {
            "id" : 2
            "type" : "student"
            "name" : "Student 2",
            "subjects" : [
                 {
                     "id": 1,
                     "type" : "subject",
                     "name" : "Math"
                 }
             ]
        },
        {
            "id" : 3
            "type" : "office"
            "name" : "student 3",
            "subjects" : [
                 {
                     "id": 1,
                     "type" : "subject",
                     "name" : "History"
                 },
                 {
                     "id": 2,
                     "type" : "subject",
                     "name" : "History"
                 }
             ]
        }
    ]
}

This is a very basic example, there are 3 students who assist to 0 or many classes. As you can see 2 or more students can have the same reference to an specific subject, but when I parse the object, Student 1 will have an object for subject 1, Student 2 will have a different object but with same information as the one for Student 1, so my question basically is, can this be achieved using the post-processors you have?

In theory what comes to mind is that before creating an object instance, there should be some kind of pool, so I look using the id and type, if I find the object I return it, otherwise I let the parser to create the instance for me. Do you have something for that case? Looks like its something between the Preprocessor and the Post-processor where you generate the actual Class.

I will appreciate any help or thoughts on this.

Missing Releases on Github

Hi,
I notice that the git repo has a tag for release 1.8.3, but there is no such release listed here on Github. Also, Maven Central has 1.8.3 so it has clearly been published.
I guess this is not a big issue. I was looking for a downloadable zip of the 1.8.3 source code, but I will just clone the repo and check out that tag instead.

Thanks,
Joel

Check for required fields

This is a pretty common request for Gson, so I thought maybe we could implement this using a custom PostProcessor?


I came up with this little thing, tell me what you think of it:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.SerializedName;

import io.gsonfire.PostProcessor;

public class DeserializeNullChecker implements PostProcessor<Object> {

	@Documented
	@Retention(RetentionPolicy.RUNTIME)
	@Target({ ElementType.FIELD })
	public @interface DeserializeNonNull {
	}

	@Override
	public void postDeserialize(Object result, JsonElement src, Gson gson) {
		check(result, src);
	}

	@Override
	public void postSerialize(JsonElement result, Object src, Gson gson) {
	}

	private void check(Object result, JsonElement src) {
		try {
			List<String> nullFields = new ArrayList<>();
			for (Field f : result.getClass().getDeclaredFields()) {
				if (f.isAnnotationPresent(DeserializeNonNull.class)) {
					String name = f.getName();
					if (f.isAnnotationPresent(SerializedName.class))
						name = f.getAnnotation(SerializedName.class).value();
					if (f.get(result) == null)
						nullFields.add('"' + name + '"');
				}
			}
			if (!nullFields.isEmpty()) {
				if (nullFields.size() == 1)
					throw new JsonParseException("Field " + nullFields.get(0) + " in object '"
							+ ellipsisString(src.toString())
							+ "' must be specified");
				else
					throw new JsonParseException("Fields " + nullFields + " in object '"
							+ ellipsisString(src.toString())
							+ "' must be specified");
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new JsonParseException("Could not check all null fields", e);
		}
	}

	private String ellipsisString(String text) {
		if (text.length() < 40)
			return text;
		else
			return text.substring(0, 30) + "[…]" + text.substring(text.length() - 10, text.length());
	}
}

Type Selector question

I have a large hierarchy of classes with a common base, but i don't appear to be able to use my common base, i'd need to specify each object that is extended. Is this correct?

e.g. say i have:
Class Base
A extends Base
B extends A
C extends B
(etc)

Can i not create a type selector from the base class for the extended model

.registerTypeSelector(Base.class, new TypeSelector<Base>() {
      @Override
      public Class<? extends Base> getClassForElement(JsonElement readElement) {
      ...

Add support for one-way serialization

The idea would be to annotate a field like with something similar to this (names might change):

@Expose
@OneWay(OneWaySerialization.serialize) 
private String someField;

That would cause to write someField only when serializing to json, but not when serializing from json.

The OneWaySerialization enum would have serialize and unserialize

Thanks @rubioz for the idea

Can't serialize NaN

Per the subject, if I get the GsonBuilder and set it to allow NaN, it is not taking effect and I get the following:

Exception in thread "main" java.lang.IllegalArgumentException: JSON forbids NaN and infinities: NaN
see comments below for updated exception and code.

Custom deserialization without deserializer/type adapter?

I got a lot of smaller classes that need custom (de)serialization logic. And I don't want to create a Type Adapter class for each of them, especially because this would require registering the adapter for the class and not all classes are known at runtime.

So I'd like to have something like:

public class MyData {
    private int dataField = 10;

    // @Annotation?
    private void writeJsonObject(/* args */) {
        // Custom logic here
    }

    // @Annotation?
    private void readJsonObject(/* args */) {
        // Custom logic here
    }
}

Both of the methods should be recognized and called automatically for the serialization without the need of registering it to the Gson object. Is something like this possible?

Inconsistent licensing information

Hi,
Could you please clarify the licensing status of the code :
The meta data in the pom file mentions the MIT license while the license file in the code mentions the Apache-2.0.
Thanks

Add more powerful wrapping/unwrapping

Is it possible to implement a feature similar to Jackson's @JsonUnwrap that would automatically wrap/unwrap a Json field (potentially unwrapping its field(s) further)?

Example of the desired behavior:

class Address {
    String street;
    String number;
}

class Person {
    String fullName;
    @GsonUnwrap Address address;
}

class Business {
    String businessName;
    @GsonUnwrap Person owner;
}

This would then allow a flat Json structure such as:

{ 
    "businessName" : "BN", 
    "fullName" : "Some Dude", 
    "street" : "Big street", 
    "number" : "301A"
}

to be (de)serialized to/from a Business object.

Ideally, the strategy for deciding what to unwrap would be configurable so that annotations (as used above) are only one option, so that editing the beans isn't necessary.
Going even further, supporting custom prefixing/suffixing to avoid name collision (see how I had to call fields businessName and fullName instead of just name) like @JsonUnwrap does would be absolute perfection.

Do you think this is feasible?

Support RFC3339 full-date

The standard supports a full-date format, which only contains date information, and does not have any time and timezone information. Currently the date serialiser rejects dates coming in this format. It would be also nice to add an option to the deserializer to only use full-date and not emit any time information, so consumers can accept the generated string even if they strictly only use the full-date part.

This full-date format is used by lots of frameworks like Swagger as default date type. Currently GSON Fire cannot work with them, because it expects and generates date-time.

BTW, full-time support can be also added, but that is less used.

Reuse Exclusion Strategies

Hi, is there a way to make classes that extend ExclusionByValueStrategy singleton? I profiled my app and the ExcludeLogic Class apparently gets created every time an object is being serialized, when there is really just one instance required.

Exclusion strategy for methods?

It would be useful to be able to write an ExclusionStrategy that could decide whether to skip methods, rather than always including every exposed method in the serialization.

This could be done by subclassing ExclusionStrategy to create a new class, like FireExclusionStrategy, that has a function shouldSkipMethod() as well as the ExclusionStrategy functions shouldSkipField() and shouldSkipClass(). Then when iterating over the exposed methods, they could be included only if they pass all FireExclusionStrategies.

Are you open to adding this to the library?

Unresolved requirement: Import-Package: com.google.gson.internal.bind

Hi,

when providing gson and gson-fire as modules in an osgi container gson-fire can't be resolved as it's referencing the internal package com.google.gson.internal.bind which is not exported by gson. Only by including both modules in every other module they're used in the problem disappears

I would love the get rid of all compileInclude statements and gson-fire is one of the last on my list I can't find a workaround for. Can you help me?

Thanks
Marc

Custom Deserialization of same field based on it's type

Hi
I am trying to use some of the features of this library particularly related to custom deserialization of one json element which can be an "array" or a "object". I need to fill the my class object based on if it is array or a plain object for eg.
below are 2 sample json where the "payload" element is "array" in the first example while it is an "object" in the second one.

"nat_b":{
payload":[
{
"provider":"1"
},
{
"provider":"2"
},
{
"provider":"3"
}
]
}

OR

"nat_b":{
payload": {
"index":"3"
},
"comment":"1"
}

I have contemplated using either "registerTypeSelector" or "registerPreProcessor" but the issue is the "payload" element is under 4-5 level nesting and getting the type of the field is proving to be tricky and based on the type of element it is, how will I return the that type.
do you have any suggestions here ?

Access to JsonElement in @PostDeserialize

It seems that @PostDeserialize'd methods need to have 0 arguments. Is there a way to access the source JsonElement from within the method?

If not, could it be added as an argument please?

This would be useful when the JSON contains keys that do not have matching property names in the class.

I'd be happy to submit a pull request with changes to FireTypeAdapter.java and HooksInvoker.java if that makes sense.

Use custom deserialization after registerTypeSelector

Firstly, thx for a great add-on to gson!

I am using registerTypeSelector to find the type when doing deserializations and it works as expected. Though, my json looks like below and I only want to select the event field when doing the actual deserialization to an object. How would i approach this? I tried using registerPreProcessor and alter the src like src = src.getAsJsonObject().getAsJsonObject("event"); but it doesn't seam to work. Is there a way to actually do this or is it outside of the gson-fire scope?

{
  "event" : { "id": 1, "name": "Fredrik"},
  "type" : "UserCreatedEvent"
}

Thanks!

Create an Iterable wrapper to be able to serialize and unserialize Iterables

Right now Gson does not support Iterables. This might a be a problem because in some cases one might want to work with inmutable streams of elements, and Collections are not inmutable.

The idea would be to create a final class called GsonIterable or similar, that wraps an Iterable and allows its serialization and unserialization as an inmutable stream of elements.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.