Java tutorial
// Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See License.txt in the repository root. package com.microsoft.tfs.jni.helpers; import java.net.InetAddress; import java.text.MessageFormat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.microsoft.tfs.jni.PlatformMiscUtils; import com.microsoft.tfs.util.Platform; /** * <p> * Contains static helper methods for discovering machine settings (host name, * etc.). * </p> * * @since TEE-SDK-10.1 */ public abstract class LocalHost { /** * <b>Constant Duplication Warning</b> * <p> * This constant is also defined in * com.microsoft.tfs.core.clients.versioncontrol.VersionControlConstants * which this project does not depend on, so it is redefined here to avoid * moving all the constants around. * </p> */ public final static int MAX_COMPUTER_NAME_SIZE = 31; private static final Log log = LogFactory.getLog(LocalHost.class); /** * The system property that, if set to a non-empty string, overrides all * other methods for determining the computer's short host name. */ public static final String SHORT_NAME_OVERRIDE_PROPERTY = "computerName"; //$NON-NLS-1$ /** * Where the cached computer name string goes. */ private static String computerName; /** * <p> * Gets the short name of the current computer. This method uses multiple * techniques to determine the host name, allowing for a system property * override. The short name is cached forever: the name returned the first * time is returned for the life of the {@link LocalHost}'s classloader * regardless of actual host name changes. * <p> * The returned hostname is at most {@value #MAX_COMPUTER_NAME_SIZE} * characters (longer hostnames are truncated). * </p> * <p> * The {@link #SHORT_NAME_OVERRIDE_PROPERTY} may be used to define the * computer name exactly. * </p> * * @return a short identifier (name of this computer). Never * <code>null</code> or empty. */ public synchronized static String getShortName() { if (computerName == null) { String name = null; /* * The system property overrides all other settings. */ name = getSystemPropertyShortName(); /* * Native code (or the appropriate fallback from that layer) is * quite accurate. This will almost always work for all platforms. */ if (name == null) { name = getNativeShortName(); } /* * Some platforms expose an environment variable. */ if (name == null) { name = getEnvironmentShortName(); } /* * The last real technique is pure Java, which fails in certain * network configurations because it uses DNS. */ if (name == null) { name = getPureJavaShortName(); } /* * If we still don't have a host name, make up a cheesy one. */ if (name == null || name.length() == 0) { name = getMadeUpShortName(); } // Cache the name forever. Truncate if too long. computerName = name.substring(0, (name.length() > MAX_COMPUTER_NAME_SIZE) ? MAX_COMPUTER_NAME_SIZE : name.length()); } return computerName; } /** * Gets the host name using environment variables. Many major versions of * Java do not support reading environment variables, and on those platforms * this method returns null, so it is not often useful. Also, Windows * usually sets COMPUTERNAME to the right value, but no variables are read * on Unix because there isn't a convention for exposing the host name with * an environment variable. * * @return the host name read from the environment variables, or null if * none was found. */ private static String getEnvironmentShortName() { /* * On Windows, the COMPUTERNAME environment variable is usually set to * the correct thing. Unix doesn't have a common environment variable * containing the host name. */ if (Platform.isCurrentPlatform(Platform.WINDOWS)) { final String computerName = PlatformMiscUtils.getInstance().getEnvironmentVariable("COMPUTERNAME"); //$NON-NLS-1$ if (computerName != null && computerName.length() > 0) { return computerName; } } return null; } /** * Gets the host name using native code (or appropriate fallback if native * code does not load for this platform). * * @return the host name determined in native code, or null if the host name * could not be determined. */ private static String getNativeShortName() { final String name = PlatformMiscUtils.getInstance().getComputerName(); if (name != null && name.length() > 0) { return name; } return null; } /** * Gets the host name by checking the {@link #SHORT_NAME_OVERRIDE_PROPERTY} * system property's value. * * @return the host name read from the system property, or null if the * property was not set or was empty. */ private static String getSystemPropertyShortName() { final String name = System.getProperty(SHORT_NAME_OVERRIDE_PROPERTY); if (name != null && name.length() > 0) { return name; } return null; } /** * Only called when all techniques to get the host name fail. Simply makes * up a string based on the username. * * @return a made-up hostname including the username running Java and some * other text. Never null. */ private static String getMadeUpShortName() { String username = System.getProperty("user.name"); //$NON-NLS-1$ /* * Scrub out non-alphanumeric characters. */ if (username != null) { final StringBuffer newUsername = new StringBuffer(); for (int i = 0; i < username.length(); i++) { final char c = username.charAt(i); if (Character.isLetterOrDigit(c)) { newUsername.append(c); } } username = newUsername.toString(); } if (username != null && username.length() != 0) { // Something like "JohnComputer". return username + "Computer"; //$NON-NLS-1$ } log.warn(MessageFormat.format( "Could not make a hostname from the username '{0}' because it had no usable characters", //$NON-NLS-1$ username)); // Everything failed. return "TEEComputer"; //$NON-NLS-1$ } /** * Gets the host name using only standard Java features. This method is * unreliable in certain network configurations because it relies on Java's * DNS features to resolve the local interface, and DNS may not always work. * Other methods should be preferred to this one. * * @return the short host name (without domain names), or null if none could * be determined. */ private static String getPureJavaShortName() { /* * I have a feeling this may fail for some computers with unusual network * configurations (lots of interfaces; no DNS; etc.). It may need to be * scrapped and re-written. */ String name = null; try { final InetAddress localMachine = InetAddress.getLocalHost(); name = localMachine.getHostName(); } catch (final java.net.UnknownHostException e) { log.warn("Pure Java host name lookup failed", e); //$NON-NLS-1$ /* * This happens in some network configurations on Unix, and possibly * Windows. */ return null; } /* * GCJ (and possibly others) returns a full hostname * ("fun.whatever.domain") instead of just "fun", so we use only the * first part. */ final int dotIndex = name.indexOf('.'); if (dotIndex != -1) { name = name.substring(0, dotIndex); } return name; } }