001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.util;
018
019import java.io.File;
020import java.util.ArrayList;
021import java.util.Collections;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Locale;
025import java.util.Set;
026
027import org.apache.commons.lang3.SystemProperties;
028import org.apache.commons.lang3.SystemUtils;
029
030/**
031 * Class to help to determine the OS.
032 *
033 * @deprecated Use Apache Commons Lang's {@link SystemUtils}. Remove in 3.0.
034 */
035@Deprecated
036public final class Os {
037
038    /**
039     * All Windows based OSes.
040     */
041    public static final OsFamily OS_FAMILY_WINDOWS = new OsFamily("windows");
042
043    /**
044     * All DOS based OSes.
045     */
046    public static final OsFamily OS_FAMILY_DOS = new OsFamily("dos");
047
048    /**
049     * All Windows NT based OSes.
050     */
051    public static final OsFamily OS_FAMILY_WINNT = new OsFamily("nt", new OsFamily[] {OS_FAMILY_WINDOWS});
052
053    /**
054     * All Windows 9x based OSes.
055     */
056    public static final OsFamily OS_FAMILY_WIN9X = new OsFamily("win9x", new OsFamily[] {OS_FAMILY_WINDOWS, OS_FAMILY_DOS});
057
058    /**
059     * OS/2.
060     */
061    public static final OsFamily OS_FAMILY_OS2 = new OsFamily("os/2", new OsFamily[] {OS_FAMILY_DOS});
062
063    /**
064     * Netware.
065     */
066    public static final OsFamily OS_FAMILY_NETWARE = new OsFamily("netware");
067
068    /**
069     * All Unix based OSes.
070     */
071    public static final OsFamily OS_FAMILY_UNIX = new OsFamily("unix");
072
073    /**
074     * All Mac based OSes.
075     */
076    public static final OsFamily OS_FAMILY_MAC = new OsFamily("mac");
077
078    /**
079     * OSX.
080     */
081    public static final OsFamily OS_FAMILY_OSX = new OsFamily("osx", new OsFamily[] {OS_FAMILY_UNIX, OS_FAMILY_MAC});
082
083    private static final String OS_NAME = SystemProperties.getOsName().toLowerCase(Locale.US);
084    private static final String OS_ARCH = SystemProperties.getOsArch().toLowerCase(Locale.US);
085    private static final String OS_VERSION = SystemProperties.getOsVersion().toLowerCase(Locale.US);
086    private static final String PATH_SEP = File.pathSeparator;
087    private static final OsFamily OS_FAMILY;
088    private static final OsFamily[] OS_ALL_FAMILIES;
089
090    private static final OsFamily[] ALL_FAMILIES = {OS_FAMILY_DOS, OS_FAMILY_MAC, OS_FAMILY_NETWARE, OS_FAMILY_OS2, OS_FAMILY_OSX, OS_FAMILY_UNIX,
091        OS_FAMILY_WINDOWS, OS_FAMILY_WINNT, OS_FAMILY_WIN9X};
092
093    static {
094        OS_FAMILY = determineOsFamily();
095        OS_ALL_FAMILIES = determineAllFamilies();
096    }
097
098    private static boolean archMatches(final String arch) {
099        boolean isArch = true;
100        if (arch != null) {
101            isArch = arch.equalsIgnoreCase(OS_ARCH);
102        }
103        return isArch;
104    }
105
106    private static OsFamily[] determineAllFamilies() {
107        // Determine all families the current OS belongs to
108        final Set<OsFamily> allFamilies = new HashSet<>();
109        if (OS_FAMILY != null) {
110            final List<OsFamily> queue = new ArrayList<>();
111            queue.add(OS_FAMILY);
112            while (!queue.isEmpty()) {
113                final OsFamily family = queue.remove(0);
114                allFamilies.add(family);
115                final OsFamily[] families = family.getFamilies();
116                Collections.addAll(queue, families);
117            }
118        }
119        return allFamilies.toArray(OsFamily.EMPTY_OS_FAMILY_ARRAY);
120    }
121
122    private static OsFamily determineOsFamily() {
123        // Determine the most specific OS family
124        if (OS_NAME.contains("windows")) {
125            if (OS_NAME.contains("xp") || OS_NAME.contains("2000") || OS_NAME.contains("nt")) {
126                return OS_FAMILY_WINNT;
127            }
128            return OS_FAMILY_WIN9X;
129        }
130        if (OS_NAME.contains("os/2")) {
131            return OS_FAMILY_OS2;
132        }
133        if (OS_NAME.contains("netware")) {
134            return OS_FAMILY_NETWARE;
135        }
136        if (OS_NAME.contains("mac")) {
137            if (OS_NAME.endsWith("x")) {
138                return OS_FAMILY_OSX;
139            }
140            return OS_FAMILY_MAC;
141        }
142        if (PATH_SEP.equals(":")) {
143            return OS_FAMILY_UNIX;
144        }
145        return null;
146    }
147
148    private static boolean familyMatches(final OsFamily family) {
149        if (family == null) {
150            return false;
151        }
152        for (final OsFamily osFamily : OS_ALL_FAMILIES) {
153            if (family == osFamily) {
154                return true;
155            }
156        }
157        return false;
158    }
159
160    /**
161     * Locates an OsFamily by name (case-insensitive).
162     *
163     * @param name The family name to lookup.
164     * @return the OS family, or null if not found.
165     */
166    public static OsFamily getFamily(final String name) {
167        for (final OsFamily osFamily : ALL_FAMILIES) {
168            if (osFamily.getName().equalsIgnoreCase(name)) {
169                return osFamily;
170            }
171        }
172
173        return null;
174    }
175
176    /**
177     * Determines if the OS on which Ant is executing matches the given OS architecture.
178     *
179     * @param arch The architecture to check.
180     * @return true if the architecture matches.
181     */
182    public static boolean isArch(final String arch) {
183        return isOs((OsFamily) null, null, arch, null);
184    }
185
186    /**
187     * Determines if the OS on which Ant is executing matches the given OS family.
188     *
189     * @param family The family to check.
190     * @return true if the family matches.
191     */
192    public static boolean isFamily(final OsFamily family) {
193        return isOs(family, null, null, null);
194    }
195
196    /**
197     * Determines if the OS on which Ant is executing matches the given OS family.
198     *
199     * @param family The family to check.
200     * @return true if the family matches.
201     */
202    public static boolean isFamily(final String family) {
203        return isOs(family, null, null, null);
204    }
205
206    /**
207     * Determines if the OS on which Ant is executing matches the given OS name.
208     *
209     * @param name Description of Parameter
210     * @return The Name value
211     * @since 1.7
212     */
213    public static boolean isName(final String name) {
214        return isOs((OsFamily) null, name, null, null);
215    }
216
217    /**
218     * Determines if the OS on which Ant is executing matches the given OS family, name, architecture and version.
219     *
220     * @param family The OS family
221     * @param name The OS name
222     * @param arch The OS architecture
223     * @param version The OS version
224     * @return The Os value
225     */
226    public static boolean isOs(final OsFamily family, final String name, final String arch, final String version) {
227        if (family != null || name != null || arch != null || version != null) {
228            final boolean isFamily = familyMatches(family);
229            final boolean isName = nameMatches(name);
230            final boolean isArch = archMatches(arch);
231            final boolean isVersion = versionMatches(version);
232
233            return isFamily && isName && isArch && isVersion;
234        }
235        return false;
236    }
237
238    /**
239     * Determines if the OS on which Ant is executing matches the given OS family, name, architecture and version.
240     *
241     * @param family The OS family
242     * @param name The OS name
243     * @param arch The OS architecture
244     * @param version The OS version
245     * @return The Os value
246     */
247    public static boolean isOs(final String family, final String name, final String arch, final String version) {
248        return isOs(getFamily(family), name, arch, version);
249    }
250
251    /**
252     * Determines if the OS on which Ant is executing matches the given OS version.
253     *
254     * @param version The version to check.
255     * @return true if the version matches.
256     */
257    public static boolean isVersion(final String version) {
258        return isOs((OsFamily) null, null, null, version);
259    }
260
261    private static boolean nameMatches(final String name) {
262        boolean isName = true;
263        if (name != null) {
264            isName = name.equalsIgnoreCase(OS_NAME);
265        }
266        return isName;
267    }
268
269    private static boolean versionMatches(final String version) {
270        boolean isVersion = true;
271        if (version != null) {
272            isVersion = version.equalsIgnoreCase(OS_VERSION);
273        }
274        return isVersion;
275    }
276
277    /**
278     * Private constructor to block instantiation.
279     */
280    private Os() {
281    }
282}