code: /*******************************************************************************
   * Copyright (c) 2009-2014 Richard Eckart de Castilho.
   *
   * 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.
   * 
   * Contributors:
   *     Richard Eckart de Castilho - initial API and implementation
   ******************************************************************************/
  package org.annolab.tt4j;
  
  import java.nio.ByteOrder;
  
  /**
   * Detect platform information and normalize it.
   *
   * @author Richard Eckart de Castilho
   */
  public
  class PlatformDetector
  {
  	public static String OS_WINDOWS   = "windows";
  	public static String OS_OSX       = "osx";
  	public static String OS_SOLARIS   = "solaris";
  	public static String OS_LINUX     = "linux";
  
  	public static String ARCH_PPC     = "ppc";
  	public static String ARCH_X86_32  = "x86_32";
  	public static String ARCH_X86_64  = "x86_64";
  	public static String ARCH_SPARC   = "sparc";
  
  	private String _arch = "";
  	private String _os = "";
  	private String _executableSuffix = "";
  	private ByteOrder _byteOrder = ByteOrder.nativeOrder();
  	private String[] _chmodCmd;
  
  	{
  		updatePlatform(
  				System.getProperties().getProperty("os.name"),
  				System.getProperties().getProperty("os.arch"),
  				ByteOrder.nativeOrder());
  	}
  
  	/**
  	 * Override the operating system name.
  	 * This should only be used in test cases.
  	 *
  	 * @param aOs an OS name as could be found in the os.name system
  	 * 		  property.
  	 */
  	public
  	void setOs(
  			final String aOs)
  	{
  		updatePlatform(aOs, _arch, _byteOrder);
  	}
  
  	/**
  	 * Get the operating system.
  	 *
  	 * @return {@literal "windows"}, {@literal "osx"}, {@literal "linux"} or
  	 *    {@literal "solaris"}.
  	 */
  	public
  	String getOs()
  	{
  		return _os;
  	}
  
  	/**
  	 * Override the architecture.
  	 * This should only be used in test cases.
  	 *
  	 * @param aArch {@literal "big-endian"} for PowerPC or Sparc systems or
  	 *      {@literal "little-endian"} for x86 systems.
  	 */
  	public
  	void setArch(
  			final String aArch)
  	{
  		updatePlatform(_os, aArch, _byteOrder);
  	}
  
  	/**
  	 * Get the platform architecture.
  	 *
  	 * @return {@literal "ppc"}, {@literal "x86_32"}, {@literal "x86_64"} or
  	 *    {"amd64"}
  	 */
  	public
  	String getArch()
  	{
  		return _arch;
  	}
  
  	/**
  	 * Set the byte order. TreeTagger models are sensitive to the byte order.
  	 * This should only be used in test cases.
  	 *
  	 * @param aByteOrder the byte order.
  	 */
  	public
  	void setByteOrder(
  			final ByteOrder aByteOrder)
  	{
  		updatePlatform(_os, _arch, aByteOrder);
  	}
  
  	/**
  	 * Get the file suffix used for executable files on the currently configured
  	 * platform.
  	 *
  	 * @return the file suffix used for executable files.
  	 */
  	public
  	String getExecutableSuffix()
  	{
  		return _executableSuffix;
  	}
  
  	/**
  	 * Get the byte order.
  	 *
  	 * @return the byte order.
  	 */
  	public
  	String getByteOrder()
  	{
  		return _byteOrder.toString().replace("_", "-").toLowerCase();
  	}
  
  	/**
  	 * Get the platform ID which is {@link #getOs()} and {@link #getArch()}
  	 * separated by a {@literal "-"} (dash).
  	 *
  	 * @return the platform ID.
  	 */
  	public
  	String getPlatformId()
  	{
  		return _os+"-"+_arch;
  	}
  
      /**
       * Updates the platform-specific settings and normalizes them.
       *
       * @param aOs the operating system string.
       * @param aArch the architecture string.
       * @param aByteOrder the byte-order string.
       */
      public
      void updatePlatform(
      		final String aOs,
      		final String aArch,
      		final ByteOrder aByteOrder)
      {
      	_os = aOs.toLowerCase();
      	_arch = aArch.toLowerCase();
      	String[] chmod = { "chmod", "755", null };
  
      	// Resolve arch "synonyms"
      	if (
      			_arch.equals("x86") ||
      			_arch.equals("i386") ||
      			_arch.equals("i486") ||
      			_arch.equals("i586") ||
      			_arch.equals("i686")
      	) {
      		_arch = ARCH_X86_32;
      	}
      	if (
      			_arch.equals("amd64")
      	) {
      		_arch = ARCH_X86_64;
      	}
      	if (_arch.equals("powerpc")) {
      		_arch = ARCH_PPC;
      	}
  
      	// Resolve name "synonyms"
      	if (_os.startsWith("windows")) {
      		_os = OS_WINDOWS;
      		_executableSuffix = ".exe";
      		chmod  = null;
      	}
      	if (_os.startsWith("mac")) {
      		_os = OS_OSX;
      	}
      	if (_os.startsWith("linux")) {
      		_os = OS_LINUX;
      	}
      	if (_os.startsWith("sun")) {
      		_os = OS_SOLARIS;
      	}
  
      	_chmodCmd = chmod;
  
      	_byteOrder = aByteOrder;
      }
  
      /**
       * Get the {@literal chmod} (change permissions) command for the current
       * platform (if one is necessary).
       *
       * @return the name of the {@literal chmod} command.
       */
      public
      String[] getChmodCmd()
      {
  		return _chmodCmd;
  	}
  }
  