getting detail country name and country code of a given phone number - java

I able to detect incoming calls in android but problem is that I want to know to the country code of that phone number so that I can analyze whether it is a national or international number. I know about libphonenumber
but It needs to know region code before hand to get the country code as shown in the example
String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber swissNumberProto = phoneUtil.parse(swissNumberStr, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
it already knows to put "CH" as a parameter. but we don't know if the number is to known to us then how we can analyze that number.

As long as it is not a regional number (in which case it is just a plain number and no lib in this world could determine where it is from) you can specify "ZZ" or null for the second parameter of parse.
This is what the documentation says:
region that we are expecting the number to be from. This is only used
if the number being parsed is not written in international format. The
country_code for the number in this case would be stored as that of
the default region supplied. If the number is guaranteed to start with
a '+' followed by the country calling code, then "ZZ" or null can be
supplied.
After you where able to create an instace of PhoneNumber you can simply call getRegionCodeForNumber as shown below.
String swissNumberStr = "044 668 18 00";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
PhoneNumber numberProto = phoneUtil.parse(swissNumberStr, "ZZ");
System.out.println(phoneUtil.getRegionCodeForNumber(numberProto));
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}

Related

Generating human readable SWIFT messages using Prowide-Core?

I'm using Prowide-Core for SWIFT message handling. At the moment I use the JSON methods to produce human readable versions of my messages if I need to dump them out. This produces output like this:
...
}, {
"97A" : ":SAFE//0123-0123456-55-000"
}, {
...
I.e. I get alphanumeric codes, like 97A, for the field names.
However it I look at Field97A.java:471 I can see that it (and all other fields) know their more human readable names (Qualifier and Account in the case of 97A).
I've tried looking for some toString() like method that makes use of this information to produce something even more readable than the JSON output but haven't found anything yet.
Is there such a method on SwiftMessage or one of the related classes? Or has someone written something nice that can traverse a message and print it out using the information returned by getComponentLabels() etc?
I'm one of the authors. For future reference, in the upcoming SRU2018 release (scheduled for October) we have revamped all the JSON API in all model abstraction layers.
The toJson in SwiftMessage object still produces plain name/value tuples for the Tags. However, in the MTnnn classes, the toJson uses Field to produce JSON with business labels such as:
{ "name": "90A",
"qualifier": "DEAL",
"percentageTypeCode": "PRCT",
"price": "102,713552"
},
{ "name": "36B",
"qualifier": "ESTT",
"quantityTypeCode": "AMOR",
"quantity": "7999999,573"
},
{ "name": "97A",
"qualifier": "SAFE",
"account": "0123-0123456-55formatted
}
Besides the JSON, you can iterate the fields and print formated name and values with the available getLabel and getValueDisplay methods.
For example:
Locale locale = Locale.getDefault();
SwiftMessage sm = SwiftMessage.parse("{1:F01BACOARB1A0B20000000000}{2:I103ADRBNL21XXXXU2}{3:{108:FOOB3926BE868XXX}}{4:\n" +
":20:REFERENCE\n" +
":23B:CRED\n" +
":32A:180730USD1234567,89\n" +
":50A:/12345678901234567890\n" +
"CFIMHKH1XXX\n" +
":59:/12345678901234567890\n" +
"JOE DOE\n" +
"MyStreet 1234\n" +
":71A:OUR\n" +
"-}");
System.out.println("Sender: " + sm.getSender());
System.out.println("Receiver: " + sm.getReceiver() + "\n");
for (Tag tag : sm.getBlock4().getTags()) {
Field field = tag.asField();
System.out.println(Field.getLabel(field.getName(), "103", null, locale));
System.out.println(field.getValueDisplay(locale) + "\n");
}
Will produce this output:
Sender: BACOARB1A0B2
Receiver: ADRBNL21XXXX
Sender's Reference
REFERENCE
Bank Operation Code
CRED
Value Date/Currency/Interbank Settled Amount
Jul 30, 2018 USD 1,234,567.89
Ordering Customer
12345678901234567890 CFIMHKH1XXX
Beneficiary Customer
12345678901234567890 JOE DOE MyStreet 1234
Details of Charges
OUR
Where components are split and formatted for the locale.
And if you also need labels per component, you can further iterate the components like this:
for (Tag tag : sm.getBlock4().getTags()) {
Field field = tag.asField();
System.out.println("\n" + Field.getLabel(field.getName(), "103", null, locale));
for (int component = 1 ; component <= field.componentsSize() ; component++) {
if (field.getComponent(component) != null) {
System.out.print(field.getComponentLabel(component) + ": ");
System.out.println(field.getValueDisplay(component, locale));
}
}
}
Pruducing this other output:
Sender's Reference
Reference: REFERENCE
Bank Operation Code
Type: CRED
Value Date/Currency/Interbank Settled Amount
Date: Jul 30, 2018
Currency: USD
Amount: 1,234,567.89
Ordering Customer
Account: 12345678901234567890
BIC: CFIMHKH1XXX
Beneficiary Customer
Account: 12345678901234567890
Name And Address: JOE DOE
Name And Address 2: MyStreet 1234
Details of Charges
Code: OUR
Finally, if you are interested, the Integrator library from Prowide includes out-of-the-box printout visitors to produce HTML, TXT, and XML including structured sequences and BIC expanded with the institution information. You may ask Prowide for a trial.
SwiftTagListBlock provides a toJson method that iterates over Tag objects:
public String toJson() {
final StringBuilder sb = new StringBuilder();
sb.append("[ \n");
if (this.tags != null && !this.tags.isEmpty()) {
for (int i=0;i<this.tags.size();i++) {
final Tag t = this.tags.get(i);
sb.append("{ \"").append(t.getName()).append("\" : \"").append(escapeJson(t.getValue())).append("\" }");
if (i+1<this.tags.size()) {
sb.append(',');
}
sb.append('\n');
}
}
sb.append("]");
return sb.toString();
}
You could tweak the source code and call the asField() method of Tag, in order to have access to the Field representation and use the information required for your output.

com.ibm.icu.text.DecimalFormat always throws ParseException

With the following code I only want to allow positive numbers. For some reason i am not even able to parse the strings correctly:
DecimalFormat dfNoNegative = new DecimalFormat("#,##0.00");
dfNoNegative.setNegativePrefix("");
try {
System.out.println(dfNoNegative.parse("123.00"));
} catch (ParseException e) {
System.out.println(e.getMessage());
System.out.println(e.getErrorOffset());
e.printStackTrace();
}
Error message and ErrorOffset:
Unparseable number: "123.00"
6
Can anyone guide me where I am mistaken? An example for a working String would be good as well
My mistake was to dfNoNegative.setNegativePrefix(""); to nothing (""). This doesn't work, because the String started directly with the number and 123 is not "", and therefore it fails. Basically this method overwrites what should be used as negative prefix (default is -). If you set it to ! as example, System.out.println(dfNoNegative.parse("!123.00")); would print -123.

accountExpires attribute not listed when read from Java

Hello Java and AD experts..
I am having an issue while reading accountExpires attribute value from AD. When I read this attribute using Java code, I got the result null.
Then I thought of checking various attributes provided by AD by printing the all the AD attributes using the following code:
Attributes allAttrs = ldapCtx.getAttributes(distinguishedName);
System.out.println("Total no.of properties: " + allAttrs.size());
try{
String attrs = "";
for (NamingEnumeration ae = allAttrs.getAll(); ae.hasMore();) {
Attribute attr = (Attribute) ae.next();
attrs = attrs+"\nFor attribute: "+ attr.getID()+" values are - ";
/* print each value */
for (NamingEnumeration e = attr.getAll(); e.hasMore(); attrs = attrs + e.next()+";");
}
System.out.println(attrs);
}
catch(Exception e){
System.out.println("Exception in getAttribute: " + e);
}
It had listed 72 properties. And accountExpires property itself is not present there :(
Can anyone guide me why this property is not available in my case and how to get rid of this
Regards,
FH
It wont list any account expiration attribute. You need to calculate it. Suppose your password expiration limit is 90 days and you need to send a warning mail to the user when there is 10 days left for expiration. You will get account created date, find the number of days between the account created date and current date if the difference is 80 then send a warning mail.

Java Style: Catching a bunch of slightly different errors

In a program I'm working on in Java where I have to read data from a file. The data is formatted so that each line contains all the necessary information to construct a new object. When I parse the data, I have a block of code that looks something like this:
String[] parts = file.nextLine().split(",");
String attr1 = parts[0];
int attr2, attr3;
try{
attr2 = Integer.parseInt(parts[1]);
} catch (NumberFormatException ex){
System.out.println("Could not parse attr2, got " + parts[1] + ".");
return;
}
try{
attr3 = Integer.parseInt(parts[2]);
} catch (NumberFormatException ex){
System.out.println("Could not parse attr3, got " + parts[2] + ".");
return;
}
ClassA attr4 = null, attr5 = null, attr6 = null;
try{
...
} catch (SomeExceptionType ex){
System.out.println("Could not parse attr4, got " + parts[3] + ".");
}
...
I find myself repeating the same simple try block over and over again. In an attempt to mitigate the situation and adhere to the DRY principle a bit more, I introduced some attempt methods:
int attr2 = attemptGetInt(parts, 1, "attr2");
int attr3 = attemptGetInt(parts, 2, "attr3");
ClassA attr4 = attemptGetClassA(parts, 3, "attr4");
...
// Somewhere in the class
public int attemptGetInt(String[] parts, int index, String name) throws SomeOtherException1{
try{
return Integer.parseInt(parts[index]);
} catch (NumberFormatException ex){
throw new SomeOtherException1("Could not parse " + name + ", got " + parts[index] + ".");
}
}
public ClassA attemptGetClassA(String[] parts, int index, String name) throws SomeOtherException2{
try{
return ...
} catch (SomeExceptionType ex){
throw new SomeOtherException2("Could not parse " + name + ", got" + parts[index] + ".");
}
}
...
Even this feels weird though, because there are a lot of different types I have to return that all sort of have the same but slightly different code and need to catch a slightly different error each time (i.e. I have to create an attemptGetClassB and attemptGetClassC and so on, a bunch of times with similar code each time).
Is there an elegant way of writing code like this?
If you have control over the format of the input file you might wish to change it to XML with a schema. That way the parser itself takes care of a lot of this type of checking for you.
However from the nature of the question I assume the format is fixed. In that case I would suggest splitting the syntax checking and parsing into separate steps for each line.
An easy way to do the syntax checking is using a regexp. Fairly complex syntax can be encoded in a regular expression so unless the files contain some sort of nesting (in which case DEFINITELY use XML instead) then it should be fairly straightforward.
The second step of parsing should then only return exceptions by exception :-) You still need to catch them but it's perfectly good form to gather all of your catches into a single block because it should only be used when debugging: in normal operations the syntax check will catch errors before this step.
My view is that this design is more intuitive and obvious. It may have a downside in error reporting if you specifically want to report on each error separately. In that case you'll need to break the string into substrings first (using a Scanner for example) and then syntax check each substring.
As a final note, opinions vary on this but my personal preference is not to use exception handling for conditions that occur in normal operations. They are not well suited for that (in my opinion). Better to do what I'm suggesting here: have explicit code to check error conditions before processing and then use exceptions for things that should not normally occur.

How to bind an hstore[] value in Java

I'm trying to store people's telephone numbers and addresses in a database table. I would like to support multiple phone numbers and addresses and expect the format to be different in different countries. I've decided to use hstore to allow that flexibility and allow efficient querying by specific fields. As it stands I can receive the values from database, but could not find a way to insert them from Java. The table (simplified) looks like that:
CREATE TABLE IF NOT EXISTS contacts ( "
+ "id uuid NOT NULL, "
+ "title character varying NOT NULL DEFAULT '', "
+ "first_name character varying NOT NULL, "
+ "last_name character varying NOT NULL, "
+ "phones hstore[] NOT NULL DEFAULT '{}', "
+ "addresses hstore[] NOT NULL DEFAULT '{}')"
I have created a custom JDBI Binder to bind the values, but however I try I can't get the statement to execute. Currently Binder code snippet looks like this:
#Override
public void bind(SQLStatement<?> q, BindContactBean bind, ContactBean bean) {
q.bind("phones",
getHstoreArray(q, PhoneDetailMapper.toMapArray(bean.phones.get())));
q.bind("addresses",
getHstoreArray(q, AddressDetailMapper.toMapArray(bean.addresses.get())));
The getHstoreArray function is a helper that converts java Array into SQL array and looks like this:
private Array getHstoreArray(SQLStatement<?> q, Map<String, String>[] map) {
try {
return q.getContext().getConnection().createArrayOf("hstore", map);
} catch (SQLException e) {
throw new IllegalArgumentException(e);
}
}
I think the problem is in encoding of the data. For example, for data (in JSON notation for simplicity)
{
"firstName": "Maximum",
"lastName": "Details",
"status": "active",
"phones": [{
"type": "mobile",
"number": "0777 66 55 44"
}]
}
the query is expanded to:
INSERT INTO contacts (
id, first_name, last_name, status, phones )
VALUES ( '9be1a040-b408-11e3-bb43-00231832fa86', 'Maximum', 'Details', 4,
'{"{type=mobile, extracted_number=extracted, number=07777 66 55 44}"}'
)
and if I try to run it from PGAdmin's SQL editor the error returned is:
ERROR: Syntax error near 'm' at position 6
LINE 5: '{"{type=mobile, extracted_number=extracted, number=07777 66...
^
********** Error **********
ERROR: Syntax error near 'm' at position 6
SQL state: XX000
Character: 179
I have considered using JSON instead of hstore[], but that would make querying by specific fields slower and less accurate (essentially a text search) and I'd rather avoid it.
Another option I tried before hstore is array of UDT, but couldn't even get it to read from database without writing parser for PGobject which doesn't look like a simple task.
EDIT
I had a look at the data in the database and when escaped in the following way:
'{"\"type\"=>\"mobile\", \"number\"=>\"07777 66 55 44\", \"extracted_number\"=>\"777665544\""}'
I can run query manually from SQL editor, but still no luck in Java.
I have found a solution, there is a class available in Postgres driver called HStoreConverter which can convert Map to String literal. Not sure this is the best approach, but it seems to work, modified helper function below.
private Array getHstoreArray(SQLStatement<?> q, Map<String, String>[] maps) {
try {
String[] hstores = new String[maps.length];
for (int i = 0; i < maps.length; i++)
hstores[i] = HStoreConverter.toString(maps[i]);
return q.getContext().getConnection().createArrayOf("hstore", hstores);
} catch (SQLException e) {
throw new IllegalArgumentException(e);
}
}

Categories