MMSAddresspublic class MMSAddress extends Object MMS address parsing and validation.
MMS address is validated according to Table D-2 in WMA2.0 specification.
In addition address is parsed into the fields of MMSAddress
object. |
Fields Summary |
---|
public static final int | INVALID_ADDRESSType corresponding to invalid address. | public static final int | EMAILType corresponding to the e-mail address. | public static final int | GLOBAL_PHONE_NUMBERType corresponding to global phone number address. | public static final int | IPV4Type corresponding to the ipv4 address. | public static final int | IPV6Type corresponding to the ipv6 address. | public static final int | SHORTCODEType corresponding to the shortcode address. | public static final int | APP_IDType corresponding to the application id address. | public String | addressField that holds address part of the mms address
(without "mms://" and ":" separator before app id). | public String | appIdField that holds application id part of the mms address
which appears after "mms://:" or
after phone number, ipv4, or ipv6 followed by ":" . | public int | typeType of this MMSAddress instance,
INVALID_ADDRESS when uninitialized . |
Constructors Summary |
---|
MMSAddress()MMSAddress constructor to create uninitialized instance.
clear();
| MMSAddress(String address, String appId, int type)MMSAddress constructor to create initialized instance.
set(address, appId, type);
|
Methods Summary |
---|
private static boolean | alpha(char c)Determines whether a character is a letter.
return (c >= 'a" && c <= 'z") || (c >= 'A" && c <= 'Z");
| private static boolean | asciiControl(char c)Determines whether a character represents an ascii control
character.
return ((int)c >= 0 && (int)c <= 31);
| private static boolean | atomChar(char c)Determines whether a character represents an atom character.
as specified in WMA 2.0 specification.
return ((int)c <= 127 && (int)c > 32 && !specials(c));
| void | clear()Clears MMSAddress fields.
Type is set to INVALID_ADDRESS while
address and appId are set to null.
address = appId = null;
type = INVALID_ADDRESS;
| private static boolean | digit(char c)Determines whether a character represents a digit.
return (c >= '0" && c <= '9");
| java.lang.String | getMMSAddressString()Creates a valid mms address corresponding to the values
in this MMSAddress object.
If the object is not intialized null is returned.
if (type == INVALID_ADDRESS ||
(address == null && appId == null)) {
return null;
}
StringBuffer mmsAddr = new StringBuffer("mms://");
if (address != null) mmsAddr.append(address);
if (appId != null) mmsAddr.append(":").append(appId);
return mmsAddr.toString();
| public static com.sun.midp.io.j2me.mms.MMSAddress | getParsedMMSAddress(java.lang.String addressStr)Determines whether a string represents a valid mms address
as specified in WMA 2.0 specification and parses the
incoming string into address and application id strings.
return getParsedMMSAddress(addressStr, null);
| public static com.sun.midp.io.j2me.mms.MMSAddress | getParsedMMSAddress(java.lang.String addressStr, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid mms address
as specified in WMA 2.0 specification and parses the
incoming string into address and application id strings.
if (addressStr == null || !addressStr.startsWith("mms://")) {
return null;
}
if (mmsAddress == null) {
mmsAddress = new MMSAddress();
}
if (parsePhoneNumber(addressStr, 6, mmsAddress) ||
parseIpv4(addressStr, 6, mmsAddress) ||
parseIpv6(addressStr, 6, mmsAddress) ||
parseEmail(addressStr, 6, mmsAddress) ||
parseShortCode(addressStr, 6, mmsAddress) ||
parseApplicationId(addressStr, 6, mmsAddress)) {
return mmsAddress;
}
return null;
| private static boolean | hex(char c)Determines whether a character represents a hexadecimal number.
('0' - '9' and 'A' - 'F')
return (digit(c) || (c >= 'A" && c <= 'F"));
| private static boolean | isChar(char c)Determines whether a character represents a character.
return ((int)c) >= 0 && ((int)c) <= 127;
| private static int | isDomain(java.lang.String s, int i, int n)Determines whether a string represents a valid "domain"
starting from an index.
Domain syntax is specified in WMA 2.0 spec as
1*(atom | "[" *(text w/o ",[,],\r but with linear space | "\"alpha) "]")
where atom is represented by at least one char or more which is
not a space or a special or control character.
return isSequenceOfAtomAndText(s, i, n, '[", ']", true);
| private static int | isLocalAtDomain(java.lang.String s, int i, int n)Determines whether a string starting from an index satisfies the
following syntax: local-part"@"domain
if (n > s.length()) {
n = s.length();
}
if (i >= n) {
return -1;
}
// local
if ((i = isLocalPart(s, i, n)) <= 0) {
return -1;
}
if (i == n || s.charAt(i) != '@") {
return -1;
}
i++;
// domain
return isDomain(s, i, n);
| private static int | isLocalPart(java.lang.String s, int i, int n)Determines whether a string represents a valid "local-part"
starting from an index.
Local-part syntax is specified in WMA 2.0 spec as
(atom | "\"alpha) *("." (atom | "\"alpha)) where
atom is represented by at least one char which is
not a space or a special or control character.
return isSequenceOfAtomAndText(s, i, n, '"", '"", true);
| private static int | isMailbox(java.lang.String s, int i, int n)Determines whether a string represents a valid mailbox address
starting from an index.
Mailbox syntax is specified in WMA 2.0 spec as
local-part"@"domain or as
[phrase] "<"[("@"domain) [*("," ("@"domain))]] local-part"@"domain">"
if (n > s.length()) {
n = s.length();
}
if (i >= n) {
return -1;
}
int initI = i;
if ((i = isLocalAtDomain(s, initI, n)) > 0) {
return i;
}
i = initI;
// check for [phrase] <[1#(@ domain):] local @ domain>
// note phrase is optional
if ((s.charAt(i) != '<") &&
(i = isPhrase(s, initI, n)) < 0) {
return -1;
}
if (i == n || s.charAt(i) != '<") {
return -1;
}
i++;
if (i == n) {
return -1;
}
// there can be a list of domains:
// @ domain, @domain, @domain :
boolean atLeastOneDomain = false;
while (s.charAt(i) == '@") {
atLeastOneDomain = true;
if ((i = isDomain(s, i+1, n)) < 0) {
return -1;
}
if (i == n) {
return -1;
}
if (s.charAt(i) == ':") {
break;
}
// @domain,,@domain is allowed
while (s.charAt(i) == ',") {
i++;
if (i == n || s.charAt(i) == ':") {
return -1;
}
}
}
if (atLeastOneDomain) {
if (i == n || s.charAt(i) != ':") {
return -1;
}
i++;
}
// local @ domain
if ((i = isLocalAtDomain(s, i, n)) <= 0) {
return -1;
}
if (i < n && s.charAt(i) == '>") {
return i + 1;
}
return -1;
| private static int | isPhrase(java.lang.String s, int i, int n)Determines whether a string represents a valid "phrase"
starting from an index.
Phrase syntax is specified in WMA 2.0 spec as
1*(atom | """ *(text w/o ",\,\r but with linear space | "\"alpha) """)
where atom is represented by at least one char or more which is
not a space or a special or control character.
return isSequenceOfAtomAndText(s, i, n, '"", '"", false);
| private static int | isSequenceOfAtomAndText(java.lang.String s, int i, int n, char begSep, char endSep, boolean dotSeparated)Determines whether a string starting from an index
represents a valid sequence that satisfies the following
syntax:
text ::==
*(1*(|\ALPHA))
sequence ::== 1*(atom | text) | (atom | text) *("." (atom | text))
where atom is represented by at least one or more characters that
are not space or special or control characters
and begSep/endSep are separators that are placed around text.
LWSP is a linear white space (space and tabs and \r\n but not \r).
if (i >= s.length()) {
return -1;
}
if (n > s.length()) {
n = s.length();
}
// see if there is at least one word
boolean withinQuotation = false;
boolean atLeastOneWord = false;
char c;
int initI = i;
for (; i < n; i++) {
c = s.charAt(i);
if (c == begSep) {
if (begSep == endSep) {
withinQuotation = !withinQuotation;
} else if (withinQuotation) {
return -1;
} else {
withinQuotation = true;
}
atLeastOneWord = true;
} else if (c == endSep) {
if (!withinQuotation) {
return -1;
}
withinQuotation = false;
} else if (c == '\\") {
// chars can be quoated only within separators
// and there has to be another char after '\'
if (!withinQuotation || i == n-1) {
return -1;
}
i++;
c = s.charAt(i);
// only ALPHA character can be quoted
if (!alpha(c)) {
return -1;
}
} else if (dotSeparated && c == '.") {
if (i == initI ||
((i - initI) > 0 && s.charAt(i-1) == '.")) {
// empty word
// string starts with .
return -1;
}
} else if (withinQuotation) {
// within quotation \r is not allowed but
// \r is allowed as part of linear-white-space
if (c == ' " || c == '\t" || c == '\r") {
if ((i = linearWhiteSpaceSeq(s, i, n)) < 0) {
return -1;
}
i--;
}
} else if (atomChar(c)) {
atLeastOneWord = true;
} else {
// this is supposed to be an atom
break;
}
}
// open quotation or no words or
// dot separator is the last char
if (withinQuotation || !atLeastOneWord ||
(dotSeparated && i > initI && s.charAt(i-1) == '.")) {
return -1;
}
return i;
| private static int | linearWhiteSpaceSeq(java.lang.String s, int i, int n)Determines first not linear white space character
in s after character with index i but
before character with index n .
char c;
for (; i < n; i++) {
c = s.charAt(i);
if (c == ' " || c == '\t") {
continue;
}
if (c == '\r") {
// only CR LF one after another are allowed
// CR by itself is not allowed
if (i == n-1 || s.charAt(i+1) != '\n") {
return i;
}
i++;
} else {
return i;
}
}
return i;
| static boolean | parseApplicationId(java.lang.String s, int i, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid application ID
starting from an index.If the address string is a valid
application id representation it is parsed into the fields of
MMSAddress object (application id and null for the
address).
Application ID syntax is specified in WMA 2.0 spec as :
":"[*(1*(alpha | digit | "." | "_") ".")]1*(alpha | digit | "." | "_").
The number of characters in application ID must not exceed 32.
int len = s.length();
/*
* Empty string or string like ":" are not allowed.
* Only 32 characters are allowed.
* Note: When checking appID length, keep in mind that
* i is pointing to ":"
*/
if (i <= 0 || i >= len || (len-i-1) > 32 || (len-i-1) < 0 ||
s.charAt(i) != ':") {
return false;
}
i++; // to skip ':'
char c;
int initI = i;
for (int j = 0; i < len; i++) {
c = s.charAt(i);
for (j = 0; i < len; i++, j++) {
c = s.charAt(i);
if ((c != '_") && /* dot is also allowed in the spec ??? */
!digit(c) && !alpha(c)) {
break;
}
}
if (i == len) {
if (mmsAddress.type == INVALID_ADDRESS) {
mmsAddress.set(null, s.substring(initI), APP_ID);
} else {
mmsAddress.setAppid(s.substring(initI));
}
return true;
}
// there has to be at least one digit or letter and
// nondigit and nonalpha char can be only dot (one dot only)
if (j == 0 || c != '.") {
return false;
}
}
return false;
| static boolean | parseEmail(java.lang.String s, int i, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid e-mail address
starting from an index. If the address string is a valid
e-mail address representation it is parsed into the fields of
MMSAddress object (address and null for appId).
E-mail syntax is specified in WMA 2.0 spec.
int len = s.length();
if (i <= 0 || i >= len) {
return false;
}
int initI = i;
// email can be on of the following:
// emial ::== mailbox | phrase : [#mailbox] ;
// if there is a ';' at the end then there should be a phrase
// at the beginning
if (s.charAt(len-1) == ';") {
if ((i = isPhrase(s, i, len-1)) <= 0) {
return false;
}
// there was no ":"
if (i >= len-1 || s.charAt(i) != ':") {
return false;
}
i++; // move after ':'
if (i == len-1) {
mmsAddress.set(s.substring(initI), null, EMAIL);
return true; // phrase : ; is allowed string
}
if ((i = isMailbox(s, i, len-1)) <= 0) {
return false;
}
while (i < len-1) {
// there has to be a ',' sep
if (i >= len-2 && s.charAt(i) != ',") {
return false;
}
if ((i = isMailbox(s, i+1, len-1)) <= 0) {
return false;
}
}
if (i == len-1) {
mmsAddress.set(s.substring(initI), null, EMAIL);
return true;
}
return false;
}
if (isMailbox(s, i, len) == len) {
mmsAddress.set(s.substring(initI), null, EMAIL);
return true;
}
return false;
| static boolean | parseIpv4(java.lang.String s, int i, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid ipv4 address
starting from an index. If the address string is a valid
ipv4 representation it is parsed into the fields of
MMSAddress object (address and application id).
ipv4 syntax is specified in WMA 2.0 spec as :
1*3digit "." 1*3digit "." 1*3digit "." 1*3digit [applicationId]
int len = s.length();
if (i <= 0 || i >= len) {
return false;
}
char c;
int j;
int initI = i;
for (int num = 1; num < 5; num++) {
for (j = 0; j < 3 && i < len; i++, j++) {
c = s.charAt(i);
if (!digit(c)) {
break;
}
}
// there should be at least one digit and
// the number between dots should be less then 256
if (j == 0 ||
(j == 3 &&
(((s.charAt(i-3)-'0")*10 + (s.charAt(i-2)-'0"))*10 +
(s.charAt(i-1)-'0")) > 255)) {
return false;
}
// check if this is the end of the string
if (i == len) {
if (num == 4) {
mmsAddress.set(s.substring(initI), null, IPV4);
return true;
}
return false;
}
c = s.charAt(i);
if (c == ':") {
mmsAddress.set(s.substring(initI, i), null, IPV4);
return parseApplicationId(s, i, mmsAddress);
}
if (c != '.") {
return false; // 4th character after beg (or dot)
// should be dot;
// only dots are allowed as non digit char
}
// allowed '.' => continue
i++;
}
return false;
| static boolean | parseIpv6(java.lang.String s, int i, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid ipv6 address
starting from an index. If the address string is a valid
ipv6 representation it is parsed into the fields of
MMSAddress object (address and application id).
ipv6 syntax is specified in WMA 2.0 spec as :
ipv6-atom ":" ipv6-atom ":" ipv6-atom ":" ipv6-atom ":"
ipv6-atom ":" ipv6-atom ":" ipv6-atom ":" ipv6-atom [appId]
where ipv6-atom is 1*4(digit | hex-alpha).
int len = s.length();
if (i <= 0 || i >= len) {
return false;
}
char c;
int j;
int initI = i;
for (int num = 1; num < 9; num++) {
for (j = 0; j < 4 && i < len; i++, j++) {
c = s.charAt(i);
if (!hex(c)) {
break;
}
}
// there should be at least one digit
if (j == 0) {
return false;
}
// check if this is the end of the string
if (i == len) {
if (num == 8) {
mmsAddress.set(s.substring(initI), null, IPV6);
return true;
}
return false;
}
c = s.charAt(i);
if (c == ':") {
if (num == 8) {
mmsAddress.set(s.substring(initI, i),
null, IPV6);
return parseApplicationId(s, i, mmsAddress);
}
} else {
return false; // 5th character after beg (or :)
// should be :
// only : are allowed as non digit char
}
// allowed ':' => continue
i++;
}
return false;
| static boolean | parsePhoneNumber(java.lang.String s, int i, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid phone number
starting from an index. If the address string is a valid
phone number representation it is parsed into the fields of
MMSAddress object (address and application id).
General phone number syntax is specified in WMA 2.0 spec as :
("+" 1*digit | 1*digit) [applicationId]
int len = s.length();
if (i < 0 || i >= len) {
return false;
}
int initI = i;
char c = s.charAt(i);
if (c == '+") {
i++;
if (len == i) {
return false;
}
}
int j = 0;
for (; i < len; j++, i++) {
c = s.charAt(i);
if (!digit(c)) {
break;
}
}
if (j == 0) {
return false;
}
if (i == len) {
mmsAddress.set(s.substring(initI), null, GLOBAL_PHONE_NUMBER);
return true;
}
if (c == ':") {
mmsAddress.set(s.substring(initI, i),
null, GLOBAL_PHONE_NUMBER);
return parseApplicationId(s, i, mmsAddress);
}
return false;
| static boolean | parseShortCode(java.lang.String s, int i, com.sun.midp.io.j2me.mms.MMSAddress mmsAddress)Determines whether a string represents a valid shortcode
starting from an index. If the address string is a valid
shortcode representation it is parsed into the fields of
MMSAddress object (address and null for appId).
Shortcode syntax is specified in WMA 2.0 spec as :
*(digit | alpha)
int len = s.length();
if (i > len) {
return false;
}
if (i == len) {
return false; // Even though spec allows "mms://" as a valid
// shortcode, we disallow it here
}
int initI = i;
char c;
for (; i < s.length(); i++) {
c = s.charAt(i);
if (!digit(c) && !alpha(c)) {
return false;
}
}
mmsAddress.set(s.substring(initI), null, SHORTCODE);
return true;
| void | set(java.lang.String address, java.lang.String appId, int type)Sets MMSAddress fields to the passed in values.
this.address = address;
this.appId = appId;
this.type = type;
| void | setAppid(java.lang.String appId)Sets MMSAddress application id field to
the passed in value.
this.appId = appId;
| private static boolean | specials(char c)Determines whether a character represents a special e-mail character.
if (c == '(" || c == ')" || c == '<" || c == '>" ||
c == '@" || c == '," || c == ';" || c == ':" ||
c == '\\" || c == '"" || c == '." || c == '[" || c == ']") {
return true;
}
return false;
|
|