001    /*
002     * Created on Aug 30, 2007
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     *
013     * Copyright @2007-2010 the original author or authors.
014     */
015    package org.fest.swing.util;
016    
017    import static java.lang.String.valueOf;
018    import static org.fest.assertions.Assertions.assertThat;
019    import static org.fest.swing.util.Modifiers.keysFor;
020    import static org.fest.util.Strings.concat;
021    
022    import java.awt.Event;
023    import java.awt.HeadlessException;
024    import java.awt.event.KeyEvent;
025    import org.fest.util.VisibleForTesting;
026    
027    /**
028     * Understands platform-specific functionality.
029     *
030     * @author Alex Ruiz
031     */
032    public final class Platform {
033    
034      private static OSIdentifier osIdentifier;
035      private static ToolkitProvider toolkitProvider;
036    
037      static {
038        reload();
039      }
040    
041      @VisibleForTesting
042      static void reload() {
043        initialize(new OSIdentifier(), new ToolkitProvider());
044      }
045    
046      @VisibleForTesting
047      static void initialize(OSIdentifier newOSIdentifier, ToolkitProvider newToolkitProvider) {
048        osIdentifier = newOSIdentifier;
049        toolkitProvider = newToolkitProvider;
050      }
051    
052      /**
053       * Return the modifier key for the appropriate accelerator key for menu shortcuts:
054       * <code>{@link KeyEvent#VK_CONTROL}</code> (default) or <code>{@link KeyEvent#VK_META}</code> (MacOS.)
055       * @return the modifier key for the appropriate accelerator key for menu shortcuts.
056       * @throws AssertionError if unable to find the appropriate key.
057       * @throws HeadlessException if <code>GraphicsEnvironment.isHeadless()</code>.
058       */
059      public static int controlOrCommandKey() {
060        int menuShortcutKeyMask = controlOrCommandMask();
061        int[] keys = keysFor(menuShortcutKeyMask);
062        assertThat(keys).as(concat("Key code for mask ", valueOf(menuShortcutKeyMask))).isNotNull().hasSize(1);
063        return keys[0];
064      }
065    
066      /**
067       * Return the modifier mask for the appropriate accelerator key for menu shortcuts:
068       * <code>{@link Event#CTRL_MASK}</code> (default) or <code>{@link Event#META_MASK}</code> (MacOS.)
069       * @return the modifier mask for the appropriate accelerator key for menu shortcuts.
070       * @throws HeadlessException if <code>GraphicsEnvironment.isHeadless()</code>.
071       */
072      public static int controlOrCommandMask() {
073        return toolkitProvider.toolkit().getMenuShortcutKeyMask();
074      }
075    
076      /**
077       * Indicates whether it is possible to resize windows that are not an instance of <code>{@link java.awt.Frame}</code>
078       * or <code>{@link java.awt.Dialog}</code>. Most X11 window managers will allow this, but stock Macintosh and Windows
079       * do not.
080       * @return <code>true</code> if it is possible to resize windows other than <code>Frame</code>s or
081       * <code>Dialog</code>s, <code>false</code> otherwise.
082       */
083      public static boolean canResizeWindows() {
084        return !isWindows() && !isMacintosh();
085      }
086    
087      /**
088       * Indicates whether it is possible to move windows that are not an instance of <code>{@link java.awt.Frame}</code> or
089       * <code>{@link java.awt.Dialog}</code>. Most X11 window managers will allow this, but stock Macintosh and Windows do
090       * not.
091       * @return <code>true</code> if it is possible to move windows other than <code>Frame</code>s or <code>Dialog</code>s,
092       * <code>false</code> otherwise.
093       */
094      public static boolean canMoveWindows() {
095        return !isWindows() && !isMacintosh();
096      }
097    
098      /**
099       * Indicates whether the operating system is Windows.
100       * @return <code>true</code> if the operation system is Windows, <code>false</code> otherwise.
101       */
102      public static boolean isWindows() {
103        return osIdentifier.isWindows();
104      }
105    
106      /**
107       * Indicates whether the operating system is Windows 9x (95, 98 or ME.)
108       * @return <code>true</code> if the operating system is Windows 9x (95, 98 or ME,) <code>false</code> otherwise.
109       */
110      public static boolean isWindows9x() {
111        return osIdentifier.isWindows9x();
112      }
113    
114      /**
115       * Indicates whether the operating system is Windows XP.
116       * @return <code>true</code> if the operating system is Windows XP, <code>false</code> otherwise.
117       */
118      public static boolean isWindowsXP() {
119        return osIdentifier.isWindowsXP();
120      }
121    
122      /**
123       * Indicates whether the operating system is a Macintosh OS.
124       * @return <code>true</code> is the operating system is a Macintosh OS, <code>false</code> otherwise.
125       */
126      public static boolean isMacintosh() {
127        return osIdentifier.isMacintosh();
128      }
129    
130      /**
131       * Indicates whether the operating system is Mac OS X.
132       * @return <code>true</code> if the operating system is Mac OS X, <code>false</code> otherwise.
133       */
134      public static boolean isOSX() {
135        return osIdentifier.isOSX();
136      }
137    
138      /**
139       * Indicates whether the operating system is using the X11 Windowing system.
140       * @return <code>true</code> if the operating system is using the X11 Windowing system, <code>false</code> otherwise.
141       */
142      public static boolean isX11() {
143        return osIdentifier.isX11();
144      }
145    
146      /**
147       * Indicates whether the operating system is Solaris.
148       * @return <code>true</code> if the operating system is Solaris, <code>false</code> otherwise.
149       */
150      public static boolean isSolaris() {
151        return osIdentifier.isSolaris();
152      }
153    
154      /**
155       * Indicates whether the operating system is HP-UX.
156       * @return <code>true</code> if the operating system is HP-UX, <code>false</code> otherwise.
157       */
158      public static boolean isHPUX() {
159        return osIdentifier.isHPUX();
160      }
161    
162      /**
163       * Indicates whether the operating system is Linux.
164       * @return <code>true</code> if the operating system is Linux, <code>false</code> otherwise.
165       */
166      public static boolean isLinux() {
167        return osIdentifier.isLinux();
168      }
169    
170      /**
171       * Returns the current operating system family.
172       * @return the current operating system family.
173       * @since 1.2
174       */
175      public static OSFamily osFamily() {
176        return osIdentifier.osFamily();
177      }
178    
179      private Platform() {}
180    }