source: josm/trunk/src/org/openstreetmap/josm/data/imagery/LayerDetails.java@ 13870

Last change on this file since 13870 was 13870, checked in by wiktorn, 6 years ago

Fix NPE when style title is null

Closes: #16333

File size: 5.7 KB
RevLine 
[13733]1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.List;
7import java.util.Map;
8import java.util.concurrent.ConcurrentHashMap;
9import java.util.stream.Stream;
10
11import org.openstreetmap.josm.data.Bounds;
12
13/**
14 * The details of a layer of this WMS server.
15 */
16public class LayerDetails {
[13824]17 private final Map<String, String> styles = new ConcurrentHashMap<>(); // name -> title
18 private final Collection<String> crs = new ArrayList<>();
[13733]19 /**
20 * The layer name (WMS {@code Title})
21 */
22 private String title;
23 /**
24 * The layer name (WMS {@code Name})
25 */
26 private String name;
27 /**
28 * The layer abstract (WMS {@code Abstract})
29 * @since 13199
30 */
31 private String abstr;
[13824]32 private final LayerDetails parentLayer;
[13733]33 private Bounds bounds;
34 private List<LayerDetails> children = new ArrayList<>();
35
36 /**
37 * Constructor pointing to parent layer. Set to null if this is topmost layer.
38 * This is needed to properly handle layer attributes inheritance.
39 *
[13742]40 * @param parentLayer parent layer
[13733]41 */
42 public LayerDetails(LayerDetails parentLayer) {
43 this.parentLayer = parentLayer;
44 }
45
46 /**
47 * @return projections that are supported by this layer
48 */
49 public Collection<String> getCrs() {
50 Collection<String> ret = new ArrayList<>();
51 if (parentLayer != null) {
52 ret.addAll(parentLayer.getCrs());
53 }
54 ret.addAll(crs);
[13743]55 return ret;
[13733]56 }
57
58 /**
59 *
60 * @return styles defined for this layer
61 */
62 public Map<String, String> getStyles() {
63 Map<String, String> ret = new ConcurrentHashMap<>();
64 if (parentLayer != null) {
65 ret.putAll(parentLayer.getStyles());
66 }
67 ret.putAll(styles);
68 return ret;
69 }
70
71 /**
[13742]72 * @return title "Human readable" title of this layer
[13733]73 * @see LayerDetails#getName()
74 */
75 public String getTitle() {
76 return title;
77 }
78
79 /**
[13742]80 * @param title set title of this layer
[13733]81 * @see LayerDetails#getName()
82 */
83 public void setTitle(String title) {
84 this.title = title;
85 }
86
87 /**
88 *
[13818]89 * Citation from OGC WMS specification (WMS 1.3.0):<p><i>
90 * A number of elements have both a {@literal <Name>} and a {@literal <Title>}. The Name is a text string used for machine-to-machine
91 * communication while the Title is for the benefit of humans. For example, a dataset might have the descriptive Title
92 * “Maximum Atmospheric Temperature” and be requested using the abbreviated Name “ATMAX”.</i></p>
[13733]93 *
[13818]94 * And second citation:<p><i>
95 * If, and only if, a layer has a {@literal <Name>}, then it is a map layer that can be requested by using that Name in the
96 * LAYERS parameter of a GetMap request. A Layer that contains a {@literal <Name>} element is referred to as a “named
97 * layer” in this International Standard. If the layer has a Title but no Name, then that layer is only a category title for
98 * all the layers nested within.</i></p>
[13733]99 * @return name of this layer
100 */
101 public String getName() {
102 return name;
103 }
104
105 /**
[13742]106 * @param name sets the name of this Layer
[13733]107 * @see LayerDetails#getName()
108 */
109 public void setName(String name) {
110 this.name = name;
111 }
112
113 /**
114 * Add style to list of styles defined by this layer
115 * @param name machine-to-machine name of this style
116 * @param title human readable title of this style
117 */
118 public void addStyle(String name, String title) {
[13870]119 this.styles.put(name, title == null ? "" : title);
[13733]120 }
121
122 /**
123 * Add projection supported by this layer
124 * @param crs projection code
125 */
126 public void addCrs(String crs) {
127 this.crs.add(crs);
128 }
129
130 /**
131 *
132 * @return bounds within layer might be queried
133 */
134 public Bounds getBounds() {
135 return bounds;
136 }
137
138 /**
139 * sets bounds of this layer
[13742]140 * @param bounds of this layer
[13733]141 */
142 public void setBounds(Bounds bounds) {
143 this.bounds = bounds;
144 }
145
146 @Override
147 public String toString() {
148 String baseName = (title == null || title.isEmpty()) ? name : title;
149 return abstr == null || abstr.equalsIgnoreCase(baseName) ? baseName : baseName + " (" + abstr + ')';
150 }
151
152 /**
153 *
154 * @return parent layer for his layer
155 */
156 public LayerDetails getParent() {
157 return parentLayer;
158 }
159
160 /**
161 * sets children layers for this layer
[13742]162 * @param children children of this layer
[13733]163 */
164 public void setChildren(List<LayerDetails> children) {
165 this.children = children;
166
167 }
168
169 /**
170 *
171 * @return children layers of this layer
172 */
173 public List<LayerDetails> getChildren() {
174 return children;
175 }
176
177 /**
178 * if user may select this layer (is it possible to request it from server)
179 * @return true if user may select this layer, false if this layer is only grouping other layers
180 */
181 public boolean isSelectable() {
182 return !(name == null || name.isEmpty());
183 }
184
185 /**
186 * @return "Narrative description of the layer"
187 */
188 public String getAbstract() {
189 return abstr;
190 }
191
192 /**
193 * Sets abstract of this layer
[13742]194 * @param abstr abstract of this layer
[13733]195 */
196 public void setAbstract(String abstr) {
197 this.abstr = abstr;
198 }
199
200 /**
201 * @return flattened stream of this layer and its children (as well as recursively children of its children)
202 */
203 public Stream<LayerDetails> flattened() {
204 return Stream.concat(
205 Stream.of(this),
206 getChildren().stream().flatMap(LayerDetails::flattened)
207 );
208 }
209}
Note: See TracBrowser for help on using the repository browser.