New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix immutable collection or map fields deserialization issue. #260
Conversation
…sageFactories accept check for IncrementalIdStrategy.
@dyu Would you help to review this PR? The change is small and focused, and I have added test cases to verify the specific issue. Many thanks. |
} | ||
catch (IllegalArgumentException e) | ||
{ | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an expensive way to check if it exists ... if there's no other way, then this will probably do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. Iterating the enums is probably heavy. How about caching it as static?
public static boolean accept(String name)
{
return MESSAGE_FACTORIES_NAMES.contains(name);
}
static Set<String> MESSAGE_FACTORIES_NAMES;
static
{
MessageFactories[] messageFactories = MessageFactories.values();
MESSAGE_FACTORIES_NAMES = new HashSet<String>(messageFactories.length);
for (MessageFactories messageFactory : messageFactories) {
MESSAGE_FACTORIES_NAMES.add(messageFactory.name());
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have updated the PR by using a less expensive way. Please check.
…cept less expensive by caching enum names.
…cept less expensive by caching enum names.
* This is used by {@link MessageFactories#accept(String)} method. Rather than iterating enums in runtime | ||
* which can be an expensive way to do, caching all the enums as static property will be a good way. | ||
*/ | ||
static Set<String> MESSAGE_FACTORIES_NAMES; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mark as final
* This is used by {@link MapSchema.MessageFactories#accept(String)} method. Rather than iterating enums in runtime | ||
* which can be an expensive way to do, caching all the enums as static property will be a good way. | ||
*/ | ||
static Set<String> MESSAGE_FACTORIES_NAMES; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mark as final
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch! done.
What changes were proposed in this pull request?
Immutable collection or map fields usually does not support operations like add/set/remove, for example
java.util.HashMap$KeySet
,com.google.common.collect.ImmutableCollection
, one solution is to createDelegate
for the specific type to do custommergeFrom
andwriteTo
action.In
DefaultIdStrategy
class, theregisterDelegate
method relies ontypeClass()
provided byDelegate
to get the class name.But in some cases where class name can not be initiated like
java.util.HashMap$KeySet
, because the inner class is not visible since the class modifier is default.So there should be a way to set specific class name manually. This PR add another
registerDelegate
method for people to specify class name.Moreover, this PR will solve the issue #227. If one collection is not inlined and cannot be found by
CollectionSchema$MessageFactories
, the following exception will be thrown.This PR also solves this issue by checking whether the collection or map class can be found in
CollectionSchema$MessageFactories
orMapSchema$MessageFactories
, if not the collection id or map id will use the full class name instead of simple class name.How was this patch tested?
Add two test cases in
AbstractRuntimeObjectSchemaTest
inprotosutff-runtime
module.One to check
java.util.HashMap$KeySet
can be ser and deser successfully.One to check customized immutable list can be ser and deser successfully.