/** @since 4.0.0 */
public class SosGetCapabilitiesOperatorV100
    extends AbstractV1RequestOperator<
        AbstractGetCapabilitiesDAO, GetCapabilitiesRequest, GetCapabilitiesResponse> {
  // TODO check for SOS 1.0.0
  private static final Set<String> CONFORMANCE_CLASSES =
      Collections.singleton("http://www.opengis.net/spec/SOS/1.0/conf/core");

  private static final String OPERATION_NAME = SosConstants.Operations.GetCapabilities.name();

  public SosGetCapabilitiesOperatorV100() {
    super(OPERATION_NAME, GetCapabilitiesRequest.class);
  }

  @Override
  public Set<String> getConformanceClasses() {
    return Collections.unmodifiableSet(CONFORMANCE_CLASSES);
  }

  @Override
  public GetCapabilitiesResponse receive(GetCapabilitiesRequest sosRequest)
      throws OwsExceptionReport {
    return getDao().getCapabilities(sosRequest);
  }

  @Override
  protected void checkParameters(GetCapabilitiesRequest request) throws OwsExceptionReport {}
}
public class GetCapabilitiesKvpDecoder extends AbstractKvpDecoder {

  private static final Set<DecoderKey> KVP_DECODER_KEY_TYPE =
      Sets.<DecoderKey>newHashSet(
          new OperationDecoderKey(
              SosConstants.SOS,
              null,
              SosConstants.Operations.GetCapabilities.name(),
              MediaTypes.APPLICATION_KVP),
          new OperationDecoderKey(
              SosConstants.SOS,
              Sos2Constants.SERVICEVERSION,
              SosConstants.Operations.GetCapabilities.name(),
              MediaTypes.APPLICATION_KVP),
          new OperationDecoderKey(
              null,
              Sos2Constants.SERVICEVERSION,
              SosConstants.Operations.GetCapabilities.name(),
              MediaTypes.APPLICATION_KVP),
          new OperationDecoderKey(
              null,
              null,
              SosConstants.Operations.GetCapabilities.name(),
              MediaTypes.APPLICATION_KVP));

  @Override
  public Set<DecoderKey> getDecoderKeyTypes() {
    return Collections.unmodifiableSet(KVP_DECODER_KEY_TYPE);
  }

  /**
   * parses the String representing the getCapabilities request and creates a SosGetCapabilities
   * request
   *
   * @param decoderKeyType the matched <code>KvpDecoderKeyType</code>
   * @param element String with getCapabilities parameters
   * @return Returns SosGetCapabilitiesRequest representing the request
   * @throws OwsExceptionReport If parsing the String failed
   */
  @Override
  public GetCapabilitiesRequest decode(Map<String, String> element) throws OwsExceptionReport {

    GetCapabilitiesRequest request = new GetCapabilitiesRequest();
    CompositeOwsException exceptions = new CompositeOwsException();

    for (String parameterName : element.keySet()) {
      String parameterValues = element.get(parameterName);
      try {
        if (!parseDefaultParameter(request, parameterValues, parameterName)) {
          //                    // service (mandatory SOS 1.0.0, SOS 2.0 default)
          //                    if
          // (parameterName.equalsIgnoreCase(OWSConstants.RequestParams.service.name())) {
          //
          // request.setService(KvpHelper.checkParameterSingleValue(parameterValues,
          // parameterName));
          //                    } // request (mandatory)
          //                    else if
          // (parameterName.equalsIgnoreCase(OWSConstants.RequestParams.request.name())) {
          //                        KvpHelper.checkParameterSingleValue(parameterValues,
          // parameterName);
          //                    } // acceptVersions (optional)
          //                    else
          if (parameterName.equalsIgnoreCase(
              SosConstants.GetCapabilitiesParams.AcceptVersions.name())) {
            if (!parameterValues.isEmpty()) {
              request.setAcceptVersions(
                  Arrays.asList(parameterValues.split(Constants.COMMA_STRING)));
            } else {
              exceptions.add(new MissingParameterValueException(parameterName));
            }
          }
          // acceptFormats (optional)
          else if (parameterName.equalsIgnoreCase(
              SosConstants.GetCapabilitiesParams.AcceptFormats.name())) {
            request.setAcceptFormats(
                KvpHelper.checkParameterMultipleValues(parameterValues, parameterName));
          }
          // updateSequence (optional)
          else if (parameterName.equalsIgnoreCase(
              SosConstants.GetCapabilitiesParams.updateSequence.name())) {
            request.setUpdateSequence(
                KvpHelper.checkParameterSingleValue(parameterValues, parameterName));
          }
          // sections (optional)
          else if (parameterName.equalsIgnoreCase(
              SosConstants.GetCapabilitiesParams.Sections.name())) {
            request.setSections(
                KvpHelper.checkParameterMultipleValues(parameterValues, parameterName));
          }
          // capabilitiesId (optional; non-standard)
          else if (parameterName.equalsIgnoreCase(
              SosConstants.GetCapabilitiesParams.CapabilitiesId.name())) {
            request.setCapabilitiesId(
                KvpHelper.checkParameterSingleValue(parameterValues, parameterName));
          } else {
            exceptions.add(new ParameterNotSupportedException(parameterName));
          }
        }
      } catch (OwsExceptionReport owse) {
        exceptions.add(owse);
      }
    }
    exceptions.throwIfNotEmpty();

    return request;
  }
}