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

Implement xml:lang support in ConnectionConfiguration and AbstractXMPPConnection #325

Closed
wants to merge 1 commit into from

Conversation

ge0rg
Copy link
Contributor

@ge0rg ge0rg commented Jul 26, 2019

This patch makes it possible to change the stream-level language as part
of the connection configuration, to allow a properly implemented
entities to provide i18n'ed response messages.

This code does not cover XMPPBOSHConnection!

X-Signed-Off-By: Georg Lukas georg@op-co.de

@GitCop
Copy link

GitCop commented Jul 26, 2019

There were the following issues with your Pull Request

  • Commit: ffd3432
  • Your subject line is longer than 72 characters

Guidelines are available at https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors


This message was auto-generated by https://gitcop.com

@@ -118,6 +118,8 @@
private final String password;
private final Resourcepart resource;

private final String language;
Copy link
Member

Choose a reason for hiding this comment

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

This should be of type java.util.Locale.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Isn't a locale more than just the language? Are we going to have issues of ambiguity here?

Copy link
Member

@Flowdalic Flowdalic Jul 27, 2019

Choose a reason for hiding this comment

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

Isn't a locale more than just the language?

"A locale" yes, it describes how your date is formatted, your preferred input method and other things.

But think of java.util.Locale as a wrapper around BCP 47, which is what xml:lang also uses.

Are we going to have issues of ambiguity here?

I don't see any.

* @param language the language to use.
* @return a reference to this builder.
* @see <a href="https://tools.ietf.org/html/rfc6120#section-4.7.4">RFC 6120 § 4.7.4</a>
*/
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to additionally add a @see to linking to "XML 1.0 § 2.12" https://www.w3.org/TR/xml/#sec-lang-tag

@GitCop
Copy link

GitCop commented Jul 29, 2019

There were the following issues with your Pull Request

  • Commit: ffd3432
  • Your subject line is longer than 72 characters

Guidelines are available at https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors


This message was auto-generated by https://gitcop.com

@ge0rg
Copy link
Contributor Author

ge0rg commented Jul 29, 2019

So I've updated the code, just to realize that Locale.toLanguageTag() didn't exist in Android prior to r21. No idea how it even compiled with targetSdkLevel 17. I suppose the least ugly workaround would be to use Locale.toString.replace("_", "-"). Other ideas?

@Flowdalic
Copy link
Member

No idea how it even compiled with targetSdkLevel 17.

What did you compile against an Android API 17 runtime jar? Smack, besides smack-android and smack-android-extensions is compiled with the Java SE runtime jar set bootstrapClasspath.

But do not worry, Smack also uses AnimalSniffer to ensure Android compatibility, which got you covered here and is the reason travis fails for the PR in the current state.

I suppose the least ugly workaround would be to use Locale.toString.replace("_", "-"). Other ideas?

Works for me. We can always switch to a better approach if we come up with one. Please also add the following comment:

// TODO: Change to Locale.toLanguageTag() once Smack's minimum Android API level is 21 or higher

Thanks

@GitCop
Copy link

GitCop commented Jul 30, 2019

There were the following issues with your Pull Request

  • Commit: ffd3432
  • Your subject line is longer than 72 characters

Guidelines are available at https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors


This message was auto-generated by https://gitcop.com

@@ -577,7 +578,7 @@ public boolean isEnabledSaslMechanism(String saslMechanism) {
private CharSequence username;
private String password;
private Resourcepart resource;
private String language = "en";
private Locale language = Locale.ENGLISH;
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason to not use Locale.getDefault() to initialize the value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't dare to change the default, which was "en". If you feel that using the default locale is good, and it's not going to break anything, I can patch it in.

Copy link
Member

Choose a reason for hiding this comment

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

I'm pretty sure, that there may be some tests that might break on non-english systems.
There was one such case pretty recently, but fixing those tests in the first place is probably a good idea :D

Copy link
Member

Choose a reason for hiding this comment

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

What @vanitasvitae said :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The "nice" thing about that is that now we are leaking the environment of the user into the test setup, and from my experience, it will only break on locales that are not used by the maintainers in the first place, like Turkish (capital "i"), or Arabic (number parsing / formatting will bite you!). Feel free to rework the test setup to iterate through all existing locales, but I'm keeping this status-quo as is in this PR.

@@ -2012,7 +2012,7 @@ protected void sendStreamOpen() throws NotConnectedException, InterruptedExcepti
from = XmppStringUtils.completeJidFrom(localpart, to);
}
String id = getStreamId();
sendNonza(new StreamOpen(to, from, id));
sendNonza(new StreamOpen(to, from, id, config.getLanguage().toString().replace("_", "-"), StreamOpen.StreamContentNamespace.client));
Copy link
Member

Choose a reason for hiding this comment

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

