/*************************************************************************
 *
 *  $RCSfile: javainfo.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: vg $ $Date: 2003/05/22 09:39:49 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#if !defined INCLUDED_JVMACCESS_JAVAINFO_HXX
#define INCLUDED_JVMACCESS_JAVAINFO_HXX

#include <vector>

namespace rtl { class OUString; }

namespace jvmaccess {
/** @internal
    To check if the versions are formed and ordered correctly build sunversion.cxx
    with the define SUNVERSION_SELFTEST (see sunversion.hxx). Then when this lib is
    loaded a test is run (see class SelfTest in sunversion.cxx). 
 */   

/** Provides information about a Java installation.

    This API was tested only with SUN Java, but other vendors may work as
    well if they use the same:
    1 versioning scheme
    2 directory structure
    3 library and executable names (especially of the runtime library and
      java executable)
    4 way to identify accessibility support

    If in this file the term "SUN compatible" is used then the compatibility
    refers to the previous items. Therefore, a Java may not be compatible
    although it appears so.
    
    At least the directory structure must match so as to find the runtime
    library. This of course includes that the library name is the same as well.
    If this is not the case, then an object cannot be instantiated. An object
    must therefore alway provide the runtime lib (getRuntimeLibLocation).

    The support of SUN's versioning scheme is necessary to order instances.

    Te constructor

    explicit JavaInfo(const rtl::OUString& sDirectory);

    allows to create an instance for a Java installation which is not conform
    to a SUN java as long as the runtime library can be determined.
    
    If a method is called, that needs information which cannot be obtained
    from the Java installation, because it is not compatible to a SUN Java,
    then an UnsupportedException is being thrown.

    The function isComplete determines of all necessary information could be
    obtained from the Java installation. If it returns false then that Java
    might not be compatible.

    An instance of JavaInfo is no guarantee that the Java is workable.
    
    It is not guaranteed that a java prior to version 1.3.1 is recognized.
    Pre FCS (First Customer Shipments) releases, e.g 1.4.1-beta, 1.4.1-ea, 1.4.1-rc1,
    are recogized but they are regarded as minor to FCS releases of whatever version.
    For example:
    1.3.1 > 1.4.1-beta
 */
class JavaInfo
{
public:
    class InitException
    {
    public:
        InitException();

        InitException(const InitException &);

        virtual ~InitException();

        InitException & operator =(const InitException &);
    };

    class UnsupportedException
    {
    public:
        UnsupportedException();

        UnsupportedException(const UnsupportedException &);

        virtual ~UnsupportedException();

        UnsupportedException & operator =(const UnsupportedException &);
    };
    

    /** These flags are used to specify requirements.

        They are used with the constructor
        JavaInfo::JavaInfo(const rtl::OUString& sVersion, int nFlags).

        @see JavaInfo(const rtl::OUString& sVersion, int nFlags)
     */
    enum
    {
        EqualVersion = 0x1,
        GreaterVersion = 0x2,
        SmallerVersion = 0x4,
        Accessibility = 0x8
    };

    /** Creates a JavaInfo from a given Java directory.

        In case the directory is a top level directory of a Java installation,
        then a JavaInfo object is constructed as long as the java runtime
        library is found, otherwise an InitException will be
        thrown. That is, even if some information could not be retrieved
        from the java installation, the object is constructed. In this
        case the method isComplete will return false.

        @see JavaInfo::isComplete
        
        @param sDirectory
        The absolute file URL of a directory.

        @exception InitException
    */
    explicit JavaInfo(const rtl::OUString& sDirectory);

    /** Creates a JavaInfo that meets certain requirements.

        Requirements
        are currently a version and the support of accessibility. The version is
        determined by providing a string in sVersion and flags which indicate
        how a Java version must relate to the version as determined by sVersion.
        For example sVersion contains "1.4":

        nFlags                     possible versions
        ================================================================
        EqualVersion               1.4, 1.4.0

        EqualVersion |
        GreaterVersion             1.4, 1.4.0, 1.4.0_01, 1.4.0_02, 1.4.1

        EqualVersion |
        SmallerVersion             1.4, 1.4.0, 1.3.1, 1.3.1_03

        SmallerVersion             1.3.1, 1.3.1_03

        The flags relating to a version can be combined. Combinitions can be
        EqualVersion | GreaterVersion,
        EqualVersion | SmallerVersion.

        If sVersion is empty, then any given version flags are dismissed and the
        first Java found that meets all remaining requirements is used. If
        sVersion contains a valid version string and no flags are provided, then
        a Java with exactly the specified version is searched for (same as
        flags = EqualVersion). If no suitable Java can be found then a
        InitException is thrown.

        An object can only be instantiated if it is compatible to a SUN Java.

        @param sVersion
        A String reflecting a version, e.g "1.3.1_04".

        @param nFlags
        A combinatin of flags, taken from the anonymous enum in this class.

        @exception InitException
     */
    JavaInfo(const rtl::OUString& sVersion, int nFlags);

    JavaInfo(const JavaInfo& info);

    ~JavaInfo();

    JavaInfo& operator =(const JavaInfo& info);

    /** Creates information about detected Java installations.

        The returned JavaInfo objects are at least compatible to the versioning
        scheme of a SUN Java
     */
    static void createAllInfo(std::vector<JavaInfo> *infos);

