Package io.lumify.flightTrack

Source Code of io.lumify.flightTrack.FlightRepository$Airline

package io.lumify.flightTrack;

import com.google.inject.Inject;
import io.lumify.core.exception.LumifyException;
import io.lumify.core.model.properties.LumifyProperties;
import io.lumify.core.model.workQueue.WorkQueueRepository;
import io.lumify.core.util.LumifyLogger;
import io.lumify.core.util.LumifyLoggerFactory;
import org.json.JSONArray;
import org.json.JSONObject;
import org.securegraph.*;
import org.securegraph.mutation.ExistingElementMutation;
import org.securegraph.type.GeoPoint;
import org.supercsv.io.CsvListReader;
import org.supercsv.prefs.CsvPreference;

import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static org.securegraph.util.IterableUtils.toList;

public class FlightRepository {
    private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(FlightRepository.class);
    public static final SimpleDateFormat ISO8601DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    private static final String MULTI_VALUE_PROPERTY_KEY = FlightRepository.class.getName();
    private static final String SOURCE_NAME = "FlightAware.com";
    private Graph graph;
    private WorkQueueRepository workQueueRepository;
    private Map<String, Airport> airportCodeMap = new HashMap<String, Airport>();
    private Map<String, Airline> identPrefixMap = new HashMap<String, Airline>();
    private Map<String, Vertex> identToVertex = new HashMap<String, Vertex>();
    private Map<String, Vertex> airportCodeToVertex = new HashMap<String, Vertex>();
    private Map<String, Vertex> airlinePrefixToVertex = new HashMap<String, Vertex>();

    public FlightRepository() {
        try {
            loadAirlines();
            loadAirports();
        } catch (IOException ex) {
            throw new LumifyException("Could not read dat files", ex);
        }
    }

    private void loadAirports() throws IOException {
        InputStreamReader reader = new InputStreamReader(FlightRepository.class.getResourceAsStream("airports.dat"));
        CsvListReader listReader = new CsvListReader(reader, CsvPreference.STANDARD_PREFERENCE);
        List<String> line;
        while ((line = listReader.read()) != null) {
            String title = line.get(1);
            String airportCode = line.get(5);
            double lat = Double.parseDouble(line.get(6));
            double lon = Double.parseDouble(line.get(7));
            if (airportCode == null) {
                continue;
            }
            airportCodeMap.put(airportCode.toLowerCase(), new Airport(airportCode, title, new GeoPoint(lat, lon)));
        }
    }

    private void loadAirlines() throws IOException {
        InputStreamReader reader = new InputStreamReader(FlightRepository.class.getResourceAsStream("airlines.dat"));
        CsvListReader listReader = new CsvListReader(reader, CsvPreference.STANDARD_PREFERENCE);
        List<String> line;
        while ((line = listReader.read()) != null) {
            String title = line.get(1);
            String identPrefix = line.get(4);
            if (identPrefix == null) {
                continue;
            }
            identPrefixMap.put(identPrefix.toLowerCase(), new Airline(identPrefix, title));
        }
    }

    public void save(JSONObject json, Visibility visibility, Authorizations authorizations) {
        JSONArray aircraft = json
                .getJSONObject("SearchResult")
                .getJSONArray("aircraft");
        for (int i = 0; i < aircraft.length(); i++) {
            JSONObject flight = aircraft.getJSONObject(i);
            saveFlightData(flight, visibility, authorizations);
        }
    }

    public void saveFlightData(JSONObject flightJson, Visibility visibility, Authorizations authorizations) {
        double latitude = flightJson.getDouble("latitude");
        double longitude = flightJson.getDouble("longitude");
        double altitude = flightJson.getDouble("altitude");
        double heading = flightJson.getDouble("heading");
        String ident = flightJson.getString("ident");
        String origin = flightJson.getString("origin");
        String destination = flightJson.getString("destination");

        Vertex airplaneVertex = saveAirplane(ident, visibility, authorizations);
        Vertex originVertex = saveAirport(origin, visibility, authorizations);
        Vertex destinationVertex = saveAirport(destination, visibility, authorizations);

        if (updateOrigin(airplaneVertex, originVertex, visibility, authorizations)
                || updateDestination(airplaneVertex, destinationVertex, visibility, authorizations)) {
            identToVertex.remove(ident); // edges are now invalid in the cache and we need to refresh
        }

        updateLocation(airplaneVertex, latitude, longitude, altitude, heading, visibility, authorizations);
    }

    public void updateLocation(Vertex airplaneVertex, double latitude, double longitude, double altitude, double heading, Visibility visibility, Authorizations authorizations) {
        LOGGER.debug("updating location of airplane %s (lat: %f, lon: %f, alt: %f, head: %f)", airplaneVertex.getId(), latitude, longitude, altitude, heading);

        ExistingElementMutation<Vertex> m = airplaneVertex.prepareMutation();
        FlightTrackOntology.LOCATION.addPropertyValue(m, MULTI_VALUE_PROPERTY_KEY, new GeoPoint(latitude, longitude, altitude), visibility);
        FlightTrackOntology.ALTITUDE.addPropertyValue(m, MULTI_VALUE_PROPERTY_KEY, altitude, visibility);
        FlightTrackOntology.HEADING.addPropertyValue(m, MULTI_VALUE_PROPERTY_KEY, heading, visibility);
        m.save(authorizations);

        graph.flush();

        workQueueRepository.pushGraphPropertyQueue(airplaneVertex, MULTI_VALUE_PROPERTY_KEY, FlightTrackOntology.LOCATION.getPropertyName());
        workQueueRepository.pushGraphPropertyQueue(airplaneVertex, MULTI_VALUE_PROPERTY_KEY, FlightTrackOntology.ALTITUDE.getPropertyName());
        workQueueRepository.pushGraphPropertyQueue(airplaneVertex, MULTI_VALUE_PROPERTY_KEY, FlightTrackOntology.HEADING.getPropertyName());
    }

    public boolean updateDestination(Vertex airplaneVertex, Vertex destinationVertex, Visibility visibility, Authorizations authorizations) {
        List<String> currentDestinations = toList(airplaneVertex.getVertexIds(Direction.BOTH, FlightTrackOntology.EDGE_LABEL_HAS_DESTINATION, authorizations));
        if (currentDestinations.size() == 0 || !currentDestinations.get(0).equals(destinationVertex.getId())) {
            LOGGER.debug("airplane %s changed destinations to %s", airplaneVertex.getId(), destinationVertex.getId());
            for (Object currentDestinationEdgeId : airplaneVertex.getEdgeIds(Direction.BOTH, FlightTrackOntology.EDGE_LABEL_HAS_DESTINATION, authorizations)) {
                graph.removeEdge((String) currentDestinationEdgeId, authorizations);
            }
            Edge e = graph.addEdge(toDestinationEdgeId(airplaneVertex, destinationVertex), airplaneVertex, destinationVertex, FlightTrackOntology.EDGE_LABEL_HAS_DESTINATION, visibility, authorizations);
            graph.flush();
            workQueueRepository.pushElement(e);
            return true;
        }
        return false;
    }

    public boolean updateOrigin(Vertex airplaneVertex, Vertex originVertex, Visibility visibility, Authorizations authorizations) {
        List<String> currentOrigins = toList(airplaneVertex.getVertexIds(Direction.BOTH, FlightTrackOntology.EDGE_LABEL_HAS_ORIGIN, authorizations));
        if (currentOrigins.size() == 0 || !currentOrigins.get(0).equals(originVertex.getId())) {
            LOGGER.debug("airplane %s changed origin to %s", airplaneVertex.getId(), originVertex.getId());
            for (Object currentOriginEdgeId : airplaneVertex.getEdgeIds(Direction.BOTH, FlightTrackOntology.EDGE_LABEL_HAS_ORIGIN, authorizations)) {
                graph.removeEdge((String) currentOriginEdgeId, authorizations);
            }
            Edge e = graph.addEdge(toOriginEdgeId(airplaneVertex, originVertex), airplaneVertex, originVertex, FlightTrackOntology.EDGE_LABEL_HAS_ORIGIN, visibility, authorizations);
            graph.flush();
            workQueueRepository.pushElement(e);
            return true;
        }
        return false;
    }

