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

Last change on this file since 15007 was 15007, checked in by Don-vip, 5 years ago

remove deprecated API

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