This could cause an NPE if language is null. I suggest to create a ConnectionConfiguration.getLanguageTag() method which returns null if language is null. This is also the method the TODO comment should go to, which I am still missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, right. The TODO comment! Sorry about that! Is there a particular reason why getLanguageTag should return null and not the default "en" value?

Copy link
Member

Choose a reason for hiding this comment

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

Sorry about that! Is there a particular reason why getLanguageTag should return null

It is not getLanguageTag() that I am worried about returning null, it is getLanguage(). Currently it is possible to set the language to null in the configuration, and that is desirable given that xml:lang in stream open elements is optional. But the code should take that into consideration and not throw NPEs in that, arguably rare, case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood. The questions that I'm looking at, are:

  • is it reasonable to allow the user to supply a null Locale?
  • what is the expected outcome in that case? "en", "" or no xml:lang tag at all?

Copy link
Member

@Flowdalic Flowdalic Jul 31, 2019

Choose a reason for hiding this comment

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

  • is it reasonable to allow the user to supply a null Locale?

I think so, especially for integration tests and the like. The point is, the standard is designed with an non-existing xml:lang in the stream open element in mind, and a library implementing the standard should allow for it. Of course, users deliberately providing a null value here, go down the "you should know what you are doing" road. And that is why Smack defaults to a non-empty xml:lang.

  • what is the expected outcome in that case? "en", "" or no xml:lang tag at all?

No xml:lang at all, otherwise the user would have provided Locale.ENGLISH for "en" or a Locale which returns the empty string as language tag for "".

The latter case is especially interesting: values where the empty string is allowed often cause pain, as, for example, their semantic is usually not as clearly defined as people believe to be or cause different behavior by different implementations. I really would like to be able to investigate how server implementations behave if a stream open with xml:lang="" is send (AFAIKT it is not explicitly forbidden by the standard). That said, given the current design we are aiming for, it is not possible to configure Smack to do so. That is because

jshell> var l = new java.util.Locale("");
l ==> 
jshell> l.getLanguage()
$3 ==> ""
jshell> l.toLanguageTag()
$4 ==> "und"

so once we use toLangaugeTag() which is the goal, using a Locale constructed with the empty string as sole argument, will cause toLanguageTag() to return "und" (which I assume stands for 'undefined'). Hence the stream open will carry xml:lang="und".

That means we should probably not introduce a method ConnectionConfiguration.getLanguageTag(), but ConnectionConfiguration.getXmlLang(), which

  • returns null if language is null
  • returns "" if language.getLanguage() returns the empty string
  • returns language.toLanguageTag() otherwise

@GitCop
Copy link

GitCop commented Jul 31, 2019

There were the following issues with your Pull Request

  • Commit: ffd3432
  • Your subject line is longer than 72 characters

Guidelines are available at https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors


This message was auto-generated by https://gitcop.com

* @return the stream language to use when connecting to the server.
*/
public String getXmlLang() {
// TODO: use language.getLanguageTag() once we are on Java1.8 / Android r21+
Copy link
Member

Choose a reason for hiding this comment

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

Could you please use the exact comment string as I mentioned? I using this "pattern" allows me to grep Smack's source code for those situations and eventually fix them once the minimum Android API level was raised.

public String getXmlLang() {
// TODO: use language.getLanguageTag() once we are on Java1.8 / Android r21+
// This will need a workaround for new Locale("").getLanguageTag() returning "und".
// Discussion in https://github.com/igniterealtime/Smack/pull/325
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer an in-code comment summarizing the discussion, but this is also ok.

@GitCop
Copy link

GitCop commented Jul 31, 2019

There were the following issues with your Pull Request

  • Commit: ffd3432
  • Your subject line is longer than 72 characters

Guidelines are available at https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors


This message was auto-generated by https://gitcop.com

@Flowdalic
Copy link
Member

This looks like it is good to go. Please squash the commits.

…PConnection

This patch makes it possible to change the stream-level language as part
of the connection configuration, to allow a properly implemented
entities to provide i18n'ed response messages. The Locale type is used
for this configuration, and the effective language string can be
obtained via `ConnectionConfiguration.getXmlLang()`.

This code does not cover XMPPBOSHConnection!

Signed-off-by: Georg Lukas <georg@op-co.de>
@GitCop
Copy link

GitCop commented Aug 3, 2019

There were the following issues with your Pull Request

  • Commit: faaf8aa
  • Your subject line is longer than 72 characters

Guidelines are available at https://github.com/igniterealtime/Smack/wiki/Guidelines-for-Smack-Developers-and-Contributors


This message was auto-generated by https://gitcop.com

@Flowdalic
Copy link
Member

Applied with minor modifications as 6a0e0f0

Thanks for your contribution.

@Flowdalic Flowdalic closed this Aug 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants