diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/AbstractTile3dProvider.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/AbstractTile3dProvider.java index ff80cfa10..54ead20cc 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/AbstractTile3dProvider.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/AbstractTile3dProvider.java @@ -43,22 +43,30 @@ protected void onStarted() { (from, to) -> { try (MDC.MDCCloseable closeable = LogContext.putCloseable(CONTEXT.SERVICE, getData().getId())) { - LOGGER.info("3dTile provider with id '{}' state changed: {}", getId(), getState()); + if (LOGGER.isInfoEnabled()) { + LOGGER.info("3dTile provider with id '{}' state changed: {}", getId(), getState()); + } } }, true); - LOGGER.info("3dTile provider with id '{}' started successfully.", getId()); + if (LOGGER.isInfoEnabled()) { + LOGGER.info("3dTile provider with id '{}' started successfully.", getId()); + } } @Override protected void onReloaded(boolean forceReload) { - LOGGER.info("3dTile provider with id '{}' reloaded successfully.", getId()); + if (LOGGER.isInfoEnabled()) { + LOGGER.info("3dTile provider with id '{}' reloaded successfully.", getId()); + } } @Override protected void onStopped() { - LOGGER.info("3dTile provider with id '{}' stopped.", getId()); + if (LOGGER.isInfoEnabled()) { + LOGGER.info("3dTile provider with id '{}' stopped.", getId()); + } } @Override diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dGeneratorFeatures.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dGeneratorFeatures.java index e64437128..f8f3b6947 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dGeneratorFeatures.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dGeneratorFeatures.java @@ -85,10 +85,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +@SuppressWarnings({"PMD.GodClass", "PMD.CyclomaticComplexity", "PMD.TooManyMethods"}) public class Tile3dGeneratorFeatures extends AbstractVolatileComposed implements Tile3dGenerator { private static final Logger LOGGER = LoggerFactory.getLogger(Tile3dGeneratorFeatures.class); - private static ObjectMapper MAPPER = + private static final ObjectMapper MAPPER = new ObjectMapper() .registerModule(new Jdk8Module()) .registerModule(new GuavaModule()) @@ -162,11 +163,7 @@ private void initAsync(VolatileRegistry volatileRegistry) { } DelayedVolatile delayedVolatile = - new DelayedVolatile<>( - volatileRegistry, - String.format("generator.%s", featureProviderId), - false, - "generation"); + createDelayedVolatile(volatileRegistry, featureProviderId); addSubcomponent(delayedVolatile, true); @@ -257,19 +254,7 @@ public TileMatrixSetData getTileMatrixSetData( .build()); for (int level = 0; level <= levels.upperEndpoint(); level++) { - double resolution = 360.0 / (256 * Math.pow(2, level)); - builder.addTileMatrices( - new ImmutableTileMatrix.Builder() - .id(String.valueOf(level)) - .tileWidth(256) - .tileHeight(256) - .matrixWidth((long) Math.pow(2, level)) - .matrixHeight((long) Math.pow(2, level)) - // not needed for TileWalker, but mandatory - .scaleDenominator(BigDecimal.valueOf(0)) - .cellSize(BigDecimal.valueOf(0)) - .pointOfOrigin(new BigDecimal[] {BigDecimal.valueOf(0), BigDecimal.valueOf(0)}) - .build()); + builder.addTileMatrices(createTileMatrix(level)); } return builder.build(); @@ -329,11 +314,11 @@ public boolean isTileAvailable(Subtree parent, Tile3dCoordinates tile, int subtr int localLevel = tile.getLevel() % subtreeLevels; return always - || (buffer.length > 0 + || buffer.length > 0 && getAvailability( buffer, localLevel, - TileTree.getMortonCurveIndex(localLevel, tile.getCol(), tile.getRow()))); + TileTree.getMortonCurveIndex(localLevel, tile.getCol(), tile.getRow())); } @Override @@ -348,7 +333,7 @@ public boolean isSubtreeAvailable(Subtree parent, TileTree child, int subtreeLev && childSubtreeAvailability.getConstant().filter(c -> c == 1).isPresent(); return always - || (buffer.length > 0 && getAvailability(buffer, child.getMortonCurveIndex(subtreeLevels))); + || buffer.length > 0 && getAvailability(buffer, child.getMortonCurveIndex(subtreeLevels)); } @Override @@ -512,6 +497,27 @@ private FeatureProvider getFeatureProvider(Tileset3dFeatures tileset) { String.format("Feature provider with id '%s' not found.", featureProviderId))); } + private DelayedVolatile createDelayedVolatile( + VolatileRegistry volatileRegistry, String featureProviderId) { + return new DelayedVolatile<>( + volatileRegistry, String.format("generator.%s", featureProviderId), false, "generation"); + } + + private ImmutableTileMatrix createTileMatrix(int level) { + return new ImmutableTileMatrix.Builder() + .id(String.valueOf(level)) + .tileWidth(256) + .tileHeight(256) + .matrixWidth((long) Math.pow(2, level)) + .matrixHeight((long) Math.pow(2, level)) + // not needed for TileWalker, but mandatory + .scaleDenominator(BigDecimal.valueOf(0)) + .cellSize(BigDecimal.valueOf(0)) + .pointOfOrigin(new BigDecimal[] {BigDecimal.valueOf(0), BigDecimal.valueOf(0)}) + .build(); + } + + @SuppressWarnings("PMD.CognitiveComplexity") private void processZ( FeatureProvider featureProvider, Tileset3dFeatures tileset, @@ -682,7 +688,7 @@ private static void setAvailability( availability[byteIndex] |= 1 << bitIndex; } - @SuppressWarnings("PMD.ExcessiveMethodLength") + @SuppressWarnings({"PMD.ExcessiveMethodLength", "PMD.CognitiveComplexity", "PMD.NPathComplexity"}) private static ImmutableSubtree buildSubtree( int subtreeLevels, int size, @@ -815,7 +821,7 @@ private static Optional computeExclusionPolygon( */ // handle the special cases first - if (tile.getCol() == 0 && tile.getRow() == (factor - 1)) { + if (tile.getCol() == 0 && tile.getRow() == factor - 1) { return Optional.empty(); } else if (tile.getCol() == 0) { double xmin = bbox.getXmin() + dx / factor * tile.getCol(); @@ -823,7 +829,7 @@ private static Optional computeExclusionPolygon( double ymin = bbox.getYmin() + dy / factor * (tile.getRow() + 1); double ymax = ymin + dy / factor; return Optional.of(Polygon.ofBbox(xmin, ymin, xmax, ymax, OgcCrs.CRS84)); - } else if (tile.getRow() == (factor - 1)) { + } else if (tile.getRow() == factor - 1) { double xmin = bbox.getXmin() + dx / factor * (tile.getCol() - 1); double xmax = xmin + dx / factor; double ymin = bbox.getYmin() + dy / factor * tile.getRow(); diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFeatures.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFeatures.java index c880ebec4..908334181 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFeatures.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFeatures.java @@ -65,7 +65,6 @@ import de.ii.xtraplatform.tiles3d.domain.spec.Tileset3d; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.nio.file.Path; import java.time.Instant; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.ArrayList; @@ -92,10 +91,12 @@ value = Tile3dProviderFeaturesData.PROVIDER_SUBTYPE) }, data = Tile3dProviderFeaturesData.class) +@SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods"}) public class Tile3dProviderFeatures extends AbstractTile3dProvider implements Tile3dProvider, Tile3dAccess, Tile3dSeeding { private static final Logger LOGGER = LoggerFactory.getLogger(Tile3dProviderFeatures.class); + private static final byte[] NO_CONTENT = new byte[0]; private final ResourceStore rootStore; private final Map metadata; @@ -175,23 +176,10 @@ private void init() { stores.put(tilesetCfg.getId(), store); } - List caches = - !getData().getCaches().isEmpty() - ? getData().getCaches() - : List.of( - new ImmutableCache3d.Builder() - .type(Cache3d.Type.DYNAMIC) - .levels( - getData() - .getTilesetDefaults() - .getLevels() - .getOrDefault("default", MinMax.of(0, 0))) - .tilesetLevels( - getData().getTilesets().entrySet().stream() - .collect( - Collectors.toMap( - Entry::getKey, e -> e.getValue().getLevels().get("default")))) - .build()); + List caches = getData().getCaches(); + if (caches.isEmpty()) { + caches = List.of(createDefaultCache()); + } initCaches(caches); @@ -199,42 +187,46 @@ private void init() { } private void initCaches(List caches) { - for (int i = 0; i < caches.size(); i++) { - Cache3d cache = caches.get(i); - + for (Cache3d cache : caches) { if (cache.getType() == Cache3d.Type.DYNAMIC) { - Map>> cacheRanges = getCacheRanges(cache); - Map> customTms = - cacheRanges.entrySet().stream() - .map( - entry -> - Map.entry( - entry.getKey(), - entry.getValue().entrySet().stream() - .map( - tmsEntry -> { - String tmsId = tmsEntry.getKey(); - TileMatrixSetData tmsData = - tileGenerator.getTileMatrixSetData( - entry.getKey(), tmsId, tmsEntry.getValue()); - return Map.entry( - tmsId, (TileMatrixSetBase) TileMatrixSet.custom(tmsData)); - }) - .collect(MapStreams.toMap()))) - .collect(MapStreams.toMap()); - Tile3dCacheDynamic current = - new Tile3dCacheDynamic(tileWalker, customTms, cacheRanges, cache.getSeeded()); - - generatorCaches.add(current); + generatorCaches.add(createDynamicCache(cache)); } } } - @Override - protected void onStopped() { - // unregisterChangeHandlers(); + private Cache3d createDefaultCache() { + return new ImmutableCache3d.Builder() + .type(Cache3d.Type.DYNAMIC) + .levels(getData().getTilesetDefaults().getLevels().getOrDefault("default", MinMax.of(0, 0))) + .tilesetLevels( + getData().getTilesets().entrySet().stream() + .collect( + Collectors.toMap(Entry::getKey, e -> e.getValue().getLevels().get("default")))) + .build(); + } - super.onStopped(); + private Tile3dCacheDynamic createDynamicCache(Cache3d cache) { + Map>> cacheRanges = getCacheRanges(cache); + Map> customTms = + cacheRanges.entrySet().stream() + .map( + entry -> + Map.entry( + entry.getKey(), + entry.getValue().entrySet().stream() + .map( + tmsEntry -> { + String tmsId = tmsEntry.getKey(); + TileMatrixSetData tmsData = + tileGenerator.getTileMatrixSetData( + entry.getKey(), tmsId, tmsEntry.getValue()); + return Map.entry( + tmsId, (TileMatrixSetBase) TileMatrixSet.custom(tmsData)); + }) + .collect(MapStreams.toMap()))) + .collect(MapStreams.toMap()); + + return new Tile3dCacheDynamic(tileWalker, customTms, cacheRanges, cache.getSeeded()); } @Override @@ -243,6 +235,7 @@ public Optional getMetadata(String tilesetId) { } @Override + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.AvoidDeeplyNestedIfStmts"}) public Optional getFile(Tile3dQuery tileQuery) throws IOException { Optional error = validate(tileQuery); @@ -277,10 +270,10 @@ public Optional getFile(Tile3dQuery tileQuery) throws IOException { true, shouldStore); - if (!shouldStore && bytes != null) { + if (!shouldStore && bytes.length > 0) { return Optional.of( ImmutableBlob.builder() - .path(Path.of(tileQuery.getFileName().get())) + .path(java.nio.file.Path.of(tileQuery.getFileName().get())) .lastModified(Instant.now().toEpochMilli()) .size(bytes.length) .contentSupplier(() -> new ByteArrayInputStream(bytes)) @@ -290,10 +283,10 @@ public Optional getFile(Tile3dQuery tileQuery) throws IOException { byte[] bytes = seedSubtree(tileQueryImplicit.toTileSubMatrix(), tileset, () -> {}, true, shouldStore); - if (!shouldStore && bytes != null) { + if (!shouldStore && bytes.length > 0) { return Optional.of( ImmutableBlob.builder() - .path(Path.of(tileQuery.getFileName().get())) + .path(java.nio.file.Path.of(tileQuery.getFileName().get())) .lastModified(Instant.now().toEpochMilli()) .size(bytes.length) .contentSupplier(() -> new ByteArrayInputStream(bytes)) @@ -363,6 +356,7 @@ public void seedSubtrees(Tile3dSeedingJob job, Consumer updateProgress) } } + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CyclomaticComplexity"}) private byte[] seedSubtree( TileSubMatrix coords, Tileset3dFeatures tileset, @@ -390,7 +384,7 @@ private byte[] seedSubtree( child.getCol(), child.getRow()); } - return null; + return NO_CONTENT; } byte[] subtreeBytes = @@ -405,7 +399,7 @@ private byte[] seedSubtree( coords.getColMin(), coords.getRowMin()); } - return null; + return NO_CONTENT; } } @@ -427,7 +421,7 @@ private byte[] seedSubtree( } finally { updateProgress2.run(); } - return null; + return NO_CONTENT; } @Override @@ -452,6 +446,7 @@ public void seedTiles( } } + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CyclomaticComplexity"}) private byte[] seedTiles( TileSubMatrix subMatrix, Tileset3dFeatures tileset, @@ -474,7 +469,7 @@ private byte[] seedTiles( } updateProgress2.accept((int) subMatrix.getNumberOfTiles()); - return null; + return NO_CONTENT; } byte[] subtreeBytes = store.getSubtree(parent.getLevel(), parent.getCol(), parent.getRow()); @@ -512,7 +507,7 @@ private byte[] seedTiles( } } } - return null; + return NO_CONTENT; } private Map validTilesets( @@ -521,7 +516,9 @@ private Map validTilesets( .filter( entry -> { if (!getData().getTilesets().containsKey(entry.getKey())) { - LOGGER.warn("Tileset with name '{}' not found", entry.getKey()); + if (LOGGER.isWarnEnabled()) { + LOGGER.warn("Tileset with name '{}' not found", entry.getKey()); + } return false; } return true; diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFiles.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFiles.java index 50f91e2d6..761966979 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFiles.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dProviderFiles.java @@ -28,7 +28,6 @@ import de.ii.xtraplatform.tiles3d.domain.spec.Tileset3d; import java.io.IOException; import java.io.InputStream; -import java.nio.file.Path; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; @@ -81,15 +80,17 @@ protected boolean onStartup() throws InterruptedException { for (Entry entry : getData().getTilesets().entrySet()) { Tileset3dFiles tilesetCfg = entry.getValue().mergeDefaults(getData().getTilesetDefaults()); - Path source = Path.of(tilesetCfg.getSource()); + java.nio.file.Path source = java.nio.file.Path.of(tilesetCfg.getSource()); try { if (!rootStore.has(source)) { throw new IllegalStateException("Could not find 3D Tiles tileset file: " + source); } - InputStream inputStream = rootStore.content(source).orElseThrow(); - Tileset3d tileset = objectMapper.readValue(inputStream, Tileset3d.class); + Tileset3d tileset; + try (InputStream inputStream = rootStore.content(source).orElseThrow()) { + tileset = objectMapper.readValue(inputStream, Tileset3d.class); + } tileset.validate(source); diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dSeedingJobCreator.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dSeedingJobCreator.java index 83c3ef3ab..f3029b752 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dSeedingJobCreator.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dSeedingJobCreator.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.time.Duration; import java.time.Instant; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -72,6 +73,7 @@ public int getConcurrency(JobSet jobSet) { } @Override + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { Tile3dSeedingJobSet seedingJobSet = getSetDetails(jobSet, jobQueue); boolean isCleanup = getDetails(job, jobQueue); @@ -105,6 +107,7 @@ public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { Map>> coverage = tileProvider.seeding().get().getCoverage(seedingJobSet.getTileSetParameters()); final int[] numSubtrees = {0}; + Map tileMatrixPartitionsByJobSize = new HashMap<>(); Set tilesets = new HashSet<>(); Set levels = new HashSet<>(); @@ -117,16 +120,19 @@ public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { tileMatrixSets.forEach( (tileMatrixSet, limits) -> { + Tile3dSeedingJob.Context jobContext = + createJobContext(tileProvider, seedingJobSet, jobSet, tileSet, tileMatrixSet); TileTree tileTree = null; for (TileMatrixSetLimits limit : limits) { - TileTree next = TileTree.from(TileSubMatrix.of(limit), cfg.getSubtreeLevels()); - tileTree = tileTree == null ? next : tileTree.merge(next); + tileTree = mergeTileTree(tileTree, limit, cfg); } if (Objects.nonNull(tileTree)) { int jobSize = getJobSize(tileTree); - TileMatrixPartitions tileMatrixPartitions = new TileMatrixPartitions(jobSize); + TileMatrixPartitions tileMatrixPartitions = + tileMatrixPartitionsByJobSize.computeIfAbsent( + jobSize, TileMatrixPartitions::new); Job rootJob = tileTree.accept( @@ -134,13 +140,9 @@ public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { Job subtreeJob = Tile3dSeedingJob.subtree( jobSet.getPriority(), - tileProvider.getId(), - tileSet, - tileMatrixSet, + jobContext, seedingJobSet.isReseed(), - Set.of(tt.toSubMatrix()), - Optional.of(seedingJobSet.getTileSetParameters().get(tileSet)), - jobSet.getId()); + Set.of(tt.toSubMatrix())); int total = subtreeJob.getTotal().get(); numSubtrees[0] += total; @@ -169,14 +171,9 @@ public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { Job contentJob = Tile3dSeedingJob.content( jobSet.getPriority(), - tileProvider.getId(), - tileSet, - tileMatrixSet, + jobContext, seedingJobSet.isReseed(), - Set.of(partition), - Optional.of( - seedingJobSet.getTileSetParameters().get(tileSet)), - jobSet.getId()); + Set.of(partition)); subtreeJob = subtreeJob.with(contentJob); @@ -240,12 +237,32 @@ private static int getJobSize(TileTree tileTree) { return 8; } else if (numberOfTiles <= 4096) { return 16; - } else if (numberOfTiles <= 16384) { + } else if (numberOfTiles <= 16_384) { return 64; } return 256; } + private static TileTree mergeTileTree( + TileTree currentTree, TileMatrixSetLimits limit, Tileset3dFeatures cfg) { + TileTree next = TileTree.from(TileSubMatrix.of(limit), cfg.getSubtreeLevels()); + return currentTree == null ? next : currentTree.merge(next); + } + + private static Tile3dSeedingJob.Context createJobContext( + Tile3dProviderFeatures tileProvider, + Tile3dSeedingJobSet seedingJobSet, + JobSet jobSet, + String tileSet, + String tileMatrixSet) { + return new Tile3dSeedingJob.Context( + tileProvider.getId(), + tileSet, + tileMatrixSet, + Optional.of(seedingJobSet.getTileSetParameters().get(tileSet)), + jobSet.getId()); + } + private void cleanup( JobSet jobSet, Tile3dProvider tileProvider, Tile3dSeedingJobSet seedingJobSet) throws IOException { diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dStorePlain.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dStorePlain.java index 1bef3fc28..4d58903ed 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dStorePlain.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/app/Tile3dStorePlain.java @@ -15,15 +15,20 @@ import de.ii.xtraplatform.tiles3d.domain.Tile3dStoreReadOnly; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.nio.file.Path; +import java.util.Locale; import java.util.Optional; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -class Tile3dStorePlain implements Tile3dStore { +@SuppressWarnings({"PMD.TooManyMethods", "PMD.ExcessiveMethodCount"}) +final class Tile3dStorePlain implements Tile3dStore { - private static final Logger LOGGER = LoggerFactory.getLogger(Tile3dStorePlain.class); + private static final String UNKNOWN_PATH = "__unknown__"; + + private final ResourceStore blobStore; + + private Tile3dStorePlain(ResourceStore blobStore) { + this.blobStore = blobStore; + } static Tile3dStoreReadOnly readOnly(ResourceStore blobStore) { return new Tile3dStorePlain(blobStore); @@ -33,14 +38,6 @@ static Tile3dStore readWrite(ResourceStore blobStore) { return new Tile3dStorePlain(blobStore); } - private static final String UNKNOWN_PATH = "__unknown__"; - - private final ResourceStore blobStore; - - private Tile3dStorePlain(ResourceStore blobStore) { - this.blobStore = blobStore; - } - @Override public boolean has(Tile3dQuery tile) throws IOException { return blobStore.has(path(tile)); @@ -60,7 +57,8 @@ public Optional isEmpty(Tile3dQuery tile) throws IOException { @Override public boolean isEmpty() throws IOException { - try (Stream paths = blobStore.walk(Path.of(""), 5, (p, a) -> a.isValue())) { + try (Stream paths = + blobStore.walk(java.nio.file.Path.of(""), 5, (p, a) -> a.isValue())) { return paths.findAny().isEmpty(); } catch (IOException e) { // ignore @@ -97,18 +95,18 @@ public void putContent(int level, int x, int y, byte[] tile) throws IOException blobStore.put(pathContent(level, x, y), new ByteArrayInputStream(tile)); } - private static Path path(Tile3dQuery tile) { - return Path.of(tile.getFileName().orElse(UNKNOWN_PATH)); + private static java.nio.file.Path path(Tile3dQuery tile) { + return java.nio.file.Path.of(tile.getFileName().orElse(UNKNOWN_PATH)); } - private static Path pathSubtree(int level, int x, int y) { + private static java.nio.file.Path pathSubtree(int level, int x, int y) { String fileName = String.format("%d_%d_%d.%s", level, x, y, "subtree"); - return Path.of(fileName); + return java.nio.file.Path.of(fileName); } - private static Path pathContent(int level, int x, int y) { + private static java.nio.file.Path pathContent(int level, int x, int y) { String fileName = String.format("%d_%d_%d.%s", level, x, y, "glb"); - return Path.of(fileName); + return java.nio.file.Path.of(fileName); } private static Blob applyContentType(Blob blob) { @@ -118,8 +116,9 @@ private static Blob applyContentType(Blob blob) { return blob.withPrecomputedContentType(contentType); } + @SuppressWarnings("PMD.CyclomaticComplexity") private static String contentType(String fileName) { - String ext = Files.getFileExtension(fileName).toLowerCase(); + String ext = Files.getFileExtension(fileName).toLowerCase(Locale.ROOT); switch (ext) { case "glb": diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/ChainedTile3dProvider.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/ChainedTile3dProvider.java index e6f48ae33..fe75fe710 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/ChainedTile3dProvider.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/ChainedTile3dProvider.java @@ -37,6 +37,7 @@ public TileResult getTile(Tile3dQuery tile) { TileResult getTile(Tile3dQuery tile) throws IOException; + @SuppressWarnings("PMD.CognitiveComplexity") default TileResult get(Tile3dQuery tile) { TileResult tileResult = TileResult.notFound(); diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dJobProcessor.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dJobProcessor.java index 152302a35..f64414bf4 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dJobProcessor.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dJobProcessor.java @@ -57,6 +57,7 @@ protected abstract void executeJob( throws IOException; @Override + @SuppressWarnings("PMD.CognitiveComplexity") public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { Tile3dSeedingJob seedingJob = getDetails(job, jobQueue); Tile3dSeedingJobSet seedingJobSet = getSetDetails(jobSet, jobQueue); @@ -71,29 +72,7 @@ public JobResult process(Job job, JobSet jobSet, JobQueueMin jobQueue) { return JobResult.error("Tile provider does not support seeding"); // early return } if (!tileProvider.seeding().isAvailable()) { - if (LOGGER.isDebugEnabled(MARKER.JOBS) || LOGGER.isTraceEnabled()) { - LOGGER.trace( - MARKER.JOBS, - "Tile provider '{}' not available, suspending job ({})", - tileProvider.getId(), - job.getId()); - } - tileProvider - .seeding() - .onStateChange( - (oldState, newState) -> { - if (newState == State.AVAILABLE) { - if (LOGGER.isDebugEnabled(MARKER.JOBS) || LOGGER.isTraceEnabled()) { - LOGGER.trace( - MARKER.JOBS, - "Tile provider '{}' became available, resuming job ({})", - tileProvider.getId(), - job.getId()); - } - jobQueue.push(job); - } - }, - true); + suspendUntilAvailable(tileProvider, job, jobQueue); return JobResult.onHold(); // early return } @@ -147,4 +126,34 @@ public Map> getJobTypes() { private Optional getTileProvider(String id) { return entityRegistry.getEntity(Tile3dProviderFeatures.class, id); } + + private void suspendUntilAvailable( + Tile3dProviderFeatures tileProvider, Job job, JobQueueMin jobQueue) { + if (LOGGER.isTraceEnabled(MARKER.JOBS)) { + LOGGER.trace( + MARKER.JOBS, + "Tile provider '{}' not available, suspending job ({})", + tileProvider.getId(), + job.getId()); + } + + tileProvider + .seeding() + .onStateChange( + (oldState, newState) -> { + if (newState != State.AVAILABLE) { + return; + } + + if (LOGGER.isTraceEnabled(MARKER.JOBS)) { + LOGGER.trace( + MARKER.JOBS, + "Tile provider '{}' became available, resuming job ({})", + tileProvider.getId(), + job.getId()); + } + jobQueue.push(job); + }, + true); + } } diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFeaturesData.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFeaturesData.java index 569641904..efa046dfc 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFeaturesData.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFeaturesData.java @@ -18,6 +18,7 @@ import de.ii.xtraplatform.entities.domain.EntityDataDefaults; import de.ii.xtraplatform.entities.domain.maptobuilder.BuildableMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import javax.annotation.Nullable; @@ -198,7 +199,8 @@ public interface Tile3dProviderFeaturesData extends Tile3dProviderData { String PROVIDER_SUBTYPE = "FEATURES"; - String ENTITY_SUBTYPE = String.format("%s/%s", PROVIDER_TYPE, PROVIDER_SUBTYPE).toLowerCase(); + String ENTITY_SUBTYPE = + String.format("%s/%s", PROVIDER_TYPE, PROVIDER_SUBTYPE).toLowerCase(Locale.ROOT); /** * @langEn Always `FEATURES`. diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFilesData.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFilesData.java index cb4d9ff41..029210c5f 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFilesData.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dProviderFilesData.java @@ -17,6 +17,7 @@ import de.ii.xtraplatform.docs.DocVar; import de.ii.xtraplatform.entities.domain.EntityDataBuilder; import de.ii.xtraplatform.entities.domain.EntityDataDefaults; +import java.util.Locale; import java.util.Map; import org.immutables.value.Value; @@ -84,7 +85,8 @@ public interface Tile3dProviderFilesData extends Tile3dProviderData { String PROVIDER_SUBTYPE = "FILES"; - String ENTITY_SUBTYPE = String.format("%s/%s", PROVIDER_TYPE, PROVIDER_SUBTYPE).toLowerCase(); + String ENTITY_SUBTYPE = + String.format("%s/%s", PROVIDER_TYPE, PROVIDER_SUBTYPE).toLowerCase(Locale.ROOT); /** * @langEn Always `FILES`. diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJob.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJob.java index 27381c3f2..0c62410a1 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJob.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJob.java @@ -26,50 +26,79 @@ public interface Tile3dSeedingJob extends JobDetails { String TYPE_SUBTREE = Tile3dSeedingJobSet.type("subtree", "binary"); String TYPE_GLTF = Tile3dSeedingJobSet.type("content", "glb"); + final class Context { + private final String tileProvider; + private final String tileSet; + private final String tileMatrixSet; + private final Optional generationParameters; + private final String jobSetId; + + public Context( + String tileProvider, + String tileSet, + String tileMatrixSet, + Optional generationParameters, + String jobSetId) { + this.tileProvider = tileProvider; + this.tileSet = tileSet; + this.tileMatrixSet = tileMatrixSet; + this.generationParameters = generationParameters; + this.jobSetId = jobSetId; + } + + String getTileProvider() { + return tileProvider; + } + + String getTileSet() { + return tileSet; + } + + String getTileMatrixSet() { + return tileMatrixSet; + } + + Optional getGenerationParameters() { + return generationParameters; + } + + String getJobSetId() { + return jobSetId; + } + } + static Job subtree( - int priority, - String tileProvider, - String tileSet, - String tileMatrixSet, - boolean isReseed, - Set subMatrices, - Optional generationParameters, - String jobSetId) { + int priority, Context context, boolean isReseed, Set subMatrices) { ImmutableTile3dSeedingJob details = new ImmutableTile3dSeedingJob.Builder() - .tileProvider(tileProvider) - .tileSet(tileSet) - .tileMatrixSet(tileMatrixSet) - .generationParameters(generationParameters) + .tileProvider(context.getTileProvider()) + .tileSet(context.getTileSet()) + .tileMatrixSet(context.getTileMatrixSet()) + .generationParameters(context.getGenerationParameters()) .encoding(MediaType.APPLICATION_OCTET_STREAM_TYPE) .isReseed(isReseed) .addAllSubMatrices(subMatrices) .build(); - return Job.of(TYPE_SUBTREE, priority, details, jobSetId, (int) details.getNumberOfTiles()); + return Job.of( + TYPE_SUBTREE, priority, details, context.getJobSetId(), (int) details.getNumberOfTiles()); } static Job content( - int priority, - String tileProvider, - String tileSet, - String tileMatrixSet, - boolean isReseed, - Set subMatrices, - Optional generationParameters, - String jobSetId) { + int priority, Context context, boolean isReseed, Set subMatrices) { ImmutableTile3dSeedingJob details = new ImmutableTile3dSeedingJob.Builder() - .tileProvider(tileProvider) - .tileSet(tileSet) - .tileMatrixSet(tileMatrixSet) - .generationParameters(generationParameters) + .tileProvider(context.getTileProvider()) + .tileSet(context.getTileSet()) + .tileMatrixSet(context.getTileMatrixSet()) + .generationParameters(context.getGenerationParameters()) .encoding(new MediaType("model", "gltf-binary")) .isReseed(isReseed) .addAllSubMatrices(subMatrices) .build(); - return Job.of(TYPE_GLTF, priority, details, jobSetId, (int) details.getNumberOfTiles()); + return Job.of( + TYPE_GLTF, priority, details, context.getJobSetId(), (int) details.getNumberOfTiles()); } String getTileProvider(); diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJobSet.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJobSet.java index 200badaff..7bf7abeb8 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJobSet.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dSeedingJobSet.java @@ -34,6 +34,13 @@ public interface Tile3dSeedingJobSet extends JobSetDetails { String TYPE = "tile3d-seeding"; String TYPE_SETUP = type("setup"); String LABEL = "3D Tiles cache seeding"; + String PARAM_TILE_SET = "tileSet"; + String PARAM_TILE_MATRIX_SET = "tileMatrixSet"; + String PARAM_LEVEL = "level"; + String PARAM_COUNT = "count"; + String PARAM_DELTA = "delta"; + String PARAM_IS_FIRST_TILESET = "isFirstTileset"; + String PARAM_IS_FIRST_LEVEL = "isFirstLevel"; List INITIAL_LEVELS = IntStream.range(0, 24).map(i -> -1).boxed().toList(); static String type(String... parts) { @@ -97,56 +104,66 @@ default void init(String tileSet, String tileMatrixSet, int level, int count) { } @Override + @SuppressWarnings("PMD.CognitiveComplexity") default void init(Map parameters) { - if (parameters.containsKey("tileSet") - && parameters.containsKey("tileMatrixSet") - && parameters.containsKey("level") - && parameters.containsKey("count")) { + if (parameters.containsKey(PARAM_TILE_SET) + && parameters.containsKey(PARAM_TILE_MATRIX_SET) + && parameters.containsKey(PARAM_LEVEL) + && parameters.containsKey(PARAM_COUNT)) { init( - (String) parameters.get("tileSet"), - (String) parameters.get("tileMatrixSet"), - parameters.get("level") instanceof Integer - ? (Integer) parameters.get("level") - : Integer.parseInt((String) parameters.get("level")), - parameters.get("count") instanceof Integer - ? (Integer) parameters.get("count") - : Integer.parseInt((String) parameters.get("count"))); + (String) parameters.get(PARAM_TILE_SET), + (String) parameters.get(PARAM_TILE_MATRIX_SET), + parameters.get(PARAM_LEVEL) instanceof Integer + ? (Integer) parameters.get(PARAM_LEVEL) + : Integer.parseInt((String) parameters.get(PARAM_LEVEL)), + parameters.get(PARAM_COUNT) instanceof Integer + ? (Integer) parameters.get(PARAM_COUNT) + : Integer.parseInt((String) parameters.get(PARAM_COUNT))); } } @Override + @SuppressWarnings("PMD.CognitiveComplexity") default Map initJson(Map params) { Map jsonPathUpdates = new LinkedHashMap<>(); - if (params.containsKey("tileSet") && params.get("count") instanceof Integer) { - int delta = (Integer) params.get("count"); - boolean isFirstTileset = Objects.equals(params.get("isFirstTileset"), true); - int tilesetDelta = isFirstTileset ? 1 : 0; + if (!(params.containsKey(PARAM_TILE_SET) && params.get(PARAM_COUNT) instanceof Integer)) { + return jsonPathUpdates; + } - jsonPathUpdates.put( - "$.details.tileSets.%s.progress.total".formatted(params.get("tileSet")), - delta + tilesetDelta); - - if (params.containsKey("tileMatrixSet")) { - if (isFirstTileset) { - jsonPathUpdates.put( - "$.details.tileSets.%s.progress.levels.%s" - .formatted(params.get("tileSet"), params.get("tileMatrixSet")), - INITIAL_LEVELS); - } + int delta = (Integer) params.get(PARAM_COUNT); + boolean isFirstTileset = Objects.equals(params.get(PARAM_IS_FIRST_TILESET), true); + int tilesetDelta = isFirstTileset ? 1 : 0; - if (params.containsKey("level")) { - int levelDelta = Objects.equals(params.get("isFirstLevel"), true) ? 1 : 0; + jsonPathUpdates.put( + "$.details.tileSets.%s.progress.total".formatted(params.get(PARAM_TILE_SET)), + delta + tilesetDelta); - jsonPathUpdates.put( - "$.details.tileSets.%s.progress.levels.%s[%s]" - .formatted( - params.get("tileSet"), params.get("tileMatrixSet"), params.get("level")), - delta + levelDelta); - } - } + if (!params.containsKey(PARAM_TILE_MATRIX_SET)) { + return jsonPathUpdates; + } + + if (isFirstTileset) { + jsonPathUpdates.put( + "$.details.tileSets.%s.progress.levels.%s" + .formatted(params.get(PARAM_TILE_SET), params.get(PARAM_TILE_MATRIX_SET)), + INITIAL_LEVELS); + } + + if (!params.containsKey(PARAM_LEVEL)) { + return jsonPathUpdates; } + int levelDelta = Objects.equals(params.get(PARAM_IS_FIRST_LEVEL), true) ? 1 : 0; + + jsonPathUpdates.put( + "$.details.tileSets.%s.progress.levels.%s[%s]" + .formatted( + params.get(PARAM_TILE_SET), + params.get(PARAM_TILE_MATRIX_SET), + params.get(PARAM_LEVEL)), + delta + levelDelta); + return jsonPathUpdates; } @@ -162,19 +179,19 @@ default void update(String tileSet, String tileMatrixSet, int level, int delta) @Override default void update(Map parameters) { - if (parameters.containsKey("tileSet") - && parameters.containsKey("tileMatrixSet") - && parameters.containsKey("level") - && parameters.containsKey("delta")) { + if (parameters.containsKey(PARAM_TILE_SET) + && parameters.containsKey(PARAM_TILE_MATRIX_SET) + && parameters.containsKey(PARAM_LEVEL) + && parameters.containsKey(PARAM_DELTA)) { update( - (String) parameters.get("tileSet"), - (String) parameters.get("tileMatrixSet"), - parameters.get("level") instanceof Integer - ? (Integer) parameters.get("level") - : Integer.parseInt((String) parameters.get("level")), - parameters.get("delta") instanceof Integer - ? (Integer) parameters.get("delta") - : Integer.parseInt((String) parameters.get("delta"))); + (String) parameters.get(PARAM_TILE_SET), + (String) parameters.get(PARAM_TILE_MATRIX_SET), + parameters.get(PARAM_LEVEL) instanceof Integer + ? (Integer) parameters.get(PARAM_LEVEL) + : Integer.parseInt((String) parameters.get(PARAM_LEVEL)), + parameters.get(PARAM_DELTA) instanceof Integer + ? (Integer) parameters.get(PARAM_DELTA) + : Integer.parseInt((String) parameters.get(PARAM_DELTA))); } } @@ -182,21 +199,22 @@ default void update(Map parameters) { default Map updateJson(Map detailParameters) { Map jsonPathUpdates = new LinkedHashMap<>(); - if (detailParameters.containsKey("tileSet") - && detailParameters.get("delta") instanceof Integer) { - int delta = (Integer) detailParameters.get("delta"); + if (detailParameters.containsKey(PARAM_TILE_SET) + && detailParameters.get(PARAM_DELTA) instanceof Integer) { + int delta = (Integer) detailParameters.get(PARAM_DELTA); jsonPathUpdates.put( - "$.details.tileSets.%s.progress.current".formatted(detailParameters.get("tileSet")), + "$.details.tileSets.%s.progress.current".formatted(detailParameters.get(PARAM_TILE_SET)), delta); - if (detailParameters.containsKey("tileMatrixSet") && detailParameters.containsKey("level")) { + if (detailParameters.containsKey(PARAM_TILE_MATRIX_SET) + && detailParameters.containsKey(PARAM_LEVEL)) { jsonPathUpdates.put( "$.details.tileSets.%s.progress.levels.%s[%s]" .formatted( - detailParameters.get("tileSet"), - detailParameters.get("tileMatrixSet"), - detailParameters.get("level")), + detailParameters.get(PARAM_TILE_SET), + detailParameters.get(PARAM_TILE_MATRIX_SET), + detailParameters.get(PARAM_LEVEL)), -1 * delta); } } @@ -251,7 +269,7 @@ static Tileset3dDetails of(Tile3dGenerationParameters parameters) { interface Tileset3dProgress extends JobProgress { @JsonIgnore @Nullable - LinkedHashMap getLevels(); + Map getLevels(); @JsonProperty(value = "levels", access = Access.WRITE_ONLY) Map> getLevelsInput(); @@ -275,10 +293,11 @@ default Map> getLevelsOutput() { } @Value.Check + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") default Tileset3dProgress deser() { // Ensure that levels is initialized if (getLevels() == null) { - LinkedHashMap levelsMap = new LinkedHashMap<>(); + Map levelsMap = new LinkedHashMap<>(); for (Map.Entry> entry : getLevelsInput().entrySet()) { List levelList = entry.getValue(); AtomicIntegerArray atomicArray = new AtomicIntegerArray(levelList.size()); @@ -288,7 +307,10 @@ default Tileset3dProgress deser() { levelsMap.put(entry.getKey(), atomicArray); } - return new ImmutableTileset3dProgress.Builder().from(this).levels(levelsMap).build(); + return new ImmutableTileset3dProgress.Builder() + .from(this) + .levels(new LinkedHashMap<>(levelsMap)) + .build(); } return this; } diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dStoreReadOnly.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dStoreReadOnly.java index 07a9a9f48..9d704814f 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dStoreReadOnly.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tile3dStoreReadOnly.java @@ -17,6 +17,7 @@ public interface Tile3dStoreReadOnly { Optional get(Tile3dQuery tile) throws IOException; + @SuppressWarnings("PMD.LinguisticNaming") Optional isEmpty(Tile3dQuery tile) throws IOException; boolean isEmpty() throws IOException; diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/TileTree.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/TileTree.java index 650ed8a78..a85ab3879 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/TileTree.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/TileTree.java @@ -22,6 +22,7 @@ import org.locationtech.jts.shape.fractal.MortonCode; @Value.Immutable +@SuppressWarnings({"PMD.TooManyMethods", "PMD.ExcessiveMethodCount"}) public interface TileTree { TileTree ROOT = of(0, 0, 0); @@ -199,6 +200,7 @@ static TileTree from(TileSubMatrix contents, int subtreeLevels) { .build(); } + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") static List subtrees( int level, int row, int col, TileSubMatrix contents, int subtreeLevels) { if (level > contents.getLevel()) { @@ -224,9 +226,9 @@ static List subtrees( TileSubMatrix.of( contents.getLevel(), r * sizeCon, - (r * sizeCon) + (sizeCon) - 1, + r * sizeCon + sizeCon - 1, c * sizeCon, - (c * sizeCon) + (sizeCon) - 1) + c * sizeCon + sizeCon - 1) .intersection(contents); if (content.isPresent()) { diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tileset3dFeatures.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tileset3dFeatures.java index 11886a53d..4944e643d 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tileset3dFeatures.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/Tileset3dFeatures.java @@ -107,6 +107,7 @@ default ImmutableTileset3dFeatures.Builder getBuilder() { abstract class Builder implements BuildableBuilder {} + @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"}) default Tileset3dFeatures mergeDefaults(Tileset3dFeaturesDefaults defaults) { if (Objects.isNull(defaults)) { return this; diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tile3d.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tile3d.java index 085710829..f2efbf38d 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tile3d.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tile3d.java @@ -12,7 +12,6 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.google.common.hash.Funnel; import java.nio.charset.StandardCharsets; -import java.nio.file.Path; import java.util.List; import java.util.Optional; import org.immutables.value.Value; @@ -22,6 +21,17 @@ @JsonInclude(Include.NON_EMPTY) public interface Tile3d { + @SuppressWarnings("UnstableApiUsage") + Funnel FUNNEL = + (from, into) -> { + BoundingVolume.FUNNEL.funnel(from.getBoundingVolume(), into); + from.getGeometricError().ifPresent(into::putFloat); + from.getRefine().ifPresent(v -> into.putString(v, StandardCharsets.UTF_8)); + from.getContent().ifPresent(content -> WithUri.FUNNEL.funnel(content, into)); + from.getImplicitTiling() + .ifPresent(implicit -> ImplicitTiling.FUNNEL.funnel(implicit, into)); + }; + default Tile3d withUris(String uriPrefix) { return new ImmutableTile3d.Builder() .from(this) @@ -45,7 +55,7 @@ default Tile3d withUris(String uriPrefix) { .build(); } - default Tile3d withUris(Path directory) { + default Tile3d withUris(java.nio.file.Path directory) { return new ImmutableTile3d.Builder() .from(this) .content( @@ -59,17 +69,6 @@ default Tile3d withUris(Path directory) { .build(); } - @SuppressWarnings("UnstableApiUsage") - Funnel FUNNEL = - (from, into) -> { - BoundingVolume.FUNNEL.funnel(from.getBoundingVolume(), into); - from.getGeometricError().ifPresent(into::putFloat); - from.getRefine().ifPresent(v -> into.putString(v, StandardCharsets.UTF_8)); - from.getContent().ifPresent(content -> WithUri.FUNNEL.funnel(content, into)); - from.getImplicitTiling() - .ifPresent(implicit -> ImplicitTiling.FUNNEL.funnel(implicit, into)); - }; - BoundingVolume getBoundingVolume(); Optional getGeometricError(); @@ -93,7 +92,7 @@ static String flattenUri(String uri) { return uri.replaceAll("/", "_"); } - static String flattenUri(String uri, Path directory) { + static String flattenUri(String uri, java.nio.file.Path directory) { return flattenUri(directory.resolve(uri).normalize().toString()); } } diff --git a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tileset3d.java b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tileset3d.java index 9fe736de2..0a872c7f7 100644 --- a/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tileset3d.java +++ b/xtraplatform-tiles3d/src/main/java/de/ii/xtraplatform/tiles3d/domain/spec/Tileset3d.java @@ -11,7 +11,6 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.google.common.hash.Funnel; -import java.nio.file.Path; import java.util.List; import java.util.Map; import java.util.Objects; @@ -23,6 +22,16 @@ @JsonInclude(Include.NON_EMPTY) public interface Tileset3d { + String SCHEMA_REF = "#/components/schemas/Tileset3dTiles"; + + @SuppressWarnings("UnstableApiUsage") + Funnel FUNNEL = + (from, into) -> { + AssetMetadata.FUNNEL.funnel(from.getAsset(), into); + from.getGeometricError().ifPresent(into::putFloat); + Tile3d.FUNNEL.funnel(from.getRoot(), into); + }; + default Tileset3d withUris(String uriPrefix) { return new ImmutableTileset3d.Builder().from(this).root(getRoot().withUris(uriPrefix)).build(); } @@ -41,16 +50,6 @@ default Tileset3d withSchemaUri(String schemaUri) { return new ImmutableTileset3d.Builder().from(this).schemaUri(schemaUri).build(); } - String SCHEMA_REF = "#/components/schemas/Tileset3dTiles"; - - @SuppressWarnings("UnstableApiUsage") - Funnel FUNNEL = - (from, into) -> { - AssetMetadata.FUNNEL.funnel(from.getAsset(), into); - from.getGeometricError().ifPresent(into::putFloat); - Tile3d.FUNNEL.funnel(from.getRoot(), into); - }; - AssetMetadata getAsset(); Map getProperties(); @@ -77,10 +76,10 @@ default Tileset3d withSchemaUri(String schemaUri) { Map getExtras(); - default void validate(Path source) { + default void validate(java.nio.file.Path source) { if (Objects.isNull(getAsset()) - || (!Objects.equals(getAsset().getVersion(), "1.0") - && !Objects.equals(getAsset().getVersion(), "1.1"))) { + || !Objects.equals(getAsset().getVersion(), "1.0") + && !Objects.equals(getAsset().getVersion(), "1.1")) { throw new IllegalStateException("Invalid version found in 3D Tiles tileset file: " + source); }