Skip to content
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

Support proto maps stringification #383

Merged
merged 105 commits into from
Mar 27, 2017

Conversation

illia-shepilov
Copy link
Contributor

@illia-shepilov illia-shepilov commented Mar 10, 2017

Summary of changes:

  • Created the MapStringifier class.
  • Created the tests for the MapStringifier class.
  • Created the Types utility class.

The usage of the MapStringifier:

// Stringifier creation.
final Stringifier<Map<String, Long>> mapStringifier = Stringifiers.mapStringifier(String.class, Long.class);
// The registration of the stringifier.
final Type type = new TypeToken<Map<String, Long>>(){}.getType();
StringifierRegistry.getInstance().register(stringifier, type);
// Obtain already registered `MapStringifier`.
final Type type = Types.mapTypeOf(String.class, Long.class);
final Stringifier<Map<String, Long>> mapStringifier = StringifierRegistry.getInstance().getStringifier(type);

// Convert to string.
final Map<String, Long> mapToConvert = newHashMap();
mapToConvert.put("first", 1);
mapToConvert.put("second", 2);
 
// The result is: \"first\":\"1\",\"second\":\"2\".
final String convertedString = mapStringifier.toString(mapToConvert);

// Convert from string.
final String stringToConvert = ...
final Map<String, Long> convertedMap = mapStringifier.fromString(stringToConvert); 

@codecov
Copy link

codecov bot commented Mar 10, 2017

Codecov Report

Merging #383 into master will increase coverage by 0.05%.
The diff coverage is 95.65%.

@@             Coverage Diff             @@
##             master    #383      +/-   ##
===========================================
+ Coverage     91.84%   91.9%   +0.05%     
- Complexity     2395    2428      +33     
===========================================
  Files           240     243       +3     
  Lines          7750    7842      +92     
  Branches        558     562       +4     
===========================================
+ Hits           7118    7207      +89     
- Misses          486     490       +4     
+ Partials        146     145       -1

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 94393b7...d1adbac. Read the comment docs.

@illia-shepilov illia-shepilov self-assigned this Mar 10, 2017
Copy link
Contributor

@alexander-yevsyukov alexander-yevsyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my comments, add coverage, and escaping of delimiters in the input strings.

}

@SuppressWarnings("unchecked") // It is OK because class is verified.
private static <I> I getConvertedElement(Class<I> elementClass, String elementToConvert) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't get here, but convert.

}
}

private static boolean isStringClass(Class<?> aClass) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not isString?

@illia-shepilov illia-shepilov changed the base branch from stringifiers-and-identifiers-separation to master March 10, 2017 17:08
Copy link
Contributor

@alexander-yevsyukov alexander-yevsyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address my minor comments, and it would be LGTM.

if (keyValue.length != 2) {
final String exMessage =
"Illegal key-value format. The value should " +
"be separated with a single `:` character.";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please have constant for the separator character and use it in the message. Consider avoiding back-ticks. You can name the character (colon) and then quote it.

}
}

@SuppressWarnings("unchecked") // It is OK because class is verified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by “verified”?

@illia-shepilov
Copy link
Contributor Author

@alexander-yevsyukov PTAL.

Copy link
Contributor

@alexander-yevsyukov alexander-yevsyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed vocally, please store key value in quotes with colon as the separator (which would be similar to Json).

Copy link
Contributor

@alexander-yevsyukov alexander-yevsyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see one more question.

@SuppressWarnings("unchecked") // It is OK because class is verified.
private static <I> I convert(Class<I> elementClass, String elementToConvert) {

if (isInteger(elementClass)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we add stringifiers for well-known types instead?

@illia-shepilov
Copy link
Contributor Author

@alexander-yevsyukov PTAL.

Copy link
Contributor

@alexander-yevsyukov alexander-yevsyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see my comments and questions.

new AbstractMap.SimpleEntry<>(convertedKey, convertedValue);
return convertedBucket;
} catch (Throwable e) {
throw newIllegalArgumentException("The exception is occurred during the conversion", e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"The exception is occurred during the conversion"

Without ”is” it would read a bit better. Please also test this case.

Copy link
Contributor Author

@illia-shepilov illia-shepilov Mar 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is tested with the throw_exception_when_passed_parameter_does_not_match_expected_format test.
But CodeCove extension shows it as uncovered.

private static final long serialVersionUID = 1L;

public ConversionException(String message, Throwable cause) {
super(message, cause);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add test coverage.

Copy link
Contributor Author

@illia-shepilov illia-shepilov Mar 25, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That exception is not used in that PR, but it is used in the next PR according to stringifiers.

return unquotedValue;
}

private static boolean isQuotedKeyValue(String[] keyValue) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we pass a string array here? Why not two strings?

final int keyLength = key.length();
final int valueLength = value.length();

if (keyLength < 2 || valueLength < 2) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please test all branches.

return false;
}

final boolean result = isQuote(key.charAt(1)) && isQuote(key.charAt(keyLength - 1)) &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add a utility method called isQuotedString(). Please check for such a thing already available.

final String escapedChar = "\\" + charToEscape;
final Escaper result = Escapers.builder()
.addEscape('\"', "\\\"")
.addEscape(':', "\\:")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we still need to escape the colon character?

static class LongStringifier extends Stringifier<Long>{
@Override
protected String toString(Long obj) {
return Longs.stringConverter().reverse().convert(obj);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please format the code here and other similar places.


final Type type = new TypeToken<Map<K, V>>() {}.where(new TypeParameter<K>() {}, keyClass)
.where(new TypeParameter<V>() {}, valueClass)
.getType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Круто! 👍

@illia-shepilov
Copy link
Contributor Author

@alexander-yevsyukov PTAL.

Copy link
Contributor

@alexander-yevsyukov alexander-yevsyukov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address code formatting comments before merging. The rest LGTM.

@@ -116,8 +116,36 @@ public void convert_string_which_contains_delimiter_in_content_to_map(){
}

@Test(expected = IllegalArgumentException.class)
public void throw_exception_when_key_value_are_incorrect(){
public void throw_exception_when_value_has_not_prior_quote(){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please allow one space char before { here and in the methods below.

return result;
}

private static boolean isQuote(char character) {
private static boolean isQuote(char character){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add one space char before {.

@illia-shepilov illia-shepilov merged commit c5e41b6 into master Mar 27, 2017
@illia-shepilov illia-shepilov deleted the support-proto-maps-stringification branch March 27, 2017 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants