You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jitsi/src/net/java/sip/communicator/launcher/SIPCommunicator.java

334 lines
12 KiB

/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.launcher;
import java.awt.*;
import java.io.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.launchutils.*;
import org.apache.felix.main.*;
/**
* Starts the SIP Communicator.
*
* @author Yana Stamcheva
* @author Lyubomir Marinov
* @author Emil Ivov
* @author Sebastien Vincent
*/
public class SIPCommunicator
{
/**
* The name of the property that stores our home dir location.
*/
public static final String PNAME_SC_HOME_DIR_LOCATION =
"net.java.sip.communicator.SC_HOME_DIR_LOCATION";
/**
* The name of the property that stores our home dir name.
*/
public static final String PNAME_SC_HOME_DIR_NAME =
"net.java.sip.communicator.SC_HOME_DIR_NAME";
/**
* The currently active name.
*/
private static String overridableDirName = "Jitsi";
/**
* Legacy home directory names that we can use if current dir name
* is the currently active name (overridableDirName).
*/
private static String[] legacyDirNames =
{".sip-communicator", "SIP Communicator"};
/**
* Name of the possible configuration file names (used under macosx).
*/
private static String[] legacyConfigurationFileNames =
{"sip-communicator.properties", "jitsi.properties",
"sip-communicator.xml", "jitsi.xml"};
/**
* Starts the SIP Communicator.
*
* @param args command line args if any
*
* @throws Exception whenever it makes sense.
*/
public static void main(String[] args)
throws Exception
{
String version = System.getProperty("java.version");
String vmVendor = System.getProperty("java.vendor");
String osName = System.getProperty("os.name");
setSystemProperties(osName);
/*
* SC_HOME_DIR_* are specific to the OS so make sure they're configured
* accordingly before any other application-specific logic depending on
* them starts (e.g. Felix).
*/
setScHomeDir(osName);
// this needs to be set before any DNS lookup is run
File f = new File(System.getProperty(PNAME_SC_HOME_DIR_LOCATION),
System.getProperty(PNAME_SC_HOME_DIR_NAME)
+ File.separator + ".usednsjava");
if(f.exists())
System.setProperty(
"sun.net.spi.nameservice.provider.1", "dns,dnsjava");
if (version.startsWith("1.4") || vmVendor.startsWith("Gnu") ||
vmVendor.startsWith("Free"))
{
String os = "";
if (osName.startsWith("Mac"))
os = ChangeJVMFrame.MAC_OSX;
else if (osName.startsWith("Linux"))
os = ChangeJVMFrame.LINUX;
else if (osName.startsWith("Windows"))
os = ChangeJVMFrame.WINDOWS;
ChangeJVMFrame changeJVMFrame = new ChangeJVMFrame(os);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
changeJVMFrame.setLocation(
screenSize.width/2 - changeJVMFrame.getWidth()/2,
screenSize.height/2 - changeJVMFrame.getHeight()/2);
changeJVMFrame.setVisible(true);
return;
}
//first - pass the arguments to our arg handler
LaunchArgHandler argHandler = LaunchArgHandler.getInstance();
int argHandlerRes = argHandler.handleArgs(args);
if ( argHandlerRes == LaunchArgHandler.ACTION_EXIT
|| argHandlerRes == LaunchArgHandler.ACTION_ERROR)
{
System.exit(argHandler.getErrorCode());
}
//lock our config dir so that we would only have a single instance of
//sip communicator, no matter how many times we start it (use mainly
//for handling sip: uris after starting the application)
if ( argHandlerRes != LaunchArgHandler.ACTION_CONTINUE_LOCK_DISABLED )
{
switch (new SipCommunicatorLock().tryLock(args))
{
case SipCommunicatorLock.LOCK_ERROR:
System.err.println("Failed to lock SIP Communicator's "
+"configuration directory.\n"
+"Try launching with the --multiple param.");
System.exit(SipCommunicatorLock.LOCK_ERROR);
break;
case SipCommunicatorLock.ALREADY_STARTED:
System.out.println(
"SIP Communicator is already running and will "
+"handle your parameters (if any).\n"
+"Launch with the --multiple param to override this "
+"behaviour.");
//we exit with success because for the user that's what it is.
System.exit(SipCommunicatorLock.SUCCESS);
break;
case SipCommunicatorLock.SUCCESS:
//Successfully locked, continue as normal.
break;
}
}
//there was no error, continue;
System.setOut(new ScStdOut(System.out));
Main.main(new String[0]);
}
/**
* Sets the system properties net.java.sip.communicator.SC_HOME_DIR_LOCATION
* and net.java.sip.communicator.SC_HOME_DIR_NAME (if they aren't already
* set) in accord with the OS conventions specified by the name of the OS.
*
* Please leave the access modifier as package (default) to allow launch-
* wrappers to call it.
*
* @param osName the name of the OS according to which the SC_HOME_DIR_*
* properties are to be set
*/
static void setScHomeDir(String osName)
{
/*
* Though we'll be setting the SC_HOME_DIR_* property values depending
* on the OS running the application, we have to make sure we are
* compatible with earlier releases i.e. use
* ${user.home}/.sip-communicator if it exists (and the new path isn't
* already in use).
*/
String location = System.getProperty(PNAME_SC_HOME_DIR_LOCATION);
String name = System.getProperty(PNAME_SC_HOME_DIR_NAME);
boolean isHomeDirnameForced = name != null;
if ((location == null) || (name == null))
{
String defaultLocation = System.getProperty("user.home");
String defaultName = ".jitsi";
// Whether we should check legacy names
// 1) when such name is not forced we check
// 2) if such is forced and is the overridableDirName check it
// (the later is the case with name transition SIP Communicator
// -> Jitsi, check them only for Jitsi)
boolean chekLegacyDirNames = (name == null) ||
name.equals(overridableDirName);
if (osName.startsWith("Mac"))
{
if (location == null)
location =
System.getProperty("user.home") + File.separator
+ "Library" + File.separator
+ "Application Support";
if (name == null)
name = "Jitsi";
}
else if (osName.startsWith("Windows"))
{
/*
* Primarily important on Vista because Windows Explorer opens
* in %USERPROFILE% so .sip-communicator is always visible. But
* it may be a good idea to follow the OS recommendations and
* use APPDATA on pre-Vista systems as well.
*/
if (location == null)
location = System.getenv("APPDATA");
if (name == null)
name = "Jitsi";
}
/* If there're no OS specifics, use the defaults. */
if (location == null)
location = defaultLocation;
if (name == null)
name = defaultName;
/*
* As it was noted earlier, make sure we're compatible with previous
* releases. If the home dir name is forced (set as system property)
* doesn't look for the default dir.
*/
if (!isHomeDirnameForced
&& (new File(location, name).isDirectory() == false)
&& new File(defaultLocation, defaultName).isDirectory())
{
location = defaultLocation;
name = defaultName;
}
// if we need to check legacy names and there is no
// current home dir already created
if(chekLegacyDirNames
&& !checkHomeFolderExist(location, name, osName))
{
// now check whether some of the legacy dir names
// exists, and use it if exist
for(int i = 0; i < legacyDirNames.length; i++)
{
// check the platform specific directory
if(checkHomeFolderExist(
location, legacyDirNames[i], osName))
{
name = legacyDirNames[i];
break;
}
// now check it and in the default location
if(checkHomeFolderExist(
defaultLocation, legacyDirNames[i], osName))
{
name = legacyDirNames[i];
location = defaultLocation;
break;
}
}
}
System.setProperty(PNAME_SC_HOME_DIR_LOCATION, location);
System.setProperty(PNAME_SC_HOME_DIR_NAME, name);
}
// when we end up with the home dirs, make sure we have log dir
new File(location, name + File.separator + "log").mkdirs();
}
/**
* Checks whether home folder exists.
* Special situation checked under macosx, due to created folder
* of the new version of the updater we may end up with our
* settings in 'SIP Communicator' folder and having 'Jitsi' folder
* created by the updater(its download location).
* So we check not only the folder exist but whether it contains
* any of the known configuration files in it.
*
* @param parent the parent folder
* @param name the folder name to check.
* @param osName OS name
* @return whether folder exists.
*/
static boolean checkHomeFolderExist(
String parent, String name, String osName)
{
if(osName.startsWith("Mac"))
{
for(int i = 0; i < legacyConfigurationFileNames.length; i++)
{
if(new File(new File(parent, name)
, legacyConfigurationFileNames[i]).exists())
return true;
}
return false;
}
return new File(parent, name).isDirectory();
}
/**
* Sets some system properties specific to the OS that needs to be set at
* the very beginning of a program (typically for UI related properties,
* before AWT is launched).
*
* @param osName OS name
*/
private static void setSystemProperties(String osName)
{
// setup here all system properties that need to be initialized at
// the very beginning of an application
if(osName.startsWith("Windows"))
{
// disable Direct 3D pipeline (used for fullscreen) before
// displaying anything (frame, ...)
System.setProperty("sun.java2d.d3d", "false");
}
else if(osName.startsWith("Mac"))
{
// On Mac OS X when switch in fullscreen, all the monitors goes
// fullscreen (turns black) and only one monitors has images
// displayed. So disable this behavior because somebody may want
// to use one monitor to do other stuff while having other ones with
// fullscreen stuff.
System.setProperty("apple.awt.fullscreencapturealldisplays",
"false");
}
}
}