use of de.ii.ogcapi.foundation.domain.ApiMediaType in project ldproxy by interactive-instruments.
the class TilesQueriesHandlerImpl method getTileServerTileResponse.
private Response getTileServerTileResponse(QueryInputTileTileServerTile queryInput, ApiRequestContext requestContext) {
Tile tile = queryInput.getTile();
final String urlTemplate = tile.isDatasetTile() ? queryInput.getProvider().getUrlTemplate() : queryInput.getProvider().getUrlTemplateSingleCollection();
if (Objects.isNull(urlTemplate))
throw new IllegalStateException("The MAP_TILES configuration is invalid, no 'urlTemplate' was found.");
ApiMediaType mediaType = tile.getOutputFormat().getMediaType();
WebTarget client = ClientBuilder.newClient().target(urlTemplate).resolveTemplate("tileMatrix", tile.getTileLevel()).resolveTemplate("tileRow", tile.getTileRow()).resolveTemplate("tileCol", tile.getTileCol()).resolveTemplate("fileExtension", mediaType.fileExtension());
if (Objects.nonNull(tile.getCollectionId()))
client = client.resolveTemplate("collectionId", tile.getCollectionId());
Response response = client.request(mediaType.type()).get();
// unsuccessful? just forward the error response
if (response.getStatus() != 200)
return response;
List<Link> links = new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), ImmutableList.of(), i18n, requestContext.getLanguage());
byte[] content;
try {
content = response.readEntity(InputStream.class).readAllBytes();
} catch (IOException e) {
throw new RuntimeException("Could not read map tile from TileServer.", e);
}
Date lastModified = null;
EntityTag etag = getEtag(content);
Response.ResponseBuilder responseBuilder = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(responseBuilder))
return responseBuilder.build();
return prepareSuccessResponse(requestContext, queryInput.getIncludeLinkHeader() ? links : null, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s_%d_%d_%d.%s", tile.getTileMatrixSet().getId(), tile.getTileLevel(), tile.getTileRow(), tile.getTileCol(), tile.getOutputFormat().getMediaType().fileExtension())).entity(content).build();
}
use of de.ii.ogcapi.foundation.domain.ApiMediaType in project ldproxy by interactive-instruments.
the class QueriesHandlerStylesImpl method getStyleResponse.
private Response getStyleResponse(QueryInputStyle queryInput, ApiRequestContext requestContext) {
OgcApi api = requestContext.getApi();
OgcApiDataV2 apiData = api.getData();
Optional<String> collectionId = queryInput.getCollectionId();
String styleId = queryInput.getStyleId();
StyleFormatExtension format = styleRepository.getStyleFormatStream(apiData, collectionId).filter(f -> requestContext.getMediaType().matches(f.getMediaType().type())).findAny().orElseThrow(() -> new NotAcceptableException(MessageFormat.format("The requested media type ''{0}'' is not supported, the following media types are available: {1}", requestContext.getMediaType(), String.join(", ", styleRepository.getStyleFormatStream(apiData, collectionId).map(f -> f.getMediaType().type().toString()).collect(Collectors.toUnmodifiableList())))));
StylesheetContent stylesheetContent = styleRepository.getStylesheet(apiData, collectionId, styleId, format, requestContext, true);
// collect self/alternate links, but only, if we need to return them in the headers
List<Link> links = null;
if (queryInput.getIncludeLinkHeader()) {
final DefaultLinksGenerator defaultLinkGenerator = new DefaultLinksGenerator();
List<ApiMediaType> alternateMediaTypes = styleRepository.getStylesheetMediaTypes(apiData, collectionId, styleId, true, true).stream().filter(apiMediaType -> !apiMediaType.type().equals(format.getMediaType().type())).collect(Collectors.toUnmodifiableList());
links = defaultLinkGenerator.generateLinks(requestContext.getUriCustomizer(), format.getMediaType(), alternateMediaTypes, i18n, requestContext.getLanguage());
}
Date lastModified = styleRepository.getStylesheetLastModified(apiData, collectionId, styleId, format, true);
EntityTag etag = !format.getMediaType().type().equals(MediaType.TEXT_HTML_TYPE) || (collectionId.isEmpty() ? apiData.getExtension(HtmlConfiguration.class) : apiData.getExtension(HtmlConfiguration.class, collectionId.get())).map(HtmlConfiguration::getSendEtags).orElse(false) ? getEtag(stylesheetContent.getContent()) : null;
Response.ResponseBuilder response = evaluatePreconditions(requestContext, lastModified, etag);
if (Objects.nonNull(response))
return response.build();
return prepareSuccessResponse(requestContext, links, lastModified, etag, queryInput.getCacheControl().orElse(null), queryInput.getExpires().orElse(null), null, true, String.format("%s.%s", styleId, format.getFileExtension())).entity(format.getStyleEntity(stylesheetContent, api, collectionId, styleId, requestContext)).build();
}
use of de.ii.ogcapi.foundation.domain.ApiMediaType in project ldproxy by interactive-instruments.
the class StyleRepositoryFiles method getStyles.
@Override
public Styles getStyles(OgcApiDataV2 apiData, Optional<String> collectionId, ApiRequestContext requestContext) {
File dir = getPathStyles(apiData, collectionId).toFile();
if (!dir.exists())
dir.getParentFile().mkdirs();
final StylesLinkGenerator stylesLinkGenerator = new StylesLinkGenerator();
Map<String, StyleFormatExtension> formatMap = getStyleFormatStream(apiData, collectionId).filter(format -> !format.getDerived()).collect(Collectors.toUnmodifiableMap(format -> format.getFileExtension(), format -> format));
List<StyleEntry> styleEntries = Arrays.stream(Objects.requireNonNullElse(dir.listFiles(), ImmutableList.of().toArray(File[]::new))).filter(file -> !file.isHidden()).filter(file -> formatMap.containsKey(com.google.common.io.Files.getFileExtension(file.getName()))).map(file -> com.google.common.io.Files.getNameWithoutExtension(file.getName())).distinct().sorted().map(styleId -> {
Builder builder = ImmutableStyleEntry.builder().id(styleId).title(getTitle(apiData, collectionId, styleId, requestContext).orElse(styleId));
Date lastModified = getStyleLastModified(apiData, collectionId, styleId);
if (Objects.nonNull(lastModified))
builder.lastModified(lastModified);
List<ApiMediaType> mediaTypes = getStylesheetMediaTypes(apiData, collectionId, styleId, true, false);
builder.links(stylesLinkGenerator.generateStyleLinks(requestContext.getUriCustomizer(), styleId, mediaTypes, i18n, requestContext.getLanguage()));
if (collectionId.isPresent()) {
List<ApiMediaType> additionalMediaTypes = getStyleFormatStream(apiData, collectionId).filter(format -> format.canDeriveCollectionStyle() && !mediaTypes.contains(format.getMediaType()) && willDeriveStylesheet(apiData, collectionId, styleId, format)).map(StyleFormatExtension::getMediaType).collect(Collectors.toUnmodifiableList());
if (!additionalMediaTypes.isEmpty()) {
builder.addAllLinks(stylesLinkGenerator.generateStyleLinks(requestContext.getUriCustomizer(), styleId, additionalMediaTypes, i18n, requestContext.getLanguage()));
}
}
builder.addLinks(stylesLinkGenerator.generateStyleMetadataLink(requestContext.getUriCustomizer(), styleId, i18n, requestContext.getLanguage()));
return builder.build();
}).collect(Collectors.toList());
Styles styles = ImmutableStyles.builder().styles(styleEntries).lastModified(styleEntries.stream().map(StyleEntry::getLastModified).map(Optional::get).max(Comparator.naturalOrder())).links(new DefaultLinksGenerator().generateLinks(requestContext.getUriCustomizer(), requestContext.getMediaType(), requestContext.getAlternateMediaTypes(), i18n, requestContext.getLanguage())).build();
return styles;
}
use of de.ii.ogcapi.foundation.domain.ApiMediaType in project ldproxy by interactive-instruments.
the class ApiRequestDispatcher method dispatch.
@Path("/{entrypoint: [^/]*}")
public EndpointExtension dispatch(@PathParam("entrypoint") String entrypoint, @Context OgcApi service, @Context ContainerRequestContext requestContext, @Context Request request) {
String subPath = ((UriRoutingContext) requestContext.getUriInfo()).getFinalMatchingGroup();
String method = requestContext.getMethod();
EndpointExtension ogcApiEndpoint = findEndpoint(service.getData(), entrypoint, subPath, method).orElse(null);
if (ogcApiEndpoint == null) {
throwNotAllowedOrNotFound(getMethods(service.getData(), entrypoint, subPath));
/* TODO should this belong here or should this be done by the resources?
// check, if this may be an issue of special characters in the path, replace all non-Word characters with an underscore and test the sub path again
String subPathReduced = subPath.replaceAll("\\W","_");
if (findEndpoint(service.getData(), entrypoint, subPathReduced, null).isPresent())
throw new BadRequestException("The sub path '"+subPath+"' includes characters that are not supported for a resource. Resource ids typically only support word characters (ASCII letters, digits, underscore) for the resource names.");
throw new NotFoundException();
*/
}
Set<String> parameters = requestContext.getUriInfo().getQueryParameters().keySet();
List<OgcApiQueryParameter> knownParameters = ogcApiEndpoint.getParameters(service.getData(), subPath, method);
Set<String> unknownParameters = parameters.stream().filter(parameter -> !knownParameters.stream().filter(param -> param.getName().equalsIgnoreCase(parameter)).findAny().isPresent()).collect(Collectors.toSet());
if (!unknownParameters.isEmpty()) {
throw new BadRequestException("The following query parameters are rejected: " + String.join(", ", unknownParameters) + ". Valid parameters for this request are: " + String.join(", ", knownParameters.stream().map(ParameterExtension::getName).collect(Collectors.toList())));
}
ImmutableSet<ApiMediaType> supportedMediaTypes = method.equals("GET") || method.equals("HEAD") ? ogcApiEndpoint.getMediaTypes(service.getData(), subPath) : ogcApiEndpoint.getMediaTypes(service.getData(), subPath, method);
ApiMediaType selectedMediaType;
Set<ApiMediaType> alternateMediaTypes;
if (supportedMediaTypes.isEmpty() && NOCONTENT_METHODS.contains(method)) {
selectedMediaType = DEFAULT_MEDIA_TYPE;
alternateMediaTypes = ImmutableSet.of();
} else {
selectedMediaType = contentNegotiation.negotiate(requestContext, supportedMediaTypes).orElseThrow(() -> new NotAcceptableException(MessageFormat.format("The Accept header ''{0}'' does not match any of the supported media types for this resource: {1}.", requestContext.getHeaderString("Accept"), supportedMediaTypes.stream().map(mediaType -> mediaType.type().toString()).collect(Collectors.toList()))));
alternateMediaTypes = getAlternateMediaTypes(selectedMediaType, supportedMediaTypes);
}
Locale selectedLanguage = contentNegotiation.negotiate(requestContext).orElse(Locale.ENGLISH);
ApiRequestContext apiRequestContext = new Builder().requestUri(requestContext.getUriInfo().getRequestUri()).request(request).externalUri(getExternalUri()).mediaType(selectedMediaType).alternateMediaTypes(alternateMediaTypes).language(selectedLanguage).api(service).build();
// validate request
ApiEndpointDefinition apiDef = ogcApiEndpoint.getDefinition(service.getData());
if (!apiDef.getResources().isEmpty()) {
// check that the subPath is valid
OgcApiResource resource = apiDef.getResource("/" + entrypoint + subPath).orElse(null);
if (resource == null)
throw new NotFoundException("The requested path is not a resource in this API.");
// no need to check the path parameters here, only the parent path parameters (service, endpoint) are available;
// path parameters in the sub-path have to be checked later
ApiOperation operation = apiDef.getOperation(resource, method).orElse(null);
if (operation == null) {
throwNotAllowedOrNotFound(getMethods(service.getData(), entrypoint, subPath));
}
Optional<String> collectionId = resource.getCollectionId(service.getData());
// validate query parameters
requestContext.getUriInfo().getQueryParameters().entrySet().stream().forEach(p -> {
String name = p.getKey();
List<String> values = p.getValue();
operation.getQueryParameters().stream().filter(param -> param.getName().equalsIgnoreCase(name)).forEach(param -> {
Optional<String> result = param.validate(service.getData(), collectionId, values);
if (result.isPresent())
throw new BadRequestException(result.get());
});
});
}
// TODO check lang, too
ogcApiInjectableContext.inject(requestContext, apiRequestContext);
return ogcApiEndpoint;
}
use of de.ii.ogcapi.foundation.domain.ApiMediaType in project ldproxy by interactive-instruments.
the class CollectionsOnLandingPage method process.
@Override
public ImmutableLandingPage.Builder process(Builder landingPageBuilder, OgcApi api, URICustomizer uriCustomizer, ApiMediaType mediaType, List<ApiMediaType> alternateMediaTypes, Optional<Locale> language) {
OgcApiDataV2 apiData = api.getData();
if (!isEnabledForApi(apiData)) {
return landingPageBuilder;
}
List<String> collectionNames = apiData.getCollections().values().stream().filter(featureType -> featureType.getEnabled()).map(featureType -> featureType.getLabel()).collect(Collectors.toList());
String suffix = (collectionNames.size() > 0 && collectionNames.size() <= 4) ? " (" + String.join(", ", collectionNames) + ")" : "";
landingPageBuilder.addLinks(new ImmutableLink.Builder().href(uriCustomizer.copy().ensureNoTrailingSlash().ensureLastPathSegment("collections").removeParameters("f").toString()).rel("data").title(i18n.get("dataLink", language) + suffix).build()).addLinks(new ImmutableLink.Builder().href(uriCustomizer.copy().ensureNoTrailingSlash().ensureLastPathSegment("collections").removeParameters("f").toString()).rel("http://www.opengis.net/def/rel/ogc/1.0/data").title(i18n.get("dataLink", language) + suffix).build());
ImmutableList.Builder<Link> distributionLinks = new ImmutableList.Builder<Link>().addAll(apiData.getExtension(CollectionsConfiguration.class).map(CollectionsConfiguration::getAdditionalLinks).orElse(ImmutableList.<Link>of()).stream().filter(link -> Objects.equals(link.getRel(), "enclosure")).collect(Collectors.toUnmodifiableList()));
// links to the features in the API)
if (apiData.getCollections().size() == 1) {
String collectionId = apiData.getCollections().keySet().iterator().next();
FeatureTypeConfigurationOgcApi featureTypeConfiguration = apiData.getCollections().get(collectionId);
distributionLinks.addAll(featureTypeConfiguration.getAdditionalLinks().stream().filter(link -> Objects.equals(link.getRel(), "enclosure")).collect(Collectors.toUnmodifiableList()));
ImmutableOgcApiCollection.Builder ogcApiCollection = ImmutableOgcApiCollection.builder().id(collectionId);
for (CollectionExtension ogcApiCollectionExtension : extensionRegistry.getExtensionsForType(CollectionExtension.class)) {
ogcApiCollection = ogcApiCollectionExtension.process(ogcApiCollection, featureTypeConfiguration, api, uriCustomizer.copy().clearParameters().ensureLastPathSegments("collections", collectionId).ensureNoTrailingSlash(), false, mediaType, alternateMediaTypes, language);
}
distributionLinks.addAll(ogcApiCollection.build().getLinks().stream().filter(link -> Objects.equals(link.getRel(), "items") && !Objects.equals(link.getType(), "text/html")).collect(Collectors.toUnmodifiableList()));
}
landingPageBuilder.putExtensions("datasetDownloadLinks", distributionLinks.build());
return landingPageBuilder;
}
Aggregations