    private Vertex saveAirport(String airportCode, Visibility visibility, Authorizations authorizations) {
        Vertex v = airportCodeToVertex.get(airportCode);
        if (v != null) {
            return v;
        }

        String airportId = toAirportId(airportCode);
        v = graph.getVertex(airportId, authorizations);
        if (v != null) {
            airportCodeToVertex.put(airportCode, v);
            return v;
        }

        LOGGER.info("new airport %s", airportCode);

        Airport airport = airportCodeMap.get(airportCode.toLowerCase());

        VertexBuilder vb = graph.prepareVertex(airportId, visibility);
        LumifyProperties.CONCEPT_TYPE.setProperty(vb, FlightTrackOntology.CONCEPT_TYPE_AIRPORT, visibility);
        FlightTrackOntology.AIRPORT_CODE.setProperty(vb, airportCode, visibility);
        LumifyProperties.SOURCE.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, SOURCE_NAME, visibility);
        if (airport != null) {
            FlightTrackOntology.LOCATION.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, airport.getGeoPoint(), visibility);
            LumifyProperties.TITLE.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, airport.getTitle(), visibility);
        }
        v = vb.save(authorizations);
        airportCodeToVertex.put(airportCode, v);

        graph.flush();

        workQueueRepository.pushElement(v);
        workQueueRepository.pushGraphPropertyQueue(v, MULTI_VALUE_PROPERTY_KEY, FlightTrackOntology.AIRPORT_CODE.getPropertyName());

        return v;
    }

    private Vertex saveAirplane(String ident, Visibility visibility, Authorizations authorizations) {
        Vertex airplaneVertex = identToVertex.get(ident);
        if (airplaneVertex != null) {
            return airplaneVertex;
        }

        String airplaneId = toAirplaneId(ident);
        airplaneVertex = graph.getVertex(airplaneId, authorizations);
        if (airplaneVertex != null) {
            identToVertex.put(ident, airplaneVertex);
            return airplaneVertex;
        }

        LOGGER.info("new airplane %s", ident);

        VertexBuilder vb = graph.prepareVertex(airplaneId, visibility);
        LumifyProperties.CONCEPT_TYPE.setProperty(vb, FlightTrackOntology.CONCEPT_TYPE_AIRPLANE, visibility);
        FlightTrackOntology.IDENT.setProperty(vb, ident, visibility);
        LumifyProperties.SOURCE.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, SOURCE_NAME, visibility);
        airplaneVertex = vb.save(authorizations);
        identToVertex.put(ident, airplaneVertex);
        graph.flush();

        workQueueRepository.pushElement(airplaneVertex);
        workQueueRepository.pushGraphPropertyQueue(airplaneVertex, MULTI_VALUE_PROPERTY_KEY, FlightTrackOntology.IDENT.getPropertyName());

        Vertex airlineVertex = findAirlineVertexFromIdent(ident, visibility, authorizations);
        graph.flush();

        if (airlineVertex != null) {
            String airlineHasAirplaneId = toAirlineHasAirplaneId(airlineVertex, airplaneVertex);

            if (graph.getEdge(airlineHasAirplaneId, authorizations) == null) {
                Edge e = graph.addEdge(airlineHasAirplaneId, airlineVertex, airplaneVertex, FlightTrackOntology.EDGE_LABEL_HAS_AIRPLANE, visibility, authorizations);
                graph.flush();
                workQueueRepository.pushElement(e);
            }
        }

        return airplaneVertex;
    }

    private Vertex findAirlineVertexFromIdent(String ident, Visibility visibility, Authorizations authorizations) {
        Airline airline = findAirlineFromIdent(ident);
        if (airline == null) {
            return null;
        }

        Vertex v = airlinePrefixToVertex.get(airline.getIdentPrefix());
        if (v != null) {
            return v;
        }

        String airlineId = toAirlineId(airline.getIdentPrefix());
        v = graph.getVertex(airlineId, authorizations);
        if (v != null) {
            airlinePrefixToVertex.put(airline.getIdentPrefix(), v);
            return v;
        }

        LOGGER.info("new airline %s", airline.getTitle());

        VertexBuilder vb = graph.prepareVertex(airlineId, visibility);
        LumifyProperties.CONCEPT_TYPE.setProperty(vb, FlightTrackOntology.CONCEPT_TYPE_AIRLINE, visibility);
        LumifyProperties.TITLE.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, airline.getTitle(), visibility);
        FlightTrackOntology.AIRLINE_PREFIX.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, airline.getIdentPrefix(), visibility);
        LumifyProperties.SOURCE.addPropertyValue(vb, MULTI_VALUE_PROPERTY_KEY, SOURCE_NAME, visibility);
        v = vb.save(authorizations);
        airlinePrefixToVertex.put(airline.getIdentPrefix(), v);

        graph.flush();

        workQueueRepository.pushElement(v);
        workQueueRepository.pushGraphPropertyQueue(v, MULTI_VALUE_PROPERTY_KEY, LumifyProperties.TITLE.getPropertyName());
        workQueueRepository.pushGraphPropertyQueue(v, MULTI_VALUE_PROPERTY_KEY, FlightTrackOntology.AIRLINE_PREFIX.getPropertyName());

        return v;
    }

    private Airline findAirlineFromIdent(String ident) {
        ident = ident.toLowerCase();
        while (ident.length() > 1) {
            Airline airline = identPrefixMap.get(ident);
            if (airline != null) {
                return airline;
            }
            ident = ident.substring(0, ident.length() - 1);
        }
        return null;
    }

    private String toAirplaneId(String ident) {
        return "FlightTrack_Airplane_" + ident;
    }

    private String toAirportId(String airportCode) {
        return "FlightTrack_Airport_" + airportCode;
    }

    private String toAirlineId(String identPrefix) {
        return "FlightTrack_Airline_" + identPrefix;
    }

    private String toAirlineHasAirplaneId(Vertex airlineVertex, Vertex airplaneVertex) {
        return airlineVertex.getId() + "_has_" + airplaneVertex;
    }

    private String toOriginEdgeId(Vertex airplaneVertex, Vertex destinationVertex) {
        return airplaneVertex.getId() + "_has_org_" + destinationVertex.getId();
    }

    private String toDestinationEdgeId(Vertex airplaneVertex, Vertex destinationVertex) {
        return airplaneVertex.getId() + "_has_dest_" + destinationVertex.getId();
    }

    @Inject
    public void setGraph(Graph graph) {
        this.graph = graph;
    }

    @Inject
    public void setWorkQueueRepository(WorkQueueRepository workQueueRepository) {
        this.workQueueRepository = workQueueRepository;
    }

    private static class Airport {
        private final String airportCode;
        private final String title;
        private final GeoPoint geoPoint;

        public Airport(String airportCode, String title, GeoPoint geoPoint) {
            this.airportCode = airportCode;
            this.title = title;
            this.geoPoint = geoPoint;
        }

        public String getAirportCode() {
            return airportCode;
        }

        public String getTitle() {
            return title;
        }

        public GeoPoint getGeoPoint() {
            return geoPoint;
        }
    }

    private static class Airline {
        private final String identPrefix;
        private final String title;

        public Airline(String identPrefix, String title) {
            this.identPrefix = identPrefix;
            this.title = title;
        }

        public String getIdentPrefix() {
            return identPrefix;
        }

        public String getTitle() {
            return title;
        }
    }
}
TOP

Related Classes of io.lumify.flightTrack.FlightRepository$Airline

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.