source: josm/trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSource.java@ 13691

Last change on this file since 13691 was 13647, checked in by Don-vip, 6 years ago

see #16204 - Allow to start and close JOSM in WebStart sandbox mode (where every external access is denied). This was very useful to reproduce some very tricky bugs that occured in real life but were almost impossible to diagnose.

  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.mappaint;
3
4import static org.openstreetmap.josm.tools.I18n.trn;
5
6import java.awt.Color;
7import java.io.File;
8import java.io.IOException;
9import java.io.InputStream;
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.Collections;
13import java.util.HashMap;
14import java.util.List;
15import java.util.Map;
16import java.util.Set;
17import java.util.concurrent.CopyOnWriteArrayList;
18import java.util.concurrent.CopyOnWriteArraySet;
19
20import javax.swing.ImageIcon;
21
22import org.openstreetmap.josm.data.osm.OsmPrimitive;
23import org.openstreetmap.josm.data.preferences.sources.SourceEntry;
24import org.openstreetmap.josm.data.preferences.sources.SourceType;
25import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
26import org.openstreetmap.josm.io.CachedFile;
27import org.openstreetmap.josm.tools.ImageOverlay;
28import org.openstreetmap.josm.tools.ImageProvider;
29import org.openstreetmap.josm.tools.Utils;
30
31/**
32 * A mappaint style (abstract class).
33 *
34 * Handles everything from parsing the style definition to application
35 * of the style to an osm primitive.
36 */
37public abstract class StyleSource extends SourceEntry {
38
39 private final List<Throwable> errors = new CopyOnWriteArrayList<>();
40 private final Set<String> warnings = new CopyOnWriteArraySet<>();
41 /**
42 * The zip file containing the icons for this style
43 */
44 public File zipIcons;
45
46 /** image provider returning the icon for this style */
47 private ImageProvider imageIconProvider;
48
49 /** image provider returning the default icon */
50 private static ImageProvider defaultIconProvider;
51
52 /**
53 * The following fields is additional information found in the header of the source file.
54 */
55 public String icon;
56
57 /**
58 * List of settings for user customization.
59 */
60 public final List<StyleSetting> settings = new ArrayList<>();
61 /**
62 * Values of the settings for efficient lookup.
63 */
64 public Map<String, Object> settingValues = new HashMap<>();
65
66 /**
67 * Constructs a new, active {@link StyleSource}.
68 * @param url URL that {@link org.openstreetmap.josm.io.CachedFile} understands
69 * @param name The name for this StyleSource
70 * @param title The title that can be used as menu entry
71 */
72 public StyleSource(String url, String name, String title) {
73 super(SourceType.MAP_PAINT_STYLE, url, name, title, true);
74 }
75
76 /**
77 * Constructs a new {@link StyleSource}
78 * @param entry The entry to copy the data (url, name, ...) from.
79 */
80 public StyleSource(SourceEntry entry) {
81 super(entry);
82 }
83
84 /**
85 * Apply style to osm primitive.
86 *
87 * Adds properties to a MultiCascade. All active {@link StyleSource}s add
88 * their properties on after the other. At a later stage, concrete painting
89 * primitives (lines, icons, text, ...) are derived from the MultiCascade.
90 * @param mc the current MultiCascade, empty for the first StyleSource
91 * @param osm the primitive
92 * @param scale the map scale
93 * @param pretendWayIsClosed For styles that require the way to be closed,
94 * we pretend it is. This is useful for generating area styles from the (segmented)
95 * outer ways of a multipolygon.
96 */
97 public abstract void apply(MultiCascade mc, OsmPrimitive osm, double scale, boolean pretendWayIsClosed);
98
99 /**
100 * Loads the style source.
101 */
102 public abstract void loadStyleSource();
103
104 /**
105 * Returns a new {@code InputStream} to the style source. When finished, {@link #closeSourceInputStream(InputStream)} must be called.
106 * @return A new {@code InputStream} to the style source that must be closed by the caller
107 * @throws IOException if any I/O error occurs.
108 * @see #closeSourceInputStream(InputStream)
109 */
110 public abstract InputStream getSourceInputStream() throws IOException;
111
112 /**
113 * Returns a new {@code CachedFile} to the local file containing style source (can be a text file or an archive).
114 * @return A new {@code CachedFile} to the local file containing style source
115 * @throws IOException if any I/O error occurs.
116 * @since 7081
117 */
118 public abstract CachedFile getCachedFile() throws IOException;
119
120 /**
121 * Closes the source input stream previously returned by {@link #getSourceInputStream()} and other linked resources, if applicable.
122 * @param is The source input stream that must be closed
123 * @see #getSourceInputStream()
124 * @since 6289
125 */
126 public void closeSourceInputStream(InputStream is) {
127 Utils.close(is);
128 }
129
130 /**
131 * Log an error that occured with this style.
132 * @param e error
133 */
134 public void logError(Throwable e) {
135 errors.add(e);
136 }
137
138 /**
139 * Log a warning that occured with this style.
140 * @param w warnings
141 */
142 public void logWarning(String w) {
143 warnings.add(w);
144 }
145
146 /**
147 * Replies the collection of errors that occured with this style.
148 * @return collection of errors
149 */
150 public Collection<Throwable> getErrors() {
151 return Collections.unmodifiableCollection(errors);
152 }
153
154 /**
155 * Replies the collection of warnings that occured with this style.
156 * @return collection of warnings
157 */
158 public Collection<String> getWarnings() {
159 return Collections.unmodifiableCollection(warnings);
160 }
161
162 /**
163 * Determines if this style is valid (no error, no warning).
164 * @return {@code true} if this style has 0 errors and 0 warnings
165 */
166 public boolean isValid() {
167 return errors.isEmpty() && warnings.isEmpty();
168 }
169
170 /**
171 * Initialize the class.
172 */
173 protected void init() {
174 errors.clear();
175 imageIconProvider = null;
176 icon = null;
177 }
178
179 /**
180 * Image provider for default icon.
181 *
182 * @return image provider for default styles icon
183 * @see #getIconProvider()
184 * @since 8097
185 */
186 private static synchronized ImageProvider getDefaultIconProvider() {
187 if (defaultIconProvider == null) {
188 defaultIconProvider = new ImageProvider("dialogs/mappaint", "pencil");
189 }
190 return defaultIconProvider;
191 }
192
193 /**
194 * Image provider for source icon. Uses default icon, when not else available.
195 *
196 * @return image provider for styles icon
197 * @see #getIconProvider()
198 * @since 8097
199 */
200 protected ImageProvider getSourceIconProvider() {
201 if (imageIconProvider == null) {
202 if (icon != null) {
203 imageIconProvider = MapPaintStyles.getIconProvider(new IconReference(icon, this), true);
204 }
205 if (imageIconProvider == null) {
206 imageIconProvider = getDefaultIconProvider();
207 }
208 }
209 return imageIconProvider;
210 }
211
212 /**
213 * Image provider for source icon.
214 *
215 * @return image provider for styles icon
216 * @since 8097
217 */
218 public final ImageProvider getIconProvider() {
219 ImageProvider i = getSourceIconProvider();
220 if (!getErrors().isEmpty()) {
221 i = new ImageProvider(i).addOverlay(new ImageOverlay(new ImageProvider("misc", "error"), 0.5, 0.5, 1, 1));
222 } else if (!getWarnings().isEmpty()) {
223 i = new ImageProvider(i).addOverlay(new ImageOverlay(new ImageProvider("warning-small"), 0.5, 0.5, 1, 1));
224 }
225 return i.setOptional(true);
226 }
227
228 /**
229 * Image for source icon.
230 *
231 * @return styles icon for display
232 */
233 public final ImageIcon getIcon() {
234 return getIconProvider().setMaxSize(ImageProvider.ImageSizes.MENU).get();
235 }
236
237 /**
238 * Return text to display as ToolTip.
239 *
240 * @return tooltip text containing error status
241 */
242 public String getToolTipText() {
243 if (errors.isEmpty() && warnings.isEmpty())
244 return null;
245 int n = errors.size() + warnings.size();
246 return trn("There was an error when loading this style. Select ''Info'' from the right click menu for details.",
247 "There were {0} errors when loading this style. Select ''Info'' from the right click menu for details.",
248 n, n);
249 }
250
251 /**
252 * Gets the background color that was set in this style
253 * @return The color or <code>null</code> if it was not set
254 */
255 public Color getBackgroundColorOverride() {
256 return null;
257 }
258}
Note: See TracBrowser for help on using the repository browser.