WFSFeatureSourceHelper.java

/*
 * Copyright (C) 2022 B3Partners B.V.
 *
 * SPDX-License-Identifier: MIT
 */
package org.tailormap.api.geotools.featuresources;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.geotools.api.data.DataStore;
import org.geotools.api.data.ResourceInfo;
import org.geotools.api.data.SimpleFeatureSource;
import org.geotools.data.wfs.WFSDataStoreFactory;
import org.geotools.data.wfs.internal.FeatureTypeInfo;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.util.UriComponentsBuilder;
import org.tailormap.api.geotools.PreventLocalAllowNestedJarEntityResolver;
import org.tailormap.api.geotools.wfs.SimpleWFSHelper;
import org.tailormap.api.persistence.TMFeatureSource;
import org.tailormap.api.persistence.TMFeatureType;
import org.tailormap.api.persistence.helper.GeoToolsHelper;
import org.tailormap.api.persistence.json.ServiceAuthentication;
import org.tailormap.api.persistence.json.TMFeatureTypeInfo;

public class WFSFeatureSourceHelper extends FeatureSourceHelper {
  @Override
  public DataStore createDataStore(TMFeatureSource tmfs, Integer timeout) throws IOException {
    Map<String, Object> params = new HashMap<>();
    params.put(WFSDataStoreFactory.ENTITY_RESOLVER.key, PreventLocalAllowNestedJarEntityResolver.INSTANCE);

    if (timeout != null) {
      params.put(WFSDataStoreFactory.TIMEOUT.key, timeout);
    }

    LinkedCaseInsensitiveMap<String> wfsUrlParams = new LinkedCaseInsensitiveMap<>();
    wfsUrlParams.putAll(UriComponentsBuilder.fromUriString(tmfs.getUrl())
        .build()
        .getQueryParams()
        .toSingleValueMap());
    String version = wfsUrlParams.get("VERSION");
    if (!"2.0.0".equals(version)) {
      version = SimpleWFSHelper.DEFAULT_WFS_VERSION;
    }
    params.put(
        WFSDataStoreFactory.URL.key,
        SimpleWFSHelper.getWFSRequestURL(tmfs.getUrl(), "GetCapabilities", version, null)
            .toURL());

    ServiceAuthentication authentication = tmfs.getAuthentication();
    if (authentication != null) {
      if (authentication.getMethod() != ServiceAuthentication.MethodEnum.PASSWORD) {
        throw new IllegalArgumentException(authentication.getMethod().getValue());
      }
      params.put(WFSDataStoreFactory.USERNAME.key, authentication.getUsername());
      params.put(WFSDataStoreFactory.PASSWORD.key, authentication.getPassword());
    }
    return openDatastore(params, WFSDataStoreFactory.PASSWORD.key);
  }

  @Override
  protected TMFeatureTypeInfo getFeatureTypeInfo(TMFeatureType pft, ResourceInfo info, SimpleFeatureSource gtFs) {
    TMFeatureTypeInfo tmInfo = super.getFeatureTypeInfo(pft, info, gtFs);
    if (info instanceof FeatureTypeInfo ftInfo) {
      tmInfo.schema(info.getSchema())
          .wgs84BoundingBox(GeoToolsHelper.fromEnvelope(ftInfo.getWGS84BoundingBox()))
          .defaultSrs(ftInfo.getDefaultSRS())
          .otherSrs(Set.copyOf(ftInfo.getOtherSRS()))
          .outputFormats(ftInfo.getOutputFormats())
          .abstractText(ftInfo.getAbstract());
    }
    return tmInfo;
  }
}