Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.n52.sos.ds.AbstractSosGetCapabilitiesHandler Maven / Gradle / Ivy
/*
* Copyright (C) 2012-2019 52°North Initiative for Geospatial Open Source
* Software GmbH
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* If the program is linked with libraries which are licensed under one of
* the following licenses, the combination of the program with the linked
* library is not considered a "derivative work" of the program:
*
* - Apache License, version 2.0
* - Apache Software License, version 1.0
* - GNU Lesser General Public License, version 3
* - Mozilla Public License, versions 1.0, 1.1 and 2.0
* - Common Development and Distribution License (CDDL), version 1.0
*
* Therefore the distribution of the program linked with libraries licensed
* under the aforementioned licenses, is permitted by the copyright holders
* if the distribution is compliant with both the GNU General Public
* License version 2 and the aforementioned licenses.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*/
package org.n52.sos.ds;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.xml.namespace.QName;
import org.n52.iceland.binding.Binding;
import org.n52.iceland.binding.MediaTypeBindingKey;
import org.n52.iceland.exception.ows.concrete.InvalidServiceParameterException;
import org.n52.iceland.ogc.ows.OwsServiceMetadataRepository;
import org.n52.iceland.ogc.ows.extension.OwsCapabilitiesExtensionProvider;
import org.n52.iceland.ogc.ows.extension.OwsCapabilitiesExtensionRepository;
import org.n52.iceland.ogc.ows.extension.OwsOperationMetadataExtensionProvider;
import org.n52.iceland.ogc.ows.extension.OwsOperationMetadataExtensionProviderRepository;
import org.n52.iceland.ogc.ows.extension.StaticCapabilities;
import org.n52.iceland.request.handler.OperationHandlerRepository;
import org.n52.iceland.request.operator.RequestOperatorRepository;
import org.n52.iceland.util.LocalizedProducer;
import org.n52.janmayen.Comparables;
import org.n52.janmayen.function.Functions;
import org.n52.janmayen.function.Suppliers;
import org.n52.janmayen.http.MediaType;
import org.n52.janmayen.http.MediaTypes;
import org.n52.janmayen.i18n.LocaleHelper;
import org.n52.shetland.ogc.OGCConstants;
import org.n52.shetland.ogc.filter.FilterCapabilities;
import org.n52.shetland.ogc.filter.FilterConstants.ComparisonOperator;
import org.n52.shetland.ogc.filter.FilterConstants.ConformanceClassConstraintNames;
import org.n52.shetland.ogc.filter.FilterConstants.SpatialOperator;
import org.n52.shetland.ogc.filter.FilterConstants.TimeOperator;
import org.n52.shetland.ogc.gml.GmlConstants;
import org.n52.shetland.ogc.gml.time.TimePeriod;
import org.n52.shetland.ogc.ows.OWSConstants;
import org.n52.shetland.ogc.ows.OWSConstants.GetCapabilitiesParams;
import org.n52.shetland.ogc.ows.OwsAllowedValues;
import org.n52.shetland.ogc.ows.OwsCapabilitiesExtension;
import org.n52.shetland.ogc.ows.OwsDomain;
import org.n52.shetland.ogc.ows.OwsNoValues;
import org.n52.shetland.ogc.ows.OwsOperation;
import org.n52.shetland.ogc.ows.OwsOperationMetadataExtension;
import org.n52.shetland.ogc.ows.OwsOperationsMetadata;
import org.n52.shetland.ogc.ows.OwsServiceIdentification;
import org.n52.shetland.ogc.ows.OwsValue;
import org.n52.shetland.ogc.ows.exception.CompositeOwsException;
import org.n52.shetland.ogc.ows.exception.InvalidParameterValueException;
import org.n52.shetland.ogc.ows.exception.OwsExceptionReport;
import org.n52.shetland.ogc.ows.exception.VersionNegotiationFailedException;
import org.n52.shetland.ogc.ows.extension.MergableExtension;
import org.n52.shetland.ogc.ows.extension.StringBasedCapabilitiesExtension;
import org.n52.shetland.ogc.ows.service.GetCapabilitiesRequest;
import org.n52.shetland.ogc.ows.service.GetCapabilitiesResponse;
import org.n52.shetland.ogc.sos.Sos1Constants;
import org.n52.shetland.ogc.sos.Sos2Constants;
import org.n52.shetland.ogc.sos.SosCapabilities;
import org.n52.shetland.ogc.sos.SosConstants;
import org.n52.shetland.ogc.sos.SosObservationOffering;
import org.n52.shetland.util.CollectionHelper;
import org.n52.shetland.util.ReferencedEnvelope;
import org.n52.sos.coding.encode.ProcedureDescriptionFormatRepository;
import org.n52.sos.coding.encode.ResponseFormatRepository;
import org.n52.sos.config.CapabilitiesExtensionService;
import org.n52.sos.ogc.sos.SosObservationOfferingExtensionRepository;
import org.n52.sos.util.GeometryHandler;
import org.n52.svalbard.ConformanceClass;
import org.n52.svalbard.ConformanceClasses;
import org.n52.svalbard.decode.DecoderRepository;
import org.n52.svalbard.encode.EncoderRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
/**
* Implementation of the interface AbstractGetCapabilitiesHandler
*
* @since 4.0.0
*/
public abstract class AbstractSosGetCapabilitiesHandler extends AbstractGetCapabilitiesHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractSosGetCapabilitiesHandler.class);
/* section flags (values are powers of 2) */
private static final int SERVICE_IDENTIFICATION = 0x01;
private static final int SERVICE_PROVIDER = 0x02;
private static final int OPERATIONS_METADATA = 0x04;
private static final int FILTER_CAPABILITIES = 0x08;
private static final int CONTENTS = 0x10;
private static final int ALL =
0x20 | SERVICE_IDENTIFICATION | SERVICE_PROVIDER | OPERATIONS_METADATA | FILTER_CAPABILITIES | CONTENTS;
@Inject
private CapabilitiesExtensionService capabilitiesExtensionService;
@Inject
private EncoderRepository encoderRepository;
@Inject
private DecoderRepository decoderRepository;
@Inject
private OperationHandlerRepository operationHandlerRepository;
@Inject
private OwsServiceMetadataRepository serviceMetadataRepository;
@Inject
private RequestOperatorRepository requestOperatorRepository;
@Inject
private ResponseFormatRepository responseFormatRepository;
@Inject
private GeometryHandler geometryHandler;
@Inject
private OwsOperationMetadataExtensionProviderRepository owsExtendedCapabilitiesProviderRepository;
@Inject
private SosObservationOfferingExtensionRepository offeringExtensionRepository;
@Inject
private OwsCapabilitiesExtensionRepository capabilitiesExtensionRepository;
@Inject
private ProcedureDescriptionFormatRepository procedureDescriptionFormatRepository;
public AbstractSosGetCapabilitiesHandler() {
this(SosConstants.SOS);
}
public AbstractSosGetCapabilitiesHandler(String service) {
super(service);
}
@Override
public GetCapabilitiesResponse getCapabilities(GetCapabilitiesRequest request) throws OwsExceptionReport {
String capabilitiesId = request.getCapabilitiesId();
String service = request.getService();
String version = negotiateVersion(request);
GetCapabilitiesResponse response = new GetCapabilitiesResponse(service, version);
if (capabilitiesId == null && this.capabilitiesExtensionService.isStaticCapabilitiesActive()) {
createStaticCapabilities(request, response);
} else if (capabilitiesId != null
&& !capabilitiesId.equals(GetCapabilitiesParams.DYNAMIC_CAPABILITIES_IDENTIFIER)) {
createStaticCapabilitiesWithId(request, response);
} else {
createDynamicCapabilities(request, response);
}
return response;
}
private String negotiateVersion(GetCapabilitiesRequest request) throws OwsExceptionReport {
if (request.isSetVersion()) {
return request.getVersion();
} else {
String service = request.getService();
String version;
if (request.isSetAcceptVersions()) {
version = request.getAcceptVersions().stream()
.filter(v -> getServiceOperatorRepository().isVersionSupported(service, v)).findFirst()
.orElseThrow(this::versionNegotiationFailed);
} else {
version = getServiceOperatorRepository().getSupportedVersions(service).stream()
.max(Comparables.version()).orElseThrow(() -> new InvalidServiceParameterException(service));
}
request.setVersion(version);
return version;
}
}
private OwsExceptionReport versionNegotiationFailed() {
return new VersionNegotiationFailedException().withMessage(
"The requested '%s' values are not supported by this service!",
OWSConstants.GetCapabilitiesParams.AcceptVersions);
}
private void addSectionSpecificContent(SectionSpecificContentObject sectionSpecificContentObject,
GetCapabilitiesRequest request) throws OwsExceptionReport {
String version = sectionSpecificContentObject.getGetCapabilitiesResponse().getVersion();
String service = sectionSpecificContentObject.getGetCapabilitiesResponse().getService();
if (isServiceIdentificationSectionRequested(sectionSpecificContentObject.getRequestedSections())) {
sectionSpecificContentObject.getSosCapabilities()
.setServiceIdentification(getServiceIdentification(request, service, version));
}
if (isServiceProviderSectionRequested(sectionSpecificContentObject.getRequestedSections())) {
sectionSpecificContentObject.getSosCapabilities()
.setServiceProvider(this.serviceMetadataRepository.getServiceProviderFactory(service).get());
}
if (isOperationsMetadataSectionRequested(sectionSpecificContentObject.getRequestedSections())) {
sectionSpecificContentObject.getSosCapabilities()
.setOperationsMetadata(getOperationsMetadataForOperations(request, service, version));
}
if (isFilterCapabilitiesSectionRequested(sectionSpecificContentObject.getRequestedSections())) {
sectionSpecificContentObject.getSosCapabilities().setFilterCapabilities(getFilterCapabilities(version));
}
if (isContentsSectionRequested(sectionSpecificContentObject.getRequestedSections())) {
if (isV2(sectionSpecificContentObject.getGetCapabilitiesResponse())) {
sectionSpecificContentObject.getSosCapabilities()
.setContents(getContentsForSosV2(sectionSpecificContentObject));
} else {
sectionSpecificContentObject.getSosCapabilities()
.setContents(getContentsForSosV1(sectionSpecificContentObject));
}
}
if (isV2(sectionSpecificContentObject.getGetCapabilitiesResponse())) {
if (sectionSpecificContentObject.getRequestedSections() == ALL) {
sectionSpecificContentObject.getSosCapabilities()
.setExtensions(getAndMergeExtensions(service, version));
} else if (!sectionSpecificContentObject.getRequestedExtensionSesctions().isEmpty()) {
sectionSpecificContentObject.getSosCapabilities().setExtensions(getExtensions(
sectionSpecificContentObject.getRequestedExtensionSesctions(), service, version));
}
}
}
protected abstract List getContentsForSosV1(
SectionSpecificContentObject sectionSpecificContentObject) throws OwsExceptionReport;
protected abstract List getContentsForSosV2(
SectionSpecificContentObject sectionSpecificContentObject) throws OwsExceptionReport;
private int identifyRequestedSections(GetCapabilitiesRequest request, GetCapabilitiesResponse response,
Set availableExtensionSections, Set requestedExtensionSections) throws OwsExceptionReport {
if (!request.isSetSections()) {
// FIXME:
// requestedExtensionSections.addAll(availableExtensionSections)?
return ALL;
}
int sections = 0;
for (String section : request.getSections()) {
if (section.isEmpty()) {
LOGGER.warn("A section element is empty! Check if operator checks for empty elements!");
} else if (section.equals(SosConstants.CapabilitiesSections.All.name())) {
sections |= ALL;
} else if (section.equals(SosConstants.CapabilitiesSections.ServiceIdentification.name())) {
sections |= SERVICE_IDENTIFICATION;
} else if (section.equals(SosConstants.CapabilitiesSections.ServiceProvider.name())) {
sections |= SERVICE_PROVIDER;
} else if (section.equals(SosConstants.CapabilitiesSections.OperationsMetadata.name())) {
sections |= OPERATIONS_METADATA;
} else if (section.equals(Sos1Constants.CapabilitiesSections.Filter_Capabilities.name())
&& isV1(response)) {
sections |= FILTER_CAPABILITIES;
} else if (section.equals(Sos2Constants.CapabilitiesSections.FilterCapabilities.name())
&& isV2(response)) {
sections |= FILTER_CAPABILITIES;
} else if (section.equals(SosConstants.CapabilitiesSections.Contents.name())) {
sections |= CONTENTS;
} else if (availableExtensionSections.contains(section) && isV2(response)) {
requestedExtensionSections.add(section);
} else {
throw new InvalidParameterValueException().at(GetCapabilitiesParams.Section)
.withMessage("The requested section '%s' does not exist or is not supported!", section);
}
}
return sections;
}
private OwsServiceIdentification getServiceIdentification(GetCapabilitiesRequest request, String service,
String version) throws OwsExceptionReport {
Locale locale = getRequestedLocale(request);
LocalizedProducer serviceIdentificationFactory =
this.serviceMetadataRepository.getServiceIdentificationFactory(service);
OwsServiceIdentification serviceIdentification = serviceIdentificationFactory.get(locale);
if (version.equals(Sos2Constants.SERVICEVERSION)) {
serviceIdentification.setProfiles(getProfiles(SosConstants.SOS, Sos2Constants.SERVICEVERSION));
}
return serviceIdentification;
}
private Set getProfiles(String service, String version) {
Set profiles = Stream
.of(getBindingRepository().getBindings().values(),
getRequestOperatorRepository().getRequestOperators(), getDecoderRepository().getDecoders(),
getEncoderRepository().getEncoders(),
getOperationHandlerRepository().getOperationHandlers().values())
.flatMap(Collection::stream).filter(c -> c instanceof ConformanceClass).map(c -> (ConformanceClass) c)
.map(c -> c.getConformanceClasses(service, version)).flatMap(Set::stream).map(URI::create)
.collect(Collectors.toSet());
if (Sos2Constants.SERVICEVERSION.equals(version)) {
checkBindingConformanceClasses(getBindingRepository().getBindings().values(), profiles);
}
// FIXME additional profiles
if ("hydrology".equalsIgnoreCase(getProfileHandler().getActiveProfile().getIdentifier())) {
profiles.add(URI.create("http://www.opengis.net/spec/SOS_application-profile_hydrology/1.0/req/hydrosos"));
}
return profiles;
}
private void checkBindingConformanceClasses(Collection values, Set profiles) {
Set collect = Stream.of(getBindingRepository().getBindings().values()).flatMap(Collection::stream)
.map(b -> b.getKeys()).flatMap(Set::stream).filter(k -> k instanceof MediaTypeBindingKey)
.map(k -> (MediaTypeBindingKey) k).map(k -> {
if (k.getMediaType().equals(MediaTypes.APPLICATION_KVP)) {
return ConformanceClasses.SOS_V2_KVP_CORE_BINDING;
} else if (k.getMediaType().equals(MediaTypes.APPLICATION_JSON)) {
return "http://www.opengis.net/spec/SOS/2.0/conf/json";
} else if (k.getMediaType().equals(MediaTypes.APPLICATION_SOAP_XML)) {
return ConformanceClasses.SOS_V2_SOAP_BINDING;
} else if (k.getMediaType().equals(MediaTypes.APPLICATION_XML)) {
return ConformanceClasses.SOS_V2_POX_BINDING;
} else if (k.getMediaType().equals(MediaTypes.APPLICATION_EXI)) {
return "http://www.opengis.net/spec/SOS/2.0/conf/exi";
}
return null;
}).filter(Objects::nonNull).map(URI::create).collect(Collectors.toSet());
profiles.addAll(collect);
}
/**
* Get the OperationsMetadat for all supported operations
*
* @param request
* the request
* @param service
* Requested service
* @param version
* Requested service version
*
* @return OperationsMetadata for all operations supported by the requested
* service and version
*
* @throws OwsExceptionReport
* If an error occurs
*/
private OwsOperationsMetadata getOperationsMetadataForOperations(GetCapabilitiesRequest request, String service,
String version) throws OwsExceptionReport {
List parameters = getParameters(service, version);
List operations = getOperations(service, version);
List constraints = Collections.emptyList();
OwsOperationMetadataExtension owsExtendedCapabilities = null;
/*
* check if an OwsExtendedCapabilities provider is available for this
* service and check if this provider provides OwsExtendedCapabilities
* for the request
*/
OwsOperationMetadataExtensionProvider provider =
owsExtendedCapabilitiesProviderRepository.getExtendedCapabilitiesProvider(service, version);
if (provider != null && provider.hasExtendedCapabilitiesFor(request)) {
owsExtendedCapabilities = provider.getOwsExtendedCapabilities(request);
}
return new OwsOperationsMetadata(operations, parameters, constraints, owsExtendedCapabilities);
}
/**
* Get the FilterCapabilities
*
* @param version
* Requested service version
*
* @return FilterCapabilities
*/
private FilterCapabilities getFilterCapabilities(final String version) {
final FilterCapabilities filterCapabilities = new FilterCapabilities();
if (Sos2Constants.SERVICEVERSION.equals(version)) {
getConformance(filterCapabilities);
}
if (version.equals(Sos1Constants.SERVICEVERSION)) {
getScalarFilterCapabilities(filterCapabilities, version);
}
getSpatialFilterCapabilities(filterCapabilities, version);
getTemporalFilterCapabilities(filterCapabilities, version);
return filterCapabilities;
}
private void getConformance(FilterCapabilities filterCapabilities) {
OwsValue trueValue = new OwsValue("true");
OwsValue falseValue = new OwsValue("false");
OwsNoValues noValues = OwsNoValues.instance();
filterCapabilities
.addConformance(new OwsDomain(ConformanceClassConstraintNames.ImplementsQuery, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsAdHocQuery, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsFunctions, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsResourceld, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsMinStandardFilter, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsStandardFilter, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsMinSpatialFilter, noValues, trueValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsSpatialFilter, noValues, trueValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsMinTemporalFilter, noValues, trueValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsTemporalFilter, noValues, trueValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsVersionNav, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsSorting, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsExtendedOperators, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsMinimumXPath, noValues, falseValue));
filterCapabilities.addConformance(
new OwsDomain(ConformanceClassConstraintNames.ImplementsSchemaElementFunc, noValues, falseValue));
}
protected boolean checkOfferingValues(ReferencedEnvelope envelopeForOffering, Set featuresForOffering,
Collection responseFormats) {
return ReferencedEnvelope.isNotNullOrEmpty(envelopeForOffering)
&& CollectionHelper.isNotEmpty(featuresForOffering) && CollectionHelper.isNotEmpty(responseFormats);
}
/**
* Set SpatialFilterCapabilities to FilterCapabilities
*
* @param filterCapabilities
* FilterCapabilities
* @param version
* SOS version
*/
private void getSpatialFilterCapabilities(final FilterCapabilities filterCapabilities, final String version) {
// set GeometryOperands
final List operands = new LinkedList<>();
if (version.equals(Sos2Constants.SERVICEVERSION)) {
operands.add(GmlConstants.QN_ENVELOPE_32);
} else if (version.equals(Sos1Constants.SERVICEVERSION)) {
operands.add(GmlConstants.QN_ENVELOPE);
operands.add(GmlConstants.QN_POINT);
operands.add(GmlConstants.QN_LINESTRING);
operands.add(GmlConstants.QN_POLYGON);
}
filterCapabilities.setSpatialOperands(operands);
// set SpatialOperators
Map> ops = new EnumMap<>(SpatialOperator.class);
// final SetMultiMap ops =
// MultiMaps.newSetMultiMap(SpatialOperator.class);
if (version.equals(Sos2Constants.SERVICEVERSION)) {
ops.put(SpatialOperator.BBOX, Collections.singleton(GmlConstants.QN_ENVELOPE_32));
} else if (version.equals(Sos1Constants.SERVICEVERSION)) {
ops.put(SpatialOperator.BBOX, Collections.singleton(GmlConstants.QN_ENVELOPE));
// set Contains
Set filterOperands = new HashSet<>(
Arrays.asList(GmlConstants.QN_POINT, GmlConstants.QN_LINESTRING, GmlConstants.QN_POLYGON));
Stream.of(SpatialOperator.Contains, SpatialOperator.Intersects, SpatialOperator.Overlaps)
.forEach(op -> ops.put(op, filterOperands));
}
filterCapabilities.setSpatialOperators(ops);
}
/**
* Set TemporalFilterCapabilities to FilterCapabilities
*
* @param filterCapabilities
* FilterCapabilities
* @param version
* SOS version
*/
private void getTemporalFilterCapabilities(FilterCapabilities filterCapabilities, String version) {
// set TemporalOperands
final List operands = new ArrayList<>(2);
switch (version) {
case Sos2Constants.SERVICEVERSION:
operands.add(GmlConstants.QN_TIME_PERIOD_32);
operands.add(GmlConstants.QN_TIME_INSTANT_32);
break;
case Sos1Constants.SERVICEVERSION:
operands.add(GmlConstants.QN_TIME_PERIOD);
operands.add(GmlConstants.QN_TIME_INSTANT);
break;
default:
logNotSupportedVersion(version);
break;
}
filterCapabilities.setTemporalOperands(operands);
// set TemporalOperators
final Map> ops = CollectionHelper.synchronizedMap(0);
switch (version) {
case Sos2Constants.SERVICEVERSION:
for (final TimeOperator op : TimeOperator.values()) {
ops.computeIfAbsent(op, createSynchronizedSet()).add(GmlConstants.QN_TIME_INSTANT_32);
ops.computeIfAbsent(op, createSynchronizedSet()).add(GmlConstants.QN_TIME_PERIOD_32);
}
break;
case Sos1Constants.SERVICEVERSION:
for (final TimeOperator op : TimeOperator.values()) {
ops.computeIfAbsent(op, createSynchronizedSet()).add(GmlConstants.QN_TIME_INSTANT);
ops.computeIfAbsent(op, createSynchronizedSet()).add(GmlConstants.QN_TIME_PERIOD);
}
break;
default:
logNotSupportedVersion(version);
break;
}
filterCapabilities.setTemporalOperators(ops);
}
private void logNotSupportedVersion(String version) {
LOGGER.trace("Not supported version '{}'", version);
}
/**
* Set ScalarFilterCapabilities to FilterCapabilities
*
* @param filterCapabilities
* FilterCapabilities
* @param version
* the service version
*/
private void getScalarFilterCapabilities(final FilterCapabilities filterCapabilities, String version) {
// TODO PropertyIsNil, PropertyIsNull? better:
// filterCapabilities.setComparisonOperators(Arrays.asList(ComparisonOperator.values()));
final List comparisonOperators = new ArrayList<>(8);
comparisonOperators.add(ComparisonOperator.PropertyIsBetween);
comparisonOperators.add(ComparisonOperator.PropertyIsEqualTo);
if (version.equals(Sos1Constants.SERVICEVERSION)) {
comparisonOperators.add(ComparisonOperator.PropertyIsNotEqualTo);
}
comparisonOperators.add(ComparisonOperator.PropertyIsLessThan);
comparisonOperators.add(ComparisonOperator.PropertyIsLessThanOrEqualTo);
comparisonOperators.add(ComparisonOperator.PropertyIsGreaterThan);
comparisonOperators.add(ComparisonOperator.PropertyIsGreaterThanOrEqualTo);
comparisonOperators.add(ComparisonOperator.PropertyIsLike);
filterCapabilities.setComparisonOperators(comparisonOperators);
}
/**
* Get FOIs contained in an offering
*
* @param offering
* Offering identifier
*
* @return FOI identifiers
*
*
* @throws OwsExceptionReport
* * If an error occurs
*/
protected Set getFOI4offering(final String offering) throws OwsExceptionReport {
final Set featureIDs = new HashSet<>(0);
final Set features = getCache().getFeaturesOfInterestForOffering(offering);
if (!getProfileHandler().getActiveProfile().isListFeatureOfInterestsInOfferings() || features == null) {
featureIDs.add(OGCConstants.UNKNOWN);
} else {
featureIDs.addAll(features);
}
return featureIDs;
}
protected Collection getObservationTypes(String offering) {
Set observationTypes = getCache().getObservationTypesForOffering(offering).stream()
.filter(Predicate.isEqual(SosConstants.NOT_DEFINED).negate()).collect(Collectors.toSet());
if (observationTypes.isEmpty()) {
getCache().getAllowedObservationTypesForOffering(offering).stream()
.filter(Predicate.isEqual(SosConstants.NOT_DEFINED).negate()).forEach(observationTypes::add);
}
return observationTypes;
}
@Override
protected Set getExtensionSections(String service, String version) throws OwsExceptionReport {
return getAndMergeExtensions(service, version).stream().map(OwsCapabilitiesExtension::getSectionName)
.collect(Collectors.toSet());
}
/**
* Get extensions and merge MergableExtension of the same class.
*
* @param service
* the service name
* @param version
* the service version
* @return Extensions
*
*
* @throws OwsExceptionReport
* if an error occurs
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private List getAndMergeExtensions(String service, String version)
throws OwsExceptionReport {
List providers =
capabilitiesExtensionRepository.getCapabilitiesExtensionProvider(service, version);
List extensions = new LinkedList<>();
if (CollectionHelper.isNotEmpty(providers)) {
Map map = new HashMap<>(providers.size());
providers.stream().filter(Objects::nonNull).map(OwsCapabilitiesExtensionProvider::getExtension)
.forEachOrdered(extension -> {
if (extension instanceof MergableExtension) {
map.merge(extension.getSectionName(), (MergableExtension) extension,
Functions.mergeLeft(MergableExtension::merge));
} else {
extensions.add(extension);
}
});
extensions.addAll(map.values());
}
Map activeCapabilitiesExtensions =
this.capabilitiesExtensionService.getActiveCapabilitiesExtensions();
if (activeCapabilitiesExtensions != null && !activeCapabilitiesExtensions.isEmpty()) {
extensions.addAll(activeCapabilitiesExtensions.values());
}
return extensions;
}
private Collection getExtensions(Set requestedExtensionSections, String service,
String version) throws OwsExceptionReport {
return getAndMergeExtensions(service, version).stream()
.filter(e -> requestedExtensionSections.contains(e.getSectionName())).collect(Collectors.toList());
}
protected void setUpPhenomenaForOffering(String offering, String procedure, SosObservationOffering sosOffering) {
setUpPhenomenaForOffering(Sets.newHashSet(offering), procedure, sosOffering);
}
protected void setUpPhenomenaForOffering(final Set offerings, final String procedure,
final SosObservationOffering sosOffering) {
Collection phenomenons = offerings.stream().flatMap(offering -> {
Collection observableProperties = getCache().getObservablePropertiesForOffering(offering);
return observableProperties.stream().filter(observableProperty -> {
Set procedures = getCache().getProceduresForObservableProperty(observableProperty);
return procedures.contains(procedure)
|| isHiddenChildProcedureObservableProperty(offering, procedures);
});
}).collect(Collectors.toList());
sosOffering.setCompositePhenomena(offerings.stream().map(getCache()::getCompositePhenomenonsForOffering)
.flatMap(Set::stream).collect(Collectors.toSet()));
sosOffering.setPhens4CompPhens(sosOffering.getCompositePhenomena().stream().collect(
Collectors.toMap(Function.identity(), getCache()::getObservablePropertiesForCompositePhenomenon)));
sosOffering.setObservableProperties(phenomenons);
}
private boolean isHiddenChildProcedureObservableProperty(String offering,
Set proceduresForObservableProperty) {
return getCache().getHiddenChildProceduresForOffering(offering).stream()
.anyMatch(proceduresForObservableProperty::contains);
}
protected void setUpRelatedFeaturesForOffering(String offering, String version, SosObservationOffering sosOffering)
throws OwsExceptionReport {
setUpRelatedFeaturesForOffering(Collections.singleton(offering), version, sosOffering);
}
protected void setUpRelatedFeaturesForOffering(Set offerings, String version,
SosObservationOffering sosOffering) {
setUpRelatedFeaturesForOffering(offerings.stream(), sosOffering);
}
protected void setUpRelatedFeaturesForOffering(Stream offerings, SosObservationOffering sosOffering) {
sosOffering.setRelatedFeatures(offerings.map(getCache()::getRelatedFeaturesForOffering).flatMap(Set::stream)
.collect(Collectors.toMap(Function.identity(), getCache()::getRolesForRelatedFeature)));
}
protected void setUpTimeForOffering(Stream offerings, SosObservationOffering sosOffering) {
TimePeriod phenomenonTime = new TimePeriod();
TimePeriod resultTime = new TimePeriod();
offerings.forEach(offering -> {
phenomenonTime.extendToContain(getPhenomeonTime(offering));
resultTime.extendToContain(getResultTime(offering));
});
sosOffering.setPhenomenonTime(phenomenonTime);
sosOffering.setResultTime(resultTime);
}
protected void setUpTimeForOffering(Set offerings, SosObservationOffering sosOffering) {
setUpTimeForOffering(offerings.stream(), sosOffering);
}
protected void setUpTimeForOffering(final String offering, final SosObservationOffering sosOffering) {
sosOffering.setPhenomenonTime(getPhenomeonTime(offering));
sosOffering.setResultTime(getResultTime(offering));
}
private TimePeriod getPhenomeonTime(String offering) {
return new TimePeriod(getCache().getMinPhenomenonTimeForOffering(offering),
getCache().getMaxPhenomenonTimeForOffering(offering));
}
private TimePeriod getResultTime(String offering) {
return new TimePeriod(getCache().getMinResultTimeForOffering(offering),
getCache().getMaxResultTimeForOffering(offering));
}
protected void setUpFeatureOfInterestTypesForOffering(String offering, SosObservationOffering sosOffering) {
setUpFeatureOfInterestTypesForOffering(Collections.singleton(offering), sosOffering);
}
protected void setUpFeatureOfInterestTypesForOffering(Set offerings, SosObservationOffering sosOffering) {
sosOffering.setFeatureOfInterestTypes(offerings.stream().map(getCache()::getAllObservationTypesForOffering)
.flatMap(Set::stream).collect(Collectors.toSet()));
}
protected void setUpResponseFormatForOffering(SosObservationOffering sosOffering, String version) {
// initialize as new HashSet so that collection is modifiable
sosOffering.setResponseFormats(
new HashSet<>(getResponseFormatRepository().getSupportedResponseFormats(SosConstants.SOS, version)));
// TODO set as property
}
protected Set getResponseFormatForOffering(String offering, String version) {
Set responseFormats = getCache().getAllObservationTypesForOffering(offering).stream().map(
observationType -> getResponseFormatsForObservationType(observationType, SosConstants.SOS, version))
.filter(Objects::nonNull).flatMap(Set::stream).collect(Collectors.toSet());
switch (version) {
case Sos1Constants.SERVICEVERSION:
return checkForMimeType(responseFormats, true);
case Sos2Constants.SERVICEVERSION:
return checkForMimeType(responseFormats, false);
default:
return responseFormats;
}
}
private Set checkForMimeType(Set responseFormats, boolean onlyMimeTypes) {
return responseFormats.stream().filter(format -> isMimeType(format) == onlyMimeTypes)
.collect(Collectors.toSet());
}
private boolean isMimeType(String responseFormat) {
try {
return MediaType.parse(responseFormat) != null;
} catch (IllegalArgumentException e) {
return false;
}
}
protected void setUpProcedureDescriptionFormatForOffering(SosObservationOffering sosOffering, String version) {
// TODO: set procDescFormat <-- what is required here?
sosOffering.setProcedureDescriptionFormat(procedureDescriptionFormatRepository
.getSupportedProcedureDescriptionFormats(SosConstants.SOS, version));
}
protected ReferencedEnvelope getObservedArea(String offering) throws OwsExceptionReport {
if (getCache().hasSpatialFilteringProfileEnvelopeForOffering(offering)) {
return getCache().getSpatialFilteringProfileEnvelopeForOffering(offering);
} else {
return getCache().getEnvelopeForOffering(offering);
}
}
protected Collection getProceduresForOffering(String offering, String version) throws OwsExceptionReport {
Collection procedures = new HashSet<>(getCache().getProceduresForOffering(offering));
if (version.equals(Sos1Constants.SERVICEVERSION)) {
procedures.addAll(getCache().getHiddenChildProceduresForOffering(offering));
}
return procedures.stream().filter(getCache().getPublishedProcedures()::contains).collect(Collectors.toSet());
}
private boolean isContentsSectionRequested(int sections) {
return (sections & CONTENTS) != 0;
}
private boolean isFilterCapabilitiesSectionRequested(int sections) {
return (sections & FILTER_CAPABILITIES) != 0;
}
private boolean isOperationsMetadataSectionRequested(int sections) {
return (sections & OPERATIONS_METADATA) != 0;
}
private boolean isServiceProviderSectionRequested(int sections) {
return (sections & SERVICE_PROVIDER) != 0;
}
private boolean isServiceIdentificationSectionRequested(int sections) {
return (sections & SERVICE_IDENTIFICATION) != 0;
}
protected String getGetDataAvailabilityUrl() {
return addParameter(getBaseGetUrl(), "request", "GetDataAvailability");
}
private String getBaseGetUrl() {
final StringBuilder url = new StringBuilder();
// service URL
url.append(getServiceURL());
// ?
url.append('?');
// service
url.append(OWSConstants.RequestParams.service.name()).append('=').append(SosConstants.SOS);
// version
url.append('&').append(OWSConstants.RequestParams.version.name()).append('=')
.append(Sos2Constants.SERVICEVERSION);
return url.toString();
}
protected String addParameter(String url, String parameter, String value) {
return new StringBuilder(url).append('&').append(parameter).append('=').append(value).toString();
}
protected RequestOperatorRepository getRequestOperatorRepository() {
return this.requestOperatorRepository;
}
protected ResponseFormatRepository getResponseFormatRepository() {
return this.responseFormatRepository;
}
private void createStaticCapabilities(GetCapabilitiesRequest request, GetCapabilitiesResponse response)
throws OwsExceptionReport {
response.setXmlString(this.capabilitiesExtensionService.getActiveStaticCapabilitiesDocument());
}
private void createStaticCapabilitiesWithId(GetCapabilitiesRequest request, GetCapabilitiesResponse response)
throws OwsExceptionReport {
StaticCapabilities sc = this.capabilitiesExtensionService.getStaticCapabilities(request.getCapabilitiesId());
if (sc == null) {
throw new InvalidParameterValueException(GetCapabilitiesParams.CapabilitiesId,
request.getCapabilitiesId());
}
response.setXmlString(sc.getDocument());
}
private void createDynamicCapabilities(GetCapabilitiesRequest request, GetCapabilitiesResponse response)
throws OwsExceptionReport {
Set availableExtensionSections = getExtensionSections(response.getService(), response.getVersion());
Set requestedExtensionSections = new HashSet<>(availableExtensionSections.size());
int requestedSections =
identifyRequestedSections(request, response, availableExtensionSections, requestedExtensionSections);
SosCapabilities sosCapabilities = new SosCapabilities(request.getService(), request.getVersion(), null, null,
null, null, null, null, null, null);
SectionSpecificContentObject sectionSpecificContentObject = new SectionSpecificContentObject()
.setRequest(request).setResponse(response).setRequestedExtensionSections(requestedExtensionSections)
.setRequestedSections(requestedSections).setSosCapabilities(sosCapabilities);
addSectionSpecificContent(sectionSpecificContentObject, request);
response.setCapabilities(sosCapabilities);
}
private List getOperations(String service, String version) throws OwsExceptionReport {
CompositeOwsException exceptions = new CompositeOwsException();
List operations = getRequestOperatorRepository().getActiveRequestOperatorKeys().stream()
.filter(k -> k.getService().equals(service)).filter(k -> k.getVersion().equals(version))
.map(getRequestOperatorRepository()::getRequestOperator).map(operator -> {
try {
return operator.getOperationMetadata(service, version);
} catch (OwsExceptionReport ex) {
exceptions.add(ex);
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
exceptions.throwIfNotEmpty();
return operations;
}
private List getParameters(String service, String version) {
return Arrays.asList(getServiceParameter(service, version), getVersionParameter(service, version),
getCrsParameter(service, version), getLanguageParameter(service, version));
}
private OwsDomain getServiceParameter(String service, String version) {
OwsValue owsValue = new OwsValue(SosConstants.SOS);
return new OwsDomain(OWSConstants.RequestParams.service, new OwsAllowedValues(owsValue));
}
private OwsDomain getVersionParameter(String service, String version) {
Set supportedVersions = getServiceOperatorRepository().getSupportedVersions(service);
Stream allowedValues = supportedVersions.stream().map(OwsValue::new);
return new OwsDomain(OWSConstants.RequestParams.version, new OwsAllowedValues(allowedValues));
}
private OwsDomain getCrsParameter(String service, String version) {
Set crs = this.geometryHandler.addOgcCrsPrefix(getCache().getEpsgCodes());
Stream allowedValues = crs.stream().map(OwsValue::new);
return new OwsDomain(OWSConstants.AdditionalRequestParams.crs, new OwsAllowedValues(allowedValues));
}
private OwsDomain getLanguageParameter(String service, String version) {
Set languages = getCache().getSupportedLanguages();
Stream allowedValues = languages.stream().map(LocaleHelper::encode).map(OwsValue::new);
return new OwsDomain(OWSConstants.AdditionalRequestParams.language, new OwsAllowedValues(allowedValues));
}
public CapabilitiesExtensionService getCapabilitiesExtensionService() {
return capabilitiesExtensionService;
}
public EncoderRepository getEncoderRepository() {
return encoderRepository;
}
public DecoderRepository getDecoderRepository() {
return decoderRepository;
}
public OperationHandlerRepository getOperationHandlerRepository() {
return operationHandlerRepository;
}
public OwsServiceMetadataRepository getServiceMetadataRepository() {
return serviceMetadataRepository;
}
public GeometryHandler getGeometryHandler() {
return geometryHandler;
}
public OwsOperationMetadataExtensionProviderRepository getOwsExtendedCapabilitiesProviderRepository() {
return owsExtendedCapabilitiesProviderRepository;
}
public SosObservationOfferingExtensionRepository getOfferingExtensionRepository() {
return offeringExtensionRepository;
}
public OwsCapabilitiesExtensionRepository getCapabilitiesExtensionRepository() {
return capabilitiesExtensionRepository;
}
public ProcedureDescriptionFormatRepository getProcedureDescriptionFormatRepository() {
return procedureDescriptionFormatRepository;
}
private static boolean isV2(GetCapabilitiesResponse response) {
return response.getVersion().equals(Sos2Constants.SERVICEVERSION);
}
private static boolean isV1(GetCapabilitiesResponse response) {
return response.getVersion().equals(Sos1Constants.SERVICEVERSION);
}
private static Function> createSynchronizedSet() {
return Suppliers.> asFunction(HashSet::new).andThen(Collections::synchronizedSet);
}
protected static class SectionSpecificContentObject {
private GetCapabilitiesRequest request;
private GetCapabilitiesResponse response;
private Set requestedExtensionSections;
private int requestedSections;
private SosCapabilities sosCapabilities;
public SectionSpecificContentObject setRequest(GetCapabilitiesRequest request) {
this.request = request;
return this;
}
public GetCapabilitiesRequest getGetCapabilitiesRequest() {
return request;
}
public SectionSpecificContentObject setResponse(GetCapabilitiesResponse response) {
this.response = response;
return this;
}
public GetCapabilitiesResponse getGetCapabilitiesResponse() {
return response;
}
public SectionSpecificContentObject setRequestedExtensionSections(Set requestedExtensionSections) {
this.requestedExtensionSections = requestedExtensionSections;
return this;
}
public Set getRequestedExtensionSesctions() {
return requestedExtensionSections;
}
public SectionSpecificContentObject setRequestedSections(int requestedSections) {
this.requestedSections = requestedSections;
return this;
}
public int getRequestedSections() {
return requestedSections;
}
public SectionSpecificContentObject setSosCapabilities(SosCapabilities sosCapabilities) {
this.sosCapabilities = sosCapabilities;
return this;
}
public SosCapabilities getSosCapabilities() {
return sosCapabilities;
}
}
}