/*
* TeleStax, Open Source Cloud Communications Copyright 2012.
* and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.mobicents.smsc.slee.services.http.server.tx.data;
import org.mobicents.smsc.domain.HttpEncoding;
import org.mobicents.smsc.domain.HttpUsersManagement;
import org.mobicents.smsc.domain.SmscPropertiesManagement;
import org.mobicents.smsc.slee.services.http.server.tx.enums.*;
import org.mobicents.smsc.slee.services.http.server.tx.exceptions.HttpApiException;
import org.mobicents.smsc.slee.services.http.server.tx.exceptions.UnauthorizedException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by tpalucki on 08.09.16.
*
* @author Tomasz Pa?ucki
*/
public class HttpSendMessageIncomingData extends BaseIncomingData {
private String msg;
/**
* Optional parameter
* possible: english, arabic
* values: UCS-2, UTF-8
* Default is english
*/
private SmscMessageEncoding smscEncoding;
/**
* Optional parameter
* Possible values: UTF-8, UTF-16
* Default is UTF-8
*/
private MessageBodyEncoding messageBodyEncoding;
private String sender;
private List<String> destAddresses = new ArrayList<String>();
private TON senderTon;
private NPI senderNpi;
private byte[] udh;
public HttpSendMessageIncomingData(String userId, String password, String msg, String formatParam, String smscEncodingStr, String messageBodyEncodingStr,
String sender, String senderTon, String senderNpi, String[] to, SmscPropertiesManagement smscPropertiesManagement, HttpUsersManagement httpUsersManagement, String udhStr) throws HttpApiException, UnauthorizedException {
super(userId, password, formatParam, httpUsersManagement);
if (isEmptyOrNull(msg)) {
throw new HttpApiException("'" + RequestParameter.MESSAGE_BODY.getName() + "' parameter is not set properly or not valid in the Http Request.");
}
if (isEmptyOrNull(sender)) {
throw new HttpApiException("'" + RequestParameter.SENDER.getName() + "' parameter is not set properly or not valid in the Http Request.");
}
if (to == null || to.length < 1 || checkAllElements(to)) {
throw new HttpApiException("'" + RequestParameter.TO.getName() + "' parameter is not set in the Http Request.");
}
this.destAddresses = new ArrayList<String>(removePlusPrefixFromDestNumbers(Arrays.asList(to)));
//check only digits
List<String> notValidNumbers = validateDestNumbersAndRemoveEmpty(this.destAddresses);
if (!notValidNumbers.isEmpty()) {
throw new HttpApiException("'" + RequestParameter.TO.getName() + "' parameter contains not valid value. Wrong format of numbers:" + Arrays.toString(notValidNumbers.toArray()));
}
if (smscEncodingStr != null && !SmscMessageEncoding.isValid(smscEncodingStr)) {
throw new HttpApiException("'" + RequestParameter.SMSC_ENCODING.getName() + "' parameter is not set properly or not valid in the Http Request.");
}
if (messageBodyEncodingStr != null && !MessageBodyEncoding.isValid(messageBodyEncodingStr)) {
throw new HttpApiException("'" + RequestParameter.MESSAGE_BODY_ENCODING.getName() + "' parameter is not set properly or not valid in the Http Request.");
}
if (senderTon != null && TON.fromString(senderTon) == null) {
throw new HttpApiException("'" + RequestParameter.SENDER_TON.getName() + "' parameter is not set properly or not valid in the Http Request.");
}
if (senderNpi != null && NPI.fromString(senderNpi) == null) {
throw new HttpApiException("'" + RequestParameter.SENDER_NPI.getName() + "' parameter is not set properly or not valid in the Http Request.");
}
//setting the defaults
if (smscEncodingStr != null) {
this.smscEncoding = SmscMessageEncoding.fromString(smscEncodingStr);
}
if (messageBodyEncodingStr != null) {
this.messageBodyEncoding = MessageBodyEncoding.fromString(messageBodyEncodingStr);
} else {
HttpEncoding httpEncoding;
if (SmscMessageEncoding.GSM7.equals(getSmscEncoding())) {
httpEncoding = smscPropertiesManagement.getHttpEncodingForGsm7();
} else {
httpEncoding = smscPropertiesManagement.getHttpEncodingForUCS2();
}
switch (httpEncoding) {
case Utf8:
this.messageBodyEncoding = MessageBodyEncoding.UTF8;
break;
case Unicode:
this.messageBodyEncoding = MessageBodyEncoding.UTF16;
break;
default:
this.messageBodyEncoding = MessageBodyEncoding.UTF8;
break;
}
}
if (!isEmptyOrNull(udhStr)) {
this.udh = udhToByte(udhStr);
}
this.sender = sender;
this.msg = decodeMessage(msg, getMessageBodyEncoding());
if (senderTon != null && senderNpi != null) {
// senderTon & senderNpi are specified in HTTP request
this.senderTon = TON.fromString(senderTon);
this.senderNpi = NPI.fromString(senderNpi);
} else {
int defaultSourceTon = smscPropertiesManagement.getHttpDefaultSourceTon();
int defaultSourceNpi = smscPropertiesManagement.getHttpDefaultSourceNpi();
if (defaultSourceTon < 0 || defaultSourceNpi < 0) {
// senderTon & senderNpi auto detection
if (defaultSourceTon == -1 || defaultSourceNpi == -1) {
// -1: international (a string contains only digits with "+" at the begin) /
// national (a string contains only digits without "+" at the begin) /
// alphanumerical (a string does not contain only digits)
Matcher m = regExDigitsWithPlus.matcher(this.sender);
if (m.matches()) {
this.senderTon = TON.INTERNATIONAL;
this.senderNpi = NPI.ISDN;
this.sender = this.sender.substring(1);
} else {
m = regExDigits.matcher(this.sender);
if (m.matches()) {
this.senderTon = TON.NATIONAL;
this.senderNpi = NPI.ISDN;
} else {
this.senderTon = TON.ALFANUMERIC;
this.senderNpi = NPI.UNKNOWN;
}
}
} else {
// -2: international (a string contains only digits) /
// alphanumerical (a string does not contain only digits)
Matcher m = regExDigits.matcher(this.sender);
if (m.matches()) {
this.senderTon = TON.INTERNATIONAL;
this.senderNpi = NPI.ISDN;
} else {
this.senderTon = TON.ALFANUMERIC;
this.senderNpi = NPI.UNKNOWN;
}
}
} else {
this.senderTon = TON.fromInt(defaultSourceTon);
this.senderNpi = NPI.fromInt(defaultSourceNpi);
}
}
}
private Pattern regExDigits = Pattern.compile("^[0-9]+$");
private Pattern regExDigitsWithPlus = Pattern.compile("^\\+\\d+$");
private String decodeMessage(String msgParameter, MessageBodyEncoding messageBodyEncoding) throws HttpApiException {
String encoding;
switch (messageBodyEncoding) {
case UTF8:
encoding = "UTF-8";
break;
case UTF16:
encoding = "UTF-16";
break;
default:
encoding = "UTF-8";
break;
}
try {
return new String(msgParameter.getBytes("iso-8859-1"), Charset.forName(encoding));
} catch (UnsupportedEncodingException e) {
throw new HttpApiException(e.getMessage(),e);
}
}
private boolean checkAllElements(String[] addresses) {
for (String e : addresses) {
if (e != null && !e.trim().isEmpty()) {
return false;
}
}
return true;
}
private List<String> validateDestNumbersAndRemoveEmpty(List<String> toCheck) {
List<String> notValidDestinationNumbers = new ArrayList<>();
Iterator<String> iterator = toCheck.iterator();
while (iterator.hasNext()) {
String number = iterator.next().trim();
if (number.isEmpty()) {
//remove empty strings
iterator.remove();
} else {
try {
Long.parseLong(number);
} catch (NumberFormatException e) {
notValidDestinationNumbers.add(number);
}
}
}
return notValidDestinationNumbers;
}
private List<String> removePlusPrefixFromDestNumbers(List<String> toCheck) {
for (int i=0; i<toCheck.size(); i++) {
String number = toCheck.get(i).trim();
if (number.startsWith("+")) {
number = number.substring(1);
}
if (number.startsWith("%2B")) {
number = number.substring(3);
}
toCheck.set(i, number);
}
return toCheck;
}
private byte[] udhToByte(String udhDecoded) throws HttpApiException {
try {
return udhDecoded.getBytes("iso-8859-1");
} catch (UnsupportedEncodingException e) {
throw new HttpApiException(e.getMessage(),e);
}
}
public List<String> getDestAddresses() {
return destAddresses;
}
public String getMsg() {
return msg;
}
public SmscMessageEncoding getSmscEncoding() {
return smscEncoding;
}
public MessageBodyEncoding getMessageBodyEncoding() {
return messageBodyEncoding;
}
public String getSender() {
return sender;
}
public TON getSenderTon() { return senderTon; }
public NPI getSenderNpi() { return senderNpi; }
public int getDefaultMsgId() {
return 0;
}
public String getShortMessage() {
return this.msg;
}
public byte[] getUdh() {
return udh;
}
public String udhToString (byte[] udhs) {
if (udhs != null) {
StringBuilder udhtoString = new StringBuilder();
int length = udhs.length;
for (int i = 0; i < length; i++) {
udhtoString.append(String.format("%02X ", udhs[i]));
}
return udhtoString.toString();
} else {
return "";
}
}
@Override
public String toString() {
return "HttpSendMessageIncomingData{" +
"userId='" + userId + '\'' +
", password='" + password + '\'' +
", networkId='" + getNetworkId() + '\'' +
", msg='" + msg + '\'' +
", format='" + format + '\'' +
", smscEncoding=" + smscEncoding +
", messageBodyEncoding=" + messageBodyEncoding +
", sender='" + sender + '\'' +
", senderTon='" + senderTon + '\'' +
", senderNpi='" + senderNpi + '\'' +
", destAddresses=" + destAddresses + '\'' +
", udh=" + udhToString(udh) + '\'' +
'}';
}
}