From c9ce72c1bed50dcccdaebb31069b648f4db7b40e Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Wed, 27 Aug 2025 17:44:16 +0200 Subject: [PATCH 01/19] enhance AutoHandler to support cfg generation from existing entity --- .../de/ii/xtraplatform/cli/AutoHandler.java | 682 +++++++++++------- .../java/de/ii/xtraplatform/cli/cmd/Auto.java | 5 +- 2 files changed, 420 insertions(+), 267 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index ac03ba4..3f3ce13 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -13,307 +13,457 @@ import de.ii.xtraplatform.features.sql.domain.ConnectionInfoSql; import de.ii.xtraplatform.features.sql.domain.ImmutableFeatureProviderSqlData; import de.ii.xtraplatform.values.domain.Identifier; + import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.function.Consumer; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.Map; +import java.io.File; + public class AutoHandler { + public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { + if (Objects.isNull(ldproxyCfg)) { + return Result.failure("Not connected to store"); + } - public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { - if (Objects.isNull(ldproxyCfg)) { - return Result.failure("Not connected to store"); - } + ldproxyCfg.initStore(); - ldproxyCfg.initStore(); + if (!parameters.containsKey("id")) { + return Result.failure("No id given"); + } - if (!parameters.containsKey("id")) { - return Result.failure("No id given"); - } + String id = parameters.get("id"); - String id = parameters.get("id"); + if (id.length() < 3) { + return Result.failure("Id has to be at least 3 characters long"); + } - if (id.length() < 3) { - return Result.failure("Id has to be at least 3 characters long"); - } + Identifier identifier = Identifier.from(id, "providers"); + + if (ldproxyCfg.getEntityDataStore().has(identifier)) { + return Result.failure("A provider with id '" + id + "' already exists"); + } + + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("PGIS") + && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { + return Result.failure("Host is required for PGIS connection"); + } - Identifier identifier = Identifier.from(id, "providers"); + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("WFS")) { + if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { + return Result.failure("URL is required for WFS connection"); + } + try { + URI uri = URI.create(parameters.get("url")); + if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { + return Result.failure("Invalid URL scheme for WFS connection"); + } + } catch (IllegalArgumentException e) { + return Result.failure("Invalid URL for WFS connection"); + } + } - if (ldproxyCfg.getEntityDataStore().has(identifier)) { - return Result.failure("A provider with id '" + id + "' already exists"); + return Result.empty(); } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("PGIS") - && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { - return Result.failure("Host is required for PGIS connection"); + public static Result check( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + + // TODO: check connectionInfo + + return Result.ok("All good"); } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("WFS")) { - if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { - return Result.failure("URL is required for WFS connection"); - } - try { - URI uri = URI.create(parameters.get("url")); - if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { - return Result.failure("Invalid URL scheme for WFS connection"); + public static Result analyze( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + Result result = new Result(); + + try { + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + Map> types = autoFactory.analyze(featureProvider); + + result.success("All good"); + result.details("types", types); + } catch (Throwable e) { + e.printStackTrace(); + if (e instanceof RuntimeException + && Objects.nonNull(e.getCause()) + && Objects.nonNull(e.getCause().getMessage())) { + result.error(e.getCause().getMessage()); + } else if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } } - } catch (IllegalArgumentException e) { - return Result.failure("Invalid URL for WFS connection"); - } + + return result; } - return Result.empty(); - } - - public static Result check( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - - // TODO: check connectionInfo - - return Result.ok("All good"); - } - - public static Result analyze( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - Result result = new Result(); - - try { - FeatureProviderDataV2 featureProvider = - parseFeatureProvider(parameters, ldproxyCfg, Map.of()); - - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - Map> types = autoFactory.analyze(featureProvider); - - result.success("All good"); - result.details("types", types); - } catch (Throwable e) { - e.printStackTrace(); - if (e instanceof RuntimeException - && Objects.nonNull(e.getCause()) - && Objects.nonNull(e.getCause().getMessage())) { - result.error(e.getCause().getMessage()); - } else if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + public static Result generate( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug, + Map> types, + Consumer tracker) { + Result result = new Result(); + + System.out.println("Initial types: " + types); + + if (types == null || types.isEmpty()) { + try { + String selectedConfig = parameters.get("selectedConfig"); + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + + Map cfgJava = ldproxyCfg.getObjectMapper().readValue( + new File(selectedConfig), + Map.class + ); + + Map featureProviderTypeAndTypes = determineFeatureProviderTypeAndTypes(parameters, cfgJava); + types = (Map>) featureProviderTypeAndTypes.get("types"); + } catch (IOException e) { + e.printStackTrace(); + return Result.failure("Failed to read YAML file: " + e.getMessage()); + } + } + + System.out.println("New types: " + types); + + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + long count = types.values().stream().mapToLong(List::size).sum(); + + Consumer>> tracker2 = + progress -> { + long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); + String currentTable = + progress.entrySet().stream() + .skip(progress.size() - 1) + .map( + entry -> + entry.getKey() + + "." + + entry.getValue().get(entry.getValue().size() - 1)) + .findFirst() + .orElse("???"); + + System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); + + Map details = + Map.of( + "currentCount", + current, + "targetCount", + count, + "currentTable", + currentTable, + "progress", + progress); + + tracker.accept(Result.ok("progress", details)); + }; + FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); + + Map typeObject = parseTypeObject(parameters.get("typeObject")); + + try { + if (typeObject.getOrDefault("provider", true)) { + ldproxyCfg.writeEntity(entityData); + + result.details( + "new_provider_files", + List.of( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString())); + } + + // generate service + if (typeObject.getOrDefault("service", true)) { + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + + // get from provider-configuration as well? + Map> types2 = + Map.of("", new ArrayList<>(entityData.getTypes().keySet())); + + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} + + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { + }); + + ldproxyCfg.writeEntity(entityData2); + + result.details( + "new_service_files", + List.of( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString())); + } + + result.success("All good"); + } catch (Throwable e) { + e.printStackTrace(); + if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } + } + return result; } - return result; - } - - public static Result generate( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug, - Map> types, - Consumer tracker) { - Result result = new Result(); - - try { - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); - - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - long count = types.values().stream().mapToLong(List::size).sum(); - - Consumer>> tracker2 = - progress -> { - long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); - String currentTable = - progress.entrySet().stream() - .skip(progress.size() - 1) - .map( - entry -> - entry.getKey() - + "." - + entry.getValue().get(entry.getValue().size() - 1)) - .findFirst() - .orElse("???"); - - System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - - Map details = - Map.of( - "currentCount", - current, - "targetCount", - count, - "currentTable", - currentTable, - "progress", - progress); - - tracker.accept(Result.ok("progress", details)); - }; - - FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - - ldproxyCfg.writeEntity(entityData); - - // generate service - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - - Map> types2 = - Map.of("", new ArrayList<>(entityData.getTypes().keySet())); - - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> {}); - - ldproxyCfg.writeEntity(entityData2); - - result.success("All good"); - result.details( - "new_files", - List.of( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString(), - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString())); - } catch (Throwable e) { - e.printStackTrace(); - if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + private static AutoEntityFactory getAutoFactory( + LdproxyCfg ldproxyCfg, String type, Optional subType) { + EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); + + AutoEntityFactory autoFactory = + factory + .auto() + .orElseThrow( + () -> + new IllegalArgumentException( + "No auto factory found for entity type " + factory.fullType())); + return autoFactory; } - return result; - } - - private static AutoEntityFactory getAutoFactory( - LdproxyCfg ldproxyCfg, String type, Optional subType) { - EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); - - AutoEntityFactory autoFactory = - factory - .auto() - .orElseThrow( - () -> - new IllegalArgumentException( - "No auto factory found for entity type " + factory.fullType())); - return autoFactory; - } - - private static FeatureProviderDataV2 parseFeatureProvider( - Map parameters, LdproxyCfg ldproxyCfg, Map> types) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); + private static FeatureProviderDataV2 parseFeatureProvider( + Map parameters, LdproxyCfg ldproxyCfg, Map> types) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } + + String id = parameters.get("id"); + + String featureProviderTypeString = parameters.get("featureProviderType"); + + if (featureProviderTypeString == null || featureProviderTypeString.isBlank()) { + featureProviderTypeString = "UNKNOWN"; + } + + FeatureProviderType featureProviderType; + try { + featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid featureProviderType: " + featureProviderTypeString + ". Expected one of: " + + Arrays.toString(FeatureProviderType.values()), e); + } + + if (featureProviderType == FeatureProviderType.UNKNOWN) { + try { + String selectedConfig = parameters.get("selectedConfig"); + if (selectedConfig == null || selectedConfig.isBlank()) { + throw new IllegalArgumentException("No selectedConfig provided in parameters"); + } + + Map cfgJava = ldproxyCfg.getObjectMapper().readValue( + new File(selectedConfig), + Map.class + ); + + Map featureProviderTypeAndTypes = determineFeatureProviderTypeAndTypes(parameters, cfgJava); + String featureProviderTypeString2 = (String) featureProviderTypeAndTypes.get("featureProviderType"); + System.out.println("initial featureProviderTypeString: " + featureProviderTypeString2); + try { + featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString2); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid featureProviderType: " + featureProviderTypeString + ". Expected one of: " + + Arrays.toString(FeatureProviderType.values()), e); + } + + } catch (IOException e) { + throw new IllegalArgumentException( + "Unknown featureProviderType: " + parameters.get("featureProviderType")); + } + } + + System.out.println("new featureProviderType: " + featureProviderType); + + FeatureProviderDataV2.Builder builder = + AutoTypes.getBuilder( + ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) + .id(id); + + switch (featureProviderType) { + case PGIS: + return parseFeatureProviderPgis( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); + case GPKG: + return parseFeatureProviderGpkg( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters); + case WFS: + return parseFeatureProviderWfs( + (ImmutableFeatureProviderWfsData.Builder) builder, parameters); + } + + return builder.build(); } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + + private static FeatureProviderDataV2 parseFeatureProviderPgis( + ImmutableFeatureProviderSqlData.Builder builder, + Map parameters, + Map> types) { + Set schemas = types.keySet(); + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.PGIS.name()) + .host(Optional.ofNullable(parameters.get("host"))) + .database(parameters.get("database")) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) + .schemas(schemas) + .poolBuilder(); + + return builder.build(); } - String id = parameters.get("id"); + private static FeatureProviderDataV2 parseFeatureProviderGpkg( + ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { - FeatureProviderType featureProviderType = - FeatureProviderType.valueOf(parameters.get("featureProviderType")); + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.GPKG.name()) + .database(parameters.get("database")) + .poolBuilder(); - if (featureProviderType == FeatureProviderType.UNKNOWN) { - throw new IllegalArgumentException( - "Unknown featureProviderType: " + parameters.get("featureProviderType")); + return builder.build(); } - FeatureProviderDataV2.Builder builder = - AutoTypes.getBuilder( - ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) - .id(id); - - switch (featureProviderType) { - case PGIS: - return parseFeatureProviderPgis( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); - case GPKG: - return parseFeatureProviderGpkg( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters); - case WFS: - return parseFeatureProviderWfs( - (ImmutableFeatureProviderWfsData.Builder) builder, parameters); + private static FeatureProviderDataV2 parseFeatureProviderWfs( + ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { + + builder + .connectionInfoBuilder() + .uri(URI.create(parameters.get("url"))) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map( + pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); + return builder.build(); } - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderPgis( - ImmutableFeatureProviderSqlData.Builder builder, - Map parameters, - Map> types) { - Set schemas = types.keySet(); - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.PGIS.name()) - .host(Optional.ofNullable(parameters.get("host"))) - .database(parameters.get("database")) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) - .schemas(schemas) - .poolBuilder(); - - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderGpkg( - ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.GPKG.name()) - .database(parameters.get("database")) - .poolBuilder(); - - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderWfs( - ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { - - builder - .connectionInfoBuilder() - .uri(URI.create(parameters.get("url"))) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map( - pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); - return builder.build(); - } - - private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } + + String id = parameters.get("id"); + + OgcApiDataV2.Builder builder = + AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + + return builder.build(); } - String id = parameters.get("id"); + private static Map determineFeatureProviderTypeAndTypes( + Map parameters, Map yamlConfig) { + + Map result = new HashMap<>(); + + // Determine featureProviderType + String featureProviderType = parameters.getOrDefault("featureProviderType", "").trim(); + if (featureProviderType.isEmpty()) { + String providerSubType = (String) yamlConfig.getOrDefault("providerSubType", ""); + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + String dialect = (connectionInfo != null && connectionInfo.containsKey("dialect")) + ? (String) connectionInfo.get("dialect") + : ""; + + if ("GPKG".equalsIgnoreCase(dialect)) { + featureProviderType = "GPKG"; + } else if ("WFS".equalsIgnoreCase(providerSubType)) { + featureProviderType = "WFS"; + } else { + featureProviderType = "PGIS"; + } + } + result.put("featureProviderType", featureProviderType); + + // Extract types + Map yamlTypes = (Map) yamlConfig.get("types"); + Map> extractedTypes = new HashMap<>(); + + if (yamlTypes != null) { + for (Map.Entry entry : yamlTypes.entrySet()) { + String key = entry.getKey(); + Map typeDetails = (Map) entry.getValue(); + String sourcePath = (String) typeDetails.get("sourcePath"); + + if (sourcePath != null) { + sourcePath = sourcePath.startsWith("/") ? sourcePath.substring(1) : sourcePath; + + String namespace = sourcePath.contains(":") ? sourcePath.split(":")[0] : ""; + String value = sourcePath.contains(":") ? sourcePath.split(":")[1] : sourcePath; + extractedTypes.computeIfAbsent(namespace, k -> new ArrayList<>()).add(value); + } + } + } + + // Handle missing types + if (extractedTypes.isEmpty()) { + extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); + } + + result.put("types", extractedTypes); - OgcApiDataV2.Builder builder = - AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + return result; + } - return builder.build(); - } + private static Map parseTypeObject(String typeObjectString) { + Map typeObject = new HashMap<>(); + if (typeObjectString != null && !typeObjectString.isBlank()) { + typeObjectString = typeObjectString.replace("{", "").replace("}", ""); + String[] entries = typeObjectString.split(","); + for (String entry : entries) { + String[] keyValue = entry.split("="); + if (keyValue.length == 2) { + typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + } + } + } + return typeObject; + } } + diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java index a699e23..ab26b7e 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java @@ -30,7 +30,10 @@ public Auto( this.path = optionalString(parameters, "path"); this.parameters = stringMap( - parameters, "id", "featureProviderType", "host", "database", "user", "password", "url"); + parameters, "id", "featureProviderType", "host", "database", "user", "password", "url", "selectedConfig"); + if (parameters.containsKey("typeObject") && parameters.get("typeObject") instanceof Map) { + this.parameters.put("typeObject", parameters.get("typeObject").toString()); + } this.types = parseTypes(parameters); this.tracker = tracker; } From 7fb911a2445bc8f6f625db1fb230dd8f3eab5858 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Thu, 28 Aug 2025 09:30:57 +0200 Subject: [PATCH 02/19] if featureProviderType is WFS, extract the URI and set it in parameters --- .../java/de/ii/xtraplatform/cli/AutoHandler.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 3f3ce13..15b0663 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -129,6 +129,7 @@ public static Result generate( Consumer tracker) { Result result = new Result(); + System.out.println("myParameters: " + parameters); System.out.println("Initial types: " + types); if (types == null || types.isEmpty()) { @@ -193,6 +194,8 @@ public static Result generate( Map typeObject = parseTypeObject(parameters.get("typeObject")); + System.out.println("typeObject: " + typeObject); + try { if (typeObject.getOrDefault("provider", true)) { ldproxyCfg.writeEntity(entityData); @@ -213,7 +216,7 @@ public static Result generate( AutoEntityFactory autoFactory2 = getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - // get from provider-configuration as well? + // get from provider-configuration as well? Seems to work just fine Map> types2 = Map.of("", new ArrayList<>(entityData.getTypes().keySet())); @@ -370,6 +373,8 @@ private static FeatureProviderDataV2 parseFeatureProviderGpkg( private static FeatureProviderDataV2 parseFeatureProviderWfs( ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { + System.out.println("WFS parameters: " + parameters); + builder .connectionInfoBuilder() .uri(URI.create(parameters.get("url"))) @@ -421,6 +426,15 @@ private static Map determineFeatureProviderTypeAndTypes( } result.put("featureProviderType", featureProviderType); + // If featureProviderType is WFS, extract the URI and set it in parameters + if ("WFS".equalsIgnoreCase(featureProviderType)) { + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + if (connectionInfo != null && connectionInfo.containsKey("uri")) { + String uri = (String) connectionInfo.get("uri"); + parameters.put("url", uri); + } + } + // Extract types Map yamlTypes = (Map) yamlConfig.get("types"); Map> extractedTypes = new HashMap<>(); From a3c64195ee0bd19f1af2851e244c33776fe8911d Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Thu, 28 Aug 2025 10:19:14 +0200 Subject: [PATCH 03/19] refactor featureProviderType handling in AutoHandler --- .../de/ii/xtraplatform/cli/AutoHandler.java | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 15b0663..91d8725 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -273,10 +273,6 @@ private static FeatureProviderDataV2 parseFeatureProvider( String featureProviderTypeString = parameters.get("featureProviderType"); - if (featureProviderTypeString == null || featureProviderTypeString.isBlank()) { - featureProviderTypeString = "UNKNOWN"; - } - FeatureProviderType featureProviderType; try { featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); @@ -286,35 +282,6 @@ private static FeatureProviderDataV2 parseFeatureProvider( + Arrays.toString(FeatureProviderType.values()), e); } - if (featureProviderType == FeatureProviderType.UNKNOWN) { - try { - String selectedConfig = parameters.get("selectedConfig"); - if (selectedConfig == null || selectedConfig.isBlank()) { - throw new IllegalArgumentException("No selectedConfig provided in parameters"); - } - - Map cfgJava = ldproxyCfg.getObjectMapper().readValue( - new File(selectedConfig), - Map.class - ); - - Map featureProviderTypeAndTypes = determineFeatureProviderTypeAndTypes(parameters, cfgJava); - String featureProviderTypeString2 = (String) featureProviderTypeAndTypes.get("featureProviderType"); - System.out.println("initial featureProviderTypeString: " + featureProviderTypeString2); - try { - featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString2); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - "Invalid featureProviderType: " + featureProviderTypeString + ". Expected one of: " - + Arrays.toString(FeatureProviderType.values()), e); - } - - } catch (IOException e) { - throw new IllegalArgumentException( - "Unknown featureProviderType: " + parameters.get("featureProviderType")); - } - } - System.out.println("new featureProviderType: " + featureProviderType); FeatureProviderDataV2.Builder builder = @@ -424,6 +391,8 @@ private static Map determineFeatureProviderTypeAndTypes( featureProviderType = "PGIS"; } } + parameters.put("featureProviderType", featureProviderType); + result.put("featureProviderType", featureProviderType); // If featureProviderType is WFS, extract the URI and set it in parameters From 3774999d69376d75897b0c3462466d336c1fae1a Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Thu, 28 Aug 2025 11:36:27 +0200 Subject: [PATCH 04/19] if featureProviderType is PGIS, set additional parameters --- .../de/ii/xtraplatform/cli/AutoHandler.java | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 91d8725..774719d 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -129,7 +129,6 @@ public static Result generate( Consumer tracker) { Result result = new Result(); - System.out.println("myParameters: " + parameters); System.out.println("Initial types: " + types); if (types == null || types.isEmpty()) { @@ -144,7 +143,7 @@ public static Result generate( Map.class ); - Map featureProviderTypeAndTypes = determineFeatureProviderTypeAndTypes(parameters, cfgJava); + Map featureProviderTypeAndTypes = determineMissingParameters(parameters, cfgJava); types = (Map>) featureProviderTypeAndTypes.get("types"); } catch (IOException e) { e.printStackTrace(); @@ -196,6 +195,7 @@ public static Result generate( System.out.println("typeObject: " + typeObject); + try { if (typeObject.getOrDefault("provider", true)) { ldproxyCfg.writeEntity(entityData); @@ -283,6 +283,7 @@ private static FeatureProviderDataV2 parseFeatureProvider( } System.out.println("new featureProviderType: " + featureProviderType); + System.out.println("myParameters: " + parameters); FeatureProviderDataV2.Builder builder = AutoTypes.getBuilder( @@ -369,7 +370,7 @@ private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyC return builder.build(); } - private static Map determineFeatureProviderTypeAndTypes( + private static Map determineMissingParameters( Map parameters, Map yamlConfig) { Map result = new HashMap<>(); @@ -393,8 +394,6 @@ private static Map determineFeatureProviderTypeAndTypes( } parameters.put("featureProviderType", featureProviderType); - result.put("featureProviderType", featureProviderType); - // If featureProviderType is WFS, extract the URI and set it in parameters if ("WFS".equalsIgnoreCase(featureProviderType)) { Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); @@ -404,6 +403,21 @@ private static Map determineFeatureProviderTypeAndTypes( } } + // If featureProviderType is PGIS, set additional parameters + if ("PGIS".equalsIgnoreCase(featureProviderType)) { + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + if (connectionInfo != null) { + parameters.put("host", (String) connectionInfo.getOrDefault("host", "")); + parameters.put("database", (String) connectionInfo.getOrDefault("database", "")); + parameters.put("user", (String) connectionInfo.getOrDefault("user", "")); + String encodedPassword = (String) connectionInfo.getOrDefault("password", ""); + if (!encodedPassword.isBlank()) { + String decodedPassword = new String(Base64.getDecoder().decode(encodedPassword), StandardCharsets.UTF_8); + parameters.put("password", decodedPassword); + } + } + } + // Extract types Map yamlTypes = (Map) yamlConfig.get("types"); Map> extractedTypes = new HashMap<>(); From ff4b74f7c106c41a3120956fb4d52ec8fcfb9ae3 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Thu, 28 Aug 2025 13:08:49 +0200 Subject: [PATCH 05/19] refactor entity writing and result details logic --- .../de/ii/xtraplatform/cli/AutoHandler.java | 68 +++++++++++-------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 774719d..b040122 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -187,56 +187,66 @@ public static Result generate( "progress", progress); + System.out.println("details: " + details); tracker.accept(Result.ok("progress", details)); }; FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + + // get from provider-configuration as well? Seems to work just fine + Map> types2 = + Map.of("", new ArrayList<>(entityData.getTypes().keySet())); + + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} + + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { + }); + Map typeObject = parseTypeObject(parameters.get("typeObject")); System.out.println("typeObject: " + typeObject); try { + boolean providerWritten = false; + boolean serviceWritten = false; + if (typeObject.getOrDefault("provider", true)) { ldproxyCfg.writeEntity(entityData); - - result.details( - "new_provider_files", - List.of( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString())); + providerWritten = true; } // generate service if (typeObject.getOrDefault("service", true)) { - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - - // get from provider-configuration as well? Seems to work just fine - Map> types2 = - Map.of("", new ArrayList<>(entityData.getTypes().keySet())); - - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { - }); - ldproxyCfg.writeEntity(entityData2); + serviceWritten = true; + } - result.details( - "new_service_files", - List.of( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString())); + List newFiles = new ArrayList<>(); + if (providerWritten) { + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } + if (serviceWritten) { + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString()); } + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } result.success("All good"); + } catch (Throwable e) { e.printStackTrace(); if (Objects.nonNull(e.getMessage())) { From 4c31f97d63d01aace8f39f761cd2616594fd8da2 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Thu, 28 Aug 2025 15:39:46 +0200 Subject: [PATCH 06/19] add config copy functionality to AutoHandler --- .../de/ii/xtraplatform/cli/AutoHandler.java | 204 ++++++++++-------- .../java/de/ii/xtraplatform/cli/cmd/Auto.java | 2 +- 2 files changed, 118 insertions(+), 88 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index b040122..5e58d06 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -131,9 +131,39 @@ public static Result generate( System.out.println("Initial types: " + types); - if (types == null || types.isEmpty()) { - try { - String selectedConfig = parameters.get("selectedConfig"); + try { + String createOption = parameters.get("createOption"); + String selectedConfig = parameters.get("selectedConfig"); + String newId = parameters.get("id"); + + if ("copy".equalsIgnoreCase(createOption)) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } + + File sourceFile = new File(selectedConfig); + if (!sourceFile.exists()) { + return Result.failure("Selected config file does not exist: " + selectedConfig); + } + + Map yamlContent = ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); + + if (yamlContent.containsKey("id")) { + yamlContent.put("id", newId); + } + + File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yaml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); + + result.success("Config copied successfully"); + result.details("new_files", List.of(targetFile.getPath())); + return result; + } + + if (types == null || types.isEmpty()) { if (selectedConfig == null || selectedConfig.isBlank()) { return Result.failure("No selectedConfig provided in parameters"); } @@ -145,115 +175,115 @@ public static Result generate( Map featureProviderTypeAndTypes = determineMissingParameters(parameters, cfgJava); types = (Map>) featureProviderTypeAndTypes.get("types"); - } catch (IOException e) { - e.printStackTrace(); - return Result.failure("Failed to read YAML file: " + e.getMessage()); } - } - System.out.println("New types: " + types); + System.out.println("New types: " + types); - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - long count = types.values().stream().mapToLong(List::size).sum(); + long count = types.values().stream().mapToLong(List::size).sum(); - Consumer>> tracker2 = - progress -> { - long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); - String currentTable = - progress.entrySet().stream() - .skip(progress.size() - 1) - .map( - entry -> - entry.getKey() - + "." - + entry.getValue().get(entry.getValue().size() - 1)) - .findFirst() - .orElse("???"); + Consumer>> tracker2 = + progress -> { + long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); + String currentTable = + progress.entrySet().stream() + .skip(progress.size() - 1) + .map( + entry -> + entry.getKey() + + "." + + entry.getValue().get(entry.getValue().size() - 1)) + .findFirst() + .orElse("???"); - System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); + System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - Map details = - Map.of( - "currentCount", - current, - "targetCount", - count, - "currentTable", - currentTable, - "progress", - progress); + Map details = + Map.of( + "currentCount", + current, + "targetCount", + count, + "currentTable", + currentTable, + "progress", + progress); - System.out.println("details: " + details); - tracker.accept(Result.ok("progress", details)); - }; - FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); + System.out.println("details: " + details); + tracker.accept(Result.ok("progress", details)); + }; + FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - // get from provider-configuration as well? Seems to work just fine - Map> types2 = - Map.of("", new ArrayList<>(entityData.getTypes().keySet())); + // get from provider-configuration as well? Seems to work just fine + Map> types2 = + Map.of("", new ArrayList<>(entityData.getTypes().keySet())); - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { - }); + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { + }); - Map typeObject = parseTypeObject(parameters.get("typeObject")); + Map typeObject = parseTypeObject(parameters.get("typeObject")); - System.out.println("typeObject: " + typeObject); + System.out.println("typeObject: " + typeObject); - try { - boolean providerWritten = false; - boolean serviceWritten = false; + try { + boolean providerWritten = false; + boolean serviceWritten = false; - if (typeObject.getOrDefault("provider", true)) { - ldproxyCfg.writeEntity(entityData); - providerWritten = true; - } + if (typeObject.getOrDefault("provider", true)) { + ldproxyCfg.writeEntity(entityData); + providerWritten = true; + } - // generate service - if (typeObject.getOrDefault("service", true)) { - ldproxyCfg.writeEntity(entityData2); - serviceWritten = true; - } + // generate service + if (typeObject.getOrDefault("service", true)) { + ldproxyCfg.writeEntity(entityData2); + serviceWritten = true; + } - List newFiles = new ArrayList<>(); - if (providerWritten) { - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); - } - if (serviceWritten) { - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString()); - } + List newFiles = new ArrayList<>(); + if (providerWritten) { + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } + if (serviceWritten) { + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString()); + } - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); - } - result.success("All good"); + result.success("All good"); + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + } catch (Throwable e) { + e.printStackTrace(); + if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } + } + return result; } catch (Throwable e) { e.printStackTrace(); - if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + return Result.failure("Unexpected error: " + e.getMessage()); } - return result; } private static AutoEntityFactory getAutoFactory( diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java index ab26b7e..25b02a4 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java @@ -30,7 +30,7 @@ public Auto( this.path = optionalString(parameters, "path"); this.parameters = stringMap( - parameters, "id", "featureProviderType", "host", "database", "user", "password", "url", "selectedConfig"); + parameters, "id", "featureProviderType", "host", "database", "user", "password", "url", "selectedConfig", "createOption"); if (parameters.containsKey("typeObject") && parameters.get("typeObject") instanceof Map) { this.parameters.put("typeObject", parameters.get("typeObject").toString()); } From 33995ab9536fae58b60b3705ccc3b59cd79fbb6a Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Thu, 28 Aug 2025 16:27:43 +0200 Subject: [PATCH 07/19] implement generateBasicEntity for creating cfg from scratch --- .../de/ii/xtraplatform/cli/AutoHandler.java | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 5e58d06..682653e 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -136,6 +136,10 @@ public static Result generate( String selectedConfig = parameters.get("selectedConfig"); String newId = parameters.get("id"); + if ("fromScratch".equalsIgnoreCase(createOption)) { + return generateBasicEntity(parameters, ldproxyCfg); + } + if ("copy".equalsIgnoreCase(createOption)) { if (selectedConfig == null || selectedConfig.isBlank()) { return Result.failure("No selectedConfig provided in parameters"); @@ -155,7 +159,7 @@ public static Result generate( yamlContent.put("id", newId); } - File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yaml"); + File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); result.success("Config copied successfully"); @@ -502,5 +506,32 @@ private static Map parseTypeObject(String typeObjectString) { } return typeObject; } -} + private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg) { + Result result = new Result(); + + if (parameters.containsKey("id")) { + String newId = parameters.get("id"); + + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } + + Map minimalConfig = new HashMap<>(); + minimalConfig.put("id", newId); + minimalConfig.put("enabled", true); + + try { + File targetFile = new File(ldproxyCfg.getDataDirectory().toFile(), "entities/instances/providers/" + newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, minimalConfig); + + result.success("Minimal config created successfully"); + result.details("new_files", List.of(targetFile.getPath())); + } catch (IOException e) { + return Result.failure("Failed to write minimal config: " + e.getMessage()); + } + } + + return result; + } +} \ No newline at end of file From 8cd888b80025fa09e4f20f83c1208d0bbcc0c46b Mon Sep 17 00:00:00 2001 From: Andreas Zahnen Date: Fri, 29 Aug 2025 09:58:36 +0200 Subject: [PATCH 08/19] generate tile providers --- libxtracfg/java/build.gradle | 2 +- .../de/ii/xtraplatform/cli/AutoHandler.java | 941 +++++++++--------- .../de/ii/xtraplatform/cli/AutoTypes.java | 22 + 3 files changed, 510 insertions(+), 455 deletions(-) diff --git a/libxtracfg/java/build.gradle b/libxtracfg/java/build.gradle index f0b0ea6..b32ab87 100644 --- a/libxtracfg/java/build.gradle +++ b/libxtracfg/java/build.gradle @@ -27,7 +27,7 @@ repositories { } dependencies { - implementation group: 'de.interactive_instruments', name: 'ldproxy-cfg', version: '4.5.0-SNAPSHOT' + implementation group: 'de.interactive_instruments', name: 'ldproxy-cfg', version: '4.5.0-editorv2-SNAPSHOT' implementation group: 'org.slf4j', name: isCi ? 'slf4j-nop' : 'slf4j-simple', version: '2.0.16' // 24.x is for JDK 21 diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 682653e..c0d95f7 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -12,526 +12,559 @@ import de.ii.xtraplatform.features.gml.domain.ImmutableFeatureProviderWfsData; import de.ii.xtraplatform.features.sql.domain.ConnectionInfoSql; import de.ii.xtraplatform.features.sql.domain.ImmutableFeatureProviderSqlData; +import de.ii.xtraplatform.tiles.domain.TileProviderFeaturesData; import de.ii.xtraplatform.values.domain.Identifier; - +import java.io.File; +import java.io.IOException; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.*; -import java.util.function.Consumer; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; import java.util.Map; -import java.io.File; - +import java.util.function.Consumer; public class AutoHandler { - public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { - if (Objects.isNull(ldproxyCfg)) { - return Result.failure("Not connected to store"); - } + public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { + if (Objects.isNull(ldproxyCfg)) { + return Result.failure("Not connected to store"); + } - ldproxyCfg.initStore(); + ldproxyCfg.initStore(); - if (!parameters.containsKey("id")) { - return Result.failure("No id given"); - } + if (!parameters.containsKey("id")) { + return Result.failure("No id given"); + } - String id = parameters.get("id"); + String id = parameters.get("id"); - if (id.length() < 3) { - return Result.failure("Id has to be at least 3 characters long"); - } + if (id.length() < 3) { + return Result.failure("Id has to be at least 3 characters long"); + } - Identifier identifier = Identifier.from(id, "providers"); + Identifier identifier = Identifier.from(id, "providers"); - if (ldproxyCfg.getEntityDataStore().has(identifier)) { - return Result.failure("A provider with id '" + id + "' already exists"); - } + if (ldproxyCfg.getEntityDataStore().has(identifier)) { + return Result.failure("A provider with id '" + id + "' already exists"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("PGIS") - && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { - return Result.failure("Host is required for PGIS connection"); - } + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("PGIS") + && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { + return Result.failure("Host is required for PGIS connection"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("WFS")) { - if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { - return Result.failure("URL is required for WFS connection"); - } - try { - URI uri = URI.create(parameters.get("url")); - if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { - return Result.failure("Invalid URL scheme for WFS connection"); - } - } catch (IllegalArgumentException e) { - return Result.failure("Invalid URL for WFS connection"); - } + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("WFS")) { + if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { + return Result.failure("URL is required for WFS connection"); + } + try { + URI uri = URI.create(parameters.get("url")); + if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { + return Result.failure("Invalid URL scheme for WFS connection"); } + } catch (IllegalArgumentException e) { + return Result.failure("Invalid URL for WFS connection"); + } + } - return Result.empty(); + return Result.empty(); + } + + public static Result check( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + + // TODO: check connectionInfo + + return Result.ok("All good"); + } + + public static Result analyze( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + Result result = new Result(); + + try { + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + Map> types = autoFactory.analyze(featureProvider); + + result.success("All good"); + result.details("types", types); + } catch (Throwable e) { + e.printStackTrace(); + if (e instanceof RuntimeException + && Objects.nonNull(e.getCause()) + && Objects.nonNull(e.getCause().getMessage())) { + result.error(e.getCause().getMessage()); + } else if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } } - public static Result check( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { + return result; + } + + public static Result generate( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug, + Map> types, + Consumer tracker) { + Result result = new Result(); + + System.out.println("Initial types: " + types); + + try { + String createOption = parameters.get("createOption"); + String selectedConfig = parameters.get("selectedConfig"); + String newId = parameters.get("id"); + + if ("fromScratch".equalsIgnoreCase(createOption)) { + return generateBasicEntity(parameters, ldproxyCfg); + } + + if ("copy".equalsIgnoreCase(createOption)) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } - // TODO: check connectionInfo + File sourceFile = new File(selectedConfig); + if (!sourceFile.exists()) { + return Result.failure("Selected config file does not exist: " + selectedConfig); + } - return Result.ok("All good"); - } + Map yamlContent = + ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); - public static Result analyze( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - Result result = new Result(); - - try { - FeatureProviderDataV2 featureProvider = - parseFeatureProvider(parameters, ldproxyCfg, Map.of()); - - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - Map> types = autoFactory.analyze(featureProvider); - - result.success("All good"); - result.details("types", types); - } catch (Throwable e) { - e.printStackTrace(); - if (e instanceof RuntimeException - && Objects.nonNull(e.getCause()) - && Objects.nonNull(e.getCause().getMessage())) { - result.error(e.getCause().getMessage()); - } else if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + if (yamlContent.containsKey("id")) { + yamlContent.put("id", newId); } + File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); + + result.success("Config copied successfully"); + result.details("new_files", List.of(targetFile.getPath())); return result; - } + } - public static Result generate( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug, - Map> types, - Consumer tracker) { - Result result = new Result(); - - System.out.println("Initial types: " + types); - - try { - String createOption = parameters.get("createOption"); - String selectedConfig = parameters.get("selectedConfig"); - String newId = parameters.get("id"); - - if ("fromScratch".equalsIgnoreCase(createOption)) { - return generateBasicEntity(parameters, ldproxyCfg); - } - - if ("copy".equalsIgnoreCase(createOption)) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } - - File sourceFile = new File(selectedConfig); - if (!sourceFile.exists()) { - return Result.failure("Selected config file does not exist: " + selectedConfig); - } - - Map yamlContent = ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); - - if (yamlContent.containsKey("id")) { - yamlContent.put("id", newId); - } - - File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); - - result.success("Config copied successfully"); - result.details("new_files", List.of(targetFile.getPath())); - return result; - } - - if (types == null || types.isEmpty()) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } - - Map cfgJava = ldproxyCfg.getObjectMapper().readValue( - new File(selectedConfig), - Map.class - ); - - Map featureProviderTypeAndTypes = determineMissingParameters(parameters, cfgJava); - types = (Map>) featureProviderTypeAndTypes.get("types"); - } - - System.out.println("New types: " + types); - - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - long count = types.values().stream().mapToLong(List::size).sum(); - - Consumer>> tracker2 = - progress -> { - long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); - String currentTable = - progress.entrySet().stream() - .skip(progress.size() - 1) - .map( - entry -> - entry.getKey() - + "." - + entry.getValue().get(entry.getValue().size() - 1)) - .findFirst() - .orElse("???"); - - System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - - Map details = - Map.of( - "currentCount", - current, - "targetCount", - count, - "currentTable", - currentTable, - "progress", - progress); - - System.out.println("details: " + details); - tracker.accept(Result.ok("progress", details)); - }; - FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - - // get from provider-configuration as well? Seems to work just fine - Map> types2 = - Map.of("", new ArrayList<>(entityData.getTypes().keySet())); - - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { - }); - - Map typeObject = parseTypeObject(parameters.get("typeObject")); - - System.out.println("typeObject: " + typeObject); - - - try { - boolean providerWritten = false; - boolean serviceWritten = false; - - if (typeObject.getOrDefault("provider", true)) { - ldproxyCfg.writeEntity(entityData); - providerWritten = true; - } - - // generate service - if (typeObject.getOrDefault("service", true)) { - ldproxyCfg.writeEntity(entityData2); - serviceWritten = true; - } - - List newFiles = new ArrayList<>(); - if (providerWritten) { - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); - } - if (serviceWritten) { - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString()); - } - - result.success("All good"); - - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); - } - } catch (Throwable e) { - e.printStackTrace(); - if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } - } - return result; - } catch (Throwable e) { - e.printStackTrace(); - return Result.failure("Unexpected error: " + e.getMessage()); + if (types == null || types.isEmpty()) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); } - } - private static AutoEntityFactory getAutoFactory( - LdproxyCfg ldproxyCfg, String type, Optional subType) { - EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); - - AutoEntityFactory autoFactory = - factory - .auto() - .orElseThrow( - () -> - new IllegalArgumentException( - "No auto factory found for entity type " + factory.fullType())); - return autoFactory; - } + Map cfgJava = + ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); - private static FeatureProviderDataV2 parseFeatureProvider( - Map parameters, LdproxyCfg ldproxyCfg, Map> types) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); - } + Map featureProviderTypeAndTypes = + determineMissingParameters(parameters, cfgJava); + types = (Map>) featureProviderTypeAndTypes.get("types"); + } - String id = parameters.get("id"); + System.out.println("New types: " + types); - String featureProviderTypeString = parameters.get("featureProviderType"); + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - FeatureProviderType featureProviderType; - try { - featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - "Invalid featureProviderType: " + featureProviderTypeString + ". Expected one of: " - + Arrays.toString(FeatureProviderType.values()), e); - } + long count = types.values().stream().mapToLong(List::size).sum(); - System.out.println("new featureProviderType: " + featureProviderType); - System.out.println("myParameters: " + parameters); - - FeatureProviderDataV2.Builder builder = - AutoTypes.getBuilder( - ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) - .id(id); - - switch (featureProviderType) { - case PGIS: - return parseFeatureProviderPgis( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); - case GPKG: - return parseFeatureProviderGpkg( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters); - case WFS: - return parseFeatureProviderWfs( - (ImmutableFeatureProviderWfsData.Builder) builder, parameters); - } + Consumer>> tracker2 = + progress -> { + long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); + String currentTable = + progress.entrySet().stream() + .skip(progress.size() - 1) + .map( + entry -> + entry.getKey() + + "." + + entry.getValue().get(entry.getValue().size() - 1)) + .findFirst() + .orElse("???"); - return builder.build(); - } + System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - private static FeatureProviderDataV2 parseFeatureProviderPgis( - ImmutableFeatureProviderSqlData.Builder builder, - Map parameters, - Map> types) { - Set schemas = types.keySet(); - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.PGIS.name()) - .host(Optional.ofNullable(parameters.get("host"))) - .database(parameters.get("database")) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) - .schemas(schemas) - .poolBuilder(); - - return builder.build(); - } + Map details = + Map.of( + "currentCount", + current, + "targetCount", + count, + "currentTable", + currentTable, + "progress", + progress); - private static FeatureProviderDataV2 parseFeatureProviderGpkg( - ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { + System.out.println("details: " + details); + tracker.accept(Result.ok("progress", details)); + }; + FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.GPKG.name()) - .database(parameters.get("database")) - .poolBuilder(); + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - return builder.build(); - } + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - private static FeatureProviderDataV2 parseFeatureProviderWfs( - ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { + // get from provider-configuration as well? Seems to work just fine + Map> types2 = + Map.of("", new ArrayList<>(entityData.getTypes().keySet())); - System.out.println("WFS parameters: " + parameters); + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - builder - .connectionInfoBuilder() - .uri(URI.create(parameters.get("url"))) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map( - pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); - return builder.build(); - } + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> {}); - private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); - } + /*TODO + TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); - String id = parameters.get("id"); + AutoEntityFactory autoFactory3 = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), tileProvider.getEntitySubType()); - OgcApiDataV2.Builder builder = - AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + TileProviderFeaturesData entityData3 = + autoFactory3.generate(tileProvider, types2, ignore -> {});*/ - return builder.build(); - } + Map typeObject = parseTypeObject(parameters.get("typeObject")); + + System.out.println("typeObject: " + typeObject); - private static Map determineMissingParameters( - Map parameters, Map yamlConfig) { - - Map result = new HashMap<>(); - - // Determine featureProviderType - String featureProviderType = parameters.getOrDefault("featureProviderType", "").trim(); - if (featureProviderType.isEmpty()) { - String providerSubType = (String) yamlConfig.getOrDefault("providerSubType", ""); - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - String dialect = (connectionInfo != null && connectionInfo.containsKey("dialect")) - ? (String) connectionInfo.get("dialect") - : ""; - - if ("GPKG".equalsIgnoreCase(dialect)) { - featureProviderType = "GPKG"; - } else if ("WFS".equalsIgnoreCase(providerSubType)) { - featureProviderType = "WFS"; - } else { - featureProviderType = "PGIS"; - } + try { + boolean providerWritten = false; + boolean serviceWritten = false; + + if (typeObject.getOrDefault("provider", true)) { + ldproxyCfg.writeEntity(entityData); + providerWritten = true; } - parameters.put("featureProviderType", featureProviderType); - - // If featureProviderType is WFS, extract the URI and set it in parameters - if ("WFS".equalsIgnoreCase(featureProviderType)) { - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - if (connectionInfo != null && connectionInfo.containsKey("uri")) { - String uri = (String) connectionInfo.get("uri"); - parameters.put("url", uri); - } + + // generate service + if (typeObject.getOrDefault("service", true)) { + ldproxyCfg.writeEntity(entityData2); + serviceWritten = true; } - // If featureProviderType is PGIS, set additional parameters - if ("PGIS".equalsIgnoreCase(featureProviderType)) { - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - if (connectionInfo != null) { - parameters.put("host", (String) connectionInfo.getOrDefault("host", "")); - parameters.put("database", (String) connectionInfo.getOrDefault("database", "")); - parameters.put("user", (String) connectionInfo.getOrDefault("user", "")); - String encodedPassword = (String) connectionInfo.getOrDefault("password", ""); - if (!encodedPassword.isBlank()) { - String decodedPassword = new String(Base64.getDecoder().decode(encodedPassword), StandardCharsets.UTF_8); - parameters.put("password", decodedPassword); - } - } + List newFiles = new ArrayList<>(); + if (providerWritten) { + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } + if (serviceWritten) { + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString()); } - // Extract types - Map yamlTypes = (Map) yamlConfig.get("types"); - Map> extractedTypes = new HashMap<>(); + result.success("All good"); - if (yamlTypes != null) { - for (Map.Entry entry : yamlTypes.entrySet()) { - String key = entry.getKey(); - Map typeDetails = (Map) entry.getValue(); - String sourcePath = (String) typeDetails.get("sourcePath"); + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + } catch (Throwable e) { + e.printStackTrace(); + if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } + } + return result; + } catch (Throwable e) { + e.printStackTrace(); + return Result.failure("Unexpected error: " + e.getMessage()); + } + } + + private static AutoEntityFactory getAutoFactory( + LdproxyCfg ldproxyCfg, String type, Optional subType) { + EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); + + AutoEntityFactory autoFactory = + factory + .auto() + .orElseThrow( + () -> + new IllegalArgumentException( + "No auto factory found for entity type " + factory.fullType())); + return autoFactory; + } + + private static FeatureProviderDataV2 parseFeatureProvider( + Map parameters, LdproxyCfg ldproxyCfg, Map> types) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } - if (sourcePath != null) { - sourcePath = sourcePath.startsWith("/") ? sourcePath.substring(1) : sourcePath; + String id = parameters.get("id"); - String namespace = sourcePath.contains(":") ? sourcePath.split(":")[0] : ""; - String value = sourcePath.contains(":") ? sourcePath.split(":")[1] : sourcePath; - extractedTypes.computeIfAbsent(namespace, k -> new ArrayList<>()).add(value); - } - } - } + String featureProviderTypeString = parameters.get("featureProviderType"); - // Handle missing types - if (extractedTypes.isEmpty()) { - extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); - } + FeatureProviderType featureProviderType; + try { + featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid featureProviderType: " + + featureProviderTypeString + + ". Expected one of: " + + Arrays.toString(FeatureProviderType.values()), + e); + } - result.put("types", extractedTypes); + System.out.println("new featureProviderType: " + featureProviderType); + System.out.println("myParameters: " + parameters); + + FeatureProviderDataV2.Builder builder = + AutoTypes.getBuilder( + ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) + .id(id); + + switch (featureProviderType) { + case PGIS: + return parseFeatureProviderPgis( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); + case GPKG: + return parseFeatureProviderGpkg( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters); + case WFS: + return parseFeatureProviderWfs( + (ImmutableFeatureProviderWfsData.Builder) builder, parameters); + } - return result; + return builder.build(); + } + + private static FeatureProviderDataV2 parseFeatureProviderPgis( + ImmutableFeatureProviderSqlData.Builder builder, + Map parameters, + Map> types) { + Set schemas = types.keySet(); + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.PGIS.name()) + .host(Optional.ofNullable(parameters.get("host"))) + .database(parameters.get("database")) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) + .schemas(schemas) + .poolBuilder(); + + return builder.build(); + } + + private static FeatureProviderDataV2 parseFeatureProviderGpkg( + ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.GPKG.name()) + .database(parameters.get("database")) + .poolBuilder(); + + return builder.build(); + } + + private static FeatureProviderDataV2 parseFeatureProviderWfs( + ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { + + System.out.println("WFS parameters: " + parameters); + + builder + .connectionInfoBuilder() + .uri(URI.create(parameters.get("url"))) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map( + pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); + return builder.build(); + } + + private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); } - private static Map parseTypeObject(String typeObjectString) { - Map typeObject = new HashMap<>(); - if (typeObjectString != null && !typeObjectString.isBlank()) { - typeObjectString = typeObjectString.replace("{", "").replace("}", ""); - String[] entries = typeObjectString.split(","); - for (String entry : entries) { - String[] keyValue = entry.split("="); - if (keyValue.length == 2) { - typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); - } - } - } - return typeObject; + String id = parameters.get("id"); + + OgcApiDataV2.Builder builder = + AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + + return builder.build(); + } + + private static TileProviderFeaturesData parseTileProvider( + Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); } - private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg) { - Result result = new Result(); + String id = parameters.get("id"); + + TileProviderFeaturesData.Builder builder = + (TileProviderFeaturesData.Builder) + AutoTypes.getBuilder( + ldproxyCfg, EntityType.SERVICES, AutoTypes.TileProviderType.FEATURES) + .id(id); + + return (TileProviderFeaturesData) builder.build(); + } + + private static Map determineMissingParameters( + Map parameters, Map yamlConfig) { + + Map result = new HashMap<>(); + + // Determine featureProviderType + String featureProviderType = parameters.getOrDefault("featureProviderType", "").trim(); + if (featureProviderType.isEmpty()) { + String providerSubType = (String) yamlConfig.getOrDefault("providerSubType", ""); + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + String dialect = + (connectionInfo != null && connectionInfo.containsKey("dialect")) + ? (String) connectionInfo.get("dialect") + : ""; + + if ("GPKG".equalsIgnoreCase(dialect)) { + featureProviderType = "GPKG"; + } else if ("WFS".equalsIgnoreCase(providerSubType)) { + featureProviderType = "WFS"; + } else { + featureProviderType = "PGIS"; + } + } + parameters.put("featureProviderType", featureProviderType); + + // If featureProviderType is WFS, extract the URI and set it in parameters + if ("WFS".equalsIgnoreCase(featureProviderType)) { + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + if (connectionInfo != null && connectionInfo.containsKey("uri")) { + String uri = (String) connectionInfo.get("uri"); + parameters.put("url", uri); + } + } - if (parameters.containsKey("id")) { - String newId = parameters.get("id"); + // If featureProviderType is PGIS, set additional parameters + if ("PGIS".equalsIgnoreCase(featureProviderType)) { + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + if (connectionInfo != null) { + parameters.put("host", (String) connectionInfo.getOrDefault("host", "")); + parameters.put("database", (String) connectionInfo.getOrDefault("database", "")); + parameters.put("user", (String) connectionInfo.getOrDefault("user", "")); + String encodedPassword = (String) connectionInfo.getOrDefault("password", ""); + if (!encodedPassword.isBlank()) { + String decodedPassword = + new String(Base64.getDecoder().decode(encodedPassword), StandardCharsets.UTF_8); + parameters.put("password", decodedPassword); + } + } + } - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } + // Extract types + Map yamlTypes = (Map) yamlConfig.get("types"); + Map> extractedTypes = new HashMap<>(); - Map minimalConfig = new HashMap<>(); - minimalConfig.put("id", newId); - minimalConfig.put("enabled", true); + if (yamlTypes != null) { + for (Map.Entry entry : yamlTypes.entrySet()) { + String key = entry.getKey(); + Map typeDetails = (Map) entry.getValue(); + String sourcePath = (String) typeDetails.get("sourcePath"); - try { - File targetFile = new File(ldproxyCfg.getDataDirectory().toFile(), "entities/instances/providers/" + newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, minimalConfig); + if (sourcePath != null) { + sourcePath = sourcePath.startsWith("/") ? sourcePath.substring(1) : sourcePath; - result.success("Minimal config created successfully"); - result.details("new_files", List.of(targetFile.getPath())); - } catch (IOException e) { - return Result.failure("Failed to write minimal config: " + e.getMessage()); - } + String namespace = sourcePath.contains(":") ? sourcePath.split(":")[0] : ""; + String value = sourcePath.contains(":") ? sourcePath.split(":")[1] : sourcePath; + extractedTypes.computeIfAbsent(namespace, k -> new ArrayList<>()).add(value); } + } + } - return result; + // Handle missing types + if (extractedTypes.isEmpty()) { + extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); + } + + result.put("types", extractedTypes); + + return result; + } + + private static Map parseTypeObject(String typeObjectString) { + Map typeObject = new HashMap<>(); + if (typeObjectString != null && !typeObjectString.isBlank()) { + typeObjectString = typeObjectString.replace("{", "").replace("}", ""); + String[] entries = typeObjectString.split(","); + for (String entry : entries) { + String[] keyValue = entry.split("="); + if (keyValue.length == 2) { + typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + } + } } -} \ No newline at end of file + return typeObject; + } + + private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg) { + Result result = new Result(); + + if (parameters.containsKey("id")) { + String newId = parameters.get("id"); + + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } + + Map minimalConfig = new HashMap<>(); + minimalConfig.put("id", newId); + minimalConfig.put("enabled", true); + + try { + File targetFile = + new File( + ldproxyCfg.getDataDirectory().toFile(), + "entities/instances/providers/" + newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, minimalConfig); + + result.success("Minimal config created successfully"); + result.details("new_files", List.of(targetFile.getPath())); + } catch (IOException e) { + return Result.failure("Failed to write minimal config: " + e.getMessage()); + } + } + + return result; + } +} diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java index 6500547..d476469 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java @@ -4,6 +4,7 @@ import de.ii.ogcapi.foundation.domain.OgcApiDataV2; import de.ii.xtraplatform.entities.domain.EntityFactory; import de.ii.xtraplatform.features.domain.FeatureProviderDataV2; +import de.ii.xtraplatform.tiles.domain.TileProviderData; public class AutoTypes { @@ -36,12 +37,23 @@ static EntityFactory getFactory( return ldproxyCfg.getEntityFactories().get(entityType.toString(), serviceType.toString()); } + static EntityFactory getFactory( + LdproxyCfg ldproxyCfg, EntityType entityType, TileProviderType tileProviderType) { + return ldproxyCfg.getEntityFactories().get(entityType.toString(), tileProviderType.toString()); + } + static OgcApiDataV2.Builder getBuilder( LdproxyCfg ldproxyCfg, EntityType entityType, ServiceType serviceType) { return ((OgcApiDataV2.Builder) getFactory(ldproxyCfg, entityType, serviceType).emptyDataBuilder()); } + static TileProviderData.Builder getBuilder( + LdproxyCfg ldproxyCfg, EntityType entityType, TileProviderType tileProviderType) { + return ((TileProviderData.Builder) + getFactory(ldproxyCfg, entityType, tileProviderType).emptyDataBuilder()); + } + enum Type { ENTITIES, UNKNOWN; @@ -101,4 +113,14 @@ public String toString() { return name().toUpperCase(); } } + + enum TileProviderType { + FEATURES, + UNKNOWN; + + @Override + public String toString() { + return name().toUpperCase(); + } + } } From 275ce6ff8b2c9d989a5ffb0efc11a97394e3ae6d Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 29 Aug 2025 12:35:14 +0200 Subject: [PATCH 09/19] improve seperation of provider and service creation --- .../de/ii/xtraplatform/cli/AutoHandler.java | 915 +++++++++--------- 1 file changed, 446 insertions(+), 469 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index c0d95f7..a87cf17 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -14,6 +14,7 @@ import de.ii.xtraplatform.features.sql.domain.ImmutableFeatureProviderSqlData; import de.ii.xtraplatform.tiles.domain.TileProviderFeaturesData; import de.ii.xtraplatform.values.domain.Identifier; + import java.io.File; import java.io.IOException; import java.net.URI; @@ -23,214 +24,242 @@ import java.util.function.Consumer; public class AutoHandler { - public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { - if (Objects.isNull(ldproxyCfg)) { - return Result.failure("Not connected to store"); - } - - ldproxyCfg.initStore(); - - if (!parameters.containsKey("id")) { - return Result.failure("No id given"); - } - - String id = parameters.get("id"); - - if (id.length() < 3) { - return Result.failure("Id has to be at least 3 characters long"); - } - - Identifier identifier = Identifier.from(id, "providers"); - - if (ldproxyCfg.getEntityDataStore().has(identifier)) { - return Result.failure("A provider with id '" + id + "' already exists"); - } + public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { + if (Objects.isNull(ldproxyCfg)) { + return Result.failure("Not connected to store"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("PGIS") - && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { - return Result.failure("Host is required for PGIS connection"); - } + ldproxyCfg.initStore(); - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("WFS")) { - if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { - return Result.failure("URL is required for WFS connection"); - } - try { - URI uri = URI.create(parameters.get("url")); - if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { - return Result.failure("Invalid URL scheme for WFS connection"); + if (!parameters.containsKey("id")) { + return Result.failure("No id given"); } - } catch (IllegalArgumentException e) { - return Result.failure("Invalid URL for WFS connection"); - } - } - return Result.empty(); - } + String id = parameters.get("id"); - public static Result check( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { + if (id.length() < 3) { + return Result.failure("Id has to be at least 3 characters long"); + } - // TODO: check connectionInfo + Identifier identifier = Identifier.from(id, "providers"); - return Result.ok("All good"); - } + if (ldproxyCfg.getEntityDataStore().has(identifier)) { + return Result.failure("A provider with id '" + id + "' already exists"); + } - public static Result analyze( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - Result result = new Result(); + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("PGIS") + && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { + return Result.failure("Host is required for PGIS connection"); + } - try { - FeatureProviderDataV2 featureProvider = - parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("WFS")) { + if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { + return Result.failure("URL is required for WFS connection"); + } + try { + URI uri = URI.create(parameters.get("url")); + if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { + return Result.failure("Invalid URL scheme for WFS connection"); + } + } catch (IllegalArgumentException e) { + return Result.failure("Invalid URL for WFS connection"); + } + } - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - Map> types = autoFactory.analyze(featureProvider); - - result.success("All good"); - result.details("types", types); - } catch (Throwable e) { - e.printStackTrace(); - if (e instanceof RuntimeException - && Objects.nonNull(e.getCause()) - && Objects.nonNull(e.getCause().getMessage())) { - result.error(e.getCause().getMessage()); - } else if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + return Result.empty(); } - return result; - } - - public static Result generate( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug, - Map> types, - Consumer tracker) { - Result result = new Result(); - - System.out.println("Initial types: " + types); - - try { - String createOption = parameters.get("createOption"); - String selectedConfig = parameters.get("selectedConfig"); - String newId = parameters.get("id"); - - if ("fromScratch".equalsIgnoreCase(createOption)) { - return generateBasicEntity(parameters, ldproxyCfg); - } - - if ("copy".equalsIgnoreCase(createOption)) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } + public static Result check( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { - File sourceFile = new File(selectedConfig); - if (!sourceFile.exists()) { - return Result.failure("Selected config file does not exist: " + selectedConfig); - } + // TODO: check connectionInfo - Map yamlContent = - ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); + return Result.ok("All good"); + } - if (yamlContent.containsKey("id")) { - yamlContent.put("id", newId); + public static Result analyze( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + Result result = new Result(); + + try { + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + Map> types = autoFactory.analyze(featureProvider); + + result.success("All good"); + result.details("types", types); + } catch (Throwable e) { + e.printStackTrace(); + if (e instanceof RuntimeException + && Objects.nonNull(e.getCause()) + && Objects.nonNull(e.getCause().getMessage())) { + result.error(e.getCause().getMessage()); + } else if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } } - File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); - - result.success("Config copied successfully"); - result.details("new_files", List.of(targetFile.getPath())); return result; - } + } - if (types == null || types.isEmpty()) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } + public static Result generate( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug, + Map> types, + Consumer tracker) { + Result result = new Result(); + + System.out.println("Initial types: " + types); + + try { + String createOption = parameters.get("createOption"); + String selectedConfig = parameters.get("selectedConfig"); + String newId = parameters.get("id"); + + if ("fromScratch".equalsIgnoreCase(createOption)) { + return generateBasicEntity(parameters, ldproxyCfg); + } + + if ("copy".equalsIgnoreCase(createOption)) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } + + File sourceFile = new File(selectedConfig); + if (!sourceFile.exists()) { + return Result.failure("Selected config file does not exist: " + selectedConfig); + } + + Map yamlContent = + ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); + + if (yamlContent.containsKey("id")) { + yamlContent.put("id", newId); + } + + File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); + + result.success("Config copied successfully"); + result.details("new_files", List.of(targetFile.getPath())); + return result; + } + + if (types == null || types.isEmpty()) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + + Map cfgJava = + ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); + + Map featureProviderTypeAndTypes = + determineMissingParameters(parameters, cfgJava); + types = (Map>) featureProviderTypeAndTypes.get("types"); + } + + System.out.println("New types: " + types); + + long count = types.values().stream().mapToLong(List::size).sum(); + + Consumer>> tracker2 = + progress -> { + long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); + String currentTable = + progress.entrySet().stream() + .skip(progress.size() - 1) + .map( + entry -> + entry.getKey() + + "." + + entry.getValue().get(entry.getValue().size() - 1)) + .findFirst() + .orElse("???"); + + System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); + + Map details = + Map.of( + "currentCount", + current, + "targetCount", + count, + "currentTable", + currentTable, + "progress", + progress); + + System.out.println("details: " + details); + tracker.accept(Result.ok("progress", details)); + }; + + Map typeObject = parseTypeObject(parameters.get("typeObject")); + System.out.println("typeObject: " + typeObject); + + List newFiles = new ArrayList<>(); + + if (typeObject.getOrDefault("provider", true)) { + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); + + ldproxyCfg.writeEntity(entityData); + + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } + + if (typeObject.getOrDefault("service", true)) { + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - Map cfgJava = - ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); + Map> types2 = types.containsKey("") + ? types + : Map.of("", new ArrayList<>(types.keySet())); - Map featureProviderTypeAndTypes = - determineMissingParameters(parameters, cfgJava); - types = (Map>) featureProviderTypeAndTypes.get("types"); - } + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - System.out.println("New types: " + types); + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { + }); - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - long count = types.values().stream().mapToLong(List::size).sum(); - - Consumer>> tracker2 = - progress -> { - long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); - String currentTable = - progress.entrySet().stream() - .skip(progress.size() - 1) - .map( - entry -> - entry.getKey() - + "." - + entry.getValue().get(entry.getValue().size() - 1)) - .findFirst() - .orElse("???"); - - System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - - Map details = - Map.of( - "currentCount", - current, - "targetCount", - count, - "currentTable", - currentTable, - "progress", - progress); - - System.out.println("details: " + details); - tracker.accept(Result.ok("progress", details)); - }; - FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - - // get from provider-configuration as well? Seems to work just fine - Map> types2 = - Map.of("", new ArrayList<>(entityData.getTypes().keySet())); - - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> {}); + ldproxyCfg.writeEntity(entityData2); + + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString()); + } /*TODO TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); @@ -242,329 +271,277 @@ public static Result generate( TileProviderFeaturesData entityData3 = autoFactory3.generate(tileProvider, types2, ignore -> {});*/ - Map typeObject = parseTypeObject(parameters.get("typeObject")); - - System.out.println("typeObject: " + typeObject); + result.success("All good"); - try { - boolean providerWritten = false; - boolean serviceWritten = false; - - if (typeObject.getOrDefault("provider", true)) { - ldproxyCfg.writeEntity(entityData); - providerWritten = true; + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + return result; + } catch (Throwable e) { + e.printStackTrace(); + return Result.failure("Unexpected error: " + e.getMessage()); } + } - // generate service - if (typeObject.getOrDefault("service", true)) { - ldproxyCfg.writeEntity(entityData2); - serviceWritten = true; - } + private static AutoEntityFactory getAutoFactory( + LdproxyCfg ldproxyCfg, String type, Optional subType) { + EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); + + AutoEntityFactory autoFactory = + factory + .auto() + .orElseThrow( + () -> + new IllegalArgumentException( + "No auto factory found for entity type " + factory.fullType())); + return autoFactory; + } - List newFiles = new ArrayList<>(); - if (providerWritten) { - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); + private static FeatureProviderDataV2 parseFeatureProvider( + Map parameters, LdproxyCfg ldproxyCfg, Map> types) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); } - if (serviceWritten) { - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString()); + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); } - result.success("All good"); + String id = parameters.get("id"); - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); + String featureProviderTypeString = parameters.get("featureProviderType"); + + FeatureProviderType featureProviderType; + try { + featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid featureProviderType: " + + featureProviderTypeString + + ". Expected one of: " + + Arrays.toString(FeatureProviderType.values()), + e); } - } catch (Throwable e) { - e.printStackTrace(); - if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); + + System.out.println("new featureProviderType: " + featureProviderType); + System.out.println("myParameters: " + parameters); + + FeatureProviderDataV2.Builder builder = + AutoTypes.getBuilder( + ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) + .id(id); + + switch (featureProviderType) { + case PGIS: + return parseFeatureProviderPgis( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); + case GPKG: + return parseFeatureProviderGpkg( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters); + case WFS: + return parseFeatureProviderWfs( + (ImmutableFeatureProviderWfsData.Builder) builder, parameters); } - } - return result; - } catch (Throwable e) { - e.printStackTrace(); - return Result.failure("Unexpected error: " + e.getMessage()); - } - } - - private static AutoEntityFactory getAutoFactory( - LdproxyCfg ldproxyCfg, String type, Optional subType) { - EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); - - AutoEntityFactory autoFactory = - factory - .auto() - .orElseThrow( - () -> - new IllegalArgumentException( - "No auto factory found for entity type " + factory.fullType())); - return autoFactory; - } - - private static FeatureProviderDataV2 parseFeatureProvider( - Map parameters, LdproxyCfg ldproxyCfg, Map> types) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); + + return builder.build(); } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + + private static FeatureProviderDataV2 parseFeatureProviderPgis( + ImmutableFeatureProviderSqlData.Builder builder, + Map parameters, + Map> types) { + Set schemas = types.keySet(); + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.PGIS.name()) + .host(Optional.ofNullable(parameters.get("host"))) + .database(parameters.get("database")) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) + .schemas(schemas) + .poolBuilder(); + + return builder.build(); } - String id = parameters.get("id"); + private static FeatureProviderDataV2 parseFeatureProviderGpkg( + ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { - String featureProviderTypeString = parameters.get("featureProviderType"); + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.GPKG.name()) + .database(parameters.get("database")) + .poolBuilder(); - FeatureProviderType featureProviderType; - try { - featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - "Invalid featureProviderType: " - + featureProviderTypeString - + ". Expected one of: " - + Arrays.toString(FeatureProviderType.values()), - e); + return builder.build(); } - System.out.println("new featureProviderType: " + featureProviderType); - System.out.println("myParameters: " + parameters); - - FeatureProviderDataV2.Builder builder = - AutoTypes.getBuilder( - ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) - .id(id); - - switch (featureProviderType) { - case PGIS: - return parseFeatureProviderPgis( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); - case GPKG: - return parseFeatureProviderGpkg( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters); - case WFS: - return parseFeatureProviderWfs( - (ImmutableFeatureProviderWfsData.Builder) builder, parameters); - } + private static FeatureProviderDataV2 parseFeatureProviderWfs( + ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderPgis( - ImmutableFeatureProviderSqlData.Builder builder, - Map parameters, - Map> types) { - Set schemas = types.keySet(); - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.PGIS.name()) - .host(Optional.ofNullable(parameters.get("host"))) - .database(parameters.get("database")) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) - .schemas(schemas) - .poolBuilder(); - - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderGpkg( - ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.GPKG.name()) - .database(parameters.get("database")) - .poolBuilder(); - - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderWfs( - ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { - - System.out.println("WFS parameters: " + parameters); - - builder - .connectionInfoBuilder() - .uri(URI.create(parameters.get("url"))) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map( - pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); - return builder.build(); - } - - private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + System.out.println("WFS parameters: " + parameters); + + builder + .connectionInfoBuilder() + .uri(URI.create(parameters.get("url"))) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map( + pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); + return builder.build(); } - String id = parameters.get("id"); + private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } - OgcApiDataV2.Builder builder = - AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + String id = parameters.get("id"); - return builder.build(); - } + OgcApiDataV2.Builder builder = + AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); - private static TileProviderFeaturesData parseTileProvider( - Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + return builder.build(); } - String id = parameters.get("id"); - - TileProviderFeaturesData.Builder builder = - (TileProviderFeaturesData.Builder) - AutoTypes.getBuilder( - ldproxyCfg, EntityType.SERVICES, AutoTypes.TileProviderType.FEATURES) - .id(id); - - return (TileProviderFeaturesData) builder.build(); - } - - private static Map determineMissingParameters( - Map parameters, Map yamlConfig) { - - Map result = new HashMap<>(); - - // Determine featureProviderType - String featureProviderType = parameters.getOrDefault("featureProviderType", "").trim(); - if (featureProviderType.isEmpty()) { - String providerSubType = (String) yamlConfig.getOrDefault("providerSubType", ""); - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - String dialect = - (connectionInfo != null && connectionInfo.containsKey("dialect")) - ? (String) connectionInfo.get("dialect") - : ""; - - if ("GPKG".equalsIgnoreCase(dialect)) { - featureProviderType = "GPKG"; - } else if ("WFS".equalsIgnoreCase(providerSubType)) { - featureProviderType = "WFS"; - } else { - featureProviderType = "PGIS"; - } - } - parameters.put("featureProviderType", featureProviderType); - - // If featureProviderType is WFS, extract the URI and set it in parameters - if ("WFS".equalsIgnoreCase(featureProviderType)) { - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - if (connectionInfo != null && connectionInfo.containsKey("uri")) { - String uri = (String) connectionInfo.get("uri"); - parameters.put("url", uri); - } + private static TileProviderFeaturesData parseTileProvider( + Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } + + String id = parameters.get("id"); + + TileProviderFeaturesData.Builder builder = + (TileProviderFeaturesData.Builder) + AutoTypes.getBuilder( + ldproxyCfg, EntityType.SERVICES, AutoTypes.TileProviderType.FEATURES) + .id(id); + + return (TileProviderFeaturesData) builder.build(); } - // If featureProviderType is PGIS, set additional parameters - if ("PGIS".equalsIgnoreCase(featureProviderType)) { - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - if (connectionInfo != null) { - parameters.put("host", (String) connectionInfo.getOrDefault("host", "")); - parameters.put("database", (String) connectionInfo.getOrDefault("database", "")); - parameters.put("user", (String) connectionInfo.getOrDefault("user", "")); - String encodedPassword = (String) connectionInfo.getOrDefault("password", ""); - if (!encodedPassword.isBlank()) { - String decodedPassword = - new String(Base64.getDecoder().decode(encodedPassword), StandardCharsets.UTF_8); - parameters.put("password", decodedPassword); + private static Map determineMissingParameters( + Map parameters, Map yamlConfig) { + + Map result = new HashMap<>(); + + // Determine featureProviderType + String featureProviderType = parameters.getOrDefault("featureProviderType", "").trim(); + if (featureProviderType.isEmpty()) { + String providerSubType = (String) yamlConfig.getOrDefault("providerSubType", ""); + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + String dialect = + (connectionInfo != null && connectionInfo.containsKey("dialect")) + ? (String) connectionInfo.get("dialect") + : ""; + + if ("GPKG".equalsIgnoreCase(dialect)) { + featureProviderType = "GPKG"; + } else if ("WFS".equalsIgnoreCase(providerSubType)) { + featureProviderType = "WFS"; + } else { + featureProviderType = "PGIS"; + } + } + parameters.put("featureProviderType", featureProviderType); + + // If featureProviderType is WFS, extract the URI and set it in parameters + if ("WFS".equalsIgnoreCase(featureProviderType)) { + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + if (connectionInfo != null && connectionInfo.containsKey("uri")) { + String uri = (String) connectionInfo.get("uri"); + parameters.put("url", uri); + } } - } - } - // Extract types - Map yamlTypes = (Map) yamlConfig.get("types"); - Map> extractedTypes = new HashMap<>(); + // If featureProviderType is PGIS, set additional parameters + if ("PGIS".equalsIgnoreCase(featureProviderType)) { + Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); + if (connectionInfo != null) { + parameters.put("host", (String) connectionInfo.getOrDefault("host", "")); + parameters.put("database", (String) connectionInfo.getOrDefault("database", "")); + parameters.put("user", (String) connectionInfo.getOrDefault("user", "")); + String encodedPassword = (String) connectionInfo.getOrDefault("password", ""); + if (!encodedPassword.isBlank()) { + String decodedPassword = + new String(Base64.getDecoder().decode(encodedPassword), StandardCharsets.UTF_8); + parameters.put("password", decodedPassword); + } + } + } - if (yamlTypes != null) { - for (Map.Entry entry : yamlTypes.entrySet()) { - String key = entry.getKey(); - Map typeDetails = (Map) entry.getValue(); - String sourcePath = (String) typeDetails.get("sourcePath"); + // Extract types + Map yamlTypes = (Map) yamlConfig.get("types"); + Map> extractedTypes = new HashMap<>(); - if (sourcePath != null) { - sourcePath = sourcePath.startsWith("/") ? sourcePath.substring(1) : sourcePath; + if (yamlTypes != null) { + List values = new ArrayList<>(yamlTypes.keySet()); + extractedTypes.put("", values); + } - String namespace = sourcePath.contains(":") ? sourcePath.split(":")[0] : ""; - String value = sourcePath.contains(":") ? sourcePath.split(":")[1] : sourcePath; - extractedTypes.computeIfAbsent(namespace, k -> new ArrayList<>()).add(value); + // Handle missing types + if (extractedTypes.isEmpty()) { + extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); } - } + + result.put("types", extractedTypes); + + return result; } - // Handle missing types - if (extractedTypes.isEmpty()) { - extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); + private static Map parseTypeObject(String typeObjectString) { + Map typeObject = new HashMap<>(); + if (typeObjectString != null && !typeObjectString.isBlank()) { + typeObjectString = typeObjectString.replace("{", "").replace("}", ""); + String[] entries = typeObjectString.split(","); + for (String entry : entries) { + String[] keyValue = entry.split("="); + if (keyValue.length == 2) { + typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + } + } + } + return typeObject; } - result.put("types", extractedTypes); + private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg) { + Result result = new Result(); + + if (parameters.containsKey("id")) { + String newId = parameters.get("id"); + + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } + + Map minimalConfig = new HashMap<>(); + minimalConfig.put("id", newId); + minimalConfig.put("enabled", true); - return result; - } + try { + File targetFile = + new File( + ldproxyCfg.getDataDirectory().toFile(), + "entities/instances/providers/" + newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, minimalConfig); - private static Map parseTypeObject(String typeObjectString) { - Map typeObject = new HashMap<>(); - if (typeObjectString != null && !typeObjectString.isBlank()) { - typeObjectString = typeObjectString.replace("{", "").replace("}", ""); - String[] entries = typeObjectString.split(","); - for (String entry : entries) { - String[] keyValue = entry.split("="); - if (keyValue.length == 2) { - typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + result.success("Minimal config created successfully"); + result.details("new_files", List.of(targetFile.getPath())); + } catch (IOException e) { + return Result.failure("Failed to write minimal config: " + e.getMessage()); + } } - } - } - return typeObject; - } - - private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg) { - Result result = new Result(); - - if (parameters.containsKey("id")) { - String newId = parameters.get("id"); - - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } - - Map minimalConfig = new HashMap<>(); - minimalConfig.put("id", newId); - minimalConfig.put("enabled", true); - - try { - File targetFile = - new File( - ldproxyCfg.getDataDirectory().toFile(), - "entities/instances/providers/" + newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, minimalConfig); - - result.success("Minimal config created successfully"); - result.details("new_files", List.of(targetFile.getPath())); - } catch (IOException e) { - return Result.failure("Failed to write minimal config: " + e.getMessage()); - } - } - return result; - } + return result; + } } From 4b165a2b7299b8ff9ef946fb0dc9d489607fc688 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 29 Aug 2025 12:56:42 +0200 Subject: [PATCH 10/19] remove unnecessary code from determineMissingParameters --- .../de/ii/xtraplatform/cli/AutoHandler.java | 60 ++----------------- 1 file changed, 4 insertions(+), 56 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index a87cf17..be8db09 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -174,9 +174,7 @@ public static Result generate( Map cfgJava = ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); - Map featureProviderTypeAndTypes = - determineMissingParameters(parameters, cfgJava); - types = (Map>) featureProviderTypeAndTypes.get("types"); + types = determineTypes(cfgJava); } System.out.println("New types: " + types); @@ -430,56 +428,8 @@ private static TileProviderFeaturesData parseTileProvider( return (TileProviderFeaturesData) builder.build(); } - private static Map determineMissingParameters( - Map parameters, Map yamlConfig) { - - Map result = new HashMap<>(); - - // Determine featureProviderType - String featureProviderType = parameters.getOrDefault("featureProviderType", "").trim(); - if (featureProviderType.isEmpty()) { - String providerSubType = (String) yamlConfig.getOrDefault("providerSubType", ""); - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - String dialect = - (connectionInfo != null && connectionInfo.containsKey("dialect")) - ? (String) connectionInfo.get("dialect") - : ""; - - if ("GPKG".equalsIgnoreCase(dialect)) { - featureProviderType = "GPKG"; - } else if ("WFS".equalsIgnoreCase(providerSubType)) { - featureProviderType = "WFS"; - } else { - featureProviderType = "PGIS"; - } - } - parameters.put("featureProviderType", featureProviderType); - - // If featureProviderType is WFS, extract the URI and set it in parameters - if ("WFS".equalsIgnoreCase(featureProviderType)) { - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - if (connectionInfo != null && connectionInfo.containsKey("uri")) { - String uri = (String) connectionInfo.get("uri"); - parameters.put("url", uri); - } - } - - // If featureProviderType is PGIS, set additional parameters - if ("PGIS".equalsIgnoreCase(featureProviderType)) { - Map connectionInfo = (Map) yamlConfig.get("connectionInfo"); - if (connectionInfo != null) { - parameters.put("host", (String) connectionInfo.getOrDefault("host", "")); - parameters.put("database", (String) connectionInfo.getOrDefault("database", "")); - parameters.put("user", (String) connectionInfo.getOrDefault("user", "")); - String encodedPassword = (String) connectionInfo.getOrDefault("password", ""); - if (!encodedPassword.isBlank()) { - String decodedPassword = - new String(Base64.getDecoder().decode(encodedPassword), StandardCharsets.UTF_8); - parameters.put("password", decodedPassword); - } - } - } - + private static Map> determineTypes( + Map yamlConfig) { // Extract types Map yamlTypes = (Map) yamlConfig.get("types"); Map> extractedTypes = new HashMap<>(); @@ -494,9 +444,7 @@ private static Map determineMissingParameters( extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); } - result.put("types", extractedTypes); - - return result; + return extractedTypes; } private static Map parseTypeObject(String typeObjectString) { From 03fb42bd1e640433e5c9a2d5c892f3ee2881cbcd Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 29 Aug 2025 13:56:47 +0200 Subject: [PATCH 11/19] support creating provider and service configs for fromScratch --- .../de/ii/xtraplatform/cli/AutoHandler.java | 50 +++++++++++++------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index be8db09..eba24aa 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -133,9 +133,10 @@ public static Result generate( String createOption = parameters.get("createOption"); String selectedConfig = parameters.get("selectedConfig"); String newId = parameters.get("id"); + Map typeObject = parseTypeObject(parameters.get("typeObject")); if ("fromScratch".equalsIgnoreCase(createOption)) { - return generateBasicEntity(parameters, ldproxyCfg); + return generateBasicEntity(parameters, ldproxyCfg, typeObject); } if ("copy".equalsIgnoreCase(createOption)) { @@ -162,7 +163,9 @@ public static Result generate( ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); result.success("Config copied successfully"); - result.details("new_files", List.of(targetFile.getPath())); + result.details( + "new_files", + List.of(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString())); return result; } @@ -212,9 +215,6 @@ public static Result generate( tracker.accept(Result.ok("progress", details)); }; - Map typeObject = parseTypeObject(parameters.get("typeObject")); - System.out.println("typeObject: " + typeObject); - List newFiles = new ArrayList<>(); if (typeObject.getOrDefault("provider", true)) { @@ -462,7 +462,7 @@ private static Map parseTypeObject(String typeObjectString) { return typeObject; } - private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg) { + private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg, Map typeObject) { Result result = new Result(); if (parameters.containsKey("id")) { @@ -472,19 +472,39 @@ private static Result generateBasicEntity(Map parameters, Ldprox return Result.failure("No id provided in parameters"); } - Map minimalConfig = new HashMap<>(); - minimalConfig.put("id", newId); - minimalConfig.put("enabled", true); + List newFiles = new ArrayList<>(); try { - File targetFile = - new File( - ldproxyCfg.getDataDirectory().toFile(), - "entities/instances/providers/" + newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, minimalConfig); + if (typeObject.getOrDefault("provider", true)) { + Map providerConfig = new HashMap<>(); + providerConfig.put("id", newId); + providerConfig.put("enabled", true); + + File providerFile = + new File( + ldproxyCfg.getDataDirectory().toFile(), + "entities/instances/providers/" + newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(providerFile, providerConfig); + newFiles.add(providerFile.getPath()); + } + + if (typeObject.getOrDefault("service", true)) { + Map serviceConfig = new HashMap<>(); + serviceConfig.put("id", newId); + serviceConfig.put("enabled", true); + + File serviceFile = + new File( + ldproxyCfg.getDataDirectory().toFile(), + "entities/instances/services/" + newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(serviceFile, serviceConfig); + newFiles.add(serviceFile.getPath()); + } result.success("Minimal config created successfully"); - result.details("new_files", List.of(targetFile.getPath())); + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } } catch (IOException e) { return Result.failure("Failed to write minimal config: " + e.getMessage()); } From e5f788969616b9c94998bdfe2a29833e2e1a60bf Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 29 Aug 2025 14:24:41 +0200 Subject: [PATCH 12/19] refactor entity creation for provider and service (fromScratch) --- .../de/ii/xtraplatform/cli/AutoHandler.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index eba24aa..05104aa 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -476,29 +476,34 @@ private static Result generateBasicEntity(Map parameters, Ldprox try { if (typeObject.getOrDefault("provider", true)) { - Map providerConfig = new HashMap<>(); - providerConfig.put("id", newId); - providerConfig.put("enabled", true); - - File providerFile = - new File( - ldproxyCfg.getDataDirectory().toFile(), - "entities/instances/providers/" + newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(providerFile, providerConfig); - newFiles.add(providerFile.getPath()); + parameters.put("featureProviderType", "PGIS"); + + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + + ldproxyCfg.writeEntity(featureProvider); + + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(featureProvider).normalize()) + .toString()); } if (typeObject.getOrDefault("service", true)) { - Map serviceConfig = new HashMap<>(); - serviceConfig.put("id", newId); - serviceConfig.put("enabled", true); - - File serviceFile = - new File( - ldproxyCfg.getDataDirectory().toFile(), - "entities/instances/services/" + newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(serviceFile, serviceConfig); - newFiles.add(serviceFile.getPath()); + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + + AutoEntityFactory autoFactory = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + + OgcApiDataV2 entityData = autoFactory.generate(ogcApi, Map.of(), ignore -> {}); + + ldproxyCfg.writeEntity(entityData); + + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); } result.success("Minimal config created successfully"); From d57d7e41f17e135f99ed651419b1823689524b8d Mon Sep 17 00:00:00 2001 From: Andreas Zahnen Date: Fri, 29 Aug 2025 16:25:12 +0200 Subject: [PATCH 13/19] fix parseTileProvider --- .../de/ii/xtraplatform/cli/AutoHandler.java | 831 +++++++++--------- .../de/ii/xtraplatform/cli/AutoTypes.java | 26 +- 2 files changed, 435 insertions(+), 422 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 05104aa..32d4562 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -14,7 +14,6 @@ import de.ii.xtraplatform.features.sql.domain.ImmutableFeatureProviderSqlData; import de.ii.xtraplatform.tiles.domain.TileProviderFeaturesData; import de.ii.xtraplatform.values.domain.Identifier; - import java.io.File; import java.io.IOException; import java.net.URI; @@ -24,497 +23,499 @@ import java.util.function.Consumer; public class AutoHandler { - public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { - if (Objects.isNull(ldproxyCfg)) { - return Result.failure("Not connected to store"); - } + public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { + if (Objects.isNull(ldproxyCfg)) { + return Result.failure("Not connected to store"); + } - ldproxyCfg.initStore(); + ldproxyCfg.initStore(); - if (!parameters.containsKey("id")) { - return Result.failure("No id given"); - } + if (!parameters.containsKey("id")) { + return Result.failure("No id given"); + } - String id = parameters.get("id"); + String id = parameters.get("id"); - if (id.length() < 3) { - return Result.failure("Id has to be at least 3 characters long"); - } + if (id.length() < 3) { + return Result.failure("Id has to be at least 3 characters long"); + } - Identifier identifier = Identifier.from(id, "providers"); + Identifier identifier = Identifier.from(id, "providers"); - if (ldproxyCfg.getEntityDataStore().has(identifier)) { - return Result.failure("A provider with id '" + id + "' already exists"); - } + if (ldproxyCfg.getEntityDataStore().has(identifier)) { + return Result.failure("A provider with id '" + id + "' already exists"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("PGIS") - && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { - return Result.failure("Host is required for PGIS connection"); - } + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("PGIS") + && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { + return Result.failure("Host is required for PGIS connection"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("WFS")) { - if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { - return Result.failure("URL is required for WFS connection"); - } - try { - URI uri = URI.create(parameters.get("url")); - if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { - return Result.failure("Invalid URL scheme for WFS connection"); - } - } catch (IllegalArgumentException e) { - return Result.failure("Invalid URL for WFS connection"); - } + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("WFS")) { + if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { + return Result.failure("URL is required for WFS connection"); + } + try { + URI uri = URI.create(parameters.get("url")); + if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { + return Result.failure("Invalid URL scheme for WFS connection"); } - - return Result.empty(); + } catch (IllegalArgumentException e) { + return Result.failure("Invalid URL for WFS connection"); + } } - public static Result check( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { + return Result.empty(); + } + + public static Result check( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + + // TODO: check connectionInfo + + return Result.ok("All good"); + } - // TODO: check connectionInfo + public static Result analyze( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + Result result = new Result(); - return Result.ok("All good"); + try { + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + Map> types = autoFactory.analyze(featureProvider); + + result.success("All good"); + result.details("types", types); + } catch (Throwable e) { + e.printStackTrace(); + if (e instanceof RuntimeException + && Objects.nonNull(e.getCause()) + && Objects.nonNull(e.getCause().getMessage())) { + result.error(e.getCause().getMessage()); + } else if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } } - public static Result analyze( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - Result result = new Result(); - - try { - FeatureProviderDataV2 featureProvider = - parseFeatureProvider(parameters, ldproxyCfg, Map.of()); - - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - Map> types = autoFactory.analyze(featureProvider); - - result.success("All good"); - result.details("types", types); - } catch (Throwable e) { - e.printStackTrace(); - if (e instanceof RuntimeException - && Objects.nonNull(e.getCause()) - && Objects.nonNull(e.getCause().getMessage())) { - result.error(e.getCause().getMessage()); - } else if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + return result; + } + + public static Result generate( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug, + Map> types, + Consumer tracker) { + Result result = new Result(); + + System.out.println("Initial types: " + types); + + try { + String createOption = parameters.get("createOption"); + String selectedConfig = parameters.get("selectedConfig"); + String newId = parameters.get("id"); + Map typeObject = parseTypeObject(parameters.get("typeObject")); + + if ("fromScratch".equalsIgnoreCase(createOption)) { + return generateBasicEntity(parameters, ldproxyCfg, typeObject); + } + + if ("copy".equalsIgnoreCase(createOption)) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); } + File sourceFile = new File(selectedConfig); + if (!sourceFile.exists()) { + return Result.failure("Selected config file does not exist: " + selectedConfig); + } + + Map yamlContent = + ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); + + if (yamlContent.containsKey("id")) { + yamlContent.put("id", newId); + } + + File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); + + result.success("Config copied successfully"); + result.details( + "new_files", + List.of(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString())); return result; - } + } - public static Result generate( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug, - Map> types, - Consumer tracker) { - Result result = new Result(); - - System.out.println("Initial types: " + types); - - try { - String createOption = parameters.get("createOption"); - String selectedConfig = parameters.get("selectedConfig"); - String newId = parameters.get("id"); - Map typeObject = parseTypeObject(parameters.get("typeObject")); - - if ("fromScratch".equalsIgnoreCase(createOption)) { - return generateBasicEntity(parameters, ldproxyCfg, typeObject); - } - - if ("copy".equalsIgnoreCase(createOption)) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } - - File sourceFile = new File(selectedConfig); - if (!sourceFile.exists()) { - return Result.failure("Selected config file does not exist: " + selectedConfig); - } - - Map yamlContent = - ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); - - if (yamlContent.containsKey("id")) { - yamlContent.put("id", newId); - } - - File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); - - result.success("Config copied successfully"); - result.details( - "new_files", - List.of(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString())); - return result; - } - - if (types == null || types.isEmpty()) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } - - Map cfgJava = - ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); - - types = determineTypes(cfgJava); - } - - System.out.println("New types: " + types); - - long count = types.values().stream().mapToLong(List::size).sum(); - - Consumer>> tracker2 = - progress -> { - long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); - String currentTable = - progress.entrySet().stream() - .skip(progress.size() - 1) - .map( - entry -> - entry.getKey() - + "." - + entry.getValue().get(entry.getValue().size() - 1)) - .findFirst() - .orElse("???"); - - System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - - Map details = - Map.of( - "currentCount", - current, - "targetCount", - count, - "currentTable", - currentTable, - "progress", - progress); - - System.out.println("details: " + details); - tracker.accept(Result.ok("progress", details)); - }; - - List newFiles = new ArrayList<>(); - - if (typeObject.getOrDefault("provider", true)) { - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); - - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - - ldproxyCfg.writeEntity(entityData); - - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); - } - - if (typeObject.getOrDefault("service", true)) { - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - - Map> types2 = types.containsKey("") - ? types - : Map.of("", new ArrayList<>(types.keySet())); + if (types == null || types.isEmpty()) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} + Map cfgJava = + ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { - }); + types = determineTypes(cfgJava); + } - ldproxyCfg.writeEntity(entityData2); + System.out.println("New types: " + types); - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString()); - } + long count = types.values().stream().mapToLong(List::size).sum(); - /*TODO - TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); + Consumer>> tracker2 = + progress -> { + long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); + String currentTable = + progress.entrySet().stream() + .skip(progress.size() - 1) + .map( + entry -> + entry.getKey() + + "." + + entry.getValue().get(entry.getValue().size() - 1)) + .findFirst() + .orElse("???"); - AutoEntityFactory autoFactory3 = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), tileProvider.getEntitySubType()); + System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); - TileProviderFeaturesData entityData3 = - autoFactory3.generate(tileProvider, types2, ignore -> {});*/ + Map details = + Map.of( + "currentCount", + current, + "targetCount", + count, + "currentTable", + currentTable, + "progress", + progress); - result.success("All good"); + System.out.println("details: " + details); + tracker.accept(Result.ok("progress", details)); + }; - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); - } - return result; - } catch (Throwable e) { - e.printStackTrace(); - return Result.failure("Unexpected error: " + e.getMessage()); - } - } + List newFiles = new ArrayList<>(); - private static AutoEntityFactory getAutoFactory( - LdproxyCfg ldproxyCfg, String type, Optional subType) { - EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); + if (typeObject.getOrDefault("provider", true)) { + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); AutoEntityFactory autoFactory = - factory - .auto() - .orElseThrow( - () -> - new IllegalArgumentException( - "No auto factory found for entity type " + factory.fullType())); - return autoFactory; - } + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - private static FeatureProviderDataV2 parseFeatureProvider( - Map parameters, LdproxyCfg ldproxyCfg, Map> types) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); - } + FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - String id = parameters.get("id"); + ldproxyCfg.writeEntity(entityData); - String featureProviderTypeString = parameters.get("featureProviderType"); + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } - FeatureProviderType featureProviderType; - try { - featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - "Invalid featureProviderType: " - + featureProviderTypeString - + ". Expected one of: " - + Arrays.toString(FeatureProviderType.values()), - e); - } + if (typeObject.getOrDefault("service", true)) { + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - System.out.println("new featureProviderType: " + featureProviderType); - System.out.println("myParameters: " + parameters); - - FeatureProviderDataV2.Builder builder = - AutoTypes.getBuilder( - ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) - .id(id); - - switch (featureProviderType) { - case PGIS: - return parseFeatureProviderPgis( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); - case GPKG: - return parseFeatureProviderGpkg( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters); - case WFS: - return parseFeatureProviderWfs( - (ImmutableFeatureProviderWfsData.Builder) builder, parameters); - } + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - return builder.build(); - } + Map> types2 = + types.containsKey("") ? types : Map.of("", new ArrayList<>(types.keySet())); - private static FeatureProviderDataV2 parseFeatureProviderPgis( - ImmutableFeatureProviderSqlData.Builder builder, - Map parameters, - Map> types) { - Set schemas = types.keySet(); - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.PGIS.name()) - .host(Optional.ofNullable(parameters.get("host"))) - .database(parameters.get("database")) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) - .schemas(schemas) - .poolBuilder(); - - return builder.build(); - } + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - private static FeatureProviderDataV2 parseFeatureProviderGpkg( - ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> {}); - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.GPKG.name()) - .database(parameters.get("database")) - .poolBuilder(); + ldproxyCfg.writeEntity(entityData2); - return builder.build(); - } + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString()); + } + + /*TODO + TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); - private static FeatureProviderDataV2 parseFeatureProviderWfs( - ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { + AutoEntityFactory autoFactory3 = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), tileProvider.getEntitySubType()); - System.out.println("WFS parameters: " + parameters); + TileProviderFeaturesData entityData3 = + autoFactory3.generate(tileProvider, types2, ignore -> {});*/ - builder - .connectionInfoBuilder() - .uri(URI.create(parameters.get("url"))) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map( - pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); - return builder.build(); + result.success("All good"); + + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + return result; + } catch (Throwable e) { + e.printStackTrace(); + return Result.failure("Unexpected error: " + e.getMessage()); + } + } + + private static AutoEntityFactory getAutoFactory( + LdproxyCfg ldproxyCfg, String type, Optional subType) { + EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); + + AutoEntityFactory autoFactory = + factory + .auto() + .orElseThrow( + () -> + new IllegalArgumentException( + "No auto factory found for entity type " + factory.fullType())); + return autoFactory; + } + + private static FeatureProviderDataV2 parseFeatureProvider( + Map parameters, LdproxyCfg ldproxyCfg, Map> types) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); } - private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); - } + String id = parameters.get("id"); - String id = parameters.get("id"); + String featureProviderTypeString = parameters.get("featureProviderType"); - OgcApiDataV2.Builder builder = - AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + FeatureProviderType featureProviderType; + try { + featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid featureProviderType: " + + featureProviderTypeString + + ". Expected one of: " + + Arrays.toString(FeatureProviderType.values()), + e); + } - return builder.build(); + System.out.println("new featureProviderType: " + featureProviderType); + System.out.println("myParameters: " + parameters); + + FeatureProviderDataV2.Builder builder = + AutoTypes.getBuilder( + ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) + .id(id); + + switch (featureProviderType) { + case PGIS: + return parseFeatureProviderPgis( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); + case GPKG: + return parseFeatureProviderGpkg( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters); + case WFS: + return parseFeatureProviderWfs( + (ImmutableFeatureProviderWfsData.Builder) builder, parameters); } - private static TileProviderFeaturesData parseTileProvider( - Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); - } + return builder.build(); + } + + private static FeatureProviderDataV2 parseFeatureProviderPgis( + ImmutableFeatureProviderSqlData.Builder builder, + Map parameters, + Map> types) { + Set schemas = types.keySet(); + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.PGIS.name()) + .host(Optional.ofNullable(parameters.get("host"))) + .database(parameters.get("database")) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) + .schemas(schemas) + .poolBuilder(); + + return builder.build(); + } + + private static FeatureProviderDataV2 parseFeatureProviderGpkg( + ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.GPKG.name()) + .database(parameters.get("database")) + .poolBuilder(); + + return builder.build(); + } + + private static FeatureProviderDataV2 parseFeatureProviderWfs( + ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { + + System.out.println("WFS parameters: " + parameters); + + builder + .connectionInfoBuilder() + .uri(URI.create(parameters.get("url"))) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map( + pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); + return builder.build(); + } + + private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } + + String id = parameters.get("id"); - String id = parameters.get("id"); + OgcApiDataV2.Builder builder = + AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); - TileProviderFeaturesData.Builder builder = - (TileProviderFeaturesData.Builder) - AutoTypes.getBuilder( - ldproxyCfg, EntityType.SERVICES, AutoTypes.TileProviderType.FEATURES) - .id(id); + return builder.build(); + } - return (TileProviderFeaturesData) builder.build(); + private static TileProviderFeaturesData parseTileProvider( + Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); } - private static Map> determineTypes( - Map yamlConfig) { - // Extract types - Map yamlTypes = (Map) yamlConfig.get("types"); - Map> extractedTypes = new HashMap<>(); + String id = parameters.get("id"); - if (yamlTypes != null) { - List values = new ArrayList<>(yamlTypes.keySet()); - extractedTypes.put("", values); - } + TileProviderFeaturesData.Builder builder = + (TileProviderFeaturesData.Builder) + AutoTypes.getBuilder( + ldproxyCfg, + EntityType.PROVIDERS, + ProviderType.TILE, + AutoTypes.TileProviderType.FEATURES) + .id(id); - // Handle missing types - if (extractedTypes.isEmpty()) { - extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); - } + return (TileProviderFeaturesData) builder.build(); + } + + private static Map> determineTypes(Map yamlConfig) { + // Extract types + Map yamlTypes = (Map) yamlConfig.get("types"); + Map> extractedTypes = new HashMap<>(); - return extractedTypes; + if (yamlTypes != null) { + List values = new ArrayList<>(yamlTypes.keySet()); + extractedTypes.put("", values); } - private static Map parseTypeObject(String typeObjectString) { - Map typeObject = new HashMap<>(); - if (typeObjectString != null && !typeObjectString.isBlank()) { - typeObjectString = typeObjectString.replace("{", "").replace("}", ""); - String[] entries = typeObjectString.split(","); - for (String entry : entries) { - String[] keyValue = entry.split("="); - if (keyValue.length == 2) { - typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); - } - } - } - return typeObject; + // Handle missing types + if (extractedTypes.isEmpty()) { + extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); } - private static Result generateBasicEntity(Map parameters, LdproxyCfg ldproxyCfg, Map typeObject) { - Result result = new Result(); + return extractedTypes; + } + + private static Map parseTypeObject(String typeObjectString) { + Map typeObject = new HashMap<>(); + if (typeObjectString != null && !typeObjectString.isBlank()) { + typeObjectString = typeObjectString.replace("{", "").replace("}", ""); + String[] entries = typeObjectString.split(","); + for (String entry : entries) { + String[] keyValue = entry.split("="); + if (keyValue.length == 2) { + typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + } + } + } + return typeObject; + } - if (parameters.containsKey("id")) { - String newId = parameters.get("id"); + private static Result generateBasicEntity( + Map parameters, LdproxyCfg ldproxyCfg, Map typeObject) { + Result result = new Result(); - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } + if (parameters.containsKey("id")) { + String newId = parameters.get("id"); - List newFiles = new ArrayList<>(); + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } - try { - if (typeObject.getOrDefault("provider", true)) { - parameters.put("featureProviderType", "PGIS"); + List newFiles = new ArrayList<>(); - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + try { + if (typeObject.getOrDefault("provider", true)) { + parameters.put("featureProviderType", "PGIS"); - ldproxyCfg.writeEntity(featureProvider); + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(featureProvider).normalize()) - .toString()); - } + ldproxyCfg.writeEntity(featureProvider); - if (typeObject.getOrDefault("service", true)) { - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(featureProvider).normalize()) + .toString()); + } - AutoEntityFactory autoFactory = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + if (typeObject.getOrDefault("service", true)) { + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - OgcApiDataV2 entityData = autoFactory.generate(ogcApi, Map.of(), ignore -> {}); + AutoEntityFactory autoFactory = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - ldproxyCfg.writeEntity(entityData); + OgcApiDataV2 entityData = autoFactory.generate(ogcApi, Map.of(), ignore -> {}); - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); - } + ldproxyCfg.writeEntity(entityData); - result.success("Minimal config created successfully"); - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); - } - } catch (IOException e) { - return Result.failure("Failed to write minimal config: " + e.getMessage()); - } + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); } - return result; + result.success("Minimal config created successfully"); + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + } catch (IOException e) { + return Result.failure("Failed to write minimal config: " + e.getMessage()); + } } + + return result; + } } diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java index d476469..5679577 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoTypes.java @@ -37,21 +37,33 @@ static EntityFactory getFactory( return ldproxyCfg.getEntityFactories().get(entityType.toString(), serviceType.toString()); } - static EntityFactory getFactory( - LdproxyCfg ldproxyCfg, EntityType entityType, TileProviderType tileProviderType) { - return ldproxyCfg.getEntityFactories().get(entityType.toString(), tileProviderType.toString()); - } - static OgcApiDataV2.Builder getBuilder( LdproxyCfg ldproxyCfg, EntityType entityType, ServiceType serviceType) { return ((OgcApiDataV2.Builder) getFactory(ldproxyCfg, entityType, serviceType).emptyDataBuilder()); } + static EntityFactory getFactory( + LdproxyCfg ldproxyCfg, + EntityType entityType, + ProviderType providerType, + TileProviderType tileProviderType) { + return ldproxyCfg + .getEntityFactories() + .get( + entityType.toString(), + String.format("%s/%s", providerType.toString(), tileProviderType.toString())); + } + static TileProviderData.Builder getBuilder( - LdproxyCfg ldproxyCfg, EntityType entityType, TileProviderType tileProviderType) { + LdproxyCfg ldproxyCfg, + EntityType entityType, + ProviderType providerType, + TileProviderType tileProviderType) { return ((TileProviderData.Builder) - getFactory(ldproxyCfg, entityType, tileProviderType).emptyDataBuilder()); + getFactory(ldproxyCfg, entityType, providerType, tileProviderType).emptyDataBuilder()) + .providerType(providerType.toString()) + .providerSubType(tileProviderType.toString()); } enum Type { From 0018973cfbcc42e95d2c80f12379c631f637e248 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 29 Aug 2025 16:28:46 +0200 Subject: [PATCH 14/19] first implementation step tileProvider --- .../de/ii/xtraplatform/cli/AutoHandler.java | 828 +++++++++--------- 1 file changed, 418 insertions(+), 410 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 32d4562..aaadc31 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -14,6 +14,7 @@ import de.ii.xtraplatform.features.sql.domain.ImmutableFeatureProviderSqlData; import de.ii.xtraplatform.tiles.domain.TileProviderFeaturesData; import de.ii.xtraplatform.values.domain.Identifier; + import java.io.File; import java.io.IOException; import java.net.URI; @@ -23,499 +24,506 @@ import java.util.function.Consumer; public class AutoHandler { - public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { - if (Objects.isNull(ldproxyCfg)) { - return Result.failure("Not connected to store"); - } + public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { + if (Objects.isNull(ldproxyCfg)) { + return Result.failure("Not connected to store"); + } - ldproxyCfg.initStore(); + ldproxyCfg.initStore(); - if (!parameters.containsKey("id")) { - return Result.failure("No id given"); - } + if (!parameters.containsKey("id")) { + return Result.failure("No id given"); + } - String id = parameters.get("id"); + String id = parameters.get("id"); - if (id.length() < 3) { - return Result.failure("Id has to be at least 3 characters long"); - } + if (id.length() < 3) { + return Result.failure("Id has to be at least 3 characters long"); + } - Identifier identifier = Identifier.from(id, "providers"); + Identifier identifier = Identifier.from(id, "providers"); - if (ldproxyCfg.getEntityDataStore().has(identifier)) { - return Result.failure("A provider with id '" + id + "' already exists"); - } + if (ldproxyCfg.getEntityDataStore().has(identifier)) { + return Result.failure("A provider with id '" + id + "' already exists"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("PGIS") - && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { - return Result.failure("Host is required for PGIS connection"); - } + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("PGIS") + && (!parameters.containsKey("host") || parameters.get("host").isBlank())) { + return Result.failure("Host is required for PGIS connection"); + } - if (parameters.containsKey("featureProviderType") - && parameters.get("featureProviderType").equals("WFS")) { - if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { - return Result.failure("URL is required for WFS connection"); - } - try { - URI uri = URI.create(parameters.get("url")); - if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { - return Result.failure("Invalid URL scheme for WFS connection"); + if (parameters.containsKey("featureProviderType") + && parameters.get("featureProviderType").equals("WFS")) { + if (!parameters.containsKey("url") || parameters.get("url").isBlank()) { + return Result.failure("URL is required for WFS connection"); + } + try { + URI uri = URI.create(parameters.get("url")); + if (!Objects.equals(uri.getScheme(), "http") && !Objects.equals(uri.getScheme(), "https")) { + return Result.failure("Invalid URL scheme for WFS connection"); + } + } catch (IllegalArgumentException e) { + return Result.failure("Invalid URL for WFS connection"); + } } - } catch (IllegalArgumentException e) { - return Result.failure("Invalid URL for WFS connection"); - } - } - return Result.empty(); - } - - public static Result check( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - - // TODO: check connectionInfo - - return Result.ok("All good"); - } - - public static Result analyze( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug) { - Result result = new Result(); - - try { - FeatureProviderDataV2 featureProvider = - parseFeatureProvider(parameters, ldproxyCfg, Map.of()); - - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - - Map> types = autoFactory.analyze(featureProvider); - - result.success("All good"); - result.details("types", types); - } catch (Throwable e) { - e.printStackTrace(); - if (e instanceof RuntimeException - && Objects.nonNull(e.getCause()) - && Objects.nonNull(e.getCause().getMessage())) { - result.error(e.getCause().getMessage()); - } else if (Objects.nonNull(e.getMessage())) { - result.error(e.getMessage()); - } + return Result.empty(); } - return result; - } - - public static Result generate( - Map parameters, - LdproxyCfg ldproxyCfg, - Optional path, - boolean verbose, - boolean debug, - Map> types, - Consumer tracker) { - Result result = new Result(); - - System.out.println("Initial types: " + types); - - try { - String createOption = parameters.get("createOption"); - String selectedConfig = parameters.get("selectedConfig"); - String newId = parameters.get("id"); - Map typeObject = parseTypeObject(parameters.get("typeObject")); - - if ("fromScratch".equalsIgnoreCase(createOption)) { - return generateBasicEntity(parameters, ldproxyCfg, typeObject); - } - - if ("copy".equalsIgnoreCase(createOption)) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } + public static Result check( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { - File sourceFile = new File(selectedConfig); - if (!sourceFile.exists()) { - return Result.failure("Selected config file does not exist: " + selectedConfig); - } + // TODO: check connectionInfo - Map yamlContent = - ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); + return Result.ok("All good"); + } - if (yamlContent.containsKey("id")) { - yamlContent.put("id", newId); + public static Result analyze( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug) { + Result result = new Result(); + + try { + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + + Map> types = autoFactory.analyze(featureProvider); + + result.success("All good"); + result.details("types", types); + } catch (Throwable e) { + e.printStackTrace(); + if (e instanceof RuntimeException + && Objects.nonNull(e.getCause()) + && Objects.nonNull(e.getCause().getMessage())) { + result.error(e.getCause().getMessage()); + } else if (Objects.nonNull(e.getMessage())) { + result.error(e.getMessage()); + } } - File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); - - result.success("Config copied successfully"); - result.details( - "new_files", - List.of(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString())); return result; - } + } - if (types == null || types.isEmpty()) { - if (selectedConfig == null || selectedConfig.isBlank()) { - return Result.failure("No selectedConfig provided in parameters"); - } + public static Result generate( + Map parameters, + LdproxyCfg ldproxyCfg, + Optional path, + boolean verbose, + boolean debug, + Map> types, + Consumer tracker) { + Result result = new Result(); + + System.out.println("Initial types: " + types); + + try { + String createOption = parameters.get("createOption"); + String selectedConfig = parameters.get("selectedConfig"); + String newId = parameters.get("id"); + Map typeObject = parseTypeObject(parameters.get("typeObject")); + + if ("fromScratch".equalsIgnoreCase(createOption)) { + return generateBasicEntity(parameters, ldproxyCfg, typeObject); + } + + if ("copy".equalsIgnoreCase(createOption)) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } + + File sourceFile = new File(selectedConfig); + if (!sourceFile.exists()) { + return Result.failure("Selected config file does not exist: " + selectedConfig); + } + + Map yamlContent = + ldproxyCfg.getObjectMapper().readValue(sourceFile, Map.class); + + if (yamlContent.containsKey("id")) { + yamlContent.put("id", newId); + } + + File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); + + result.success("Config copied successfully"); + result.details( + "new_files", + List.of(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString())); + return result; + } + + if (types == null || types.isEmpty()) { + if (selectedConfig == null || selectedConfig.isBlank()) { + return Result.failure("No selectedConfig provided in parameters"); + } - Map cfgJava = - ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); + Map cfgJava = + ldproxyCfg.getObjectMapper().readValue(new File(selectedConfig), Map.class); - types = determineTypes(cfgJava); - } + types = determineTypes(cfgJava); + } + + System.out.println("New types: " + types); + + long count = types.values().stream().mapToLong(List::size).sum(); + + Consumer>> tracker2 = + progress -> { + long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); + String currentTable = + progress.entrySet().stream() + .skip(progress.size() - 1) + .map( + entry -> + entry.getKey() + + "." + + entry.getValue().get(entry.getValue().size() - 1)) + .findFirst() + .orElse("???"); + + System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); + + Map details = + Map.of( + "currentCount", + current, + "targetCount", + count, + "currentTable", + currentTable, + "progress", + progress); + + System.out.println("details: " + details); + tracker.accept(Result.ok("progress", details)); + }; + + List newFiles = new ArrayList<>(); + + if (typeObject.getOrDefault("provider", true)) { + FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); + + AutoEntityFactory autoFactory = + getAutoFactory( + ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); - System.out.println("New types: " + types); + FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); - long count = types.values().stream().mapToLong(List::size).sum(); + ldproxyCfg.writeEntity(entityData); - Consumer>> tracker2 = - progress -> { - long current = Math.max(0, progress.values().stream().mapToLong(List::size).sum() - 1); - String currentTable = - progress.entrySet().stream() - .skip(progress.size() - 1) - .map( - entry -> - entry.getKey() - + "." - + entry.getValue().get(entry.getValue().size() - 1)) - .findFirst() - .orElse("???"); + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } - System.out.println("PROGRESS " + current + "/" + count + " " + currentTable); + if (typeObject.getOrDefault("service", true)) { + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - Map details = - Map.of( - "currentCount", - current, - "targetCount", - count, - "currentTable", - currentTable, - "progress", - progress); + AutoEntityFactory autoFactory2 = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - System.out.println("details: " + details); - tracker.accept(Result.ok("progress", details)); - }; + Map> types2 = + types.containsKey("") ? types : Map.of("", new ArrayList<>(types.keySet())); - List newFiles = new ArrayList<>(); + System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - if (typeObject.getOrDefault("provider", true)) { - FeatureProviderDataV2 featureProvider = parseFeatureProvider(parameters, ldproxyCfg, types); + OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { + }); - AutoEntityFactory autoFactory = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), featureProvider.getEntitySubType()); + ldproxyCfg.writeEntity(entityData2); - FeatureProviderDataV2 entityData = autoFactory.generate(featureProvider, types, tracker2); + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) + .toString()); + } - ldproxyCfg.writeEntity(entityData); + if (typeObject.getOrDefault("tileProvider", true)) { + TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); - } + AutoEntityFactory autoFactory3 = getAutoFactory(ldproxyCfg, EntityType.PROVIDERS.toString(), tileProvider.getEntitySubType()); - if (typeObject.getOrDefault("service", true)) { - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + Map> types2 = types.containsKey("") ? types : Map.of("", new ArrayList<>(types.keySet())); - AutoEntityFactory autoFactory2 = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + TileProviderFeaturesData entityData3 = autoFactory3.generate(tileProvider, types2, ignore -> { + }); - Map> types2 = - types.containsKey("") ? types : Map.of("", new ArrayList<>(types.keySet())); + ldproxyCfg.writeEntity(entityData3); - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} + newFiles.add(ldproxyCfg.getDataDirectory().relativize(ldproxyCfg.getEntityPath(entityData3).normalize()).toString()); + } - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> {}); + result.success("All good"); - ldproxyCfg.writeEntity(entityData2); + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + return result; + } catch (Throwable e) { + e.printStackTrace(); + return Result.failure("Unexpected error: " + e.getMessage()); + } + } - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData2).normalize()) - .toString()); - } + private static AutoEntityFactory getAutoFactory( + LdproxyCfg ldproxyCfg, String type, Optional subType) { + EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); - /*TODO - TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); + AutoEntityFactory autoFactory = + factory + .auto() + .orElseThrow( + () -> + new IllegalArgumentException( + "No auto factory found for entity type " + factory.fullType())); + return autoFactory; + } - AutoEntityFactory autoFactory3 = - getAutoFactory( - ldproxyCfg, EntityType.PROVIDERS.toString(), tileProvider.getEntitySubType()); + private static FeatureProviderDataV2 parseFeatureProvider( + Map parameters, LdproxyCfg ldproxyCfg, Map> types) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } - TileProviderFeaturesData entityData3 = - autoFactory3.generate(tileProvider, types2, ignore -> {});*/ + String id = parameters.get("id"); - result.success("All good"); + String featureProviderTypeString = parameters.get("featureProviderType"); - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); - } - return result; - } catch (Throwable e) { - e.printStackTrace(); - return Result.failure("Unexpected error: " + e.getMessage()); - } - } - - private static AutoEntityFactory getAutoFactory( - LdproxyCfg ldproxyCfg, String type, Optional subType) { - EntityFactory factory = ldproxyCfg.getEntityFactories().get(type, subType); - - AutoEntityFactory autoFactory = - factory - .auto() - .orElseThrow( - () -> - new IllegalArgumentException( - "No auto factory found for entity type " + factory.fullType())); - return autoFactory; - } - - private static FeatureProviderDataV2 parseFeatureProvider( - Map parameters, LdproxyCfg ldproxyCfg, Map> types) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); + FeatureProviderType featureProviderType; + try { + featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Invalid featureProviderType: " + + featureProviderTypeString + + ". Expected one of: " + + Arrays.toString(FeatureProviderType.values()), + e); + } + + System.out.println("new featureProviderType: " + featureProviderType); + System.out.println("myParameters: " + parameters); + + FeatureProviderDataV2.Builder builder = + AutoTypes.getBuilder( + ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) + .id(id); + + switch (featureProviderType) { + case PGIS: + return parseFeatureProviderPgis( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); + case GPKG: + return parseFeatureProviderGpkg( + (ImmutableFeatureProviderSqlData.Builder) builder, parameters); + case WFS: + return parseFeatureProviderWfs( + (ImmutableFeatureProviderWfsData.Builder) builder, parameters); + } + + return builder.build(); } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + + private static FeatureProviderDataV2 parseFeatureProviderPgis( + ImmutableFeatureProviderSqlData.Builder builder, + Map parameters, + Map> types) { + Set schemas = types.keySet(); + + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.PGIS.name()) + .host(Optional.ofNullable(parameters.get("host"))) + .database(parameters.get("database")) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) + .schemas(schemas) + .poolBuilder(); + + return builder.build(); } - String id = parameters.get("id"); + private static FeatureProviderDataV2 parseFeatureProviderGpkg( + ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { - String featureProviderTypeString = parameters.get("featureProviderType"); + builder + .connectionInfoBuilder() + .dialect(ConnectionInfoSql.Dialect.GPKG.name()) + .database(parameters.get("database")) + .poolBuilder(); - FeatureProviderType featureProviderType; - try { - featureProviderType = FeatureProviderType.valueOf(featureProviderTypeString); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException( - "Invalid featureProviderType: " - + featureProviderTypeString - + ". Expected one of: " - + Arrays.toString(FeatureProviderType.values()), - e); + return builder.build(); } - System.out.println("new featureProviderType: " + featureProviderType); - System.out.println("myParameters: " + parameters); - - FeatureProviderDataV2.Builder builder = - AutoTypes.getBuilder( - ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) - .id(id); - - switch (featureProviderType) { - case PGIS: - return parseFeatureProviderPgis( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters, types); - case GPKG: - return parseFeatureProviderGpkg( - (ImmutableFeatureProviderSqlData.Builder) builder, parameters); - case WFS: - return parseFeatureProviderWfs( - (ImmutableFeatureProviderWfsData.Builder) builder, parameters); - } + private static FeatureProviderDataV2 parseFeatureProviderWfs( + ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderPgis( - ImmutableFeatureProviderSqlData.Builder builder, - Map parameters, - Map> types) { - Set schemas = types.keySet(); - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.PGIS.name()) - .host(Optional.ofNullable(parameters.get("host"))) - .database(parameters.get("database")) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map(pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))) - .schemas(schemas) - .poolBuilder(); - - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderGpkg( - ImmutableFeatureProviderSqlData.Builder builder, Map parameters) { - - builder - .connectionInfoBuilder() - .dialect(ConnectionInfoSql.Dialect.GPKG.name()) - .database(parameters.get("database")) - .poolBuilder(); - - return builder.build(); - } - - private static FeatureProviderDataV2 parseFeatureProviderWfs( - ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { - - System.out.println("WFS parameters: " + parameters); - - builder - .connectionInfoBuilder() - .uri(URI.create(parameters.get("url"))) - .user(Optional.ofNullable(parameters.get("user"))) - .password( - Optional.ofNullable(parameters.get("password")) - .map( - pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); - return builder.build(); - } - - private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + System.out.println("WFS parameters: " + parameters); + + builder + .connectionInfoBuilder() + .uri(URI.create(parameters.get("url"))) + .user(Optional.ofNullable(parameters.get("user"))) + .password( + Optional.ofNullable(parameters.get("password")) + .map( + pw -> Base64.getEncoder().encodeToString(pw.getBytes(StandardCharsets.UTF_8)))); + return builder.build(); } - String id = parameters.get("id"); + private static OgcApiDataV2 parseOgcApi(Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } - OgcApiDataV2.Builder builder = - AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); + String id = parameters.get("id"); - return builder.build(); - } + OgcApiDataV2.Builder builder = + AutoTypes.getBuilder(ldproxyCfg, EntityType.SERVICES, ServiceType.OGC_API).id(id); - private static TileProviderFeaturesData parseTileProvider( - Map parameters, LdproxyCfg ldproxyCfg) { - if (!parameters.containsKey("id")) { - throw new IllegalArgumentException("No id given"); - } - if (parameters.get("id").length() < 3) { - throw new IllegalArgumentException("Id has to be at least 3 characters long"); + return builder.build(); } - String id = parameters.get("id"); - - TileProviderFeaturesData.Builder builder = - (TileProviderFeaturesData.Builder) - AutoTypes.getBuilder( - ldproxyCfg, - EntityType.PROVIDERS, - ProviderType.TILE, - AutoTypes.TileProviderType.FEATURES) - .id(id); + private static TileProviderFeaturesData parseTileProvider( + Map parameters, LdproxyCfg ldproxyCfg) { + if (!parameters.containsKey("id")) { + throw new IllegalArgumentException("No id given"); + } + if (parameters.get("id").length() < 3) { + throw new IllegalArgumentException("Id has to be at least 3 characters long"); + } - return (TileProviderFeaturesData) builder.build(); - } + String id = parameters.get("id") + "-tiles"; - private static Map> determineTypes(Map yamlConfig) { - // Extract types - Map yamlTypes = (Map) yamlConfig.get("types"); - Map> extractedTypes = new HashMap<>(); + TileProviderFeaturesData.Builder builder = + (TileProviderFeaturesData.Builder) + AutoTypes.getBuilder( + ldproxyCfg, + EntityType.PROVIDERS, + ProviderType.TILE, + AutoTypes.TileProviderType.FEATURES) + .id(id); - if (yamlTypes != null) { - List values = new ArrayList<>(yamlTypes.keySet()); - extractedTypes.put("", values); + return (TileProviderFeaturesData) builder.build(); } - // Handle missing types - if (extractedTypes.isEmpty()) { - extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); + private static Map> determineTypes(Map yamlConfig) { + // Extract types + Map yamlTypes = (Map) yamlConfig.get("types"); + Map> extractedTypes = new HashMap<>(); + + if (yamlTypes != null) { + List values = new ArrayList<>(yamlTypes.keySet()); + extractedTypes.put("", values); + } + + // Handle missing types + if (extractedTypes.isEmpty()) { + extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); + } + + return extractedTypes; } - return extractedTypes; - } - - private static Map parseTypeObject(String typeObjectString) { - Map typeObject = new HashMap<>(); - if (typeObjectString != null && !typeObjectString.isBlank()) { - typeObjectString = typeObjectString.replace("{", "").replace("}", ""); - String[] entries = typeObjectString.split(","); - for (String entry : entries) { - String[] keyValue = entry.split("="); - if (keyValue.length == 2) { - typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + private static Map parseTypeObject(String typeObjectString) { + Map typeObject = new HashMap<>(); + if (typeObjectString != null && !typeObjectString.isBlank()) { + typeObjectString = typeObjectString.replace("{", "").replace("}", ""); + String[] entries = typeObjectString.split(","); + for (String entry : entries) { + String[] keyValue = entry.split("="); + if (keyValue.length == 2) { + typeObject.put(keyValue[0].trim(), Boolean.parseBoolean(keyValue[1].trim())); + } + } } - } + return typeObject; } - return typeObject; - } - private static Result generateBasicEntity( - Map parameters, LdproxyCfg ldproxyCfg, Map typeObject) { - Result result = new Result(); + private static Result generateBasicEntity( + Map parameters, LdproxyCfg ldproxyCfg, Map typeObject) { + Result result = new Result(); - if (parameters.containsKey("id")) { - String newId = parameters.get("id"); + if (parameters.containsKey("id")) { + String newId = parameters.get("id"); - if (newId == null || newId.isBlank()) { - return Result.failure("No id provided in parameters"); - } + if (newId == null || newId.isBlank()) { + return Result.failure("No id provided in parameters"); + } - List newFiles = new ArrayList<>(); + List newFiles = new ArrayList<>(); - try { - if (typeObject.getOrDefault("provider", true)) { - parameters.put("featureProviderType", "PGIS"); + try { + if (typeObject.getOrDefault("provider", true)) { + parameters.put("featureProviderType", "PGIS"); - FeatureProviderDataV2 featureProvider = - parseFeatureProvider(parameters, ldproxyCfg, Map.of()); + FeatureProviderDataV2 featureProvider = + parseFeatureProvider(parameters, ldproxyCfg, Map.of()); - ldproxyCfg.writeEntity(featureProvider); + ldproxyCfg.writeEntity(featureProvider); - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(featureProvider).normalize()) - .toString()); - } + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(featureProvider).normalize()) + .toString()); + } - if (typeObject.getOrDefault("service", true)) { - OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); + if (typeObject.getOrDefault("service", true)) { + OgcApiDataV2 ogcApi = parseOgcApi(parameters, ldproxyCfg); - AutoEntityFactory autoFactory = - getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); + AutoEntityFactory autoFactory = + getAutoFactory(ldproxyCfg, EntityType.SERVICES.toString(), ogcApi.getEntitySubType()); - OgcApiDataV2 entityData = autoFactory.generate(ogcApi, Map.of(), ignore -> {}); + OgcApiDataV2 entityData = autoFactory.generate(ogcApi, Map.of(), ignore -> { + }); - ldproxyCfg.writeEntity(entityData); + ldproxyCfg.writeEntity(entityData); - newFiles.add( - ldproxyCfg - .getDataDirectory() - .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) - .toString()); - } + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(entityData).normalize()) + .toString()); + } - result.success("Minimal config created successfully"); - if (!newFiles.isEmpty()) { - result.details("new_files", newFiles); + result.success("Minimal config created successfully"); + if (!newFiles.isEmpty()) { + result.details("new_files", newFiles); + } + } catch (IOException e) { + return Result.failure("Failed to write minimal config: " + e.getMessage()); + } } - } catch (IOException e) { - return Result.failure("Failed to write minimal config: " + e.getMessage()); - } - } - return result; - } + return result; + } } From 3e9dc1d314582cfc027475e87c640dd00b4e4b63 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 29 Aug 2025 17:21:28 +0200 Subject: [PATCH 15/19] add tile provider handling to config creation --- .../de/ii/xtraplatform/cli/AutoHandler.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index aaadc31..9eb4e74 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -147,6 +147,10 @@ public static Result generate( return Result.failure("No id provided in parameters"); } + if (selectedConfig != null && selectedConfig.contains("-tiles")) { + newId = newId + "-tiles"; + } + File sourceFile = new File(selectedConfig); if (!sourceFile.exists()) { return Result.failure("Selected config file does not exist: " + selectedConfig); @@ -436,7 +440,6 @@ private static TileProviderFeaturesData parseTileProvider( } private static Map> determineTypes(Map yamlConfig) { - // Extract types Map yamlTypes = (Map) yamlConfig.get("types"); Map> extractedTypes = new HashMap<>(); @@ -445,7 +448,6 @@ private static Map> determineTypes(Map yaml extractedTypes.put("", values); } - // Handle missing types if (extractedTypes.isEmpty()) { extractedTypes.put("", new ArrayList<>(yamlTypes != null ? yamlTypes.keySet() : List.of())); } @@ -515,6 +517,18 @@ private static Result generateBasicEntity( .toString()); } + if (typeObject.getOrDefault("tileProvider", true)) { + TileProviderFeaturesData tileProvider = parseTileProvider(parameters, ldproxyCfg); + + ldproxyCfg.writeEntity(tileProvider); + + newFiles.add( + ldproxyCfg + .getDataDirectory() + .relativize(ldproxyCfg.getEntityPath(tileProvider).normalize()) + .toString()); + } + result.success("Minimal config created successfully"); if (!newFiles.isEmpty()) { result.details("new_files", newFiles); From 0e82488f2fe8cb9705bb8c2527d7ea613d0574aa Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Tue, 2 Sep 2025 10:09:38 +0200 Subject: [PATCH 16/19] remove logging --- .../main/java/de/ii/xtraplatform/cli/AutoHandler.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 9eb4e74..29bae7f 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -127,8 +127,6 @@ public static Result generate( Consumer tracker) { Result result = new Result(); - System.out.println("Initial types: " + types); - try { String createOption = parameters.get("createOption"); String selectedConfig = parameters.get("selectedConfig"); @@ -184,8 +182,6 @@ public static Result generate( types = determineTypes(cfgJava); } - System.out.println("New types: " + types); - long count = types.values().stream().mapToLong(List::size).sum(); Consumer>> tracker2 = @@ -248,8 +244,6 @@ public static Result generate( Map> types2 = types.containsKey("") ? types : Map.of("", new ArrayList<>(types.keySet())); - System.out.println("types2" + types2); // {=[flurstueck]} instead of {ave=[Flurstueck]} - OgcApiDataV2 entityData2 = autoFactory2.generate(ogcApi, types2, ignore -> { }); @@ -328,9 +322,6 @@ private static FeatureProviderDataV2 parseFeatureProvider( e); } - System.out.println("new featureProviderType: " + featureProviderType); - System.out.println("myParameters: " + parameters); - FeatureProviderDataV2.Builder builder = AutoTypes.getBuilder( ldproxyCfg, EntityType.PROVIDERS, ProviderType.FEATURE, featureProviderType) @@ -387,8 +378,6 @@ private static FeatureProviderDataV2 parseFeatureProviderGpkg( private static FeatureProviderDataV2 parseFeatureProviderWfs( ImmutableFeatureProviderWfsData.Builder builder, Map parameters) { - System.out.println("WFS parameters: " + parameters); - builder .connectionInfoBuilder() .uri(URI.create(parameters.get("url"))) From a45707b1bcf9188eb94ef6b84f4265c9118e0fb3 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Tue, 2 Sep 2025 16:41:05 +0200 Subject: [PATCH 17/19] handle selectedSubConfigsSelector in Auto copy option --- .../java/de/ii/xtraplatform/cli/AutoHandler.java | 13 +++++++++++++ .../main/java/de/ii/xtraplatform/cli/cmd/Auto.java | 3 +++ 2 files changed, 16 insertions(+) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 29bae7f..d2e1b61 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -138,6 +138,19 @@ public static Result generate( } if ("copy".equalsIgnoreCase(createOption)) { + //Get related configurations (selectedSubConfigsSelector) + String selectedSubConfigsSelector = parameters.get("selectedSubConfigsSelector"); + + String[] elements = selectedSubConfigsSelector.replaceAll("[\\[\\]]", "").split(","); + + List cleanedPaths = new ArrayList<>(); + for (String element : elements) { + String cleaned = element.replaceAll("\\s*\\(.*\\)", "").trim(); + cleanedPaths.add(cleaned); + } + System.out.println("Cleaned Paths: " + cleanedPaths); + + if (selectedConfig == null || selectedConfig.isBlank()) { return Result.failure("No selectedConfig provided in parameters"); } diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java index 25b02a4..0d208e8 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/cmd/Auto.java @@ -34,6 +34,9 @@ public Auto( if (parameters.containsKey("typeObject") && parameters.get("typeObject") instanceof Map) { this.parameters.put("typeObject", parameters.get("typeObject").toString()); } + if (parameters.containsKey("selectedSubConfigsSelector") && parameters.get("selectedSubConfigsSelector") instanceof List) { + this.parameters.put("selectedSubConfigsSelector", parameters.get("selectedSubConfigsSelector").toString()); + } this.types = parseTypes(parameters); this.tracker = tracker; } From 60c3a16f5cf24b130e1ce1015c4d4be8a7049300 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Tue, 2 Sep 2025 17:15:16 +0200 Subject: [PATCH 18/19] enhance config copy to handle sub-configs --- .../de/ii/xtraplatform/cli/AutoHandler.java | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index d2e1b61..9c8b54c 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -140,15 +140,15 @@ public static Result generate( if ("copy".equalsIgnoreCase(createOption)) { //Get related configurations (selectedSubConfigsSelector) String selectedSubConfigsSelector = parameters.get("selectedSubConfigsSelector"); - - String[] elements = selectedSubConfigsSelector.replaceAll("[\\[\\]]", "").split(","); - List cleanedPaths = new ArrayList<>(); - for (String element : elements) { - String cleaned = element.replaceAll("\\s*\\(.*\\)", "").trim(); - cleanedPaths.add(cleaned); + + if (selectedSubConfigsSelector != null && !selectedSubConfigsSelector.isBlank()) { + cleanedPaths = Arrays.stream( + selectedSubConfigsSelector.replaceAll("[\\[\\]]", "").split(",")) + .map(e -> e.replaceAll("\\s*\\(.*\\)", "").trim()) + .filter(e -> !e.isEmpty()) + .toList(); } - System.out.println("Cleaned Paths: " + cleanedPaths); if (selectedConfig == null || selectedConfig.isBlank()) { @@ -177,10 +177,33 @@ public static Result generate( File targetFile = new File(new File(selectedConfig).getParent(), newId + ".yml"); ldproxyCfg.getObjectMapper().writeValue(targetFile, yamlContent); + List filesToAdd = new ArrayList<>(); + filesToAdd.add(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString()); + + if (cleanedPaths.size()>0) { + for (String pathToCfg : cleanedPaths) { + File subSourceFile = new File(pathToCfg); + if (!subSourceFile.exists()) { + return Result.failure("Selected sub-config file does not exist: " + pathToCfg); + } + + Map subYamlContent = + ldproxyCfg.getObjectMapper().readValue(subSourceFile, Map.class); + + String subConfigId = newId; + if (subYamlContent.containsKey("id")) { + subYamlContent.put("id", subConfigId); + } + + File subTargetFile = new File(subSourceFile.getParent(), subConfigId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(subTargetFile, subYamlContent); + + filesToAdd.add(ldproxyCfg.getDataDirectory().relativize(subTargetFile.toPath()).toString()); + } + } + result.success("Config copied successfully"); - result.details( - "new_files", - List.of(ldproxyCfg.getDataDirectory().relativize(targetFile.toPath()).toString())); + result.details("new_files", filesToAdd); return result; } From 1fb3c95c2bf08d95fcbf13787e8c9d00c0198a83 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Tue, 2 Sep 2025 17:34:50 +0200 Subject: [PATCH 19/19] handle JSON sub-config files in AutoHandler --- .../de/ii/xtraplatform/cli/AutoHandler.java | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java index 9c8b54c..3c70282 100644 --- a/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java +++ b/libxtracfg/java/src/main/java/de/ii/xtraplatform/cli/AutoHandler.java @@ -22,6 +22,8 @@ import java.util.*; import java.util.Map; import java.util.function.Consumer; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; public class AutoHandler { public static Result preCheck(Map parameters, LdproxyCfg ldproxyCfg) { @@ -187,18 +189,34 @@ public static Result generate( return Result.failure("Selected sub-config file does not exist: " + pathToCfg); } - Map subYamlContent = - ldproxyCfg.getObjectMapper().readValue(subSourceFile, Map.class); - - String subConfigId = newId; - if (subYamlContent.containsKey("id")) { - subYamlContent.put("id", subConfigId); + // Check if the file ends with .json + if (pathToCfg.endsWith(".json")) { + // Determine the parent directory and create a new folder with the id + File parentDir = subSourceFile.getParentFile().getParentFile(); // Go one directory up + File targetDir = new File(parentDir, newId.replaceAll("\\.json|\\.yaml", "")); + if (!targetDir.exists() && !targetDir.mkdirs()) { + return Result.failure("Failed to create target directory: " + targetDir.getAbsolutePath()); + } + + // Copy the file to the new directory + File targetFile2 = new File(targetDir, subSourceFile.getName()); + Files.copy(subSourceFile.toPath(), targetFile2.toPath(), StandardCopyOption.REPLACE_EXISTING); + + filesToAdd.add(ldproxyCfg.getDataDirectory().relativize(targetFile2.toPath()).toString()); + } else { + Map subYamlContent = + ldproxyCfg.getObjectMapper().readValue(subSourceFile, Map.class); + + String subConfigId = newId; + if (subYamlContent.containsKey("id")) { + subYamlContent.put("id", subConfigId); + } + + File subTargetFile = new File(subSourceFile.getParent(), subConfigId + ".yml"); + ldproxyCfg.getObjectMapper().writeValue(subTargetFile, subYamlContent); + + filesToAdd.add(ldproxyCfg.getDataDirectory().relativize(subTargetFile.toPath()).toString()); } - - File subTargetFile = new File(subSourceFile.getParent(), subConfigId + ".yml"); - ldproxyCfg.getObjectMapper().writeValue(subTargetFile, subYamlContent); - - filesToAdd.add(ldproxyCfg.getDataDirectory().relativize(subTargetFile.toPath()).toString()); } }