All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.izforge.izpack.util.TargetFactory Maven / Gradle / Ivy

/*
 * IzPack - Copyright 2001-2008 Julien Ponge, All Rights Reserved.
 * 
 * http://izpack.org/
 * http://izpack.codehaus.org/
 * 
 * Copyright 2002 Elmar Grom
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.izforge.izpack.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

/*---------------------------------------------------------------------------*/
/**
 * The TargetFactory serves as a central mechanism to instantiate OS specific class
 * flavors, provide OS specific file extension types, default install directories and similar
 * functionality. In addition it provides services that are related to OS versions and flavors. For
 * a tutorial on using some of the features in this class see the TargetFactory Tutorial.
 *
 * @author Elmar Grom
 * @version 0.0.1 / 1/3/2002
 */
/*---------------------------------------------------------------------------*/
/*
 * $ @design
 * 
 * Reports actually observed on some systems:
 * 
 * OS OS Name Version Architecture Native Report (ver)
 * ----------------------------------------------------------------------------------------------------------
 * Windows 95 Windows 98 Windows 98 4.10 x86 Windows 98 [Version 4.10.1998] Windows-ME Windows Me
 * 4.90 x86 Windows Millennium [Version 4.90.3000] Windows-NT 3.5 Windows-NT 4.0 Windows NT 4.0 x86
 * Windows NT Version 4.0 Windows 2000 Windows 2000 5.0 x86 Microsoft Windows 2000 [Version
 * 5.00.2195] Windows-XP Windows 2000 5.1 x86 Microsoft Windows XP [Version 5.1.2600] Windows-XP
 * Windows XP 5.1 x86 Mac Mac OS-X Linux Linux 2.4.7-10 i386 Linux Linux 2.4.18-4GB i386 Solaris
 * 
 * ---------------------------------------------------------------------------
 */
public class TargetFactory
{

    // ------------------------------------------------------------------------
    // Constant Definitions
    // ------------------------------------------------------------------------

    // Basic operating systems

    /**
     * Identifies Microsoft Windows.
     */
    public static final int WINDOWS = 0;

    /**
     * Identifies generic UNIX operating systems
     */
    public static final int UNIX = 2;

    /**
     * Used to report a non specific operating system.
     */
    public static final int GENERIC = 3;

    // operating system favors

    /**
     * This is the basic flavor for every operating system.
     */
    public static final int STANDARD = 0;

    /**
     * Used to identify the Windows-NT class of operating systems in terms of an OS flavor. It is
     * reported for Windows-NT, 2000 and XP.
     */
    public static final int NT = 1;

    /**
     * Used to identify the OS X flavor of the Mac OS
     */
    public static final int X = 2;

    // system architecture

    /**
     * Identifies Intel X86 based processor types.
     */
    public static final int X86 = 0;

    /**
     * Nonspecific processor architecture, other than X86.
     */
    public static final int OTHER = 1;

