package org.saf.cdrs;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringTokenizer;
import java.util.Vector;
import org.saf.common.Utilities;
import org.saf.settings.CdrsSettings;
import com.logica.smpp.Data;
import com.logica.smpp.pdu.DeliverSM;
import com.logica.smpp.pdu.DeliverSMResp;
import com.logica.smpp.pdu.SubmitSM;
import com.logica.smpp.pdu.SubmitSMResp;
import com.logica.smpp.util.ByteBuffer;
class CdrFileHelper {
private static char CDR_SEPARATOR = '|';
private final static String ACK_STATUS = "ACK";
private final static String NACK_STATUS = "NACK";
private static Boolean mutex = false;
private CdrsSettings cdrSettings = null;
public CdrFileHelper(CdrsSettings cdrSettings) {
this.cdrSettings = cdrSettings;
}
public void appendToHourlyFile(String homePath, String prefix, String line)
throws IOException {
synchronized (mutex) {
Date now = new Date(System.currentTimeMillis());
SimpleDateFormat dailyDateFormat = new SimpleDateFormat("yyyyMMdd");
String sDailyDir = homePath + dailyDateFormat.format(now);
File dailyDir = new File(sDailyDir);
boolean exist = true;
//Create of daily cdrs directory.
if(dailyDir.exists() == false) {
exist = dailyDir.mkdirs();
}
if(exist == true) {
SimpleDateFormat hourlyDateFormat =
new SimpleDateFormat("yyyyMMddHH");
String sHourlyFile = sDailyDir + File.separator + prefix +
hourlyDateFormat.format(now) + "." +
this.cdrSettings.getExtension();
File cdrFile = new File(sHourlyFile);
if(cdrFile.exists() == false) {
exist = cdrFile.createNewFile();
}
PrintWriter pw = null;
if(exist == true) {
pw = new PrintWriter(new FileWriter(cdrFile, true));
pw.println(line);
pw.flush();
pw.close();
} else {
throw new IOException(sHourlyFile + " file dosen't exist");
}
hourlyDateFormat = null;
sHourlyFile = null;
cdrFile = null;
} else {
throw new IOException(sDailyDir + " dir dosen't exist");
}
dailyDateFormat = null;
dailyDir = null;
}
}
public void appendToFile (String prefixPath, String line) throws IOException {
synchronized (mutex) {
Date today = new Date(System.currentTimeMillis());
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String dateSubstring = dateFormat.format(today);
String cdrFileName = prefixPath + dateSubstring + "." +
this.cdrSettings.getExtension();
File cdrFile = new File(cdrFileName);
boolean exist = true;
if(cdrFile.exists() == false) {
exist = cdrFile.createNewFile();
}
PrintWriter pw = null;
if(exist == true) {
pw = new PrintWriter(new FileWriter(cdrFile, true));
pw.println(line);
pw.flush();
pw.close();
} else {
throw new IOException(cdrFileName + " file dosen't exist");
}
pw = null;
today = null;
dateFormat = null;
dateSubstring = null;
cdrFileName = null;
cdrFile = null;
}
}
public String getMTCdrEntry(SubmitSM request, SubmitSMResp response,
String timestamp, Vector<String> customInfo, String group,
String channel, long transactionTime) {
String ret = "";
char separator = CdrFileHelper.CDR_SEPARATOR;
//1 Processed (0)
StringBuffer entry = new StringBuffer("0" + separator);
//2 Group (group ini file)
if(group == null || group.length() == 0) {
entry.append("*" + separator);
} else {
entry.append(group + separator);
}
//3 Channel (section name)
if(channel == null || channel.length() == 0) {
entry.append("*" + separator);
} else {
entry.append(channel + separator);
}
//4 SMPP service_type)
String servType = request.getServiceType();
if(servType == null || servType.length() == 0) {
servType = "*";
}
entry.append( servType + separator);
//5 Timestamp
entry.append(timestamp + separator);
//6 Sender (SMPP source_addr)
entry.append(request.getSourceAddr().getAddress() + separator);
//7 Destination (SMPP destination_addr)
entry.append(request.getDestAddr().getAddress() + separator);
//8 Message ID (SMPP sequence_number)
String messageID = response.getMessageId();
if(messageID == null || messageID.length() == 0) {
messageID = "*";
}
entry.append(messageID + separator);
//9 Message size (SMPP sm_length)
entry.append(getFormattedMessageSize(
request.getSmLength()) + separator);
//10 Direction ('MT')
entry.append("MT" + separator);
//11 Status command_status == 0 (ACK)
entry.append(getStatus(response.getCommandStatus())
+ separator);
//12 Detail (SMPP command_status)
entry.append(Integer.toString(response.getCommandStatus()) +
separator);
//13 Transaction time
entry.append(Long.toString(transactionTime));
if(customInfo != null) {
for(int i = 0; i < customInfo.size(); i++ ) {
String info = customInfo.elementAt(i);
if(info == null || info.length() == 0) {
info = "*";
}
entry.append(separator + info);
}
}
ret = entry.toString();
entry = null;
return ret;
}
public String getMOCdrEntry(DeliverSM request, DeliverSMResp response,
String timestamp, Vector<String> customInfo, String group,
String channel) {
String ret = "";
char separator = CdrFileHelper.CDR_SEPARATOR;
//1 Processed (0)
StringBuffer entry = new StringBuffer("0" + separator);
//2 Group (group ini file)
if(group.length() > 0) {
entry.append(group + separator);
} else {
entry.append("*" + separator);
}
//3 Channel (section name)
if(channel.length() > 0) {
entry.append(channel + separator);
} else {
entry.append("channel_rmi" + separator);
}
//4 SMPP service_type)
String servType = request.getServiceType();
if(servType == null || servType.length() == 0) {
servType = "*";
}
entry.append( servType + separator);
//5 Timestamp
entry.append(timestamp + separator);
//6 Sender (SMPP source_addr)
entry.append(request.getSourceAddr().getAddress() + separator);
//7 Destination (SMPP destination_addr)
entry.append(request.getDestAddr().getAddress() + separator);
//8 Message ID (SMPP sequence_number)
entry.append("*" + separator);
//9 Message size (SMPP sm_length)
entry.append(getFormattedMessageSize(
request.getSmLength()) + separator);
//10 Direction ('MO')
entry.append("MO" + separator);
//11 Status command_status == 0 (ACK)
entry.append(getStatus(response.getCommandStatus())
+ separator);
//12 Detail (SMPP command_status)
entry.append(Integer.toString(response.getCommandStatus()) +
separator);
//13 Transaction time
entry.append("0");
if(customInfo != null) {
for(int i = 0; i < customInfo.size(); i++ ) {
String info = customInfo.elementAt(i);
if(info == null || info.length() == 0) {
info = "*";
}
entry.append(separator + info);
}
}
ret = entry.toString();
entry = null;
return ret;
}
public String getNotCdrEntry(String notification, String timestamp,
String recipient, String destination,
Vector<String> customInfo) {
String ret = "";
char separator = CdrFileHelper.CDR_SEPARATOR;
StringTokenizer st = new StringTokenizer(notification, " ");
String submitTimestamp = "";
String msgId = "";
String stat = "";
String donedateTimestamp = "";
String err = "";
while(st.hasMoreElements()) {
String token = st.nextToken();
if((token.indexOf(':') == -1) == true) {
if(st.hasMoreElements()) {
token += " " + st.nextToken();
}
}
int idx = token.indexOf(':');
if(idx > -1) {
String field = token.substring(0, idx);
String value = token.substring(idx + 1);
if(field.compareTo("submit date") == 0) {
submitTimestamp = getFormattedDate(value);
} else if(field.compareTo("id") == 0) {
msgId = value;
} else if(field.compareTo("stat") == 0) {
stat = getNotificationStatus(value);;
} else if(field.compareTo("done date") == 0) {
donedateTimestamp = getFormattedDate(value);;
} else if(field.compareTo("err") == 0) {
err = value;
}
}
}
//1 Processed (0) and 2 PLEX timestamp
StringBuffer entry = new StringBuffer(
"0" + separator + timestamp + separator);
//3 Submit timestamp (DR submit date)
entry.append(submitTimestamp + separator);
//4 Operator timespamp (DR done date)
entry.append(donedateTimestamp + separator);
//if dovuto a JSAG e possibilit� di switching.
if(recipient.startsWith("4") == true ||
recipient.startsWith("N") == true) {
//5 Recipient (SMPP source_addr)
entry.append(recipient + separator);
//6 Destination (SMPP destination_addr)
entry.append(destination + separator);
} else {
//5 Destination (SMPP destination_addr)
entry.append(destination + separator);
//6 Recipient (SMPP source_addr)
entry.append(recipient + separator);
}
//7 Message id (DR id)
entry.append(msgId + separator);
//8 Status (mapped DR stat)
entry.append(stat + separator);
//9 SMSC Status (DR err)
entry.append(err + separator);
if(customInfo != null) {
for(int i = 0; i < customInfo.size(); i++ ) {
String info = customInfo.elementAt(i);
if(info == null || info.length() == 0) {
info = "*";
}
entry.append(separator + info);
}
}
ret = entry.toString();
return ret;
}
private String getFormattedMessageSize (short size) {
String ret = "";
DecimalFormat df = new DecimalFormat("0000");
ret = df.format(new Short(size));
return ret;
}
@SuppressWarnings("unused")
private String getFormattedMessageSize (int size) {
String ret = "";
DecimalFormat df = new DecimalFormat("0000");
ret = df.format(new Integer(size));
return ret;
}
private String getStatus (int commandStatus) {
String status = ACK_STATUS;
if(commandStatus > Data.ESME_ROK) {
status = NACK_STATUS;
}
return status;
}
@SuppressWarnings("unused")
private String getEncodedMessage(String message, byte emsClass) {
String encodedMessage = "";
if(message != null) {
encodedMessage = message;
if(emsClass == 0x40) {
ByteBuffer bb = new ByteBuffer(encodedMessage.getBytes());
encodedMessage = bb.getHexDump();
encodedMessage = encodedMessage.toUpperCase();
} else {
encodedMessage = encodedMessage.replace('|', ' ');
encodedMessage = encodedMessage.replaceAll("\r\n", " ");
encodedMessage = encodedMessage.replace('\n', ' ');
}
}
return encodedMessage;
}
@SuppressWarnings("unused")
private String getEncodedMessagePayload(byte[] messagePayload) {
String encodedMessage = null;
String bytes = null;
if(messagePayload != null) {
bytes = new String(messagePayload);
byte[] tmp = Utilities.hexStringToBytes(bytes);
if(tmp != null) {
encodedMessage = new String(tmp);
encodedMessage = encodedMessage.replace('|', ' ');
encodedMessage = encodedMessage.replaceAll("\r\n", " ");
encodedMessage = encodedMessage.replace('\n', ' ');
}
}
return encodedMessage;
}
@SuppressWarnings("unused")
private String getPlexMessageID() {
DecimalFormat df = new DecimalFormat("000000");
String id = Long.toString(System.currentTimeMillis()) +
df.format(Thread.currentThread().getId());
return id;
}
private String getFormattedDate(String smppDate) {
String plexDate = "";
if(smppDate != null &&
smppDate.length() == 10) {
//Standard SMPP format
plexDate = "20" + smppDate.substring(0,2) + //YY
"-" + smppDate.substring(2,4) + //MM
"-" + smppDate.substring(4,6) + //DD
" " + smppDate.substring(6,8) + //H24
":" + smppDate.substring(8, 10) + //MI
":00"; //SS
} else if(smppDate != null &&
smppDate.length() == 12) {
//TI format: YYMMDDHHMISS
plexDate = "20" + smppDate.substring(4,6) + //YY
"-" + smppDate.substring(2,4) + //MM
"-" + smppDate.substring(0,2) + //DD
" " + smppDate.substring(6,8) + //H24
":" + smppDate.substring(8, 10) + //MI
":" + smppDate.substring(10, 12); //SS
}
return plexDate;
}
private String getNotificationStatus(String smppStat) {
String status = "2";
if(smppStat != null) {
if (smppStat.compareToIgnoreCase("DELIVRD") == 0 ||
smppStat.compareToIgnoreCase("DELIVERED") == 0) {
status = "0";
} else if (smppStat.compareToIgnoreCase("ACCEPTD") == 0 ||
smppStat.compareToIgnoreCase("ACCEPTED") == 0) {
status = "1";
}
}
return status;
}
}