/**
* Copyright (C) 2012-2017 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.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import org.n52.oxf.xml.NcNameResolver;
import org.n52.sos.binding.Binding;
import org.n52.sos.binding.BindingConstants;
import org.n52.sos.binding.BindingRepository;
import org.n52.sos.coding.CodingRepository;
import org.n52.sos.encode.Encoder;
import org.n52.sos.exception.CodedException;
import org.n52.sos.exception.ows.InvalidParameterValueException;
import org.n52.sos.exception.ows.MissingParameterValueException;
import org.n52.sos.exception.ows.NoApplicableCodeException;
import org.n52.sos.exception.ows.concrete.InvalidResponseFormatParameterException;
import org.n52.sos.exception.ows.concrete.MissingResponseFormatParameterException;
import org.n52.sos.exception.sos.ResponseExceedsSizeLimitException;
import org.n52.sos.ogc.gml.CodeType;
import org.n52.sos.ogc.om.OmObservableProperty;
import org.n52.sos.ogc.ows.OWSConstants;
import org.n52.sos.ogc.ows.OWSConstants.RequestParams;
import org.n52.sos.ogc.ows.OwsExceptionReport;
import org.n52.sos.ogc.sensorML.elements.SmlIo;
import org.n52.sos.ogc.sos.Sos1Constants;
import org.n52.sos.ogc.sos.Sos2Constants;
import org.n52.sos.ogc.sos.SosConstants;
import org.n52.sos.ogc.swe.SweAbstractDataComponent;
import org.n52.sos.ogc.swe.SweConstants;
import org.n52.sos.ogc.swe.simpleType.SweQuantity;
import org.n52.sos.ogc.swe.simpleType.SweTime;
import org.n52.sos.service.Configurator;
import org.n52.sos.service.ServiceConfiguration;
import org.n52.sos.service.operator.ServiceOperatorKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
/**
* Utility class for SOS
*
* @since 4.0.0
*
*/
public class SosHelper implements Constants {
private static Configuration config = new Configuration();
private static final Logger LOGGER = LoggerFactory.getLogger(SosHelper.class);
private static final int KILO_BYTE = 1024;
private static final int KILO_BYTES_256 = 256 * KILO_BYTE;
protected static Configuration getConfiguration() {
return config;
}
protected static void setConfiguration(final Configuration config) {
SosHelper.config = config;
}
private static String getBaseGetUrl(String serviceURL, String urlPattern) {
final StringBuilder url = new StringBuilder();
// service URL
url.append(serviceURL);
// URL pattern for KVP
url.append(urlPattern);
// ?
url.append(Constants.QUERSTIONMARK_CHAR);
return url.toString();
}
private static String getRequest(String requestName) {
return new StringBuilder().append(RequestParams.request.name()).append(EQUAL_SIGN_CHAR).append(requestName)
.toString();
}
private static String getServiceParam() {
return new StringBuilder().append(AMPERSAND_CHAR).append(OWSConstants.RequestParams.service.name())
.append(EQUAL_SIGN_CHAR).append(SosConstants.SOS).toString();
}
private static String getVersionParam(String version) {
return new StringBuilder().append(AMPERSAND_CHAR).append(OWSConstants.RequestParams.version.name())
.append(EQUAL_SIGN_CHAR).append(version).toString();
}
private static String getParameter(String name, String value) {
return new StringBuilder().append(AMPERSAND_CHAR).append(name).append(EQUAL_SIGN_CHAR).append(value)
.toString();
}
/**
* Creates a HTTP-Get request for FeatureOfInterst without identifier
*
* @deprecated use {@link #createFoiGetUrl(String, String, String, String)}
*
* @param version
* SOS version
* @param serviceURL
* Service URL
* @return HTTP-Get request for FeatureOfInterest
*/
@Deprecated
public static String getFoiGetUrl(final String version, final String serviceURL, final String urlPattern) {
final StringBuilder url = new StringBuilder();
// service URL
url.append(getBaseGetUrl(serviceURL, urlPattern));
// request
url.append(getRequest(SosConstants.Operations.GetFeatureOfInterest.name()));
// service
url.append(getServiceParam());
// version
url.append(getVersionParam(version));
// FOI identifier
if (version.equalsIgnoreCase(Sos1Constants.SERVICEVERSION)) {
url.append(AMPERSAND_CHAR).append(Sos1Constants.GetFeatureOfInterestParams.featureOfInterestID.name())
.append(EQUAL_SIGN_CHAR);
} else {
url.append(AMPERSAND_CHAR).append(Sos2Constants.GetFeatureOfInterestParams.featureOfInterest.name())
.append(EQUAL_SIGN_CHAR);
}
return url.toString();
}
/**
* Creates a HTTP-Get URL from FOI identifier and service URL for SOS
* version
*
* @param foiId
* FeatureOfInterst identifier
* @param version
* SOS version
* @param serviceURL
* Service URL
* @return HTTP-Get request for featureOfInterst identifier
*/
public static String createFoiGetUrl(final String foiId, final String version, final String serviceURL,
final String urlPattern) {
final StringBuilder url = new StringBuilder();
// service URL
url.append(getBaseGetUrl(serviceURL, urlPattern));
// request
url.append(getRequest(SosConstants.Operations.GetFeatureOfInterest.name()));
// service
url.append(getServiceParam());
// version
url.append(getVersionParam(version));
// FOI identifier
if (version.equalsIgnoreCase(Sos1Constants.SERVICEVERSION)) {
url.append(getParameter(Sos1Constants.GetFeatureOfInterestParams.featureOfInterestID.name(), foiId));
} else {
url.append(getParameter(Sos2Constants.GetFeatureOfInterestParams.featureOfInterest.name(), foiId));
}
return url.toString();
}
/**
* creates a HTTP-GET string for DescribeSensor.
*
* @param version
* the version of the request
* @param serviceURL
* the service url
* @param procedureId
* The procedureId for the DescribeSensor request
* @param procedureDescriptionFormat
* The procedureDescriptionFormat for the DescribeSensor request
*
* @param urlPattern
* the url pattern (e.g. /kvp)
* @return Get-URL as String
* @throws UnsupportedEncodingException
*/
public static String getDescribeSensorUrl(final String version, final String serviceURL, final String procedureId,
final String urlPattern, String procedureDescriptionFormat) throws UnsupportedEncodingException {
final StringBuilder url = new StringBuilder();
// service URL
url.append(getBaseGetUrl(serviceURL, urlPattern));
// request
url.append(getRequest(SosConstants.Operations.DescribeSensor.name()));
// service
url.append(getServiceParam());
// version
url.append(getVersionParam(version));
// procedure
url.append(getParameter(SosConstants.DescribeSensorParams.procedure.name(), procedureId));
// outputFormat
if (version.equalsIgnoreCase(Sos1Constants.SERVICEVERSION)) {
url.append(getParameter(Sos1Constants.DescribeSensorParams.outputFormat.name(),
URLEncoder.encode(procedureDescriptionFormat, "UTF-8")));
} else {
url.append(getParameter(Sos2Constants.DescribeSensorParams.procedureDescriptionFormat.name(),
URLEncoder.encode(procedureDescriptionFormat, "UTF-8")));
}
return url.toString();
}
public static String getGetObservationKVPRequest(String version) {
final StringBuilder url = new StringBuilder();
// service URL
url.append(getBaseGetUrl(ServiceConfiguration.getInstance().getServiceURL(),
BindingConstants.KVP_BINDING_ENDPOINT));
// request
url.append(getRequest(SosConstants.Operations.GetObservation.name()));
// service
url.append(getServiceParam());
// version
url.append(getVersionParam(version));
return url.toString();
}
public static String addKVPOfferingParameterToRequest(String request, String offering) {
if (StringHelper.isNotEmpty(offering)) {
final StringBuilder url = new StringBuilder(request);
url.append(getParameter(SosConstants.GetObservationParams.offering.name(), offering));
return url.toString();
}
return request;
}
public static String addKVPLanguageParameterToRequest(String request, String language) {
if (StringHelper.isNotEmpty(language)) {
final StringBuilder url = new StringBuilder(request);
url.append(getParameter(OWSConstants.AdditionalRequestParams.language.name(), language));
return url.toString();
}
return request;
}
public static String addKVPCrsParameterToRequest(String request, String crs) {
if (StringHelper.isNotEmpty(crs)) {
final StringBuilder url = new StringBuilder(request);
url.append(getParameter(OWSConstants.AdditionalRequestParams.crs.name(), crs));
return url.toString();
}
return request;
}
public static String getGetCapabilitiesKVPRequest() {
final StringBuilder url = new StringBuilder();
// service URL
url.append(getBaseGetUrl(ServiceConfiguration.getInstance().getServiceURL(),
BindingConstants.KVP_BINDING_ENDPOINT));
// request
url.append(getRequest(SosConstants.Operations.GetCapabilities.name()));
// service
url.append(getServiceParam());
return url.toString();
}
/**
*
* Parse the srsName to integer value
*
* @param srsName
* the srsName to parse
* @return srsName integer value
* @throws OwsExceptionReport
* If the srsName can not be parsed
*
*/
public static int parseSrsName(final String srsName) throws OwsExceptionReport {
int srid = -1;
if (StringHelper.isNotEmpty(srsName) && !"NOT_SET".equalsIgnoreCase(srsName)) {
final String urnSrsPrefix = getConfiguration().getSrsNamePrefix();
final String urlSrsPrefix = getConfiguration().getSrsNamePrefixSosV2();
try {
srid =
Integer.valueOf(srsName.replace(urnSrsPrefix, Constants.EMPTY_STRING).replace(urlSrsPrefix,
Constants.EMPTY_STRING));
} catch (final NumberFormatException nfe) {
throw new InvalidParameterValueException()
.causedBy(nfe)
.at(SosConstants.GetObservationParams.srsName)
.withMessage(
"Error while parsing srsName parameter! Parameter has to match "
+ "pattern '%s' or '%s' with appended EPSGcode number", urnSrsPrefix,
urlSrsPrefix);
}
}
return srid;
}
/**
* Checks the free memory size.
*
* @throws OwsExceptionReport
* If no free memory size.
*/
public static void checkFreeMemory() throws OwsExceptionReport {
Runtime runtime = Runtime.getRuntime();
// check remaining free memory on heap if too small, throw exception to
// avoid an OutOfMemoryError
long freeMem = runtime.freeMemory();
LOGGER.debug("Remaining Heap Size: " + (freeMem / KILO_BYTE) + "KB");
if ((runtime.totalMemory() == runtime.maxMemory()) && (freeMem < KILO_BYTES_256)) {
// accords to 256 kB create service exception
throw new ResponseExceedsSizeLimitException().withMessage(
"The observation response is to big for the maximal heap size of %d Byte of the "
+ "virtual machine! Please either refine your getObservation request to reduce the "
+ "number of observations in the response or ask the administrator of this SOS to "
+ "increase the maximum heap size of the virtual machine!", runtime.maxMemory());
}
}
/**
* Returns an Envelope that contains the Geometry
*
* @param envelope
* Current envelope
* @param geometry
* Geometry to include
* @return Envelope that includes the Geometry
*/
public static Envelope checkEnvelope(final Envelope envelope, final Geometry geometry) {
Envelope checkedEnvelope = envelope;
if (checkedEnvelope == null) {
checkedEnvelope = geometry.getEnvelopeInternal();
} else if (!checkedEnvelope.contains(geometry.getEnvelopeInternal())) {
checkedEnvelope.expandToInclude(geometry.getEnvelopeInternal());
}
return checkedEnvelope;
}
/**
* Parses the HTTP-Post body with a parameter
*
* @param paramNames
* Parameter names
* @param parameterMap
* Parameter map
* @return Value of the parameter
*
* @throws OwsExceptionReport
* * If the parameter is not supported by this SOS.
*/
public static String parseHttpPostBodyWithParameter(final Enumeration<?> paramNames, final Map<?, ?> parameterMap)
throws OwsExceptionReport {
while (paramNames.hasMoreElements()) {
final String paramName = (String) paramNames.nextElement();
if (RequestParams.request.name().equalsIgnoreCase(paramName)) {
final String[] paramValues = (String[]) parameterMap.get(paramName);
if (paramValues.length == 1) {
return paramValues[0];
} else {
throw new NoApplicableCodeException()
.withMessage(
"The parameter '%s' has more than one value or is empty for HTTP-Post requests by this SOS!",
paramName);
}
} else {
throw new NoApplicableCodeException().withMessage(
"The parameter '%s' is not supported for HTTP-Post requests by this SOS!", paramName);
}
}
// FIXME: valid exception
throw new NoApplicableCodeException();
}
/**
* Checks if the FOI identifier was generated by SOS
*
* @param featureOfInterestIdentifier
* FOI identifier from database
* @param version
* SOS version
* @return True if the FOI identifier was generated
*/
public static boolean checkFeatureOfInterestIdentifierForSosV2(final String featureOfInterestIdentifier,
final String version) {
return !(Sos2Constants.SERVICEVERSION.equals(version) && featureOfInterestIdentifier
.startsWith(SosConstants.GENERATED_IDENTIFIER_PREFIX));
}
/**
* get collection of hierarchy values for a key
*
* @param hierarchy
* map to example
* @param key
* start key
* @param fullHierarchy
* whether to traverse down the full hierarchy
* @param includeStartKey
* whether to include the passed key in the result collection
* @return collection of the full hierarchy
*/
// FIXME move to ReadableCache
public static Set<String> getHierarchy(final Map<String, Set<String>> hierarchy, final String key,
final boolean fullHierarchy, final boolean includeStartKey) {
final Set<String> hierarchyValues = Sets.newHashSet();
if (includeStartKey) {
hierarchyValues.add(key);
}
final Stack<String> keysToCheck = new Stack<String>();
keysToCheck.push(key);
while (!keysToCheck.isEmpty()) {
final Collection<String> keyValues = hierarchy.get(keysToCheck.pop());
if (keyValues != null) {
for (final String value : keyValues) {
if (hierarchyValues.add(value) && fullHierarchy) {
keysToCheck.push(value);
}
}
}
}
return hierarchyValues;
}
/**
* get collection of hierarchy values for a set of keys
*
* @param hierarchy
* map to example
* @param keys
* start key
* @param fullHierarchy
* whether to traverse down the full hierarchy
* @param includeStartKeys
* whether to include the passed keys in the result collection
*
* @return collection of the full hierarchy
*/
// FIXME move to ReadableCache
public static Set<String> getHierarchy(final Map<String, Set<String>> hierarchy, final Set<String> keys,
final boolean fullHierarchy, final boolean includeStartKeys) {
final Set<String> parents = new HashSet<String>();
for (final String key : keys) {
parents.addAll(getHierarchy(hierarchy, key, fullHierarchy, includeStartKeys));
}
return parents;
}
/**
* help method to check the result format parameter. If the application/zip
* result format is set, true is returned. If not and the value is text/xml;
* subtype="OM" false is returned. If neither zip nor OM is set, a
* ServiceException with InvalidParameterValue as its code is thrown.
*
* @param responseFormat
* String containing the value of the result format parameter
* @param service
* @param version
*
* @throws OwsExceptionReport
* * if the parameter value is incorrect
*/
public static void checkResponseFormat(final String responseFormat, final String service, final String version)
throws OwsExceptionReport {
if (Strings.isNullOrEmpty(responseFormat)) {
throw new MissingResponseFormatParameterException();
} else {
final Collection<String> supportedResponseFormats =
CodingRepository.getInstance().getSupportedResponseFormats(service, version);
if (!supportedResponseFormats.contains(responseFormat)) {
throw new InvalidResponseFormatParameterException(responseFormat);
}
}
}
/**
* checks whether the value of procedureDescriptionFormat parameter is valid
*
* @param procedureDescriptionFormat
* the procedureDecriptionFormat parameter which should be
* checked
* @param service
* Service
* @param version
* Service version
* @throws OwsExceptionReport
* if the value of the procedureDecriptionFormat is incorrect
*/
public static void checkProcedureDescriptionFormat(final String procedureDescriptionFormat, final String service,
final String version) throws OwsExceptionReport {
checkFormat(procedureDescriptionFormat, new ServiceOperatorKey(service, version),
Sos2Constants.DescribeSensorParams.procedureDescriptionFormat);
}
/**
* checks whether the value of outputFormat parameter is valid
*
* @param checkOutputFormat
* the outputFormat parameter which should be checked
* @param service
* Service
* @param version
* Service version
* @throws OwsExceptionReport
* if the value of the outputFormat is incorrect
*/
public static void checkOutputFormat(final String checkOutputFormat, final String service, final String version)
throws OwsExceptionReport {
checkFormat(checkOutputFormat, new ServiceOperatorKey(service, version),
Sos1Constants.DescribeSensorParams.outputFormat);
}
/**
* checks whether the value of procedure format parameter is valid
*
* @param format
* the procedure format parameter which should be checked
* @param serviceOperatorKey
* Service and version
* @param parameter
* name of the checked parameter
* @throws OwsExceptionReport
* if the value of the procedure format is incorrect
*/
private static void checkFormat(final String format, ServiceOperatorKey serviceOperatorKey, Enum<?> parameter)
throws OwsExceptionReport {
if (Strings.isNullOrEmpty(format)) {
throw new MissingParameterValueException(parameter);
} else {
final Collection<String> supportedFormats =
CodingRepository.getInstance().getSupportedProcedureDescriptionFormats(serviceOperatorKey);
if (!supportedFormats.contains(format)) {
throw new InvalidParameterValueException(parameter, format);
}
}
}
/**
* Get valid FOI identifiers for SOS 2.0
*
* @param featureIDs
* FOI identifiers to test
* @param version
* SOS version
* @return valid FOI identifiers
*/
public static Collection<String> getFeatureIDs(final Collection<String> featureIDs, final String version) {
if (Sos2Constants.SERVICEVERSION.equals(version)) {
final Collection<String> validFeatureIDs = new ArrayList<String>(featureIDs.size());
for (final String featureID : featureIDs) {
if (checkFeatureOfInterestIdentifierForSosV2(featureID, version)) {
validFeatureIDs.add(featureID);
}
}
return validFeatureIDs;
}
return featureIDs;
}
/**
* Creates the minimum and maximum values of this envelope in the default
* EPSG.
* <p/>
*
* @param envelope
* the envelope
* <p/>
* @return the {@code MinMax} describing the envelope
* <p/>
*/
public static MinMax<String> getMinMaxFromEnvelope(final Envelope envelope) {
// TODO for full 3D support add minz to parameter in setStringValue
return new MinMax<String>().setMaximum(Joiner.on(' ').join(envelope.getMaxX(), envelope.getMaxY()))
.setMinimum(Joiner.on(' ').join(envelope.getMinX(), envelope.getMinY()));
}
/**
* Creates the minimum and maximum values of this envelope in the default
* EPSG as list.
* <p/>
*
* @param envelope
* the envelope
* <p/>
* @return the {@code MinMax} describing the envelope
* <p/>
*/
public static MinMax<List<String>> getMinMaxFromEnvelopeAsList(final Envelope envelope) {
// TODO for full 3D support add minz to parameter in setStringValue
return new MinMax<List<String>>().setMaximum(
Lists.newArrayList(Double.toString(envelope.getMaxX()), Double.toString(envelope.getMaxY())))
.setMinimum(
Lists.newArrayList(Double.toString(envelope.getMinX()), Double.toString(envelope.getMinY())));
}
public static OmObservableProperty createSosOberavablePropertyFromSosSMLIo(final SmlIo<?> output) {
final SweAbstractDataComponent ioValue = output.getIoValue();
final String identifier = ioValue.getDefinition();
final String description = ioValue.getDescription();
String unit = null;
String valueType = SosConstants.NOT_DEFINED;
switch (ioValue.getDataComponentType()) {
case Boolean:
valueType = SweConstants.VT_BOOLEAN;
break;
case Category:
valueType = SweConstants.VT_CATEGORY;
break;
case Count:
valueType = SweConstants.VT_COUNT;
break;
case CountRange:
valueType = SweConstants.VT_COUNT_RANGE;
break;
case ObservableProperty:
valueType = SweConstants.VT_OBSERVABLE_PROPERTY;
break;
case Quantity:
unit = ((SweQuantity) ioValue).getUom();
valueType = SweConstants.VT_QUANTITY;
break;
case QuantityRange:
valueType = SweConstants.VT_QUANTITY_RANGE;
break;
case Text:
valueType = SweConstants.VT_TEXT;
break;
case Time:
unit = ((SweTime) ioValue).getUom();
valueType = SweConstants.VT_TIME;
break;
case TimeRange:
valueType = SweConstants.VT_TIME_RANGE;
break;
case DataArray:
valueType = SweConstants.VT_DATA_ARRAY;
break;
case DataRecord:
valueType = SweConstants.VT_DATA_RECORD;
break;
default:
break;
}
if ((unit == null) || unit.isEmpty()) {
unit = SosConstants.NOT_DEFINED;
}
return new OmObservableProperty(identifier, description, unit, valueType);
}
public static void checkHref(final String href, final String parameterName) throws OwsExceptionReport {
if (!href.startsWith("http") && !href.startsWith("urn")) {
throw new InvalidParameterValueException().at(parameterName).withMessage(
"The reference (href) has an invalid style!");
}
}
public static String createCSVFromCodeTypeList(final List<CodeType> values) {
final StringBuilder builder = new StringBuilder();
if (CollectionHelper.isNotEmpty(values)) {
for (final CodeType value : values) {
builder.append(value.getValue());
if (value.isSetCodeSpace()) {
builder.append(CSV_TOKEN_SEPARATOR);
builder.append(value.getCodeSpace());
}
builder.append(CSV_BLOCK_SEPARATOR);
}
builder.delete(builder.lastIndexOf(CSV_BLOCK_SEPARATOR), builder.length());
}
return builder.toString();
}
public static List<CodeType> createCodeTypeListFromCSV(final String csv) {
final List<CodeType> names = new ArrayList<CodeType>(0);
if (StringHelper.isNotEmpty(csv)) {
for (final String nameCodespaces : csv.split(CSV_BLOCK_SEPARATOR)) {
String[] nameCodespace = nameCodespaces.split(CSV_TOKEN_SEPARATOR);
CodeType codeType = new CodeType(nameCodespace[0]);
if (nameCodespace.length == 2) {
codeType.setCodeSpace(nameCodespace[1]);
}
names.add(codeType);
}
}
return names;
}
/**
* Hide utility constructor
*/
protected SosHelper() {
}
/**
* Class to encapsulate all calls to the {@link Configurator}. Can be
* overwritten by tests.
*
* @see SosHelper#setConfiguration(org.n52.sos.util.SosHelper.Configuration)
*/
protected static class Configuration {
protected Collection<String> getObservationTypes() {
return Configurator.getInstance().getCache().getObservationTypes();
}
protected String getSrsNamePrefix() {
return ServiceConfiguration.getInstance().getSrsNamePrefix();
}
protected String getSrsNamePrefixSosV2() {
return ServiceConfiguration.getInstance().getSrsNamePrefixSosV2();
}
protected Set<Encoder<?, ?>> getEncoders() {
return CodingRepository.getInstance().getEncoders();
}
protected Collection<Binding> getBindings() {
return BindingRepository.getInstance().getBindings().values();
}
}
@Deprecated
public static void checkSection(List<String> sections) throws CodedException {
if (CollectionHelper.isEmpty(sections)) {
throw new MissingParameterValueException(SosConstants.GetCapabilitiesParams.Section.name())
.withMessage("The section element is empty!");
}
}
public static Map<String, String> getNcNameResolvedOfferings(Collection<String> offerings) {
Map<String, String> resolvedOfferings = new HashMap<String, String>();
for (String offering : offerings) {
if (!NcNameResolver.isNCName(offering)) {
resolvedOfferings.put(NcNameResolver.fixNcName(offering), offering);
} else {
resolvedOfferings.put(offering, offering);
}
}
return resolvedOfferings;
}
}