Search in sources :

Example 1 with LDPContainerPage

use of won.protocol.util.linkeddata.LDPContainerPage in project webofneeds by researchstudio-sat.

the class RestAtomController method getAllAtoms.

/**
 * Returns a Map of atoms (key is the atomUri), value is the atom including
 * (meta)data
 *
 * @param state only return atoms with the given AtomState
 * @param modifiedAfterIsoString only return atoms that have been modified after
 * this timestamp (ISO 8601 format (UTC): yyyy-MM-dd'T'HH:mm:ss.SSS'Z')
 * @param createdAfterIsoString only return atoms that have been created after
 * this timestamp (ISO 8601 format (UTC): yyyy-MM-dd'T'HH:mm:ss.SSS'Z')
 * @param longitude geo-location
 * @param latitude geo-location
 * @param maxDistance max distance in meters that the location of an atom is
 * away from the given lat/lng coordinates
 * @param filterBySocketTypeUriString filter the results to only contain Atoms
 * with the given socketTypeUri
 * @param filterByAtomTypeUriString filter the results to only contain Atoms
 * with the given atomTypeUri
 * @param limit limit results to this size (if null, 0, or negative value do not
 * limit at all)
 * @return Map of AtomPojos {@literal ->} atoms with certain metadata @see
 * won.owner.pojo.AtomPojo
 */
@ResponseBody
@RequestMapping(value = "/all", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public Map<URI, AtomPojo> getAllAtoms(@RequestParam(value = "state", required = false) AtomState state, @RequestParam(value = "modifiedafter", required = false) String modifiedAfterIsoString, @RequestParam(value = "createdafter", required = false) String createdAfterIsoString, @RequestParam(value = "latitude", required = false) Float latitude, @RequestParam(value = "longitude", required = false) Float longitude, @RequestParam(value = "maxDistance", required = false) Integer maxDistance, @RequestParam(value = "filterBySocketTypeUri", required = false) String filterBySocketTypeUriString, @RequestParam(value = "filterByAtomTypeUri", required = false) String filterByAtomTypeUriString, @RequestParam(value = "limit", required = false) Integer limit) {
    ZonedDateTime modifiedAfter = StringUtils.isNotBlank(modifiedAfterIsoString) ? ZonedDateTime.parse(modifiedAfterIsoString, DateTimeFormatter.ISO_DATE_TIME) : null;
    ZonedDateTime createdAfter = StringUtils.isNotBlank(createdAfterIsoString) ? ZonedDateTime.parse(createdAfterIsoString, DateTimeFormatter.ISO_DATE_TIME) : null;
    Coordinate nearLocation = (latitude != null && longitude != null) ? new Coordinate(latitude, longitude) : null;
    URI nodeURI = wonNodeInformationService.getDefaultWonNodeURI();
    URI filterBySocketTypeUri = null;
    if (filterBySocketTypeUriString != null) {
        filterBySocketTypeUri = URI.create(filterBySocketTypeUriString);
    }
    URI filterByAtomTypeUri = null;
    if (filterByAtomTypeUriString != null) {
        filterByAtomTypeUri = URI.create(filterByAtomTypeUriString);
    }
    Map<URI, AtomPojo> atomMap = new HashMap<>();
    int lastBatchSize = -1;
    int lastPageSize = -1;
    int pageSize = -1;
    Optional<URI> nextLink = Optional.empty();
    // never an infinite loop
    OUTER: for (int batch = 0; batch < 10000; batch++) {
        lastPageSize = pageSize;
        LDPContainerPage<List<URI>> fetchResult = null;
        if (batch == 0 || limit == null) {
            // two options here:
            // a) first batch. Just load the amount we want, hope we can use them all
            // b) no limit. just keep fetching large pages
            // pages are 1-based
            int page = batch + 1;
            pageSize = limit != null ? limit : FETCH_PAGE_SIZE_NO_LIMIT;
            fetchResult = WonLinkedDataUtils.getNodeAtomUrisPage(nodeURI, modifiedAfter, createdAfter, state, filterBySocketTypeUri, filterByAtomTypeUri, page, pageSize, linkedDataSource);
        } else {
            // * at least second batch
            // * we have a limit we want to reach
            // now we'll determine the page size and then figure out the page number we have
            // to use in order
            // to get approximately that many new atoms without missing one
            // pages are 1-based
            int page = batch + 1;
            pageSize = determinePageSize(atomMap.size(), lastBatchSize, lastPageSize, page, limit);
            fetchResult = WonLinkedDataUtils.getNodeAtomUrisPageAfter(nodeURI, modifiedAfter, createdAfter, state, filterBySocketTypeUri, filterByAtomTypeUri, nextLink.orElse(null), pageSize, linkedDataSource);
        }
        if (fetchResult.getContent().isEmpty()) {
            break;
        }
        nextLink = fetchResult.getNextPageLink();
        int beforeBatchSize = atomMap.size();
        List<URI> atomUris = fetchResult.getContent();
        for (URI atomUri : atomUris) {
            try {
                Dataset atomDataset = WonLinkedDataUtils.getDataForPublicResource(atomUri, linkedDataSource);
                AtomPojo atom = new AtomPojo(atomDataset);
                if (atom.getState() != AtomState.ACTIVE) {
                    continue;
                }
                if (nearLocation == null || isNearLocation(nearLocation, atom.getLocation(), maxDistance) || isNearLocation(nearLocation, atom.getJobLocation(), maxDistance)) {
                    atomMap.put(atom.getUri(), atom);
                    if (limit != null && limit > 0 && atomMap.size() >= limit) {
                        // break fetching if the limit has been reached
                        break OUTER;
                    }
                }
            } catch (Exception e) {
                // we catch all exceptions here as we want to be more robust against
                // unforseen error conditions down the stack
                logger.debug("Could not retrieve atom<" + atomUri + "> cause: " + e.getMessage());
                continue;
            }
        }
        if (atomUris.size() < pageSize) {
            // Save a request and finish now.
            break;
        }
        lastBatchSize = atomMap.size() - beforeBatchSize;
    }
    return atomMap;
}
Also used : ZonedDateTime(java.time.ZonedDateTime) Coordinate(won.protocol.model.Coordinate) Dataset(org.apache.jena.query.Dataset) LDPContainerPage(won.protocol.util.linkeddata.LDPContainerPage) AtomPojo(won.owner.pojo.AtomPojo) URI(java.net.URI) URISyntaxException(java.net.URISyntaxException) AccessDeniedException(org.springframework.security.access.AccessDeniedException)

Aggregations

URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 ZonedDateTime (java.time.ZonedDateTime)1 Dataset (org.apache.jena.query.Dataset)1 AccessDeniedException (org.springframework.security.access.AccessDeniedException)1 AtomPojo (won.owner.pojo.AtomPojo)1 Coordinate (won.protocol.model.Coordinate)1 LDPContainerPage (won.protocol.util.linkeddata.LDPContainerPage)1