All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xapi.util.X_Runtime Maven / Gradle / Ivy

Go to download

Everything needed to run a comprehensive dev environment. Just type X_ and pick a service from autocomplete; new dev modules will be added as they are built. The only dev service not included in the uber jar is xapi-dev-maven, as it includes all runtime dependencies of maven, adding ~4 seconds to build time, and 6 megabytes to the final output jar size (without xapi-dev-maven, it's ~1MB).

The newest version!
package xapi.util;

import static xapi.util.X_Namespace.*;

import java.io.File;
import java.io.IOException;

import xapi.platform.JrePlatform;

/**
 * This class is magic; there are four copies of this class;
 * do not add anything to them unless you download all xapi source,
 * and do a full text search on "X_Runtime\s+{" 
 *
 * This is the public class exposed to a jre.
 * Each method compiles down to a runtime constant,
 * or as close a possible,
 * to encourage compiler inlining.
 *
 * Then, we super-source a copy for normal gwt builds, which reports false
 * for isRuntimeInjection, and GWT.isScript() for isGwtProd().
 *
 * For gwt users who inherit xapi.X_Inject, we use magic method injection
 * to replace the super-sourced copy of {@link #isRuntimeInjection()} to return
 * true or false, depending on the configuration present in gwt module xml.
 *
 * Finally, our xapi-debug module will override X_Runtime in the classloader,
 * to return true for isDebug().
 *
 * @author "James X. Nelson ([email protected])"
 *
 */
@JrePlatform
public class X_Runtime {

  private X_Runtime() {}
  
  // using static final fields to encourage inlining after clinit
  private static final boolean inject;
  private static final boolean parallel;
  private static final boolean debug;
  private static final boolean test;
  private static final boolean gwt;
  static {
    debug = "true".equals(System.getProperty(PROPERTY_DEBUG));
    test = !"false".equals(System.getProperty(PROPERTY_TEST));

    boolean success = !"false".equals(System.getProperty(PROPERTY_USE_X_INJECT, "true"));
    try {

      // Check if user has disabled with a system property.
      if (success) {
        // Make sure the X_Inject class is loadable
        Class.forName("xapi.inject.X_Inject");
      }
    } catch (Throwable e) {
      String error = "Class xapi.inject.X_Inject is not loadable." +
        (debug?"\nEnsure your module inherits xapi-core-inject, or set system property " +
                 PROPERTY_USE_X_INJECT+" to \"false\"." : "");
      if (debug || success)
        System.err.println(error);
      // If the user explicitly set use X inject to true, we bail early,
      // with a more useful error message.  Not setting the property will
      // merely print the error message, and continue w/out injection.
      if ("true".equals(System.getProperty(PROPERTY_USE_X_INJECT)))
        throw new AssertionError(error);
      success = false;
    }
    inject = success;

    try {
      // Make sure X_Process is loadable, and bail with a usable error message.
      Class.forName("xapi.process.X_Process");
      success = !"".equals(System.getProperty(PROPERTY_MULTITHREADED,"1"));
    } catch (Throwable e) {
      success = !"".equals(System.getProperty(PROPERTY_MULTITHREADED,""));
      String message = "Class xapi.process.X_Process is not loadable." +
          (debug?"\nEnsure your module inherits xapi-core-process, or set system property " +
              PROPERTY_MULTITHREADED+" to empty string \"\".":"");
      if (debug || success)
        System.err.println(message);
      if (success) { //if system property was set
        // throw now, with better error message.
        throw new AssertionError(message);
      }
      success = false;
    }
    parallel = success;

    // our last variable, isGwt, requires special handling;
    // although this class should be super-sourced in all gwt compiles,
    // we must take care not to break on any platforms that don't have gwt-user
    // on the classpath (android comes to mind).
    success = false;
    try {
      //This will bomb in gwt if our emulation layer isn't on user classpath
      Class cls = Class.forName("com.google.gwt.core.shared.GWT");
      if (cls == null) {
        //Only gwt might return null
        //in cases where a user has our emulation layer on classpath,
        //but didn't explicitly inherit wetheinter.net.gwt.Reflect;
        //Class.forName will return null instead of throw ClassNotFoundException
        success = true;
        //For users who do inherit wetheinter.net.gwt.Reflect,
        //Class.forName is a magic-method, which will return any class
        //accessible to the module being compiled
      } else {

      try {
        java.lang.reflect.Method isClient = cls.getMethod("isClient");
        //normally only gwt dev or a jre that happens to have GWT on classpath
        //will actually get to call this method.  Gwt production might,
        //if you send the GWT.class literal through X_Gwt.magicClass() method.
        success = (Boolean)isClient.invoke(null);
      }catch (NoSuchMethodError e) {
        //This is what our emulated class will throw if a class is not enhanced
        success = true;
      } catch (IllegalArgumentException e) {
        assert false : e;//should never get here
      } catch (IllegalAccessException e) {
        //eat this silently; a java enviro with a security manager is not gwt
      } catch (java.lang.reflect.InvocationTargetException e) {
        assert false : e;//should never get here, but don't punish prod
      }
      }
    } catch (VerifyError e) {
      // only ever thrown by java; can happen when gwt w/ java 8 is on classpath
    } catch (UnsupportedClassVersionError e) {
      // only ever thrown by java; can happen when gwt w/ java 8 is on classpath
    }catch(NoSuchMethodException e) {
      //What an unpatched GWT java.lang.Class will throw
      success = true;
    }catch(NoClassDefFoundError e) {
      //A jre that does not have GWT on classpath
    }catch(ClassNotFoundException e) {
      //A jre that does not have GWT on classpath
    }
    gwt = success;

  }
  /**
   * Overridden in super-source to return GWT.isScript()
   * @return - true if running in compiled javascript.
   */
  public static boolean isJavaScript() {
    return false;
  }
  /**
   * Overridden in super-source to return false.
   * @return - true in all jre runtimes, including gwt-dev
   */
  public static boolean isJava() {
    return true;
  }
  /**
   * @return - true only if xapi-flash-api is inherited.
   */
  public static boolean isActionScript() {
    return false;
  }

  /**
   * @return Convenience method for whether this is a gwt environment;
   * hardcoded to true in super-source; optimized to return true in gwt dev.
   */
  public static boolean isGwt() {
    return gwt;
  }

  /**
   * In jres, this returns true if xapi.inject.X_Inject is on classpath,
   * and the user has not set system property
   * {@link X_Namespace#PROPERTY_USE_X_INJECT} explicitly to "false".
   *
   * Overridden in super-source to return false;
   * overridden again with magic-method-injection to return true.
   *
   * The default debug module will check X_Properties on every call.
   *
   * @return true if runtime injection is enabled.
   */
  public static boolean isRuntimeInjection() {
    // defaults to true; can be inlined after clinit
    return inject;
  }


  /**
   * @return true is xapi.debug property is set to true.
   */
  public static boolean isDebug() {
    //set xapi.debug = true to enable debugging.
    return debug;
  }
  
  public static boolean isTest() {
    return test;
  }

  /**
   * @return true unless {@link X_Namespace#PROPERTY_MULTITHREADED} is set to 0
   */
  public static boolean isMultithreaded() {
    // default to true; can be inlined after clinit
    return parallel;
  }

  public static String getWorkingDirectory() {
    String pwd = System.getenv("PWD");
    if (pwd == null)
      try {
        pwd = new File(".").getCanonicalPath();
      } catch (IOException ignored) {}
    return pwd == null ? "." : pwd;
  }



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy