ReferenceNumberGeneratorBuilder.java
- package fr.sii.ogham.sms.builder.cloudhopper;
- import java.util.Random;
- import fr.sii.ogham.core.builder.Builder;
- import fr.sii.ogham.core.builder.context.BuildContext;
- import fr.sii.ogham.core.fluent.AbstractParent;
- import fr.sii.ogham.sms.splitter.RandomReferenceNumberGenerator;
- import fr.sii.ogham.sms.splitter.ReferenceNumberGenerator;
- /**
- * In the cellular phone industry, mobile phones and their networks sometimes
- * support concatenated short message service (or concatenated SMS) to overcome
- * the limitation on the number of characters that can be sent in a single SMS
- * text message transmission (which is usually 160). Using this method, long
- * messages are split into smaller messages by the sending device and recombined
- * at the receiving end. Each message is then billed separately. When the
- * feature works properly, it is nearly transparent to the user, appearing as a
- * single long text message.
- *
- * <p>
- * One way of sending concatenated SMS (CSMS) is to split the message into 153
- * 7-bit character parts (134 octets), and sending each part with a User Data
- * Header (UDH) tacked onto the beginning. A UDH can be used for various
- * purposes and its contents and size varies accordingly, but a UDH for
- * concatenating SMSes look like this:
- *
- * <ul>
- * <li>Field 1 (1 octet): Length of User Data Header, in this case 05.</li>
- * <li>Field 2 (1 octet): Information Element Identifier, equal to 00
- * (Concatenated short messages, 8-bit reference number)</li>
- * <li>Field 3 (1 octet): Length of the header, excluding the first two fields;
- * equal to 03</li>
- * <li>Field 4 (1 octet): 00-FF, CSMS reference number, must be same for all the
- * SMS parts in the CSMS</li>
- * <li>Field 5 (1 octet): 00-FF, total number of parts. The value shall remain
- * constant for every short message which makes up the concatenated short
- * message. If the value is zero then the receiving entity shall ignore the
- * whole information element</li>
- * <li>Field 6 (1 octet): 00-FF, this part's number in the sequence. The value
- * shall start at 1 and increment for every short message which makes up the
- * concatenated short message. If the value is zero or greater than the value in
- * Field 5 then the receiving entity shall ignore the whole information element.
- * [ETSI Specification: GSM 03.40 Version 5.3.0: July 1996]</li>
- * </ul>
- *
- * <p>
- * It is possible to use a 16 bit CSMS reference number in order to reduce the
- * probability that two different concatenated messages are sent with identical
- * reference numbers to a receiver. In this case, the User Data Header shall be:
- *
- * <ul>
- * <li>Field 1 (1 octet): Length of User Data Header (UDL), in this case
- * 06.</li>
- * <li>Field 2 (1 octet): Information Element Identifier, equal to 08
- * (Concatenated short messages, 16-bit reference number)</li>
- * <li>Field 3 (1 octet): Length of the header, excluding the first two fields;
- * equal to 04</li>
- * <li>Field 4 (2 octets): 0000-FFFF, CSMS reference number, must be same for
- * all the SMS parts in the CSMS</li>
- * <li>Field 5 (1 octet): 00-FF, total number of parts. The value shall remain
- * constant for every short message which makes up the concatenated short
- * message. If the value is zero then the receiving entity shall ignore the
- * whole information element</li>
- * <li>Field 6 (1 octet): 00-FF, this part's number in the sequence. The value
- * shall start at 1 and increment for every short message which makes up the
- * concatenated short message. If the value is zero or greater than the value in
- * Field 5 then the receiving entity shall ignore the whole information element.
- * [ETSI Specification: GSM 03.40 Version 5.3.0: July 1996]</li>
- * </ul>
- *
- *
- * Configures reference number generation strategy.
- *
- *
- * @author Aurélien Baudet
- *
- */
- public class ReferenceNumberGeneratorBuilder extends AbstractParent<MessageSplitterBuilder> implements Builder<ReferenceNumberGenerator> {
- private final BuildContext buildContext;
- private Random random;
- private ReferenceNumberGenerator custom;
- /**
- * Initializes the builder with a parent builder. The parent builder is used
- * when calling {@link #and()} method.
- *
- * @param parent
- * the parent builder
- * @param buildContext
- * for registering instances and property evaluation
- */
- public ReferenceNumberGeneratorBuilder(MessageSplitterBuilder parent, BuildContext buildContext) {
- super(parent);
- this.buildContext = buildContext;
- }
- /**
- * Uses a random number for reference number.
- *
- * It uses an instance of {@link Random} to generate random numbers.
- *
- * @return this instance for fluent chaining
- */
- @SuppressWarnings("squid:S2245")
- public ReferenceNumberGeneratorBuilder random() {
- return random(new Random());
- }
- /**
- * Uses a random number for reference number. The provided {@link Random}
- * instance is used to generate random numbers.
- *
- * <p>
- * If this method is called several times, only the last {@link Random}
- * instance is used.
- *
- * <p>
- * If random parameter is {@code null} then any previously registered
- * {@link Random} instance won't be used.
- *
- * @param random
- * the {@link Random} instance used to generate random numbers
- * @return this instance for fluent chaining
- */
- public ReferenceNumberGeneratorBuilder random(Random random) {
- this.random = random;
- return this;
- }
- /**
- * Uses a custom reference number generation strategy. This strategy takes
- * precedence over any other generation strategy.
- *
- * <p>
- * If this method is called several times, only the last registered
- * generator is used.
- *
- * <p>
- * If custom parameter is {@code null}, the custom strategy is disabled.
- * Other previously configured strategies (like {@link #random()}) will be
- * used instead.
- *
- * @param custom
- * custom reference number generation strategy
- * @return this instance for fluent chaining
- */
- public ReferenceNumberGeneratorBuilder generator(ReferenceNumberGenerator custom) {
- this.custom = custom;
- return this;
- }
- @Override
- public ReferenceNumberGenerator build() {
- if (custom != null) {
- return custom;
- }
- if (random != null) {
- return buildContext.register(new RandomReferenceNumberGenerator(random));
- }
- return buildContext.register(new RandomReferenceNumberGenerator());
- }
- }