All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.gridgears.held.internal.parser.LocationParser Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package at.gridgears.held.internal.parser;

import at.gridgears.held.AmlData;
import at.gridgears.held.Location;
import at.gridgears.schemas.held.*;
import org.apache.commons.lang3.mutable.MutableObject;

import javax.annotation.Nullable;
import javax.xml.datatype.XMLGregorianCalendar;
import java.time.Instant;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import static at.gridgears.held.internal.parser.ParseUtils.toInstant;

final class LocationParser {
    private final AmlDataParser amlDataParser = new AmlDataParser();

    List parse(LocationResponseType locationResponseType) {
        MutableObject timestamp = new MutableObject<>();

        List result = new LinkedList<>();

        ParseUtils.getValue(locationResponseType.getAny(), Presence.class)
                .map(Presence::getTuple)
                .map(ParseUtils::first)
                .map(storeTimestamp(timestamp))
                .map(Tuple::getStatus)
                .map(Status::getAny)
                .map(ParseUtils::first)
                .map(LocationParser::getGeopriv)
                .ifPresent(geopriv -> result.addAll(parseLocation(geopriv, timestamp.getValue())));
        return result;
    }

    private List parseLocation(Geopriv geopriv, Instant timestamp) {
        List result = new LinkedList<>();

        MutableObject amlData = new MutableObject<>();
        ParseUtils.getValue(geopriv.getAny(), AmlType.class).ifPresent(amlType -> amlData.setValue(amlDataParser.parseAmlData(amlType)));

        LocInfoType locationInfo = geopriv.getLocationInfo();
        if (locationInfo != null) {
            result.addAll(parseLocations(locationInfo.getAny(), timestamp, amlData.getValue()));
        }

        return result;
    }

    private List parseLocations(List locations, Instant timestamp, @Nullable AmlData amlData) {
        List result = new LinkedList<>();
        locations.forEach(location -> {
            Optional pointTypeOptional = ParseUtils.getValue(location, PointType.class);
            if (pointTypeOptional.isPresent()) {
                pointTypeOptional.ifPresent(point -> result.add(getLocation(timestamp, amlData, point)));
            } else {
                Optional circleTypeOptional = ParseUtils.getValue(location, CircleType.class);
                circleTypeOptional.ifPresent(circle -> result.add(getLocation(timestamp, amlData, circle)));
            }
        });
        return result;
    }

    private Function storeTimestamp(MutableObject timestamp) {
        return tuple -> {
            timestamp.setValue(getTimestamp(tuple));
            return tuple;
        };
    }


    private Instant getTimestamp(Tuple tuple) {
        XMLGregorianCalendar tupleTimestamp = tuple.getTimestamp();
        return toInstant(tupleTimestamp);
    }

    private static Geopriv getGeopriv(Object object) {
        return ParseUtils.getValue(object, Geopriv.class).get();
    }

    private Location getLocation(Instant timestamp, @Nullable AmlData amlData, PointType point) {
        List coordinates = point.getPos().getValue();
        return new Location(Double.valueOf(coordinates.get(0)), Double.valueOf(coordinates.get(1)), 0.0, timestamp, amlData);
    }

    private Location getLocation(Instant timestamp, @Nullable AmlData amlData, CircleType circle) {
        List coordinates = circle.getPos().getValue();
        return new Location(Double.valueOf(coordinates.get(0)), Double.valueOf(coordinates.get(1)), circle.getRadius().getValue(), timestamp, amlData);
    }

}