source: josm/trunk/src/org/openstreetmap/josm/data/projection/ProjectionRegistry.java@ 14273

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

see #15229 - deprecate all Main methods related to projections. New ProjectionRegistry class

  • Property svn:eol-style set to native
File size: 4.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.projection;
3
4import java.lang.ref.WeakReference;
5import java.util.List;
6import java.util.Objects;
7import java.util.concurrent.CopyOnWriteArrayList;
8
9import org.openstreetmap.josm.data.Bounds;
10import org.openstreetmap.josm.tools.CheckParameterUtil;
11
12/**
13 * Registry for a single, global projection instance.
14 * @since 14120
15 */
16public final class ProjectionRegistry {
17
18 /**
19 * The projection method used.
20 * Use {@link #getProjection()} and {@link #setProjection(Projection)} for access.
21 * Use {@link #setProjection(Projection)} in order to trigger a projection change event.
22 */
23 private static volatile Projection proj;
24
25 private static ProjectionBoundsProvider boundsProvider;
26
27 /*
28 * Keep WeakReferences to the listeners. This relieves clients from the burden of
29 * explicitly removing the listeners and allows us to transparently register every
30 * created dataset as projection change listener.
31 */
32 private static final List<WeakReference<ProjectionChangeListener>> listeners = new CopyOnWriteArrayList<>();
33
34 private ProjectionRegistry() {
35 // hide constructor
36 }
37
38 /**
39 * Replies the current projection.
40 *
41 * @return the currently active projection
42 */
43 public static Projection getProjection() {
44 return proj;
45 }
46
47 /**
48 * Sets the current projection
49 *
50 * @param p the projection
51 */
52 public static void setProjection(Projection p) {
53 CheckParameterUtil.ensureParameterNotNull(p);
54 Projection oldValue = proj;
55 Bounds b = boundsProvider != null ? boundsProvider.getRealBounds() : null;
56 proj = p;
57 fireProjectionChanged(oldValue, proj, b);
58 }
59
60 private static void fireProjectionChanged(Projection oldValue, Projection newValue, Bounds oldBounds) {
61 if ((newValue == null ^ oldValue == null)
62 || (newValue != null && oldValue != null && !Objects.equals(newValue.toCode(), oldValue.toCode()))) {
63 listeners.removeIf(x -> x.get() == null);
64 listeners.stream().map(WeakReference::get).filter(Objects::nonNull).forEach(x -> x.projectionChanged(oldValue, newValue));
65 if (newValue != null && oldBounds != null && boundsProvider != null) {
66 boundsProvider.restoreOldBounds(oldBounds);
67 }
68 /* TODO - remove layers with fixed projection */
69 }
70 }
71
72 /**
73 * Register a projection change listener.
74 * The listener is registered to be weak, so keep a reference of it if you want it to be preserved.
75 *
76 * @param listener the listener. Ignored if <code>null</code>.
77 */
78 public static void addProjectionChangeListener(ProjectionChangeListener listener) {
79 if (listener == null) return;
80 for (WeakReference<ProjectionChangeListener> wr : listeners) {
81 // already registered ? => abort
82 if (wr.get() == listener) return;
83 }
84 listeners.add(new WeakReference<>(listener));
85 }
86
87 /**
88 * Removes a projection change listener.
89 *
90 * @param listener the listener. Ignored if <code>null</code>.
91 */
92 public static void removeProjectionChangeListener(ProjectionChangeListener listener) {
93 if (listener == null) return;
94 // remove the listener - and any other listener which got garbage collected in the meantime
95 listeners.removeIf(wr -> wr.get() == null || wr.get() == listener);
96 }
97
98 /**
99 * Remove all projection change listeners. For testing purposes only.
100 */
101 public static void clearProjectionChangeListeners() {
102 listeners.clear();
103 }
104
105 /**
106 * Returns the bounds provider called in projection events.
107 * @return the bounds provider
108 */
109 public static ProjectionBoundsProvider getBoundsProvider() {
110 return boundsProvider;
111 }
112
113 /**
114 * Sets the bounds provider called in projection events. Must not be null
115 * @param provider the bounds provider
116 */
117 public static void setboundsProvider(ProjectionBoundsProvider provider) {
118 boundsProvider = Objects.requireNonNull(provider);
119 }
120}
Note: See TracBrowser for help on using the repository browser.