source: josm/trunk/src/org/openstreetmap/josm/tools/PlatformHook.java@ 12742

Last change on this file since 12742 was 12695, checked in by Don-vip, 7 years ago

see #15182 - refactor PlatformHookOsx so that all GUI actions are performed in MainApplication and only macOS-specific stuff remains in platform hook

  • Property svn:eol-style set to native
File size: 11.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.awt.GraphicsEnvironment;
5import java.io.BufferedReader;
6import java.io.File;
7import java.io.IOException;
8import java.io.InputStreamReader;
9import java.nio.charset.StandardCharsets;
10import java.security.KeyStore;
11import java.security.KeyStoreException;
12import java.security.NoSuchAlgorithmException;
13import java.security.cert.CertificateException;
14import java.security.cert.X509Certificate;
15import java.text.DateFormat;
16import java.util.Date;
17import java.util.List;
18
19import org.openstreetmap.josm.Main;
20import org.openstreetmap.josm.io.CertificateAmendment.CertAmend;
21import org.openstreetmap.josm.tools.date.DateUtils;
22
23/**
24 * This interface allows platform (operating system) dependent code
25 * to be bundled into self-contained classes.
26 * @since 1023
27 */
28public interface PlatformHook {
29
30 /**
31 * The preStartupHook will be called extremly early. It is
32 * guaranteed to be called before the GUI setup has started.
33 *
34 * Reason: On OSX we need to inform the Swing libraries
35 * that we want to be integrated with the OS before we setup our GUI.
36 */
37 default void preStartupHook() {
38 // Do nothing
39 }
40
41 /**
42 * The afterPrefStartupHook will be called early, but after
43 * the preferences have been loaded and basic processing of
44 * command line arguments is finished.
45 * It is guaranteed to be called before the GUI setup has started.
46 */
47 default void afterPrefStartupHook() {
48 // Do nothing
49 }
50
51 /**
52 * The startupHook will be called early, but after the GUI
53 * setup has started.
54 *
55 * Reason: On OSX we need to register some callbacks with the
56 * OS, so we'll receive events from the system menu.
57 * @param callback Java expiration callback, providing GUI feedback
58 * @since 12270 (signature)
59 */
60 default void startupHook(JavaExpirationCallback callback) {
61 // Do nothing
62 }
63
64 /**
65 * The openURL hook will be used to open an URL in the
66 * default web browser.
67 * @param url The URL to open
68 * @throws IOException if any I/O error occurs
69 */
70 void openUrl(String url) throws IOException;
71
72 /**
73 * The initSystemShortcuts hook will be called by the
74 * Shortcut class after the modifier groups have been read
75 * from the config, but before any shortcuts are read from
76 * it or registered from within the application.
77 *
78 * Please note that you are not allowed to register any
79 * shortuts from this hook, but only "systemCuts"!
80 *
81 * BTW: SystemCuts should be named "system:<whatever>",
82 * and it'd be best if sou'd recycle the names already used
83 * by the Windows and OSX hooks. Especially the later has
84 * really many of them.
85 *
86 * You should also register any and all shortcuts that the
87 * operation system handles itself to block JOSM from trying
88 * to use them---as that would just not work. Call setAutomatic
89 * on them to prevent the keyboard preferences from allowing the
90 * user to change them.
91 */
92 void initSystemShortcuts();
93
94 /**
95 * The makeTooltip hook will be called whenever a tooltip for
96 * a menu or button is created.
97 *
98 * Tooltips are usually not system dependent, unless the
99 * JVM is too dumb to provide correct names for all the keys.
100 *
101 * Some LAFs don't understand HTML, such as the OSX LAFs.
102 *
103 * @param name Tooltip text to display
104 * @param sc Shortcut associated (to display accelerator between parenthesis)
105 * @return Full tooltip text (name + accelerator)
106 */
107 default String makeTooltip(String name, Shortcut sc) {
108 StringBuilder result = new StringBuilder();
109 result.append("<html>").append(name);
110 if (sc != null && !sc.getKeyText().isEmpty()) {
111 result.append(" <font size='-2'>(")
112 .append(sc.getKeyText())
113 .append(")</font>");
114 }
115 return result.append("&nbsp;</html>").toString();
116 }
117
118 /**
119 * Returns the default LAF to be used on this platform to look almost as a native application.
120 * @return The default native LAF for this platform
121 */
122 String getDefaultStyle();
123
124 /**
125 * Determines if the platform allows full-screen.
126 * @return {@code true} if full screen is allowed, {@code false} otherwise
127 */
128 default boolean canFullscreen() {
129 return !GraphicsEnvironment.isHeadless() &&
130 GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().isFullScreenSupported();
131 }
132
133 /**
134 * Renames a file.
135 * @param from Source file
136 * @param to Target file
137 * @return {@code true} if the file has been renamed, {@code false} otherwise
138 */
139 default boolean rename(File from, File to) {
140 return from.renameTo(to);
141 }
142
143 /**
144 * Returns a detailed OS description (at least family + version).
145 * @return A detailed OS description.
146 * @since 5850
147 */
148 String getOSDescription();
149
150 /**
151 * Returns OS build number.
152 * @return OS build number.
153 * @since 12217
154 */
155 default String getOSBuildNumber() {
156 return "";
157 }
158
159 /**
160 * Setup system keystore to add JOSM HTTPS certificate (for remote control).
161 * @param entryAlias The entry alias to use
162 * @param trustedCert the JOSM certificate for localhost
163 * @return {@code true} if something has changed as a result of the call (certificate installation, etc.)
164 * @throws KeyStoreException in case of error
165 * @throws IOException in case of error
166 * @throws CertificateException in case of error
167 * @throws NoSuchAlgorithmException in case of error
168 * @since 7343
169 */
170 default boolean setupHttpsCertificate(String entryAlias, KeyStore.TrustedCertificateEntry trustedCert)
171 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
172 // TODO setup HTTPS certificate on Unix and OS X systems
173 return false;
174 }
175
176 /**
177 * Returns the {@code X509Certificate} matching the given certificate amendment information.
178 * @param certAmend certificate amendment
179 * @return the {@code X509Certificate} matching the given certificate amendment information, or {@code null}
180 * @throws KeyStoreException in case of error
181 * @throws IOException in case of error
182 * @throws CertificateException in case of error
183 * @throws NoSuchAlgorithmException in case of error
184 * @since 11943
185 */
186 default X509Certificate getX509Certificate(CertAmend certAmend)
187 throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
188 return null;
189 }
190
191 /**
192 * Executes a native command and returns the first line of standard output.
193 * @param command array containing the command to call and its arguments.
194 * @return first stripped line of standard output
195 * @throws IOException if an I/O error occurs
196 * @since 12217
197 */
198 default String exec(String... command) throws IOException {
199 Process p = Runtime.getRuntime().exec(command);
200 try (BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF_8))) {
201 return Utils.strip(input.readLine());
202 }
203 }
204
205 /**
206 * Returns the platform-dependent default cache directory.
207 * @return the platform-dependent default cache directory
208 * @since 7829
209 */
210 File getDefaultCacheDirectory();
211
212 /**
213 * Returns the platform-dependent default preferences directory.
214 * @return the platform-dependent default preferences directory
215 * @since 7831
216 */
217 File getDefaultPrefDirectory();
218
219 /**
220 * Returns the platform-dependent default user data directory.
221 * @return the platform-dependent default user data directory
222 * @since 7834
223 */
224 File getDefaultUserDataDirectory();
225
226 /**
227 * Returns the list of platform-dependent default datum shifting directories for the PROJ.4 library.
228 * @return the list of platform-dependent default datum shifting directories for the PROJ.4 library
229 * @since 11642
230 */
231 List<File> getDefaultProj4NadshiftDirectories();
232
233 /**
234 * Determines if the JVM is OpenJDK-based.
235 * @return {@code true} if {@code java.home} contains "openjdk", {@code false} otherwise
236 * @since 12219
237 */
238 default boolean isOpenJDK() {
239 String javaHome = System.getProperty("java.home");
240 return javaHome != null && javaHome.contains("openjdk");
241 }
242
243 /**
244 * Called when an outdated version of Java is detected at startup.
245 * @since 12270
246 */
247 @FunctionalInterface
248 interface JavaExpirationCallback {
249 /**
250 * Asks user to update its version of Java.
251 * @param updVersion target update version
252 * @param url download URL
253 * @param major true for a migration towards a major version of Java (8:9), false otherwise
254 * @param eolDate the EOL/expiration date
255 */
256 void askUpdateJava(String updVersion, String url, String eolDate, boolean major);
257 }
258
259 /**
260 * Checks if the running version of Java has expired, proposes to user to update it if needed.
261 * @param callback Java expiration callback
262 * @since 12270 (signature)
263 * @since 12219
264 */
265 default void checkExpiredJava(JavaExpirationCallback callback) {
266 Date expiration = Utils.getJavaExpirationDate();
267 if (expiration != null && expiration.before(new Date())) {
268 String version = Utils.getJavaLatestVersion();
269 callback.askUpdateJava(version != null ? version : "latest",
270 Main.pref.get("java.update.url", "https://www.java.com/download"),
271 DateUtils.getDateFormat(DateFormat.MEDIUM).format(expiration), false);
272 }
273 }
274
275 /**
276 * Called when interfacing with native OS functions. Currently only used with macOS.
277 * The callback must perform all GUI-related tasks associated to an OS request.
278 * The non-GUI, platform-specific tasks, are usually performed by the {@code PlatformHook}.
279 * @since 12695
280 */
281 interface NativeOsCallback {
282 /**
283 * macOS: Called when JOSM is asked to open a list of files.
284 * @param files list of files to open
285 */
286 void openFiles(List<File> files);
287
288 /**
289 * macOS: Invoked when JOSM is asked to quit.
290 * @return {@code true} if JOSM has been closed, {@code false} if the user has cancelled the operation.
291 */
292 boolean handleQuitRequest();
293
294 /**
295 * macOS: Called when JOSM is asked to show it's about dialog.
296 */
297 void handleAbout();
298
299 /**
300 * macOS: Called when JOSM is asked to show it's preferences UI.
301 */
302 void handlePreferences();
303 }
304
305 /**
306 * Registers the native OS callback. Currently only needed for macOS.
307 * @param callback the native OS callback
308 * @since 12695
309 */
310 default void setNativeOsCallback(NativeOsCallback callback) {
311 // To be implemented if needed
312 }
313}
Note: See TracBrowser for help on using the repository browser.