package org.maachang.util;

import java.util.Locale;

/**
 * OS判別.
 *  
 * @version 2008/02/11
 * @author  masahito suzuki
 * @since MaachangBase 1.00
 */
public class Os {
    
    /**
     * OS判別名 : unix系.
     */
    private static final String OS_NAME_UNIX = "UNIX" ;
    
    /**
     * OS判別名 : dos系.
     */
    private static final String OS_NAME_DOS = "DOS" ;
    
    /**
     * OS判別名 : windowsNT系.
     */
    private static final String OS_NAME_WINNT = "WINDOWS NT" ;
    
    /**
     * OS判別名 : windows9x系.
     */
    private static final String OS_NAME_WIN9X = "WINDOWS 9X" ;
    
    /**
     * OS判別名 : os/2系.
     */
    private static final String OS_NAME_OS_2 = "OS/2" ;
    
    /**
     * OS判別名 : macintosh系.
     */
    private static final String OS_NAME_MACINTOSH = "MACINTOSH" ;
    
    /**
     * OS判別名 : Mac os X以降系.
     */
    private static final String OS_NAME_MAC_OS_X = "MAC-OS-X" ;
    
    /**
     * OS判別名 : netware系.
     */
    private static final String OS_NAME_NETWARE = "NETWARE" ;
    
    /**
     * OS判別名 : tandem系.
     */
    private static final String OS_NAME_TANDEM = "TANDEM" ;
    
    /**
     * OS判別名 : z/os系.
     */
    private static final String OS_NAME_Z_OS = "Z/OS" ;
    
    /**
     * OS判別名 : os/400系.
     */
    private static final String OS_NAME_OS_400 = "OS/400" ;
    
    /**
     * OS判別名 : openvms系.
     */
    private static final String OS_NAME_OPENVMS = "OPENVMS" ;
    
    /**
     * OS判別名 : その他.
     */
    private static final String OS_NAME_UNKNOWN = "UNKNOWN" ;
    
    
    
    /**
     * OS判別コード : unix系.
     */
    public static final int OS_UNIX = 0x00000001 ;
    
    /**
     * OS判別コード : dos系.
     */
    public static final int OS_DOS = 0x00000010 ;
    
    /**
     * OS判別コード : windowsNT系.
     */
    public static final int OS_WINNT = 0x00000021 ;
    
    /**
     * OS判別コード : windows9x系.
     */
    public static final int OS_WIN9X = 0x00000022 ;
    
    /**
     * OS判別コード : os/2系.
     */
    public static final int OS_OS_2 = 0x00000031 ;
    
    /**
     * OS判別コード : macintosh系.
     */
    public static final int OS_MACINTOSH = 0x00000041 ;
    
    /**
     * OS判別コード : Mac os X以降系.
     */
    public static final int OS_MAC_OS_X = 0x00000042 ;
    
    /**
     * OS判別コード : netware系.
     */
    public static final int OS_NETWARE = 0x00000101 ;
    
    /**
     * OS判別コード : tandem系.
     */
    public static final int OS_TANDEM = 0x00000111 ;
    
    /**
     * OS判別コード : z/os系.
     */
    public static final int OS_Z_OS = 0x00000121 ;
    
    /**
     * OS判別コード : os/400系.
     */
    public static final int OS_OS_400 = 0x00000131 ;
    
    /**
     * OS判別コード : openvms系.
     */
    public static final int OS_OPENVMS = 0x00000141 ;
    
    /**
     * OS判別コード : その他.
     */
    public static final int OS_UNKNOWN = 0x0000ffff ;
    
    
    
    /**
     * JavaVM実行OS.
     */
    private final int osType = Os.getVmOS() ;
    
    /**
     * シングルトン.
     */
    private static final Os SNGL = new Os() ;
    
    /**
     * コンストラクタ.
     */
    private Os()
    {
    }
    
    /**
     * シングルトンオブジェクトを取得.
     * <BR><BR>
     * シングルトンオブジェクトを取得します.
     * <BR>
     * @return Os シングルトンオブジェクトが返されます.
     */
    public static final Os getInstance()
    {
        return SNGL ;
    }
    
    
    /**
     * 対象のOS判別コードを取得.
     * <BR><BR>
     * 現在Java実行しているOS判別コードを取得します.
     * <BR>
     * @return int OS判別コードが返されます.
     */
    public final int getOS()
    {
        return osType ;
    }
    
