| 1 | package fr.sii.ogham.sms.sender.impl.cloudhopper.preparator; | |
| 2 | ||
| 3 | import static com.cloudhopper.commons.charset.CharsetUtil.NAME_GSM; | |
| 4 | import static com.cloudhopper.commons.charset.CharsetUtil.NAME_GSM7; | |
| 5 | import static com.cloudhopper.commons.charset.CharsetUtil.NAME_GSM8; | |
| 6 | import static com.cloudhopper.commons.charset.CharsetUtil.NAME_PACKED_GSM; | |
| 7 | import static com.cloudhopper.commons.charset.CharsetUtil.NAME_UCS_2; | |
| 8 | import static com.cloudhopper.commons.gsm.DataCoding.CHAR_ENC_8BIT; | |
| 9 | import static com.cloudhopper.commons.gsm.DataCoding.CHAR_ENC_DEFAULT; | |
| 10 | import static com.cloudhopper.commons.gsm.DataCoding.CHAR_ENC_UCS2; | |
| 11 | import static java.util.Collections.unmodifiableMap; | |
| 12 | ||
| 13 | import java.util.HashMap; | |
| 14 | import java.util.Map; | |
| 15 | ||
| 16 | import com.cloudhopper.commons.charset.Charset; | |
| 17 | import com.cloudhopper.commons.charset.CharsetUtil; | |
| 18 | import com.cloudhopper.commons.gsm.DataCoding; | |
| 19 | ||
| 20 | import fr.sii.ogham.sms.encoder.Encoded; | |
| 21 | import fr.sii.ogham.sms.sender.impl.cloudhopper.encoder.NamedCharset; | |
| 22 | import fr.sii.ogham.sms.sender.impl.cloudhopper.exception.DataCodingException; | |
| 23 | import fr.sii.ogham.sms.sender.impl.cloudhopper.exception.UnsupportedCharsetException; | |
| 24 | ||
| 25 | /** | |
| 26 | * Provide a Data Coding Scheme according to charset used to encode the message. | |
| 27 | * The resulting encoding is <b>General Data Coding Group</b>: | |
| 28 | * | |
| 29 | * <ul> | |
| 30 | * <li>If Bits 4 {@literal &} 5 are 0 {@literal &} 0 then see above "0000 | |
| 31 | * Character Encoding Group"</li> | |
| 32 | * <li>Message Class (Bit 0 {@literal &} 1) (default 0, 0)</li> | |
| 33 | * <li>Alphabet (Bit 2 {@literal &} 3) (default 0, 0)</li> | |
| 34 | * <li>Message Class Present (Bit 4) (whether bits 0 {@literal &} 1 have | |
| 35 | * meaning)</li> | |
| 36 | * <li>Compression Flag (Bit 5) (0 - uncompressed, 1 - compressed)</li> | |
| 37 | * </ul> | |
| 38 | * | |
| 39 | * | |
| 40 | * <strong>WARNING:</strong> This provider only supports GSM 7-bit, GSM 8-bit | |
| 41 | * and UCS-2 charsets. This is due to use of | |
| 42 | * {@link DataCoding#createGeneralGroup(byte, Byte, boolean)} that only accepts | |
| 43 | * {@link DataCoding#CHAR_ENC_DEFAULT}, {@link DataCoding#CHAR_ENC_8BIT}, | |
| 44 | * {@link DataCoding#CHAR_ENC_UCS2}. | |
| 45 | * | |
| 46 | * | |
| 47 | * @author Aurélien Baudet | |
| 48 | * | |
| 49 | */ | |
| 50 | public class CharsetMapToGeneralGroupDataCodingProvider implements DataCodingProvider { | |
| 51 | private final boolean failIfUnknown; | |
| 52 | private final Map<String, Byte> alphabetIndexedByCharsetName; | |
| 53 | private final Byte messageClass; | |
| 54 | private final boolean compressed; | |
| 55 | ||
| 56 | /** | |
| 57 | * Provides {@link DataCoding} based on the charset used to encode the | |
| 58 | * message. | |
| 59 | * | |
| 60 | * <p> | |
| 61 | * The default map is used (charset name {@literal ->} alphabet): | |
| 62 | * <ul> | |
| 63 | * <li>{@link CharsetUtil#NAME_GSM7} {@literal ->} | |
| 64 | * {@link DataCoding#CHAR_ENC_DEFAULT}</li> | |
| 65 | * <li>{@link CharsetUtil#NAME_PACKED_GSM} {@literal ->} | |
| 66 | * {@link DataCoding#CHAR_ENC_DEFAULT}</li> | |
| 67 | * <li>{@link CharsetUtil#NAME_GSM} {@literal ->} | |
| 68 | * {@link DataCoding#CHAR_ENC_8BIT}</li> | |
| 69 | * <li>{@link CharsetUtil#NAME_GSM8} {@literal ->} | |
| 70 | * {@link DataCoding#CHAR_ENC_8BIT}</li> | |
| 71 | * <li>{@link CharsetUtil#NAME_UCS_2} {@literal ->} | |
| 72 | * {@link DataCoding#CHAR_ENC_UCS2}</li> | |
| 73 | * </ul> | |
| 74 | * | |
| 75 | * | |
| 76 | * <p> | |
| 77 | * The message class is set to {@code null}. | |
| 78 | * | |
| 79 | * <p> | |
| 80 | * The compressed field is set to false. | |
| 81 | * | |
| 82 | * @param failIfUnknown | |
| 83 | * if true it throws {@link UnsupportedCharsetException}, if | |
| 84 | * false is returns null to let other | |
| 85 | * {@link DataCodingProvider}(s) being executed. | |
| 86 | * | |
| 87 | */ | |
| 88 | public CharsetMapToGeneralGroupDataCodingProvider(boolean failIfUnknown) { | |
| 89 | this(failIfUnknown, defaultMap()); | |
| 90 | } | |
| 91 | ||
| 92 | /** | |
| 93 | * Provides {@link DataCoding} based on the charset used to encode the | |
| 94 | * message. | |
| 95 | * | |
| 96 | * <p> | |
| 97 | * It uses the provided map to determine alphabet from the charset used to | |
| 98 | * encode the message. | |
| 99 | * | |
| 100 | * <p> | |
| 101 | * The message class is set to {@code null}. | |
| 102 | * | |
| 103 | * <p> | |
| 104 | * The compressed field is set to false. | |
| 105 | * | |
| 106 | * | |
| 107 | * | |
| 108 | * @param failIfUnknown | |
| 109 | * if true it throws {@link UnsupportedCharsetException}, if | |
| 110 | * false is returns null to let other | |
| 111 | * {@link DataCodingProvider}(s) being executed. | |
| 112 | * @param alphabetIndexedByCharsetName | |
| 113 | * the map used to determine Data Coding Alphabet from charset | |
| 114 | * name | |
| 115 | */ | |
| 116 | public CharsetMapToGeneralGroupDataCodingProvider(boolean failIfUnknown, Map<String, Byte> alphabetIndexedByCharsetName) { | |
| 117 | this(failIfUnknown, alphabetIndexedByCharsetName, null, false); | |
| 118 | } | |
| 119 | ||
| 120 | /** | |
| 121 | * Provides {@link DataCoding} based on the charset used to encode the | |
| 122 | * message. | |
| 123 | * | |
| 124 | * <p> | |
| 125 | * It uses the provided map to determine alphabet from the charset used to | |
| 126 | * encode the message. | |
| 127 | * | |
| 128 | * <p> | |
| 129 | * It uses the provided message class to use for the Data Coding scheme. The | |
| 130 | * Message Class bit and Message Class Present bit are both determined from | |
| 131 | * the provided class. If {@code null}, the "message class" not active flag | |
| 132 | * will not be set. | |
| 133 | * | |
| 134 | * <p> | |
| 135 | * It uses the provided compressed value to indicate if the message is | |
| 136 | * compressed or not. | |
| 137 | * | |
| 138 | * | |
| 139 | * | |
| 140 | * @param failIfUnknown | |
| 141 | * if true it throws {@link UnsupportedCharsetException}, if | |
| 142 | * false is returns null to let other | |
| 143 | * {@link DataCodingProvider}(s) being executed. | |
| 144 | * @param alphabetIndexedByCharsetName | |
| 145 | * the map used to determine Data Coding Alphabet from charset | |
| 146 | * name | |
| 147 | * @param messageClass | |
| 148 | * the message class value to use | |
| 149 | * @param compressed | |
| 150 | * indicate if message is compressed or not | |
| 151 | */ | |
| 152 | public CharsetMapToGeneralGroupDataCodingProvider(boolean failIfUnknown, Map<String, Byte> alphabetIndexedByCharsetName, Byte messageClass, boolean compressed) { | |
| 153 | super(); | |
| 154 | this.failIfUnknown = failIfUnknown; | |
| 155 | this.alphabetIndexedByCharsetName = alphabetIndexedByCharsetName; | |
| 156 | this.messageClass = messageClass; | |
| 157 | this.compressed = compressed; | |
| 158 | } | |
| 159 | ||
| 160 | @Override | |
| 161 | public DataCoding provide(Encoded encoded) throws DataCodingException { | |
| 162 | NamedCharset charset = NamedCharset.from(encoded.getCharsetName()); | |
| 163 | Byte encoding = alphabetIndexedByCharsetName.get(charset.getCharsetName()); | |
| 164 |
2
1. provide : negated conditional → NO_COVERAGE 2. provide : negated conditional → KILLED |
if (encoding == null) { |
| 165 |
2
1. provide : negated conditional → NO_COVERAGE 2. provide : negated conditional → KILLED |
if (failIfUnknown) { |
| 166 | throw new UnsupportedCharsetException(encoded.getCharsetName() + " charset not supported for General Group Data Coding Scheme", encoded); | |
| 167 | } | |
| 168 | return null; | |
| 169 | } | |
| 170 |
2
1. provide : replaced return value with null for fr/sii/ogham/sms/sender/impl/cloudhopper/preparator/CharsetMapToGeneralGroupDataCodingProvider::provide → NO_COVERAGE 2. provide : replaced return value with null for fr/sii/ogham/sms/sender/impl/cloudhopper/preparator/CharsetMapToGeneralGroupDataCodingProvider::provide → KILLED |
return DataCoding.createGeneralGroup(encoding, messageClass, compressed); |
| 171 | } | |
| 172 | ||
| 173 | /** | |
| 174 | * Default mapping used to determine {@link DataCoding} encoding value from | |
| 175 | * {@link Charset}: | |
| 176 | * <ul> | |
| 177 | * <li>{@link CharsetUtil#NAME_GSM7} {@literal ->} | |
| 178 | * {@link DataCoding#CHAR_ENC_DEFAULT}</li> | |
| 179 | * <li>{@link CharsetUtil#NAME_PACKED_GSM} {@literal ->} | |
| 180 | * {@link DataCoding#CHAR_ENC_DEFAULT}</li> | |
| 181 | * <li>{@link CharsetUtil#NAME_GSM} {@literal ->} | |
| 182 | * {@link DataCoding#CHAR_ENC_8BIT}</li> | |
| 183 | * <li>{@link CharsetUtil#NAME_GSM8} {@literal ->} | |
| 184 | * {@link DataCoding#CHAR_ENC_8BIT}</li> | |
| 185 | * <li>{@link CharsetUtil#NAME_UCS_2} {@literal ->} | |
| 186 | * {@link DataCoding#CHAR_ENC_UCS2}</li> | |
| 187 | * </ul> | |
| 188 | * | |
| 189 | * @return the mapping | |
| 190 | */ | |
| 191 | public static Map<String, Byte> defaultMap() { | |
| 192 | Map<String, Byte> map = new HashMap<>(); | |
| 193 | // @formatter:off | |
| 194 | // standards only are supported (due to DataCoding.createGeneralGroup) | |
| 195 | map.put(NAME_GSM7, CHAR_ENC_DEFAULT); | |
| 196 | map.put(NAME_PACKED_GSM, CHAR_ENC_DEFAULT); | |
| 197 | map.put(NAME_GSM, CHAR_ENC_8BIT); | |
| 198 | map.put(NAME_GSM8, CHAR_ENC_8BIT); | |
| 199 | map.put(NAME_UCS_2, CHAR_ENC_UCS2); | |
| 200 | // @formatter:on | |
| 201 |
2
1. defaultMap : replaced return value with null for fr/sii/ogham/sms/sender/impl/cloudhopper/preparator/CharsetMapToGeneralGroupDataCodingProvider::defaultMap → NO_COVERAGE 2. defaultMap : replaced return value with null for fr/sii/ogham/sms/sender/impl/cloudhopper/preparator/CharsetMapToGeneralGroupDataCodingProvider::defaultMap → KILLED |
return unmodifiableMap(map); |
| 202 | } | |
| 203 | ||
| 204 | } | |
Mutations | ||
| 164 |
1.1 2.2 |
|
| 165 |
1.1 2.2 |
|
| 170 |
1.1 2.2 |
|
| 201 |
1.1 2.2 |