de.fahrgemeinschaft.FahrgemeinschaftConnector.java Source code

Java tutorial

Introduction

Here is the source code for de.fahrgemeinschaft.FahrgemeinschaftConnector.java

Source

/**
 * Fahrgemeinschaft / Ridesharing App
 * Copyright (c) 2013 by it's authors.
 * Some rights reserved. See LICENSE..
 *
 */

package de.fahrgemeinschaft;

import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.teleportr.AuthException;
import org.teleportr.Connector;
import org.teleportr.Place;
import org.teleportr.Ride;
import org.teleportr.Ride.Mode;

public class FahrgemeinschaftConnector extends Connector {

    public static final int TYPE_OFFER_REOCCURING = 53;

    private static final String ID = "/id/";
    private static final String PUT = "PUT";
    private static final String POST = "POST";
    private static final String TRIP = "/trip";
    private static final String DELETE = "DELETE";
    private static final String SESSION = "/session";
    private static final String ZERO = "0";
    private static final String EMPTY = "";
    private static final String COMMA = ", ";
    private static final String NULL = "null";
    private static final String NOTIME = "2359";

    public static final String USER = "user";
    public static final String AUTH = "auth";
    public static final String LOGIN = "login";
    public static final String APIKEY = "apikey";
    private static final String PASSWD = "Password";
    private static final String AUTHKEY = "authkey";
    private static final String AUTH_KEY = "AuthKey";

    public static String USER_AGENT = "Android-App";

    public static final String FAHRGEMEINSCHAFT_DE = "http://service.fahrgemeinschaft.de";
    public String endpoint = FAHRGEMEINSCHAFT_DE;

    private String startDate;
    static final SimpleDateFormat fulldf = new SimpleDateFormat("yyyyMMddHHmm", Locale.GERMAN);
    static final SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd", Locale.GERMAN);
    public static final String[] DAYS = new String[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
            "Saturday", "Sunday" };

    @Override
    public String authenticate(String credential) throws Exception {
        System.out.println("refreshing authtoken");
        HttpURLConnection post = (HttpURLConnection) new URL(endpoint + SESSION).openConnection();
        post.setRequestProperty("User-Agent", USER_AGENT);
        post.setRequestProperty(APIKEY, Secret.APIKEY);
        post.setDoOutput(true);
        post.getOutputStream()
                .write(new JSONObject().put(EMAIL, get(LOGIN)).put(PASSWD, credential).toString().getBytes());
        post.getOutputStream().close();
        JSONObject json = loadJson(post);
        if (post.getResponseCode() == 403)
            throw new AuthException();
        JSONObject auth = json.getJSONObject(AUTH);
        set(USER, auth.getString(ID_USER));
        JSONArray kvp = json.getJSONObject(USER).getJSONArray(KEY_VALUE_PAIRS);
        for (int i = 1; i < kvp.length(); i++) {
            String key = kvp.getJSONObject(i).getString(KEY);
            if (key.equals(FIRSTNAME))
                set(FIRSTNAME, kvp.getJSONObject(i).getString(VALUE));
            else if (key.equals(LASTNAME))
                set(LASTNAME, kvp.getJSONObject(i).getString(VALUE));
        }
        return auth.getString(AUTH_KEY);
    }

    public static final String RADIUS_TO = "radius_to";
    public static final String RADIUS_FROM = "radius_from";
    private static final String SEARCH_ORIGIN = "?searchOrigin=";
    private static final String TOLERANCE_RADIUS = "ToleranceRadius";
    private static final String SEARCH_DESTINATION = "&searchDestination=";
    private static final String ONLY_DESTINATION = "?searchDestination=";
    private static final String STARTDATE = "Startdate";
    private static final String LONGITUDE = "Longitude";
    private static final String LATITUDE = "Latitude";
    private static final String RESULTS = "results";
    public static final String REOCCUR = "Reoccur";

