CloudhopperCharsetSupportingEncoder.java
package fr.sii.ogham.sms.sender.impl.cloudhopper.encoder;
import com.cloudhopper.commons.charset.Charset;
import fr.sii.ogham.sms.encoder.Encoded;
import fr.sii.ogham.sms.encoder.EncodedMessage;
import fr.sii.ogham.sms.encoder.Encoder;
import fr.sii.ogham.sms.encoder.SupportingEncoder;
import fr.sii.ogham.sms.exception.message.EncodingException;
/**
* An {@link Encoder} that checks if the message can be encoded with a
* particular {@link Charset}.
*
* <p>
* To test if message can be encoded by the provided {@link Charset}, the
* message is first encoded into a byte array and then the byte array is decoded
* into a string (using {@link Charset#normalize(CharSequence)} method). If the
* result of normalization has not the same length, it means that the
* {@link Charset} can't handle the message properly.
*
* <p>
* Moreover, {@link Charset} implementations use '?' character if a character of
* original string can't be properly converted. Therefore, the number of '?'
* characters are count before and after normalization. If the number is not the
* same, it means that the {@link Charset} can't handle the message properly.
*
* @author Aurélien Baudet
*
*/
public class CloudhopperCharsetSupportingEncoder implements SupportingEncoder {
private final NamedCharset charset;
/**
* Initializes with the charset used to encode the message if it can.
*
* @param charset
* the charset to use
*/
public CloudhopperCharsetSupportingEncoder(NamedCharset charset) {
super();
this.charset = charset;
}
@Override
public Encoded encode(String message) throws EncodingException {
return new EncodedMessage(message, charset.getCharset().encode(message), charset.getCharsetName());
}
@Override
public boolean canEncode(String message) {
String normalized = charset.getCharset().normalize(message);
if (normalized.length() > message.length()) {
return false;
}
return countQuestionMarks(message) == countQuestionMarks(normalized);
}
private static long countQuestionMarks(String str) {
return str.chars().filter(ch -> ch == '?').count();
}
}