    /** Provides a JavaInfo object of the newest Java found on the system.

        If no Java could be found then an InitException will be thrown.

        The returned object is compatible to a SUN Java with respect to versioning
        and accessibility.

        @param bAccessibility
        If true, the newest Java that also supports accessibility is returned
        (or simply the newest Java if none supports accessibility).

        @return
        The new JavaInfo object.

        @exception InitException
     */
    static JavaInfo createBestInfo(bool bAccessibility);

    /** Determines whether this object and the argument info  represent the same
        Java installation.

        @param info
        The object which to compare to.

        @return
        True if this object and info are same, false otherwise.
     */
    bool isSame(const JavaInfo& info) const;

    /** Determines whether this object and the argument info represent Java
        installations with equal capabilities.

        Two JavaInfo object are considered equal if they represent installations
        of the same version, same type (JRE or SDK) and same accessibility
        support. If the info argument refers to this (isSame returns true) then
        they are also considered equal.

        If all the capabilities of both objects cannot be determined, beause
        their Javas are not SUN compatible, then an UnsupportedException is
        thrown.

        @param info
        The object which to compare to.

        @return
        True if this object equals info, false otherwise.

        @exception UnsupportedException
     */
    bool isEqual(const JavaInfo& info) const;

    /** Compares the Java versions.

        Value             Relationship of this object  to info
        ======================================================
        < 0               this is less than info
        = 0               versions are same
        > 0               this is higher than info


        If either object, this or the argument info, or both contain a version that
        does no correspond to a SUN Java versioning scheme, then an
        UnsupportedException is thrown.

        @param info
        The object whose version is compared with.

        @return
        A value indicating the relation of the respective versions.

        @exception UnsupportedException
     */
    int compareVersions(const JavaInfo& info) const;

    /** Provides the version.

        getVersion returns a version string or an UnsupportedException is thrown.
        If the versioning scheme of the Java represented by this object does not
        correspond to the SUN Java versioning scheme then the returned string
        may be unusable for comparison purposese. 
        An UnsupportedException is thrown if the version cannot be obtained at
        all. Then isComplete returns false.
       
        @return
        A version string.

        @exception UnsupportedException
     */
    const rtl::OUString& getVersion() const;

    /** Provides the absolute URL of the top level directory of the Java
        installation.

        An UnsupportedException is thrown if the directory could not be
        determined and isComplete returns false.

        @return
        The installation location.

        @exception UnsupportedException
     */
    const rtl::OUString& getInstallationLocation() const;

    /** Determines the type of the Java installation.

        Currently there are only "JRE", "SDK".

        If the type cannot be determined the an UnsupportedException
        is being thrown and isComplete returns false.

        @return
        The type.

        @exception UnsupportedException
     */
    const rtl::OUString& getType() const;

    /** Provides the absolute URL of the Java runtime library.

        @return
        The file URL of the Java runtime library.
     */
    const rtl::OUString& getRuntimeLibLocation() const;

    /** Determines if this Java installation supports accessibility.

        If it cannot be determined if accessibiltiy is supported then
        an UnsupportedException is being thrown and isComplete returns false.
        
        @return
        True if accessibility supported, false  otherwise.

        @exception UnsupportedException
     */
    bool supportsAccessibility() const;

    /** Provides a path string (no URL) of directories of the Java installation.

        On UNIX and derivates it can be used to extend the LD_LIBRARY_PATH
        environment variable. On Windows it may be used to extend the PATH
        environment variable, so that one can call LoadLibrary with just a
        "jvm.dll" argument.

        Example UNIX: "/usr/j2sdk1.4.1/jre/lib/sparc/client:
        /usr/j2sdk1.4.1/jre/lib/sparc/native_threads:
        /usr/java/j2sdk1.4.1/jre/lib/sparc"

        Example Windows: "C:\java\j2re\bin"

        @return
        The path string.
     */
    const rtl::OUString& getLibLocations() const;

    /** Provides the full path for a jar file.

        The function takes the name of a jar file and returns the full path as
        file URL. For example, if the argument is "javaplugin.jar", then the
        function returns somthing like
        file:///local/jre1.4.1/lib/javaplugin.jar. It is not guaranteed that a
        path is returned. This function will only work for some special files,
        which are delivered with a jre and must be used with the CLASSPATH.

        The method may throw an UnsupportedException, if isComplete
        returns false.
        
        @param sName
        The name of a jar file.
        
        @return
        Either a file URL or an empty string.

        @exception UnsupportedException
     */
    rtl::OUString getJarFilePath(const rtl::OUString& sName) const;

    /** Determines if all information of the Java installation could be obtained.
        Some information are only obtained if a particular method is being
        called. If that has not been done yet then the information is obtained
        now.
        
        If false is returned, then the functionality of the object is restricted
        and some methods may throw an UnsupportedException. That indicates that
        the Java installation is not compatible to a SUN Java.
        
        @return
        true - full functionality, false otherwise.
    */    
    bool isComplete();
    
private:
    class Impl;

    JavaInfo();

    Impl * pImpl;
};

}

#endif // INCLUDED_JVMACCESS_JAVAINFO_HXX
