View Javadoc
1   /*
2    * Copyright (C) 2022 B3Partners B.V.
3    *
4    * SPDX-License-Identifier: MIT
5    */
6   package org.tailormap.api.geotools.featuresources;
7   
8   import static org.geotools.data.sqlserver.SQLServerDataStoreFactory.GEOMETRY_METADATA_TABLE;
9   import static org.geotools.jdbc.JDBCDataStoreFactory.DATABASE;
10  import static org.geotools.jdbc.JDBCDataStoreFactory.DBTYPE;
11  import static org.geotools.jdbc.JDBCDataStoreFactory.EXPOSE_PK;
12  import static org.geotools.jdbc.JDBCDataStoreFactory.FETCHSIZE;
13  import static org.geotools.jdbc.JDBCDataStoreFactory.HOST;
14  import static org.geotools.jdbc.JDBCDataStoreFactory.MAXWAIT;
15  import static org.geotools.jdbc.JDBCDataStoreFactory.PASSWD;
16  import static org.geotools.jdbc.JDBCDataStoreFactory.PK_METADATA_TABLE;
17  import static org.geotools.jdbc.JDBCDataStoreFactory.PORT;
18  import static org.geotools.jdbc.JDBCDataStoreFactory.SCHEMA;
19  import static org.geotools.jdbc.JDBCDataStoreFactory.USER;
20  
21  import java.io.IOException;
22  import java.util.HashMap;
23  import java.util.Map;
24  import java.util.Objects;
25  import java.util.Optional;
26  import org.geotools.api.data.DataStore;
27  import org.tailormap.api.persistence.TMFeatureSource;
28  import org.tailormap.api.persistence.json.JDBCConnectionProperties;
29  import org.tailormap.api.persistence.json.ServiceAuthentication;
30  
31  public class JDBCFeatureSourceHelper extends FeatureSourceHelper {
32    private static final Map<JDBCConnectionProperties.DbtypeEnum, Integer> defaultPorts =
33        Map.of(
34            JDBCConnectionProperties.DbtypeEnum.POSTGIS, 5432,
35            JDBCConnectionProperties.DbtypeEnum.ORACLE, 1521,
36            JDBCConnectionProperties.DbtypeEnum.SQLSERVER, 1433);
37  
38    @Override
39    public DataStore createDataStore(TMFeatureSource tmfs, Integer timeout) throws IOException {
40      if (tmfs.getProtocol() != TMFeatureSource.Protocol.JDBC) {
41        throw new IllegalArgumentException(tmfs.getProtocol().getValue());
42      }
43      Objects.requireNonNull(tmfs.getJdbcConnection());
44      Objects.requireNonNull(tmfs.getAuthentication());
45      if (tmfs.getAuthentication().getMethod() != ServiceAuthentication.MethodEnum.PASSWORD) {
46        throw new IllegalArgumentException(tmfs.getAuthentication().getMethod().getValue());
47      }
48  
49      JDBCConnectionProperties c = tmfs.getJdbcConnection();
50      Objects.requireNonNull(c.getDbtype());
51      String connectionOpts =
52          Optional.ofNullable(c.getAdditionalProperties().get("connectionOptions")).orElse("");
53      if (c.getDbtype() == JDBCConnectionProperties.DbtypeEnum.POSTGIS
54          && !connectionOpts.contains("ApplicationName")) {
55        connectionOpts =
56            connectionOpts
57                + (connectionOpts.contains("?") ? "&amp;" : "?")
58                + "ApplicationName=tailormap-api";
59      }
60  
61      Map<String, Object> params = new HashMap<>();
62      params.put(DBTYPE.key, c.getDbtype().getValue());
63      params.put(HOST.key, c.getHost());
64      params.put(PORT.key, c.getPort() != null ? c.getPort() : defaultPorts.get(c.getDbtype()));
65      params.put(DATABASE.key, c.getDatabase() + connectionOpts);
66      params.put(SCHEMA.key, c.getSchema());
67      params.put(USER.key, tmfs.getAuthentication().getUsername());
68      params.put(PASSWD.key, tmfs.getAuthentication().getPassword());
69      params.put(FETCHSIZE.key, c.getFetchSize());
70      params.put(EXPOSE_PK.key, true);
71      params.put(PK_METADATA_TABLE.key, c.getPrimaryKeyMetadataTable());
72      params.put(MAXWAIT.key, timeout);
73      if (c.getDbtype() != JDBCConnectionProperties.DbtypeEnum.ORACLE) {
74        // this key is available in ao. Oracle and MS SQL datastore factories, but not in the common
75        // parent...
76        // we need this for mssql to determine a feature type on an empty table
77        params.put(GEOMETRY_METADATA_TABLE.key, "geometry_columns");
78      }
79      return openDatastore(params, PASSWD.key);
80    }
81  }