Saturday, December 18, 2010

Mobile Operator/Carrier detection using MaxMind – Second Part – Creating carriers JSON file

In this post we saw how the first steps to mobile operator/carrier detection. We saw how the data of carriers and carriers mapping is stored in database.
Now we will see how to convert this data to a JSON file. Our mobile operator/carrier detection module will be probably be used by an Ad server. Ad servers are usually not connected to database (you need Ad server to be robust and work under high pressure). Therefore, we would like to be able to load the carriers information from a simple file.
For this purpose, we will create a simple class named CarrierDataHolder that will host all the mobile operator/carrier mapping in a single map. The map is constructed from 2 inner classes: a composite key named Key and value named Value.
These are the members of the map Key:
  • countryCode
  • isp
  • org
These are the members of the map Value:
  • carrierId
  • name
Note, that for the Key of the map, we implement “hashCode” and “equals” methods, otherwise the map would not function properly.
By using this map, we later be able to get any carrier simple by supplying country code, isp and organization. The country code isp and organization will be extracted from the user ip using MaxMind.
The CarrierDataHolder contains 2 important methods:
  • loadCarriersFromDB – This method gets a database connection and loads all the carrier and carrier mapping information to the carrierMapping map.
  • toJSONFile – This method stores all the data loaded to carrierMapping map to a JSON file. The data is saved to JSON using XStream open source project.
Let’s have a look at the CarrierDataHolder class:
package com.bashan.blog.geo;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author Bashan
*/
public class CarrierDataHolder {
 
public final Map<Key, Value> carrierMapping = new HashMap<Key, Value>();
 
public void loadCarriersFromDB(Connection conn) throws SQLException {
carrierMapping.clear();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select c.carrier_id, c.country_code, c.name, cm.isp, cm.org from carrier c inner join " +
"carrier_mapping cm on c.carrier_id = cm.carrier_id order by c.carrier_id");
  while (rs.next()) {
    int carrierId = rs.getInt("carrier_id");
String countryCode = rs.getString("country_code");
String name = rs.getString("name");
String isp = rs.getString("isp");
String org = rs.getString("org");
carrierMapping.put(new Key(countryCode, isp, org), new Value(carrierId, name));
}
}
 
private XStream getXStream() {
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("carrierMapping", Map.class);
xstream.alias("key", Key.class);
xstream.alias("value", Value.class);
  return xstream;
 
public String toJSON() {
XStream xStream = getXStream();
  return xStream.toXML(carrierMapping);
 
public void toJSONFile(File file) throws IOException {
XStream xStream = getXStream();
FileWriter fileWriter = null;
  try {
fileWriter = new FileWriter(file);
xStream.toXML(carrierMapping, fileWriter);
} finally {
      if (fileWriter != null) {
fileWriter.close();
}
}
}
 
public static class Key {
 
private String countryCode;
private String isp;
private String org;
 
public Key() {
}
 
public Key(String countryCode, String isp, String org) {
  this.countryCode = countryCode;
  this.isp = isp;
  this.org = org;
}
 
public String getCountryCode() {
  return countryCode;
 
public void setCountryCode(String countryCode) {
  this.countryCode = countryCode;
 
public String getIsp() {
  return isp;
 
public void setIsp(String isp) {
  this.isp = isp;
 
public String getOrg() {
  return org;
 
public void setOrg(String org) {
  this.org = org;
}
 
@Override
public boolean equals(Object o) {
  if (this == o) return true;
  if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
  if (countryCode != null ? !countryCode.equals(key.countryCode) : key.countryCode != null) return false;
  if (isp != null ? !isp.equals(key.isp) : key.isp != null) return false;
  if (org != null ? !org.equals(key.org) : key.org != null) return false;
  return true;
 
@Override
public int hashCode() {
  int result = countryCode != null ? countryCode.hashCode() : 0;
result = 31 * result + (isp != null ? isp.hashCode() : 0);
result = 31 * result + (org != null ? org.hashCode() : 0);
  return result;
}
 
public static class Value {
 
private int carrierId;
private String name;
 
public Value() {
 
public Value(int carrierId, String name) {
  this.carrierId = carrierId;
  this.name = name;
 
public int getCarrierId() {
  return carrierId;
 
public void setCarrierId(int carrierId) {
  this.carrierId = carrierId;
 
public String getName() {
  return name;
 
public void setName(String name) {
  this.name = name;
}
}
}


The data loaded by the loadCarriersFromDB method is taken from carrier and carrier_mapping tables. This post explains how they are created.

Let’s have a look at a small test program that loads all carriers information and stores it to a JSON file. Note that we assume the name of the database is adserver:
public static void main(String[] args) {
CarrierDataHolder carrierDataHolder = new CarrierDataHolder();
Connection conn = null;
  try {
String userName = "root";
String password = "root";
String url = "jdbc:mysql://localhost:3306/adserver?useUnicode=true&characterEncoding=UTF-8";
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, userName, password);
carrierDataHolder.loadCarriersFromDB(conn);
carrierDataHolder.toJSONFile(new File("c:\\data\\carriers.json"));
} catch (Exception e) {
e.printStackTrace();
} finally {
  if (conn != null) {
    try {
conn.close();
} catch (SQLException sql) {
sql.printStackTrace();
}
}
}
}

You can download the class CarrierDataHolder by pressing this link. Note that this class is using XStream open source project. Therefore you will have to download XStream jar files as well (xstream and jettison).
Here is the mobile operators/carriers detection JSON file generated by using the CarrierDataHolder class.

No comments:

Post a Comment