    /**
     * 対象のOS判別コードをOS名に変換.
     * <BR><BR>
     * 対象のOS判別コードをOS名に変換します.
     * <BR>
     * @param type 変換対象のOS判別コードを設定します.
     * @return String 変換されたOS名が返されます.<BR>
     *                [unknown]が返された場合、範囲外の情報が指定されました.
     */
    public final String getName( int type )
    {
        
        String ret = null ;
        
        switch( type ){
            case OS_UNIX : ret = Os.OS_NAME_UNIX ; break ;
            case OS_DOS : ret = Os.OS_NAME_DOS ; break ;
            case OS_WINNT : ret = Os.OS_NAME_WINNT ; break ;
            case OS_WIN9X : ret = Os.OS_NAME_WIN9X ; break ;
            case OS_OS_2 : ret = Os.OS_NAME_OS_2 ; break ;
            case OS_MACINTOSH : ret = Os.OS_NAME_MACINTOSH ; break ;
            case OS_MAC_OS_X : ret = Os.OS_NAME_MAC_OS_X ; break ;
            case OS_NETWARE : ret = Os.OS_NAME_NETWARE ; break ;
            case OS_TANDEM : ret = Os.OS_NAME_TANDEM ; break ;
            case OS_Z_OS : ret = Os.OS_NAME_Z_OS ; break ;
            case OS_OS_400 : ret = Os.OS_NAME_OS_400 ; break ;
            case OS_OPENVMS : ret = Os.OS_NAME_OPENVMS ; break ;
            default : ret = Os.OS_NAME_UNKNOWN ; break ;
        }
        
        return ret ;
        
    }
    
    /**
     * OS判別処理.
     * <BR><BR>
     * 現在Javaが実行しているOSの判別処理を行います.
     * <BR>
     * @param type 調べるOSの判別コードを設定します.<BR>
     *             [Os.OS_UNIX]を設定した場合、Unix系OSであるかチェックします.<BR>
     *             [Os.OS_DOS]を設定した場合、Dos系OSであるかチェックします.<BR>
     *             [Os.OS_WINNT]を設定した場合、WindowsNT系OSであるかチェックします.<BR>
     *             [Os.OS_WIN9X]を設定した場合、Windows9x系OSであるかチェックします.<BR>
     *             [Os.OS_OS_2]を設定した場合、OS/2系OSであるかチェックします.<BR>
     *             [Os.OS_MACINTOSH]を設定した場合、Macintosh系OSであるかチェックします.<BR>
     *             [Os.OS_MAC_OS_X]を設定した場合、Mac os X系OSであるかチェックします.<BR>
     *             [Os.OS_NETWARE]を設定した場合、Netware系OSであるかチェックします.<BR>
     *             [Os.OS_TANDEM]を設定した場合、Tandem系OSであるかチェックします.<BR>
     *             [Os.OS_Z_OS]を設定した場合、Z/OS系OSであるかチェックします.<BR>
     *             [Os.OS_OS_400]を設定した場合、OS/400系OSであるかチェックします.<BR>
     *             [Os.OS_OPENVMS]を設定した場合、OpenVms系OSであるかチェックします.<BR>
     *             [Os.OS_UNKNOWN]を設定した場合、上記以外のOSであるかチェックします.
     * @return boolean 判別結果が返されます.<BR>
     *                 [true]が返された場合、指定判別コードは対照のOSです.<BR>
     *                 [false]が返された場合、指定判別コードではないOSです.
     */
    public final boolean isOs( int type )
    {
        return ( type == osType ) ? true : false ;
    }
    
    
    
    
    
    
    /**
     * 実行OS判別の取得.
     * <BR><BR>
     * 現在実行されているOS判別コードを取得します.
     * <BR>
     * @return int OS判別コードが返されます.
     */
    private static final int getVmOS()
    {
        
        int ret = Os.OS_UNKNOWN ;
        
        if( Os.checkOS( "windows" ) == true ){
            ret = Os.OS_WINNT ;
        }else if( Os.checkOS( "os2" ) == true ){
            ret = Os.OS_OS_2 ;
        }else if( Os.checkOS("netware" ) == true ){
            ret = Os.OS_NETWARE ;
        }else if( Os.checkOS( "dos" ) == true ){
            ret = Os.OS_DOS ;
        }else if( Os.checkOS( "mac" ) == true ){
            ret = Os.OS_MACINTOSH ;
        }else if( Os.checkOS( "macX" ) == true ){
            ret = Os.OS_MAC_OS_X ;
        }else if( Os.checkOS( "tandem" ) == true ){
            ret = Os.OS_TANDEM ;
        }else if( Os.checkOS( "unix" ) == true ){
            ret = Os.OS_UNIX ;
        }else if( Os.checkOS( "win9x" ) == true ){
            ret = Os.OS_WIN9X ;
        }else if( Os.checkOS( "z/os" ) == true ){
            ret = Os.OS_Z_OS ;
        }else if( Os.checkOS( "os/400" ) == true ){
            ret = Os.OS_OS_400 ;
        }else if( Os.checkOS( "openvms" ) == true ){
            ret = Os.OS_OPENVMS ;
        }
        
        return ret ;
        
    }
    
