package com.mehmetakiftutuncu.eshotroid.utility;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Locale;
import android.util.Log;
import com.google.gson.Gson;
import com.mehmetakiftutuncu.eshotroid.BuildConfig;
import com.mehmetakiftutuncu.eshotroid.model.BusTime;
import com.mehmetakiftutuncu.eshotroid.model.KentKartBalanceQueryResult;
import com.mehmetakiftutuncu.eshotroid.model.KentKartQueryResponse;
/** A utility class for parsing the pages
*
* @author mehmetakiftutuncu */
public class Parser
{
// Tags for a busses in Ulasim.aspx
public static final String BUS_OPEN_START = "<option value=";
public static final String BUS_OPEN_END = "\">";
public static final String BUS_CLOSE = "</option>";
// Tags for a bus route in Saatler.aspx
public static final String BUSROUTE_OPEN_START = "<span ";
public static final String BUSROUTE_OPEN_END = "Guzergah\">";
public static final String BUSROUTE_CLOSE = "</span>";
// Tags containing a bus time and wheel chair enabled status
public static final String BUSTIME_CONTAINER_OPEN = "<div style=\"";
public static final String BUSTIME_CONTAINER_CLOSE = "</div>";
// Tags for a bus time in Saatler.aspx
public static final String BUSTIME_OPEN_START = "<span ";
public static final String BUSTIME_OPEN_END = "\">";
public static final String BUSTIME_CLOSE = "</span>";
// Indicates if the bus on that time is wheel chair enabled
public static final String BUSTIME_WHEEL_CHAIR_ENABLED = "images/sandalye.png";
// Tag that encloses bus times
public static final String BUSTIME_TABLE = "<table cellspacing=";
// Format pattern of Kent Kart use time format in response
public static final String KENT_KART_TIME_FORMAT_RESPONSE = "yyyyMMddHHmmss";
// Format pattern of Kent Kart use time format in result
public static final String KENT_KART_TIME_FORMAT_RESULT = "dd MMMM yyyy, HH:mm:ss";
/** Tag for debugging */
public static final String LOG_TAG = "Eshotroid_Parser";
/** Gets the route of the bus from the times page of that bus
*
* @param page Source of the page
*
* @return Route of the bus, null if any error occurs */
public static String parseBusRoute(String page)
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Parsing bus route...");
String result = null;
// Start looking for bus route
int start = 0, end = 0;
// Get the bus route information start point
start = page.indexOf(BUSROUTE_OPEN_START);
if(start != -1)
{
// Get where the start point ends
start = page.indexOf(BUSROUTE_OPEN_END, start);
if(start != -1)
{
// This is the actual start point of the bus route information
start += BUSROUTE_OPEN_END.length();
// Now look for where the bus route information ends
end = page.indexOf(BUSROUTE_CLOSE, start);
if(end != -1)
{
// Now we extract the bus route information using the found start and end points
result = page.substring(start, end);
}
}
}
return result;
}
/** Gets the list of the bus times from the specified page
*
* @param page Source of the page
*
* @return List of the bus times, null if any error occurs */
public static ArrayList<String> parseBusTimes(String page)
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Parsing bus times...");
try
{
// Resulting list
ArrayList<String> list = new ArrayList<String>();
// First find where the actual bus times start
int beginning = page.lastIndexOf(BUSTIME_TABLE);
if(beginning != -1)
{
page = page.substring(beginning);
}
else
{
Log.e(LOG_TAG, "No times were found in the page!");
return null;
}
// Start looking for bus times
int start = 0, end = 0, last = 0;
do
{
// Get the next bus time container start point starting from the last known position
start = page.indexOf(BUSTIME_CONTAINER_OPEN, last);
if(start != -1)
{
// This is the actual start point of the bus time container
start += BUSTIME_CONTAINER_OPEN.length();
// Now look for where the bus time container ends
end = page.indexOf(BUSTIME_CONTAINER_CLOSE, start);
if(end != -1)
{
// Move the end point of the bus time container forward
end += BUSTIME_CONTAINER_CLOSE.length();
// Get actual bus time information
String currentBus = page.substring(start, end);
int busStart = 0, busEnd = 0;
// Check wheel chair enabled state
boolean isWheelChairEnabled = currentBus.contains(BUSTIME_WHEEL_CHAIR_ENABLED);
// Get the next bus time information start point
busStart = currentBus.indexOf(BUSTIME_OPEN_START);
if(busStart != -1)
{
// Get where the start point ends
busStart = currentBus.indexOf(BUSTIME_OPEN_END, busStart);
if(busStart != -1)
{
// This is the actual start point of the bus time information
busStart += BUSTIME_OPEN_END.length();
// Now look for where the bus time information ends
busEnd = currentBus.indexOf(BUSTIME_CLOSE, busStart);
if(busEnd != -1)
{
// Now we extract the bus time information using the found start and end points
String item = currentBus.substring(busStart, busEnd);
// Add wheel chair enabled status
item += BusTime.BUS_TIME_SEPARATOR + isWheelChairEnabled;
// Finally add the found and extracted bus time information to the list
list.add(item);
}
}
// Mark the last known position and continue
last = end;
}
}
// Mark the last known position and continue
last = end;
}
} while(start != -1);
return list;
}
catch(Exception e)
{
Log.e(LOG_TAG, "Error occured while parsing bus times!", e);
return null;
}
}
/** Gets the list of the busses from the specified page
*
* @param page Source of the page
*
* @return List of the busses, null if any error occurs */
public static ArrayList<String> parseBusses(String page)
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Parsing busses...");
try
{
// Resulting list
ArrayList<String> list = new ArrayList<String>();
// Start looking for busses
int start = 0, end = 0, last = 0;
do
{
// Get the next bus information start point starting from the last known position
start = page.indexOf(BUS_OPEN_START, last);
if(start != -1)
{
// Get where the start point ends
start = page.indexOf(BUS_OPEN_END, start);
if(start != -1)
{
// This is the actual start point of the bus information
start += BUS_OPEN_END.length();
// Now look for where the bus information ends
end = page.indexOf(BUS_CLOSE, start);
if(end != -1)
{
// Now we extract the bus information using the found start and end points
// Plus we fix the Turkish characters in the result
String item = fixTurkishHtmlEntityCharacters(page.substring(start, end));
// Finally add the found and extracted bus information to the list
list.add(item);
// Move the end point of the bus information forward
end += BUS_CLOSE.length();
}
}
// Mark the last known position and continue
last = end;
}
} while(start != -1);
return list;
}
catch(Exception e)
{
Log.e(LOG_TAG, "Error occured while parsing busses!", e);
return null;
}
}
/** Gets the Kent Kart balance information from the specified page
*
* @param json Source of the page
*
* @return A {@link KentKartBalanceQueryResult} object containing balance
* information, or null if any error occurs */
public static KentKartBalanceQueryResult parseKentKartBalance(String json)
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG, "Parsing Kent Kart balance...");
try
{
// Parse resulting json
Gson gson = new Gson();
KentKartQueryResponse result = gson.fromJson(json, KentKartQueryResponse.class);
// Format the parsed result correctly
SimpleDateFormat responseFormatter = new SimpleDateFormat(KENT_KART_TIME_FORMAT_RESPONSE, Locale.getDefault());
SimpleDateFormat resultFormatter = new SimpleDateFormat(KENT_KART_TIME_FORMAT_RESULT, Locale.getDefault());
// Define result attributes
String balance = result.balanceresult.equals("0") || result.balanceresult.equals("") ? null : result.balanceresult;
String lastLoadTime = null;
try
{
lastLoadTime = resultFormatter.format(responseFormatter.parse(result.chargeresult));
}
catch(Exception e)
{
Log.e(LOG_TAG, "Error occurred while parsing last load time!", e);
}
String lastLoadAmount = result.chargeAmt.equals("0") || result.chargeAmt.equals("") ? null : result.chargeAmt;
String lastUseTime = null;
try
{
lastUseTime = resultFormatter.format(responseFormatter.parse(result.usageresult));
}
catch(Exception e)
{
Log.e(LOG_TAG, "Error occurred while parsing last use time!", e);
}
String lastUseAmount = result.usageAmt.equals("0") || result.usageAmt.equals("") ? null : result.usageAmt;
// Generate and return resulting object
return new KentKartBalanceQueryResult(balance, lastLoadTime,
lastLoadAmount, lastUseTime, lastUseAmount);
}
catch(Exception e)
{
Log.e(LOG_TAG, "Error occured while parsing Kent Kart balance!", e);
return null;
}
}
/** Replaces all HTML entity characters in Turkish
*
* @param source Source string
*
* @return Source string with fixed Turkish characters */
private static String fixTurkishHtmlEntityCharacters(String source)
{
String result = source;
result = result.replaceAll("İ", "İ");
result = result.replaceAll("ı", "ı");
result = result.replaceAll("Ö", "Ö");
result = result.replaceAll("ö", "ö");
result = result.replaceAll("Ü", "Ü");
result = result.replaceAll("ü", "ü");
result = result.replaceAll("Ç", "Ç");
result = result.replaceAll("ç", "ç");
result = result.replaceAll("Ğ", "Ğ");
result = result.replaceAll("ğ", "ğ");
result = result.replaceAll("Ş", "Ş");
result = result.replaceAll("ş", "ş");
return result;
}
}