    @Override
    public long search(Ride query) throws Exception {
        HttpURLConnection get;
        StringBuffer url = new StringBuffer().append(endpoint).append(TRIP);
        if (query == null) { // myrides
            get = (HttpURLConnection) new URL(endpoint + TRIP).openConnection();
        } else {
            startDate = df.format(query.getDep());
            try {
                if (query.getFrom() != null) {
                    JSONObject from_json = new JSONObject();
                    from_json.put(LONGITUDE, query.getFrom().getLng());
                    from_json.put(LATITUDE, query.getFrom().getLat());
                    from_json.put(TOLERANCE_RADIUS, get(RADIUS_FROM));
                    from_json.put(STARTDATE, df.format(query.getDep()));
                    from_json.put(REOCCUR, JSONObject.NULL);
                    url.append(SEARCH_ORIGIN).append(from_json);
                }
                if (query.getTo() != null) {
                    JSONObject to_json = new JSONObject();
                    to_json.put(LONGITUDE, query.getTo().getLng());
                    to_json.put(LATITUDE, query.getTo().getLat());
                    to_json.put(TOLERANCE_RADIUS, get(RADIUS_TO));
                    if (query.getFrom() == null) {
                        to_json.put(STARTDATE, df.format(query.getDep()));
                        url.append(ONLY_DESTINATION).append(to_json);
                    } else {
                        url.append(SEARCH_DESTINATION).append(to_json);
                    }
                }
                // place.put("Starttime", JSONObject.NULL);
                // place.put("ToleranceDays", "3");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            get = (HttpURLConnection) new URL(url.toString()).openConnection();
        }
        get.setRequestProperty("User-Agent", USER_AGENT);
        get.setRequestProperty(APIKEY, Secret.APIKEY);
        if (getAuth() != null)
            get.setRequestProperty(AUTHKEY, getAuth());
        JSONObject json = loadJson(get);
        if (get.getResponseCode() == 403)
            throw new AuthException();
        if (json != null) {
            JSONArray results = json.getJSONArray(RESULTS);
            System.out.println("FOUND " + results.length() + " rides");

            for (int i = 0; i < results.length(); i++) {
                store(parseRide(results.getJSONObject(i)));
            }
        }
        startDate = null;
        if (query != null)
            return getNextDayMorning(query.getDep());
        else
            return 0;
    }

    public static long getNextDayMorning(long dep) {
        if (dep != 0) {
            Calendar c = Calendar.getInstance();
            c.setTimeInMillis(dep + 25 * 3600000); // plus one(!) day
            c.set(Calendar.HOUR_OF_DAY, 0); // reset
            c.set(Calendar.MINUTE, 0);
            c.set(Calendar.SECOND, 0);
            c.set(Calendar.MILLISECOND, 0);
            return c.getTimeInMillis();
        } else
            return 0;
    }

    private static final String KEY = "Key";
    private static final String VALUE = "Value";
    private static final String LASTNAME = "lastname";
    private static final String FIRSTNAME = "firstname";
    private static final String KEY_VALUE_PAIRS = "KeyValuePairs";
    private static final String ID_USER = "IDuser";

    private static final String OFFER = "offer";
    private static final String TRIP_ID = "TripID";
    private static final String TRIP_ID_WITH_SMALL_t = "tripID"; //wtf!
    private static final String TRIPTYPE = "Triptype";

    public static final String BAHN = "Bahn";
    public static final String PRICE = "Price";
    public static final String EMAIL = "Email";
    public static final String MOBILE = "Mobile";
    public static final String COMMENT = "Comment";
    public static final String PRIVACY = "Privacy";
    public static final String LANDLINE = "Landline";
    public static final String PLATE = "NumberPlate";
    private static final String CONTACTMAIL = "Contactmail";
    private static final String CONTACTMOBILE = "Contactmobile";
    private static final String CONTACTLANDLINE = "Contactlandline";
    private static final String ADDRESS = "Address";
    private static final String STARTTIME = "Starttime";
    private static final String DESTINATION = "Destination";
    private static final String ORIGIN = "Origin";
    private static final String ROUTINGS = "Routings";
    private static final String RELEVANCE = "Relevance";
    private static final String DESCRIPTION = "Description";
    private static final String PLACES = "Places";
    private static final String DE = "DE";
    private static final String GEO = "geo";
    private static final String PLACETYPE = "Placetype";
    private static final String DEUTSCHLAND = "Deutschland";
    private static final String COUNTRY_CODE = "CountryCode";
    private static final String COUNTRY_NAME = "CountryName";
    private static final String ROUTING_INDEX = "RoutingIndex";

    @SuppressWarnings("deprecation")
    private Ride parseRide(JSONObject json) throws JSONException {

        Ride ride = new Ride().type(Ride.OFFER).mode(Mode.CAR);
        if (startDate == null)
            ride.marked(); // myrides
        ride.who(json.getString(ID_USER));
        String value = json.getString(CONTACTMAIL);
        if (!value.equals(EMPTY) && !value.equals(NULL))
            ride.set(EMAIL, value);
        value = json.getString(CONTACTMOBILE);
        if (!value.equals(EMPTY) && !value.equals(NULL))
            ride.set(MOBILE, value);
        value = json.getString(CONTACTLANDLINE);
        if (!value.equals(EMPTY) && !value.equals(NULL))
            ride.set(LANDLINE, value);
        value = json.getString(PLATE);
        if (!value.equals(EMPTY) && !value.equals(NULL)) {
            ride.set(PLATE, value);
            if (value.equals(BAHN))
                ride.mode(Mode.TRAIN);
        }
        ride.getDetails().put(PRIVACY, json.getJSONObject(PRIVACY));
        ride.set(COMMENT, json.getString(DESCRIPTION));
        if (json.getInt(RELEVANCE) == 10) {
            ride.activate();
        } else {
            ride.deactivate();
        }
        ride.ref(json.getString(TRIP_ID));
        ride.seats(json.getInt(PLACES));
        if (!json.isNull(PRICE)) {
            ride.price((int) Double.parseDouble(json.getString(PRICE)) * 100);
        } else {
            ride.price(-1);
        }

        JSONObject reoccur = json.getJSONObject(REOCCUR);
        boolean isReoccuring = isReoccuring(reoccur);
        boolean isMyride = startDate == null;
        String time = parseTime(json);

        if (isReoccuring) {
            ride.getDetails().put(REOCCUR, reoccur);
        }
        if (isReoccuring && isMyride) {
            ride.type(TYPE_OFFER_REOCCURING);
        }
        if (isMyride) {
            if (time.equals(EMPTY)) {
                Date date = parseDate(json.getString(STARTDATE) + NOTIME);
                date.setSeconds(59);
                ride.dep(date);
            } else {
                ride.dep(parseDate(json.getString(STARTDATE) + time));
            }
        } else {
            if (time.equals(EMPTY)) {
                Date date = parseDate(startDate + NOTIME);
                date.setSeconds(59);
                ride.dep(date);
            } else {
                ride.dep(parseDate(startDate + time));
            }
        }

        JSONArray routings = json.getJSONArray(ROUTINGS);

        ride.from(store(parsePlace(routings.getJSONObject(0).getJSONObject(ORIGIN))));

        for (int j = 1; j < routings.length(); j++) {
            ride.via(store(parsePlace(routings.getJSONObject(j).getJSONObject(DESTINATION))));
        }

        ride.to(store(parsePlace(routings.getJSONObject(0).getJSONObject(DESTINATION))));
        return ride;
    }

    public boolean isReoccuring(JSONObject reoccur) throws JSONException {
        boolean isReoccuring = false;
        for (int i = 0; i < 7; i++) {
            if (reoccur.getBoolean(FahrgemeinschaftConnector.DAYS[i])) {
                isReoccuring = true;
                break;
            }
        }
        return isReoccuring;
    }

    private Place parsePlace(JSONObject json) throws JSONException {
        String[] split = json.getString(ADDRESS).split(COMMA);
        return new Place(Double.parseDouble(json.getString(LATITUDE)),
                Double.parseDouble(json.getString(LONGITUDE))).address(json.getString(ADDRESS))
                        .name((split.length > 0) ? split[0] : EMPTY);
    }

    private String parseTime(JSONObject json) throws JSONException {
        //              new Date(Long.parseLong(ride.getString("Enterdate"));
        String time = EMPTY;
        if (!json.isNull(STARTTIME)) {
            time = json.getString(STARTTIME);
            if (time.length() == 3)
                time = ZERO + time;
            if (time.length() != 4)
                time = EMPTY;
        }
        return time;
    }

    private Date parseDate(String date) {
        try {
            return fulldf.parse(date);
        } catch (ParseException e) {
            System.out.println("date/time parse error!");
            e.printStackTrace();
            return new Date();
        }

    }

    @Override
    public String publish(Ride offer) throws Exception {
        HttpURLConnection post;
        if (offer.getRef() == null) {
            post = (HttpURLConnection) new URL(endpoint + TRIP).openConnection();
            post.setRequestMethod(POST);
        } else {
            post = (HttpURLConnection) new URL(
                    new StringBuffer().append(endpoint).append(TRIP).append(ID).append(offer.getRef()).toString())
                            .openConnection();
            post.setRequestMethod(PUT);
        }
        post.setRequestProperty("User-Agent", USER_AGENT);
        post.setRequestProperty(APIKEY, Secret.APIKEY);
        if (getAuth() != null)
            post.setRequestProperty(AUTHKEY, getAuth());
        post.setDoOutput(true);
        JSONObject json = new JSONObject();
        //        json.put("Smoker", "no");
        json.put(TRIPTYPE, OFFER);
        json.put(TRIP_ID, offer.getRef());
        json.put(ID_USER, get(USER));
        if (offer.getMode() != null && offer.getMode().equals(Mode.TRAIN)) {
            json.put(PLATE, BAHN);
        } else {
            json.put(PLATE, offer.get(PLATE));
        }
        if (offer.isActive()) {
            json.put(RELEVANCE, 10);
        } else {
            json.put(RELEVANCE, 0);
        }
        json.put(PLACES, offer.getSeats());
        json.put(PRICE, offer.getPrice() / 100);
        json.put(CONTACTMAIL, offer.get(EMAIL));
        json.put(CONTACTMOBILE, offer.get(MOBILE));
        json.put(CONTACTLANDLINE, offer.get(LANDLINE));
        String dep = fulldf.format(offer.getDep());
        json.put(STARTDATE, dep.subSequence(0, 8));
        json.put(STARTTIME, dep.subSequence(8, 12));
        json.put(DESCRIPTION, offer.get(COMMENT));
        if (!offer.getDetails().isNull(PRIVACY))
            json.put(PRIVACY, offer.getDetails().getJSONObject(PRIVACY));
        if (!offer.getDetails().isNull(REOCCUR))
            json.put(REOCCUR, offer.getDetails().getJSONObject(REOCCUR));
        ArrayList<JSONObject> routings = new ArrayList<JSONObject>();
        List<Place> stops = offer.getPlaces();
        int max = stops.size() - 1;
        for (int dest = max; dest >= 0; dest--) {
            for (int orig = 0; orig < dest; orig++) {
                int idx = (orig == 0 ? (dest == max ? 0 : dest) : -dest);
                JSONObject route = new JSONObject();
                route.put(ROUTING_INDEX, idx);
                route.put(ORIGIN, place(stops.get(orig)));
                route.put(DESTINATION, place(stops.get(dest)));
                routings.add(route);
            }
        }
        json.put(ROUTINGS, new JSONArray(routings));
        OutputStreamWriter out = new OutputStreamWriter(post.getOutputStream());
        out.write(json.toString());
        out.flush();
        out.close();
        JSONObject response = loadJson(post);
        if (!response.isNull(TRIP_ID_WITH_SMALL_t)) {
            offer.ref(response.getString(TRIP_ID_WITH_SMALL_t));
        }
        return offer.getRef();
    }

    private JSONObject place(Place from) throws JSONException {
        JSONObject place = new JSONObject();
        place.put(LATITUDE, from.getLat());
        place.put(LONGITUDE, from.getLng());
        place.put(ADDRESS, from.getAddress());
        place.put(COUNTRY_NAME, DEUTSCHLAND);
        place.put(COUNTRY_CODE, DE);
        place.put(PLACETYPE, GEO);
        return place;
    }

    @Override
    public String delete(Ride offer) throws Exception {
        HttpURLConnection delete = (HttpURLConnection) new URL(
                new StringBuffer().append(endpoint).append(TRIP).append(ID).append(offer.getRef()).toString())
                        .openConnection();
        delete.setRequestMethod(DELETE);
        delete.setRequestProperty(AUTHKEY, getAuth());
        delete.setRequestProperty(APIKEY, Secret.APIKEY);
        return loadJson(delete).toString();
    }
}