package org.mobicents.javax.megaco.parser.text;
import java.text.ParseException;
import java.util.regex.Pattern;
import javax.megaco.CommandEvent;
public class StringMsgParser {
private String rawStringMessage;
int index = 0;
public StringMsgParser() {
}
/**
* @param args
*/
public static void main(String[] args) {
String msg = " asalnlnd MEGACO/1 [192.168.1.101]:2944";
StringMsgParser parser = new StringMsgParser();
try {
parser.parseMegacoMessage(msg);
} catch (ParseException e) {
e.printStackTrace();
}
}
public CommandEvent parseMegacoMessage(String msgString) throws ParseException {
if (msgString == null || msgString.length() == 0)
return null;
rawStringMessage = msgString;
int linestart = index;
index = msgString.indexOf(TokenNames.MegacopToken);
if (index == -1) {
index = msgString.indexOf(TokenNames.a_MegacopToken);
}
if (index == -1) {
throw new ParseException("Message has no MEGACO / ! header", index);
}
// As per ABNF definition
// megacoMessage = LWSP [authenticationHeader SEP ] message;
// we are interested in message.
// Cut off LWSP [authenticationHeader SEP ]
rawStringMessage = rawStringMessage.substring(index, rawStringMessage.length());
System.out.println(rawStringMessage);
index = 0;
decode_MegacopToken();
decode_SLASH();
decode_Version();
decode_SEP();
decode_domainName();
System.out.println("index = " + index);
return null;
}
private boolean decode_MegacopToken() {
// MegacopToken = ("MEGACO" / "!");
boolean decoded = false;
decoded = decode_StringValue("MEGACO");
if (!decoded) {
decoded = decode_StringValue("!");
}
return decoded;
}
private boolean decode_SLASH() {
// SLASH = %x2F ;
boolean decoded = false;
decoded = decode_NumericValue("[\\x2F]", 1);
return decoded;
}
private boolean decode_Version() {
// Version = 1*2(DIGIT);
boolean decoded = false;
decoded = decode_DIGIT();
if (decoded) {
decode_DIGIT();
}
return decoded;
}
private boolean decode_mId() {
// mId = (( domainAddress / domainName )
// [":" portNumber]) / mtpAddress / deviceName;
int s = index;
boolean decoded = false;
decoded = decode_domainAddress();
if (!decoded) {
decoded = decode_domainName();
}
if (decoded) {
char ch = rawStringMessage.charAt(index);
if (ch == ':') {
index += 1;
decoded = decode_portNumber();
}
}
if (!decoded) {
index = s;
decoded = decode_mtpAddress();
}
return decoded;
}
private boolean decode_deviceName() {
// deviceName = pathNAME;
boolean decoded = false;
return decoded;
}
private boolean decode_pathNAME() {
// pathNAME = ["*"] NAME *("/" / "*"/ ALPHA / DIGIT /"_" / "$" )
// ["@" pathDomainName ];
boolean decoded = false;
int s = index;
char ch = rawStringMessage.charAt(index);
if (ch == '*') {
index += 1;
}
decoded = decode_NAME();
if (decoded) {
boolean f1 = true;
while (f1) {
char ch1 = rawStringMessage.charAt(index);
if (ch1 == '/' || ch1 == '*' || ch1 == '_' || ch1 == '$') {
index += 1;
f1 = true;
}
if (!f1) {
f1 = decode_ALPHA();
}
if (!f1) {
f1 = decode_DIGIT();
}
}
f1 = true;
char ch1 = rawStringMessage.charAt(index);
if (ch1 == '@') {
}
}
return decoded;
}
private boolean decode_pathDomainName() {
// pathDomainName = (ALPHA / DIGIT / "*" )
// *63(ALPHA / DIGIT / "-" / "*" / ".");
boolean decoded = false;
int s = index;
decoded = decode_ALPHA();
if(!decoded){
decoded = decode_DIGIT();
}
if(!decoded){
//decoded
}
return decoded;
}
private boolean decode_NAME() {
// NAME = ALPHA *63(ALPHA / DIGIT / "_" );
boolean decoded = false;
int s = index;
decoded = decode_ALPHA();
if (decoded) {
boolean f1 = true;
for (int i = 0; i < 63 && f1; i++) {
f1 = decode_ALPHA();
if (!f1) {
f1 = decode_DIGIT();
}
if (!f1) {
char ch = rawStringMessage.charAt(index);
if (ch == '-') {
index += 1;
f1 = true;
}
}
}// for loop
}
if (!decoded) {
index = s;
}
return decoded;
}
private boolean decode_mtpAddress() {
// mtpAddress = MTPToken LBRKT 4*8 (HEXDIG) RBRKT;
boolean decoded = false;
int s = index;
decoded = decode_StringValue(TokenNames.MTPToken);
if (decoded) {
decoded = decode_LBRKT();
for (int i = 0; i < 4 && decoded; i++) {
decoded = decode_HEXDIG();
}
boolean f1 = decoded;
for (int i = 4; i < 8 && f1; i++) {
f1 = decode_HEXDIG();
}
if (decoded) {
decoded = decode_RBRKT();
}
}
if (!decoded) {
index = s;
}
return decoded;
}
private boolean decode_HEXDIG() {
// HEXDIG = ( DIGIT / "A" / "B" / "C" / "D" / "E" / "F" );
boolean decoded = false;
decoded = decode_DIGIT();
if (!decoded) {
char c = rawStringMessage.charAt(index);
switch (c) {
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
index += 1;
decoded = true;
break;
default:
decoded = false;
break;
}
}
return decoded;
}
private boolean decode_LBRKT() {
// LBRKT = LWSP %x7B LWSP ;
boolean decoded = false;
int s = index;
decoded = decode_LWSP();
if (decoded) {
char ch = rawStringMessage.charAt(index);
if (ch == '{') {
index += 1;
decoded = true;
decoded = decode_LWSP();
}
}
if (!decoded) {
index = s;
}
return decoded;
}
private boolean decode_RBRKT() {
// RBRKT = LWSP %x7D LWSP ;
boolean decoded = false;
int s = index;
decoded = decode_LWSP();
if (decoded) {
char ch = rawStringMessage.charAt(index);
if (ch == '{') {
index += 1;
decoded = true;
decoded = decode_LWSP();
}
}
if (!decoded) {
index = s;
}
return decoded;
}
private boolean decode_portNumber() {
// portNumber = UINT16;
return decode_UINT16();
}
private boolean decode_UINT16() {
// UINT16 = 1*5(DIGIT) ;
boolean decoded = false;
decoded = decode_DIGIT();
if (decoded) {
boolean f1 = true;
for (int i = 1; i < 5 && f1; i++) {
f1 = decode_DIGIT();
}
}
return decoded;
}
private boolean decode_domainAddress() {
// domainAddress = "[" (IPv4address / IPv6address) "]";
// TODO : Add decode for IPV6
boolean decoded = false;
int startIndex = index;
int addressStart = 0;
int addressEnd = 0;
int count = 0;
String ipAddress = null;
if (rawStringMessage.charAt(index) == '[') {
index += 1;
addressStart = index;
while (rawStringMessage.charAt(index) != ']') {
if (count == 15) {
index = startIndex;
decoded = false;
return decoded;
}
index += 1;
count += 1;
addressEnd = index;
}
index += 1;
ipAddress = rawStringMessage.substring(addressStart, addressEnd);
System.out.println(ipAddress);
}
return decoded;
}
private boolean decode_domainName() {
// domainName = "<" (ALPHA / DIGIT) *63(ALPHA / DIGIT / "-" /
// ".") ">";
int s = index;
boolean decoded = false;
int domainStart = 0;
int domainEnd = 0;
String domainName = null;
if (rawStringMessage.charAt(index) == '<') {
index += 1;
domainStart = index;
decoded = decode_ALPHA();
if (!decoded) {
decoded = decode_DIGIT();
}
if (decoded) {
boolean f1 = true;
for (int i = 0; i < 63 && f1; i++) {
f1 = decode_ALPHA();
if (!f1) {
f1 = decode_DIGIT();
}
if (!f1) {
char ch = rawStringMessage.charAt(index);
if (ch == '-') {
index += 1;
f1 = true;
}
}
if (!f1) {
char ch = rawStringMessage.charAt(index);
if (ch == '.') {
index += 1;
f1 = true;
}
}
}// for loop
char ch = rawStringMessage.charAt(index);
if (ch == '>') {
domainEnd = index;
index += 1;
decoded = true;
domainName = rawStringMessage.substring(domainStart, domainEnd);
System.out.println(domainName);
} else {
decoded = false;
index = s;
}
}
}
return decoded;
}
private boolean decode_IPv4address() {
// IPv4address = V4hex DOT V4hex DOT V4hex DOT V4hex;
// V4hex = 1*3(DIGIT) ;
boolean decoded = false;
String IPv4 = null;
char c = ' ';
while (c != '.') {
c = rawStringMessage.charAt(index);
IPv4 += c;
index += 1;
}
index += 1;
return decoded;
}
private boolean decode_WSP() {
// WSP = SP / HTAB ;
boolean decoded = false;
decoded = decode_SP();
if (!decoded) {
decoded = decode_HTAB();
}
return decoded;
}
private boolean decode_SP() {
// ABNF definition
// SP = %x20 ;
boolean decoded = false;
decoded = decode_NumericValue("[\\x20]", 1); // Decode Space
return decoded;
}
private boolean decode_HTAB() {
// ABNF definition
// HTAB = %x09 ;
boolean decoded = false;
decoded = decode_NumericValue("[\\x09]", 1);
return decoded;
}
private boolean decode_EOL() {
// EOL = (CR [LF] / LF );;
boolean decoded = false;
decoded = decode_CR();
if (decoded) {
decoded = decode_LF();
return decoded;
}
decoded = decode_LF();
return decoded;
}
private boolean decode_CR() {
// CR = %x0D ;
boolean decoded = false;
decoded = decode_NumericValue("[\\x0D]", 1);
return decoded;
}
private boolean decode_LF() {
// LF = %x0A ;
boolean decoded = false;
decoded = decode_NumericValue("[\\x0A]", 1);
return decoded;
}
private boolean decode_SEP() {
// SEP = ( WSP / EOL / COMMENT) LWSP;
boolean decoded = false;
decoded = decode_WSP();
if (!decoded) {
decoded = decode_EOL();
}
if (!decoded) {
decoded = decode_COMMENT();
}
if (decoded) {
decoded = decode_LWSP();
}
return decoded;
}
private boolean decode_LWSP() {
// LWSP = *( WSP / COMMENT / EOL );
boolean decoded = false;
boolean f1 = true;
while (f1) {
decoded = decode_WSP();
if (!decoded) {
decoded = decode_COMMENT();
}
if (!decoded) {
decoded = decode_EOL();
}
f1 = decoded;
}
return true;
}
private boolean decode_COMMENT() {
// COMMENT = ";" *(SafeChar/ RestChar / WSP / %x22) EOL;
boolean decoded = false;
int s = index;
char c = rawStringMessage.charAt(index);
if (c == ';') {
decoded = true;
index += 1;
boolean f1 = true;
while (f1) {
decoded = decode_SafeChar();
if (!decoded) {
decoded = decode_RestChar();
}
if (!decoded) {
decoded = decode_WSP();
}
if (!decoded) {
decoded = decode_NumericValue("[\\x22]", 1);
}
f1 = decoded;
}
decoded = decode_EOL();
}
if (!decoded) {
index = s;
}
return decoded;
}
private boolean decode_SafeChar() {
// SafeChar = DIGIT / ALPHA / "+" / "-" / "&" /
// "!" / "_" / "/" / "\'" / "?" / "@" /
// "^" / "`" / "~" / "*" / "$" / "\" /
// "(" / ")" / "%" / "|" / ".";
boolean decoded = false;
decoded = decode_DIGIT();
if (!decoded) {
decoded = decode_ALPHA();
}
if (!decoded) {
char c = rawStringMessage.charAt(index);
if (c == '+' || c == '-' || c == '&' || c == '!' || c == '_' || c == '/' || c == '\'' || c == '?'
|| c == '@' || c == '^' || c == '`' || c == '~' || c == '*' || c == '$' || c == '\\' || c == '('
|| c == ')' || c == '%' || c == '|' || c == '.') {
index += 1;
decoded = true;
}
}
return decoded;
}
private boolean decode_RestChar() {
// RestChar = ";" / "[" / "]" / "{" / "}" / ":" / "," / "#" /
// "<" / ">" / "=";
boolean decoded = false;
char c = rawStringMessage.charAt(index);
if (c == ';' || c == '[' || c == ']' || c == '{' || c == '}' || c == ':' || c == ',' || c == '#' || c == '<'
|| c == '>' || c == '=') {
index += 1;
decoded = true;
}
return decoded;
}
private boolean decode_DIGIT() {
// DIGIT = %x30-39 ;;
boolean decoded = false;
char ch = rawStringMessage.charAt(index);
if (ch <= 127) {
if (ch >= '0' && ch <= '9') {
index += 1;
decoded = true;
}
}
return decoded;
}
private boolean decode_ALPHA() {
// ALPHA = %x41-5A / %x61-7A ;
boolean decoded = false;
char ch = rawStringMessage.charAt(index);
if (ch <= 127) {
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
index += 1;
decoded = true;
}
}
// TODO : Handle Basic Multilingual Plane ?
return decoded;
}
private boolean decode_StringValue(String regex) {
boolean decoded = false;
int start = index;
try {
String value = rawStringMessage.substring(index, index + regex.length());
if ((decoded = value.equalsIgnoreCase(regex))) {
index += regex.length();
decoded = true;
}
} catch (IndexOutOfBoundsException e) {
decoded = false;
}
return decoded;
}
private boolean decode_NumericValue(String regex, int length) {
boolean decoded = false;
try {
String value = rawStringMessage.substring(index, index + length);
if ((decoded = Pattern.matches(regex, value))) {
index += length;
decoded = true;
}
} catch (IndexOutOfBoundsException e) {
decoded = false;
}
return decoded;
}
}