    /**
     * The extensions used for native libraries on various operating systems. The string positions
     * correspond to the basic operating system indexes. The following values are legal to use :
     * 
*
*
    *
  • WINDOWS *
  • MAC *
  • UNIX *
  • GENERIC *
*/ static final String[] LIBRARY_EXTENSION = {"dll", "so", "", ""}; /** * The os specific class prefixes for classes that implement different versions for the various * operating systems. The string positions correspond to the basic operating system indexes. The * following values are legal to use :
*
*
    *
  • WINDOWS *
  • MAC *
  • UNIX *
  • GENERIC *
*/ static final String[] CLASS_PREFIX = {"Win_", "Mac_", "Unix_", ""}; /** * The os favor specific class prefixes for classes the implement different versions for various * os favors. The string positions correspond to the flavor indexes. The following values are * legal to use :
*
*
    *
  • STANDARD *
  • NT *
  • X *
*/ static final String[] CLASS_FLAVOR_PREFIX = {"", "NT_", "X_"}; /** * The list of processor architecture specific prefixes. The string positions correspond to the * architecture indexes. The following values are leegal to use :
*
*
    *
  • X86 *
  • OTHER *
*/ static final String[] CLASS_ARCHITECTURE_PREFIX = {"X86_", // Intel X86 // architecture "U_" // unknown }; /** * The list of default install path fragments. Depending on the operating system, a path * fragment might represent either a part of the default install path or the entire path to use. * For MS-Windows it is always only a part of the full install path. The string positions * correspond to the basic operating system indexes. The following values are leegal to use : *
*
*
    *
  • WINDOWS *
  • MAC *
  • UNIX *
  • GENERIC *
*/ static final String[] INSTALL_PATH_FRAGMENT = {"Program Files" + File.separator, "/Applications" + File.separator, "/usr/local" + File.separator, File.separator + "apps" + File.separator}; /** * This is a list of keys to use when looking for resources that define the default install path * to use. The list is organized as two dimensional array of Strings. To access * the array, denote the first dimension with the operating system index and the second * dimension with the flavor index. For example to access the key for Windows-NT use * INSTALL_PATH_RESOURCE_KEY[WINDOWS][NT] The array uses a sparse population, * that is, not all array locations actually contain a key. Only locations for which a real * operating system/flavor combination exists are populated. For example, there is no such thing * as INSTALL_PATH_RESOURCE_KEY[UNIX][X] */ static final String[][] INSTALL_PATH_RESOURCE_KEY = { // Standard NT X {"TargetPanel.dir.windows", "TargetPanel.dir.windows", ""}, // Windows {"TargetPanel.dir.mac", "", "TargetPanel.dir.macosx"}, // Mac {"TargetPanel.dir.unix", "", ""}, // UNIX {"TargetPanel.dir", "", ""} // Generic }; /** * The delimiter characters used to tokenize version numbers */ private static final String VERSION_DELIMITER = ".-"; // ------------------------------------------------------------------------ // Variable Declarations // ------------------------------------------------------------------------ /** * The reference to the single instance of TargetFactory. Used in static methods * in place of this. */ private static TargetFactory me = null; /** * identifies the operating system we are running on */ private int os = -1; /** * identifies the operating system favor */ private int osFlavor = -1; /** * identifies the hardware architecture we are running on */ private int architecture = -1; /** * represents the version number of the target system */ private String version = ""; /*--------------------------------------------------------------------------*/ /** * Constructor */ /*--------------------------------------------------------------------------*/ /* * $ @design * * Identify the following about the target system: - OS type - architecture - version * * and store this information for later use. * -------------------------------------------------------------------------- */ private TargetFactory() { version = System.getProperty("os.version"); // ---------------------------------------------------- // test for Windows // ---------------------------------------------------- if (OsVersion.IS_WINDOWS) { os = WINDOWS; osFlavor = STANDARD; architecture = X86; String osName = OsVersion.OS_NAME.toLowerCase(); if (osName.indexOf("nt") > -1) { osFlavor = NT; } else if (osName.indexOf("2000") > -1) { osFlavor = NT; } else if (osName.indexOf("xp") > -1) { osFlavor = NT; } } // ---------------------------------------------------- // test for Mac OS // ---------------------------------------------------- else if (OsVersion.IS_OSX) { os = X; osFlavor = STANDARD; architecture = OTHER; } // ---------------------------------------------------- // what's left should be unix // ---------------------------------------------------- else { os = UNIX; osFlavor = STANDARD; architecture = OTHER; String osName = OsVersion.OS_NAME.toLowerCase(); if (osName.indexOf("x86") > -1) { architecture = X86; } } } /*--------------------------------------------------------------------------*/ /** * Returns an instance of TargetFactory to use. * * @return an instance of TargetFactory. */ /*--------------------------------------------------------------------------*/ public static TargetFactory getInstance() { if (me == null) { me = new TargetFactory(); } return me; } /*--------------------------------------------------------------------------*/ /** * This method returns an OS and OS flavor specific instance of the requested class.
*
* Class Naming Rules
* Class versions must be named with the OS and OS flavor as prefix. The prefixes are simply * concatenated, with the OS prefix first and the flavor prefix second. Use the following OS * specific prefixes:
*
* * * * * * * * * * * * * * * * * *
Operating SystemPrefix
Microsoft WindowsWin_
Mac OSMac_
UNIXUNIX_

* For the different OS flavors, use these prefixes:
*
* * * * * * * * * * * * * *
OS FlavorPrefix
NTNT_
Mac OS XX_

*
* Naming Example:
*
* For the class MyClass, the specific version for Windows NT must be in the * same package as MyClass and the name must be Win_NT_MyClass. A * version that should be instantiated for any non-NT flavor would be called * Win_MyClass. This would also be the version instantiated on Windows NT if the * version Win_NT_MyClass does not exist.
*
* The Loading Process
*
* The process is completed after the first successful attempt to load a class.
*
    *
  1. load a version that is OS and OS-Flavor specific *
  2. load a version that is OS specific *
  3. load the base version (without OS or OS-Flavor prefix) *
*
* See the TargetFactory Tutorial for more * information.
*
* * @param name the fully qualified name of the class to load without the extension. * @return An instance of the requested class. Note that specific initialization that can not be * accomplished in the default constructor still needs to be performed before the object can be * used. * @throws Exception if all attempts to instantiate class fail */ /*--------------------------------------------------------------------------*/ public Object makeObject(String name) throws Exception { int nameStart = name.lastIndexOf('.') + 1; String packageName = name.substring(0, nameStart); String className = name.substring(nameStart, name.length()); String actualName; try { actualName = packageName + CLASS_PREFIX[os] + CLASS_FLAVOR_PREFIX[osFlavor] + className; Class temp = Class.forName(actualName); return temp.newInstance(); } catch (Throwable exception1) { try { Class temp = Class.forName(packageName + CLASS_PREFIX[os] + className); return temp.newInstance(); } catch (Throwable exception2) { try { actualName = name; Class temp = Class.forName(actualName); return temp.newInstance(); } catch (Throwable exception3) { throw new Exception("can not instantiate class " + name); } } } } /*--------------------------------------------------------------------------*/ /** * Returns true if the version in the parameter string is higher than the version of the target * os. * * @param version the version number to compare to * @return false if the version of the target system is higher, otherwise * true */ /*--------------------------------------------------------------------------*/ /* * $ @design * * Version numbers are assumed to be constructed as follows: - a list of one or more numbers, * separated by periods as in X.X.X. ... or periods and dashes as in X.X.X-Y. ... - the numbers * follow the decimal number system - the left most number is of highest significance * * The process compares each set of numbers, beginning at the most significant and working down * the ranks (this is working left to right). The process is stopped as soon as the pair of * numbers compaired is not equal. If the numer for the target system is higher, flase is * returned, otherwise true. * -------------------------------------------------------------------------- */ public boolean versionIsHigher(String version) throws Exception { StringTokenizer targetVersion = new StringTokenizer(this.version, VERSION_DELIMITER); StringTokenizer compareVersion = new StringTokenizer(version, VERSION_DELIMITER); int target; int compare; while (targetVersion.hasMoreTokens() && compareVersion.hasMoreTokens()) { try { target = Integer.parseInt(targetVersion.nextToken()); compare = Integer.parseInt(compareVersion.nextToken()); } catch (Throwable exception) { throw new Exception("error in version string"); } if (compare > target) { return true; } else if (target > compare) { return false; } } return false; } /*--------------------------------------------------------------------------*/ /** * Returns the index number for the target operating system that was detected. * * @return an index number for the OS * @see #WINDOWS * @see #UNIX * @see #GENERIC */ /*--------------------------------------------------------------------------*/ public int getOS() { return os; } /*--------------------------------------------------------------------------*/ /** * Returns the index number for the operating system flavor that was detected on the target * system. * * @return an index for the OS flavor * @see #STANDARD * @see #NT * @see #X */ /*--------------------------------------------------------------------------*/ public int getOSFlavor() { return osFlavor; } /*--------------------------------------------------------------------------*/ /** * Returns an index number that identified the processor architecture of the target system. * * @return an index for the processor architecture * @see #X86 * @see #OTHER */ /*--------------------------------------------------------------------------*/ public int getArchitecture() { return architecture; } /*--------------------------------------------------------------------------*/ /** * Returns the file extension customarily used on the target OS for dynamically loadable * libraries. * * @return a String containing the customary library extension for the target OS. * Note that the string might be empty if there no such specific extension for the target OS. */ /*--------------------------------------------------------------------------*/ public String getNativeLibraryExtension() { return LIBRARY_EXTENSION[os]; } /*--------------------------------------------------------------------------*/ /** * Returns the system dependent default install path. This is typically used to suggest an * istall path to the end user, when performing an installation. The default install path is * assembled form the OS specific path fragment specified in INSTALL_PATH_FRAGMENT, * possibly a drive letter and the application name. The user the option to define resources * that define default paths which differ from the path fragments defined here. The following * resource names will be recognized by this method:
*
*
    *
  • TargetPanel.dir.windows *
  • TargetPanel.dir.macosx *
  • TargetPanel.dir.unix *
  • TargetPanel.dir plus the all lower case version of * System.getProperty ("os.name"), with all spaces replaced by an underscore * ('_'). *
  • TargetPanel.dir *
* * @param appName the name of the application to install. If no specific resource has been set, * then this name will be appended to the OS specific default path fragment. * @return the default install path for the target system */ /*--------------------------------------------------------------------------*/ /* * $ @design * * First try to read a path string from a resource file. This approach allows the user to * customize the default install path that is suggested to the end user by IzPack. There are a * number of choices for the naming of this resource, so we need to go through a few steps in * order to exhaust the different possibilities. If this was not successful we use the default * install path that is defined for the operating system we are running on. This path should be * expanded by the application name to form the full path that to returne. * -------------------------------------------------------------------------- */ public String getDefaultInstallPath(String appName) { String path = null; InputStream input; String keyFragment = "/res/" + INSTALL_PATH_RESOURCE_KEY[GENERIC][STANDARD]; // ---------------------------------------------------- // attempt to get an input stream through a resource // based on a key which is specific to the target OS // ---------------------------------------------------- input = getClass().getResourceAsStream("/res/" + INSTALL_PATH_RESOURCE_KEY[os][osFlavor]); // ---------------------------------------------------- // attempt to get an input stream through a resource // based on a key which is made specific to the target // OS by using the string returned by // System.getProperty ("os.name").toLowerCase () // ---------------------------------------------------- if (input == null) { String key = OsVersion.OS_NAME.toLowerCase().replace(' ', '_'); // avoid // spaces // in // file // names key = keyFragment + key.toLowerCase(); // for consistency among // TargetPanel res files input = TargetFactory.class.getResourceAsStream(key); } // ---------------------------------------------------- // attempt to get an input stream through a resource // based on a key which is not specific to any target OS // ---------------------------------------------------- if (input == null) { input = TargetFactory.class.getResourceAsStream(keyFragment); } // ---------------------------------------------------- // If we got an input stream try to read the path // from the file // ---------------------------------------------------- if (input != null) { InputStreamReader streamReader; BufferedReader reader = null; String line; try { streamReader = new InputStreamReader(input); reader = new BufferedReader(streamReader); line = reader.readLine(); while (line != null) { line = line.trim(); if (!"".equals(line)) { break; } line = reader.readLine(); } path = line; } catch (Throwable exception) { } finally { try { if (reader != null) { reader.close(); } } catch (Throwable exception) { } } } // ---------------------------------------------------- // if we were unable to obtain a path from a resource, // use the default for the traget operating system. // ---------------------------------------------------- if (path == null || "".equals(path)) { path = ""; // -------------------------------------------------- // if we run on windows, we need a valid drive letter // to put in front of the path. The drive that // contains the user's home directory is usually the // drive that also contains the install directory, // so this seems the best choice here. // -------------------------------------------------- if (os == WINDOWS) { String home = System.getProperty("user.home"); // take everything up to and including the first '\' path = home.substring(0, home.indexOf(File.separatorChar) + 1); } path = path + INSTALL_PATH_FRAGMENT[os] + appName; } return path; } /** * Gets a prefix alias for the current platform. "Win_" on Windows Systems "Win_NT_" on WinNT4, * 2000, XP Mac on Mac Mac_X on macosx and Unix_ * * @return a prefix alias for the current platform */ public static String getCurrentOSPrefix() { String OSName = System.getProperty("os.name").toLowerCase(); String OSArch = System.getProperty("os.arch").toLowerCase(); int OS = 0; int OSFlavor = 0; int OSarchitecture = 0; // ---------------------------------------------------- // test for Windows // ---------------------------------------------------- if (OSName.indexOf("windows") > -1) { OS = WINDOWS; OSFlavor = STANDARD; OSarchitecture = X86; if (OSName.indexOf("nt") > -1) { OSFlavor = NT; } else if (OSName.indexOf("2000") > -1) { OSFlavor = NT; } else if (OSName.indexOf("xp") > -1) { OSFlavor = NT; } } // ---------------------------------------------------- // test for Mac OS // ---------------------------------------------------- else if (OSName.indexOf("mac") > -1) { OS = GENERIC; OSFlavor = STANDARD; OSarchitecture = OTHER; if (OSName.indexOf("macosx") > -1) { OSFlavor = X; } } // ---------------------------------------------------- // what's left should be unix // ---------------------------------------------------- else { OS = UNIX; OSFlavor = STANDARD; OSarchitecture = OTHER; if (OSArch.indexOf("86") > -1) { OSarchitecture = X86; } } return (CLASS_PREFIX[OS] + CLASS_FLAVOR_PREFIX[OSFlavor]); } } /*---------------------------------------------------------------------------*/




© 2015 - 2024 Weber Informatics LLC | Privacy Policy