1
2
3
4
5
6 package org.tailormap.api.controller;
7
8 import static org.tailormap.api.persistence.helper.TMAttributeTypeHelper.isGeometry;
9 import static org.tailormap.api.persistence.helper.TMFeatureTypeHelper.getConfiguredAttributes;
10
11 import io.micrometer.core.annotation.Timed;
12 import java.io.Serializable;
13 import java.util.Set;
14 import org.springframework.http.HttpStatus;
15 import org.springframework.http.MediaType;
16 import org.springframework.http.ResponseEntity;
17 import org.springframework.transaction.annotation.Transactional;
18 import org.springframework.validation.annotation.Validated;
19 import org.springframework.web.bind.annotation.GetMapping;
20 import org.springframework.web.bind.annotation.ModelAttribute;
21 import org.springframework.web.bind.annotation.RequestMapping;
22 import org.springframework.web.server.ResponseStatusException;
23 import org.tailormap.api.annotation.AppRestController;
24 import org.tailormap.api.persistence.Application;
25 import org.tailormap.api.persistence.Form;
26 import org.tailormap.api.persistence.GeoService;
27 import org.tailormap.api.persistence.TMFeatureType;
28 import org.tailormap.api.persistence.helper.TMFeatureTypeHelper;
29 import org.tailormap.api.persistence.json.AppLayerSettings;
30 import org.tailormap.api.persistence.json.AppTreeLayerNode;
31 import org.tailormap.api.persistence.json.GeoServiceLayer;
32 import org.tailormap.api.persistence.json.TMAttributeDescriptor;
33 import org.tailormap.api.persistence.json.TMAttributeType;
34 import org.tailormap.api.persistence.json.TMGeometryType;
35 import org.tailormap.api.repository.FeatureSourceRepository;
36 import org.tailormap.api.repository.FormRepository;
37 import org.tailormap.api.viewer.model.Attribute;
38 import org.tailormap.api.viewer.model.LayerDetails;
39 import org.tailormap.api.viewer.model.LayerDetailsForm;
40
41 @AppRestController
42 @Validated
43 @RequestMapping(
44 path = "${tailormap-api.base-path}/{viewerKind}/{viewerName}/layer/{appLayerId}/describe",
45 produces = MediaType.APPLICATION_JSON_VALUE)
46 public class LayerDescriptionController {
47
48 private final FeatureSourceRepository featureSourceRepository;
49 private final TMFeatureTypeHelper featureTypeHelper;
50 private final FormRepository formRepository;
51
52 public LayerDescriptionController(
53 FeatureSourceRepository featureSourceRepository,
54 TMFeatureTypeHelper featureTypeHelper,
55 FormRepository formRepository) {
56 this.featureSourceRepository = featureSourceRepository;
57 this.featureTypeHelper = featureTypeHelper;
58 this.formRepository = formRepository;
59 }
60
61 @Transactional
62 @GetMapping
63 @Timed(value = "get_layer_description", description = "Get layer description")
64 public ResponseEntity<Serializable> getAppLayerDescription(
65 @ModelAttribute Application application,
66 @ModelAttribute AppTreeLayerNode appTreeLayerNode,
67 @ModelAttribute GeoService service,
68 @ModelAttribute GeoServiceLayer layer) {
69
70 if (layer == null) {
71 throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Can't find layer " + appTreeLayerNode);
72 }
73
74 TMFeatureType tmft = service.findFeatureTypeForLayer(layer, featureSourceRepository);
75 if (tmft == null) {
76 throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Layer does not have feature type");
77 }
78
79 LayerDetails r = new LayerDetails()
80 .id(appTreeLayerNode.getId())
81 .serviceId(appTreeLayerNode.getServiceId())
82 .featureTypeName(tmft.getName())
83 .geometryAttribute(tmft.getDefaultGeometryAttribute())
84
85 .geometryAttributeIndex(null )
86 .geometryType(tmft.getDefaultGeometryDescriptor()
87 .map(TMAttributeDescriptor::getType)
88 .map(TMAttributeType::getValue)
89 .map(TMGeometryType::fromValue)
90 .orElse(null))
91 .editable(TMFeatureTypeHelper.isEditable(application, appTreeLayerNode, tmft))
92 .attachmentAttributes(featureTypeHelper.getAttachmentAttributesWithMaxFileUploadSize(tmft).stream()
93 .toList());
94
95 AppLayerSettings appLayerSettings = application.getAppLayerSettings(appTreeLayerNode);
96
97 Form form;
98 if (appLayerSettings.getFormId() != null) {
99 form = formRepository.findById(appLayerSettings.getFormId()).orElse(null);
100 if (form != null) {
101 r.setForm(new LayerDetailsForm().options(form.getOptions()).fields(form.getFields()));
102 }
103 }
104
105 Set<String> editableAttributes = TMFeatureTypeHelper.getEditableAttributes(tmft, appLayerSettings);
106
107 getConfiguredAttributes(tmft, appLayerSettings).values().stream()
108 .map(attributeWithSettings -> {
109 TMAttributeDescriptor a = attributeWithSettings.attributeDescriptor();
110 return new Attribute()
111 .name(a.getName())
112 .alias(attributeWithSettings.settings().getTitle())
113
114
115
116 .type(isGeometry(a.getType()) ? TMAttributeType.GEOMETRY : a.getType())
117
118 .editable(!a.getName().equals(tmft.getPrimaryKeyAttribute())
119 && editableAttributes.contains(a.getName()))
120 .defaultValue(a.getDefaultValue())
121 .nullable(a.getNullable());
122 })
123 .forEach(r::addAttributesItem);
124
125 return ResponseEntity.ok(r);
126 }
127 }