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;
}
Aggregations