    /**
     * OS判別.
     * <BR><BR>
     * 現在動作しているOS判別を行います.
     * <BR>
     * @param name チェック対象のOS名を設定します.<BR>
     *             win9x系OSであるかチェックする場合、\"windows9x\"を指定します.<BR>
     *             windows NT系OSであるかチェックする場合、\"windowsNT\"を指定します.<BR>
     *             dos系OSであるかチェックする場合、\"dos\"を指定します.<BR>
     *             unix系OSであるかチェックする場合、\"unix\"を指定します.<BR>
     *             macintosh系OSであるかチェックする場合、\"macintosh\"を指定します.<BR>
     *             Mac Os X系OSであるかチェックする場合、\"maxX\"を指定します.<BR>
     *             os/2系OSであるかチェックする場合、\"os/2\"を指定します.<BR>
     *             netware系OSであるかチェックする場合、\"netware\"を指定します.<BR>
     *             tandem系OSであるかチェックする場合、\"tandem\"を指定します.<BR>
     *             z/os系OSであるかチェックする場合、\"z/os\"を指定します.<BR>
     *             os/400系OSであるかチェックする場合、\"os/400\"を指定します.<BR>
     *             OpenVMS系OSであるかチェックする場合、\"openvms\"を指定します.
     * @return boolean チェック結果が返されます.<BR>
     *                 [true]が返された場合、チェック対象で設定したOSです.<BR>
     *                 [false]が返された場合、チェック対象で設定したOSではありません.
     */
    private static final boolean checkOS( String name )
    {
        boolean ret = false ;
        String path_sp = null ;
        String os_name = null ;
        
        path_sp = System.getProperty( "path.separator" ) ;
        os_name = System.getProperty( "os.name" ).toLowerCase( Locale.US ) ;
        
        if( name != null ){
            
            if( name.equals( "windows" ) == true ){
                
                ret = os_name.indexOf( "windows" ) > -1 ;
                
            }else if( name.equals( "os/s" ) == true){
                
                ret = os_name.indexOf( "os/2" ) > -1 ;
                
            }else if( name.equals( "netware" ) == true ){
                
                ret= os_name.indexOf( "netware" ) > -1 ;
                
            }else if( name.equals( "dos" ) == true ){
                
                ret = path_sp.equals( ";" ) &&
                    ! Os.checkOS( "netware" ) ;
                
            }else if( name.equals( "macX" ) == true ){
                
                ret = os_name.startsWith( "Mac os" ) ;
                
            }else if( name.equals( "mac" ) == true ){
                
                ret = os_name.indexOf( "mac" ) > -1 ;
                
            }else if( name.equals( "tandem" ) == true ){
                
                ret = os_name.indexOf( "nonstop_kernel" ) > -1 ;
                
            }else if( name.equals( "unix" ) == true ){
                
                ret = path_sp.equals( ":" ) &&
                    ! Os.checkOS( "openvms" ) &&
                    ( 
                        ! Os.checkOS( "mac" ) ||
                        os_name.endsWith( "x" )
                    ) ;
                
            }else if( name.equals( "win9x" ) == true ){
                
                ret = Os.checkOS( "windows" ) &&
                    (
                        os_name.indexOf( "95" ) >= 0 ||
                        os_name.indexOf( "98" ) >= 0 ||
                        os_name.indexOf( "me" ) >= 0 ||
                        os_name.indexOf( "ce" ) >= 0
                    ) ;
                
            }else if( name.equals( "z/os" ) == true ){
                
                ret = os_name.indexOf( "z/os" ) > -1 ||
                    os_name.indexOf( "os/390" ) > -1 ;
                
            }else if( name.equals( "os/400" ) == true ){
                
                ret = os_name.indexOf( "os/400" ) > -1 ;
                
            }else if( name.equals( "openvms" ) == true ){
                
                ret = os_name.indexOf( "openvms" ) > -1 ;
                
            }
        }
        
        return ret ;
    }
}

