diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/annotation/JsonSuperType.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/annotation/JsonSuperType.java index 0a2655c80..b6c083d0e 100644 --- a/shogun-lib/src/main/java/de/terrestris/shogun/lib/annotation/JsonSuperType.java +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/annotation/JsonSuperType.java @@ -26,7 +26,8 @@ * The `JsonSuperType` annotation helps to identify a type that should be deserialized instead of a parent type. * The `type` property specifies the parent type. This annotation needs to go along with a `JsonDeserialize` pointing * to the own type. - * If the super type that should get replaced is not an interface, than `override` needs to be set to `true`. + * If the super type that should get replaced is already used by another parent, and it should be overridden by another + * type, then `override` needs to be set to `true`. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/JacksonConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/JacksonConfig.java index 79d2fef16..0eaa846dc 100644 --- a/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/JacksonConfig.java +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/JacksonConfig.java @@ -24,6 +24,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.vladmihalcea.hibernate.type.util.ObjectMapperSupplier; import de.terrestris.shogun.lib.annotation.JsonSuperType; +import lombok.extern.log4j.Log4j2; import org.locationtech.jts.geom.GeometryFactory; import org.locationtech.jts.geom.PrecisionModel; import org.reflections.Reflections; @@ -38,6 +39,7 @@ import java.util.HashMap; import java.util.Map; +@Log4j2 @Configuration public class JacksonConfig implements ObjectMapperSupplier { @@ -105,23 +107,52 @@ private Map, Class> findAnnotatedClasses() { var annotation = cl.getAnnotation(JsonSuperType.class); var superType = annotation.type(); - if (!annotation.override() && !superType.isInterface()) { - throw new IllegalStateException("The super type " + superType.getName() + " is not an interface. " + - "Set override to true if this is intended."); + if (!implementers.containsKey(superType)) { + implementers.put(superType, cl); + log.debug("(De-)serializing supertype " + superType + " with type " + cl); + continue; } - if (!implementers.containsKey(superType)) { + var previous = implementers.get(superType); + if (previous.isAssignableFrom(cl)) { implementers.put(superType, cl); - } else { - var previous = implementers.get(superType); - if (previous.isAssignableFrom(cl)) { - implementers.put(superType, cl); - } else if (!cl.isAssignableFrom(previous)) { - throw new IllegalStateException("Found 2 incompatible types that both want to deserialize to the type " - + superType.getName() + ". Any existing type should get extended."); - } + log.debug("(De-)serializing supertype " + superType + " with type " + cl); + continue; + } + + var currentOverride = annotation.override(); + var previousOverride = previous.getAnnotation(JsonSuperType.class).override(); + + log.warn("Found two conflicting (de-)serialization candidates (" + cl.getName() + ", " + + previous.getName() + ") for supertype " + superType + ". Checking for a conflict resolution " + + "(via the override field)"); + + if (currentOverride && previousOverride) { + throw new IllegalStateException("Found two types (" + cl.getName() + ", " + previous.getName() + ") " + + "that both want to (de-)serialize to the type " + superType.getName() + " and both have set " + + "override to true. Override must be set for a single type only."); + } + + if (!currentOverride && !previousOverride) { + throw new IllegalStateException("Found two types (" + cl.getName() + ", " + previous.getName() + ") " + + "that both want to (de-)serialize to the type " + superType.getName() + ". Any existing type " + + "should get extended."); + } + + if (previousOverride) { + log.info("Existing type (" + previous.getName() + ") for (de-)serialization of " + superType.getName() + + " will be used as override is set to true"); + continue; + } + + if (annotation.override()) { + implementers.remove(previous); + implementers.put(superType, cl); + log.info("Removing the existing type for (de-)serialization of " + superType.getName() + " (" + + previous.getName() + ") in favour of " + cl.getName() + " as override is set to true"); } } + return implementers; } diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/SwaggerConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/SwaggerConfig.java index fa8e082d2..ea2fed153 100644 --- a/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/SwaggerConfig.java +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/config/SwaggerConfig.java @@ -16,29 +16,34 @@ */ package de.terrestris.shogun.lib.config; +import com.fasterxml.classmate.TypeResolver; import de.terrestris.shogun.lib.annotation.JsonSuperType; import org.reflections.Reflections; -import org.reflections.scanners.SubTypesScanner; -import org.reflections.scanners.TypeAnnotationsScanner; +import org.reflections.scanners.Scanners; import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.AlternateTypeRules; import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; -import java.util.Collections; +import java.util.*; import java.util.function.Predicate; @Configuration @EnableAutoConfiguration public abstract class SwaggerConfig { + @Autowired + private TypeResolver typeResolver; + protected String title = "SHOGun REST API"; protected String description = "This is the REST API description of SHOGun"; protected String version = "1.0.0"; @@ -81,18 +86,69 @@ private SecurityScheme basicAuthScheme() { protected void directModelSubsitutions(Docket docket) { var reflections = new Reflections(new ConfigurationBuilder() .setUrls(ClasspathHelper.forJavaClassPath()) - .setScanners(new SubTypesScanner(), new TypeAnnotationsScanner())); + .setScanners( + Scanners.SubTypes, + Scanners.TypesAnnotated + ) + ); + + Map, Class> substitutions = new HashMap<>(); for (var cl : reflections.getTypesAnnotatedWith(JsonSuperType.class)) { var annotation = cl.getAnnotation(JsonSuperType.class); var superType = annotation.type(); - if (!annotation.override() && !superType.isInterface()) { - throw new IllegalStateException("The super type " + superType.getName() + " is not an interface. " + - "Set override to true if this is intended."); + if (!substitutions.containsKey(superType)) { + substitutions.put(superType, cl); + continue; + } + + var previous = substitutions.get(superType); + + var currentOverride = annotation.override(); + var previousOverride = previous.getAnnotation(JsonSuperType.class).override(); + + if (currentOverride && previousOverride) { + throw new IllegalStateException("Found two types (" + cl.getName() + ", " + previous.getName() + ") " + + "that both want to (de-)serialize to the type " + superType.getName() + " and both have set " + + "override to true. Override must be set for a single type only."); } + if (!currentOverride && !previousOverride) { + throw new IllegalStateException("Found two types (" + cl.getName() + ", " + previous.getName() + ") " + + "that both want to (de-)serialize to the type " + superType.getName() + ". Any existing type " + + "should get extended."); + } + + if (previousOverride) { + continue; + } + + if (annotation.override()) { + substitutions.remove(previous); + substitutions.put(superType, cl); + } + } + + for (var entry : substitutions.entrySet()) { + Class superType = entry.getKey(); + Class cl = entry.getValue(); + docket.directModelSubstitute(superType, cl); + docket.alternateTypeRules( + AlternateTypeRules.newRule( + typeResolver.resolve(List.class, superType), + typeResolver.resolve(List.class, cl) + ), + AlternateTypeRules.newRule( + typeResolver.resolve(Set.class, superType), + typeResolver.resolve(Set.class, cl) + ), + AlternateTypeRules.newRule( + typeResolver.resolve(Collection.class, superType), + typeResolver.resolve(Collection.class, cl) + ) + ); } } diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/Layer.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/Layer.java index 2aa119c07..856105541 100644 --- a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/Layer.java +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/Layer.java @@ -56,7 +56,7 @@ public class Layer extends BaseEntity { @ToString.Exclude @Schema( description = "The configuration of the layer which should be used to define client specific aspects of " + - "the layer. This may include the name, the visible resolution range, search configurations or similiar." + "the layer. This may include the name, the visible resolution range, search configurations or similar." ) private LayerClientConfig clientConfig; diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationClientConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationClientConfig.java new file mode 100644 index 000000000..c7411cbc2 --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationClientConfig.java @@ -0,0 +1,45 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.application; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import de.terrestris.shogun.lib.annotation.JsonSuperType; +import de.terrestris.shogun.lib.model.jsonb.ApplicationClientConfig; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@JsonDeserialize(as = DefaultApplicationClientConfig.class) +@JsonSuperType(type = ApplicationClientConfig.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultApplicationClientConfig implements ApplicationClientConfig { + @Schema( + description = "The configuration of the map view.", + required = true + ) + private DefaultMapView mapView; + + @Schema( + description = "The description of the application." + ) + private String description; +} diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationLayerConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationLayerConfig.java new file mode 100644 index 000000000..245ac21d5 --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationLayerConfig.java @@ -0,0 +1,48 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.application; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import de.terrestris.shogun.lib.annotation.JsonSuperType; +import de.terrestris.shogun.lib.model.jsonb.LayerConfig; +import de.terrestris.shogun.lib.model.jsonb.layer.DefaultLayerClientConfig; +import de.terrestris.shogun.lib.model.jsonb.layer.DefaultLayerSourceConfig; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@JsonDeserialize(as = DefaultApplicationLayerConfig.class) +@JsonSuperType(type = LayerConfig.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultApplicationLayerConfig implements LayerConfig { + @Schema( + description = "The configuration of the layer which should be used to define client specific aspects of " + + "the layer. This may include the name, the visible resolution range, search configurations or similar." + ) + private DefaultLayerClientConfig clientConfig; + + @Schema( + description = "The configuration of the datasource of the layer, e.g. the URL of the server, the name or " + + "the grid configuration." + ) + private DefaultLayerSourceConfig sourceConfig; +} diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationToolConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationToolConfig.java new file mode 100644 index 000000000..087daebbf --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultApplicationToolConfig.java @@ -0,0 +1,48 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.application; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import de.terrestris.shogun.lib.annotation.JsonSuperType; +import de.terrestris.shogun.lib.model.jsonb.ApplicationToolConfig; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.HashMap; + +@Data +@JsonDeserialize(as = DefaultApplicationToolConfig.class) +@JsonSuperType(type = ApplicationToolConfig.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultApplicationToolConfig implements ApplicationToolConfig { + @Schema( + description = "The name of the tool.", + example = "map-tool" + ) + private String name; + + @Schema( + description = "The configuration object of the tool.", + example = "{\"visible\": true}" + ) + private HashMap config; +} diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultLayerTree.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultLayerTree.java new file mode 100644 index 000000000..3871db806 --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultLayerTree.java @@ -0,0 +1,61 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.application; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import de.terrestris.shogun.lib.annotation.JsonSuperType; +import de.terrestris.shogun.lib.model.jsonb.LayerTree; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.ArrayList; + +@Data +@JsonDeserialize(as = DefaultLayerTree.class) +@JsonSuperType(type = LayerTree.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultLayerTree implements LayerTree { + @Schema( + description = "The title of the node to show.", + example = "Layer A" + ) + private String title; + + @Schema( + description = "Whether the node should be checked initially or not.", + example = "true" + ) + private Boolean checked; + + @Schema( + description = "The ID of the layer to associate to the node.", + example = "1909" + ) + private Integer layerId; + + @Schema( + description = "The children configuration", + example = "[]" + ) + private ArrayList children; +} + diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultMapView.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultMapView.java new file mode 100644 index 000000000..59a56c8f2 --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/application/DefaultMapView.java @@ -0,0 +1,60 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.application; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.io.Serializable; +import java.util.ArrayList; + +@Data +@ToString +@EqualsAndHashCode +public class DefaultMapView implements Serializable { + @Schema( + description = "The initial zoom level of the map.", + example = "1" + ) + private Integer zoom; + + @Schema( + description = "The initial center of the map (in WGS84).", + example = "[10.3, 51.08]" + ) + private ArrayList center; + + @Schema( + description = "The maximum extent of the map (in WGS84).", + example = "[2.5683045738288137, 45.429089001638076, 19.382621082401887, 57.283993958205926]" + ) + private ArrayList extent; + + @Schema( + description = "The projection of the map.", + example = "EPSG:25832" + ) + private String projection; + + @Schema( + description = "The list of resolutions/zoom levels of the map.", + example = "[2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.298582142, 0.149291071, 0.074645535]" + ) + private ArrayList resolutions; +} diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerClientConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerClientConfig.java new file mode 100644 index 000000000..2a646c89f --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerClientConfig.java @@ -0,0 +1,78 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.layer; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import de.terrestris.shogun.lib.annotation.JsonSuperType; +import de.terrestris.shogun.lib.model.jsonb.LayerClientConfig; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.ArrayList; +import java.util.Map; + +@Data +@JsonDeserialize(as = DefaultLayerClientConfig.class) +@JsonSuperType(type = LayerClientConfig.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultLayerClientConfig implements LayerClientConfig { + @Schema( + description = "The minimum resolution of the layer (at what resolution/zoom level the layer should become visible).", + example = "305.74811309814453" + ) + private Double minResolution; + + @Schema( + description = "The maximum resolution of the layer (to which resolution/zoom level the layer should be visible).", + example = "2500" + ) + private Double maxResolution; + + @Schema( + description = "Whether the layer is hoverable or not.", + example = "true" + ) + private Boolean hoverable; + + @Schema( + description = "Whether the layer is searchable or not.", + example = "true" + ) + private Boolean searchable; + + @Schema( + description = "The search configuration." + ) + private Map searchConfig; + + @Schema( + description = "The property configuration." + ) + private ArrayList propertyConfig; + + @Schema( + description = "The cross Origin mode to use.", + example = "anonymous" + ) + private String crossOrigin; +} + diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerPropertyConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerPropertyConfig.java new file mode 100644 index 000000000..ebabf1381 --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerPropertyConfig.java @@ -0,0 +1,52 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.layer; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.io.Serializable; + +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultLayerPropertyConfig implements Serializable { + + @Schema( + description = "The name of the property.", + example = "description", + required = true + ) + private String propertyName; + + @Schema( + description = "The name of the attribute to show.", + example = "Description" + ) + private String displayName; + + @Schema( + description = "Whether the attribute should be shown or not.", + example = "true" + ) + private boolean visible = true; +} + diff --git a/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerSourceConfig.java b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerSourceConfig.java new file mode 100644 index 000000000..44424ee09 --- /dev/null +++ b/shogun-lib/src/main/java/de/terrestris/shogun/lib/model/jsonb/layer/DefaultLayerSourceConfig.java @@ -0,0 +1,79 @@ +/* SHOGun, https://terrestris.github.io/shogun/ + * + * Copyright © 2022-present terrestris GmbH & Co. KG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.terrestris.shogun.lib.model.jsonb.layer; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import de.terrestris.shogun.lib.annotation.JsonSuperType; +import de.terrestris.shogun.lib.model.jsonb.LayerSourceConfig; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.ArrayList; + +@Data +@JsonDeserialize(as = DefaultLayerSourceConfig.class) +@JsonSuperType(type = LayerSourceConfig.class) +@JsonInclude(JsonInclude.Include.NON_NULL) +@ToString +@EqualsAndHashCode +public class DefaultLayerSourceConfig implements LayerSourceConfig { + @Schema( + description = "The base URL of the layer.", + example = "https://ows.terrestris.de/ows" + ) + private String url; + + @Schema( + description = "A comma separated list of layers to request.", + example = "layerA" + ) + private String layerNames; + + @Schema( + description = "A custom legend URL.", + example = "https://ows.terrestris.de/ows/my-legend.png" + ) + private String legendUrl; + + @Schema( + description = "The tile size.", + example = "512" + ) + private Double tileSize; + + @Schema( + description = "The tile origin.", + example = "[239323.44497139292, 4290144.074117256]" + ) + private ArrayList tileOrigin; + + @Schema( + description = "The list of resolutions the layer should be requested on.", + example = "[2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508]" + ) + private ArrayList resolutions; + + @Schema( + description = "The attribution to show.", + example = "© by terrestris GmbH & Co. KG" + ) + private String attribution; +} + diff --git a/shogun-lib/src/main/resources/graphql/shogun.graphqls b/shogun-lib/src/main/resources/graphql/shogun.graphqls index 56ca32682..ea7b7541d 100644 --- a/shogun-lib/src/main/resources/graphql/shogun.graphqls +++ b/shogun-lib/src/main/resources/graphql/shogun.graphqls @@ -1398,7 +1398,7 @@ type Layer implements BaseEntity { name: String """ The configuration of the layer which should be used to define client specific aspects of the layer. This may include - the name, the visible resolution range, search configurations or similiar. For example: + the name, the visible resolution range, search configurations or similar. For example: ``` { @@ -1491,7 +1491,7 @@ type Layer implements BaseEntity { sourceConfig: JSON """ Custom features for the layers that aren't available in the datasource. This might be used for custom draw layers - or similiar. It's advised to store the features using the GeoJSON format. For example: + or similar. It's advised to store the features using the GeoJSON format. For example: ``` { @@ -1666,7 +1666,7 @@ type User implements BaseEntity { details: JSON """ The configuration of the user which should be used to define client specific aspects of the user. This may include - the locale set by the user, the last application visited by the user or similiar. For example: + the locale set by the user, the last application visited by the user or similar. For example: ``` {