예제 #1
0
  // adds offline mode from system property
  private Settings enrichWithOfflineMode(Settings settings) {

    String goOffline = SecurityActions.getProperty(ALT_MAVEN_OFFLINE);
    if (goOffline != null && goOffline.length() > 0) {
      settings.setOffline(Boolean.valueOf(goOffline));
    }

    return settings;
  }
예제 #2
0
  /**
   * Loads default Maven settings from standard location or from a location specified by a property
   *
   * @return
   */
  public Settings buildDefaultSettings() {
    SettingsBuildingRequest request =
        new DefaultSettingsBuildingRequest().setSystemProperties(SecurityActions.getProperties());

    String altUserSettings = SecurityActions.getProperty(ALT_USER_SETTINGS_XML_LOCATION);
    String altGlobalSettings = SecurityActions.getProperty(ALT_GLOBAL_SETTINGS_XML_LOCATION);

    request.setUserSettingsFile(new File(DEFAULT_USER_SETTINGS_PATH));
    // set alternate files
    if (altUserSettings != null && altUserSettings.length() > 0) {
      request.setUserSettingsFile(new File(altUserSettings));
    }

    if (altGlobalSettings != null && altGlobalSettings.length() > 0) {
      request.setGlobalSettingsFile(new File(altGlobalSettings));
    }

    return buildSettings(request);
  }
예제 #3
0
  // adds local repository
  private Settings enrichWithLocalRepository(Settings settings) {

    // set default value if not set at all
    if (settings.getLocalRepository() == null || settings.getLocalRepository().length() == 0) {
      settings.setLocalRepository(DEFAULT_REPOSITORY_PATH);
    }

    // override any value with system property based location
    String altLocalRepository = SecurityActions.getProperty(ALT_LOCAL_REPOSITORY_LOCATION);
    if (altLocalRepository != null && altLocalRepository.length() > 0) {
      settings.setLocalRepository(altLocalRepository);
    }
    return settings;
  }
예제 #4
0
/**
 * Builds Maven settings from arbitrary settings.xml file
 *
 * @author <a href="mailto:[email protected]">Karel Piwko</a>
 */
public class MavenSettingsBuilder {
  private static Logger log = Logger.getLogger(MavenSettingsBuilder.class.getName());

  /** Sets an alternate location to Maven user settings.xml configuration */
  public static final String ALT_USER_SETTINGS_XML_LOCATION = "org.apache.maven.user-settings";

  /** Sets an alternate location of Maven global settings.xml configuration */
  public static final String ALT_GLOBAL_SETTINGS_XML_LOCATION = "org.apache.maven.global-settings";

  /** Sets Maven resolution either online or offline */
  public static final String ALT_MAVEN_OFFLINE = "org.apache.maven.offline";

  /** Sets an alternate location of Maven local repository */
  public static final String ALT_LOCAL_REPOSITORY_LOCATION = "maven.repo.local";

  // path to the user settings.xml
  private static final String DEFAULT_USER_SETTINGS_PATH =
      SecurityActions.getProperty("user.home").concat("/.m2/settings.xml");

  // path to the default local repository
  private static final String DEFAULT_REPOSITORY_PATH =
      SecurityActions.getProperty("user.home").concat("/.m2/repository");

  /**
   * Loads default Maven settings from standard location or from a location specified by a property
   *
   * @return
   */
  public Settings buildDefaultSettings() {
    SettingsBuildingRequest request =
        new DefaultSettingsBuildingRequest().setSystemProperties(SecurityActions.getProperties());

    String altUserSettings = SecurityActions.getProperty(ALT_USER_SETTINGS_XML_LOCATION);
    String altGlobalSettings = SecurityActions.getProperty(ALT_GLOBAL_SETTINGS_XML_LOCATION);

    request.setUserSettingsFile(new File(DEFAULT_USER_SETTINGS_PATH));
    // set alternate files
    if (altUserSettings != null && altUserSettings.length() > 0) {
      request.setUserSettingsFile(new File(altUserSettings));
    }

    if (altGlobalSettings != null && altGlobalSettings.length() > 0) {
      request.setGlobalSettingsFile(new File(altGlobalSettings));
    }

    return buildSettings(request);
  }

  /**
   * Builds Maven settings from request.
   *
   * @param request The request for new settings
   */
  public Settings buildSettings(SettingsBuildingRequest request) {
    SettingsBuildingResult result;
    try {
      SettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance();

      if (request.getGlobalSettingsFile() != null) {
        if (log.isLoggable(Level.FINE)) {
          log.fine(
              "Using "
                  + request.getGlobalSettingsFile().getAbsolutePath()
                  + " to get global Maven settings.xml");
        }
      }
      final File userSettingsFile = request.getUserSettingsFile();
      if (userSettingsFile != null) {
        if (log.isLoggable(Level.FINE)) {
          log.fine(
              "Using " + userSettingsFile.getAbsolutePath() + " to get user Maven settings.xml");
        }

        // Maven will not check the format passed in (any XML will do), so let's ensure we have a
        // settings.xml by checking just the top-level element
        final XMLStreamReader reader;
        try {
          reader =
              XMLInputFactory.newInstance()
                  .createXMLStreamReader(new FileInputStream(userSettingsFile));
          // get the first element name
          while (reader.hasNext()) {
            if (reader.next() == XMLStreamConstants.START_ELEMENT) {
              break;
            }
          }
          final String topLevel = reader.getLocalName();

          if (!"settings".equals(topLevel)) {
            throw new InvalidConfigurationFileException(
                "Invalid format settings.xml found: " + userSettingsFile);
          }
        } catch (final FileNotFoundException e) {
          // Ignore at this level
        } catch (final XMLStreamException xmlse) {
          throw new RuntimeException(
              "Could not check file format of specified settings.xml: " + userSettingsFile, xmlse);
        }
      }

      result = builder.build(request);
    }
    // wrap exception message
    catch (SettingsBuildingException e) {
      StringBuilder sb =
          new StringBuilder("Found ")
              .append(e.getProblems().size())
              .append(
                  " problems while building settings.xml model from both global Maven configuration file")
              .append(request.getGlobalSettingsFile())
              .append(" and/or user configuration file: ")
              .append(request.getUserSettingsFile())
              .append("\n");

      int counter = 1;
      for (SettingsProblem problem : e.getProblems()) {
        sb.append(counter++).append("/ ").append(problem).append("\n");
      }

      throw new InvalidConfigurationFileException(sb.toString());
    }

    // get settings object and update it according to property values
    Settings settings = result.getEffectiveSettings();
    settings = enrichWithLocalRepository(settings);
    settings = enrichWithOfflineMode(settings);
    return settings;
  }

  // adds local repository
  private Settings enrichWithLocalRepository(Settings settings) {

    // set default value if not set at all
    if (settings.getLocalRepository() == null || settings.getLocalRepository().length() == 0) {
      settings.setLocalRepository(DEFAULT_REPOSITORY_PATH);
    }

    // override any value with system property based location
    String altLocalRepository = SecurityActions.getProperty(ALT_LOCAL_REPOSITORY_LOCATION);
    if (altLocalRepository != null && altLocalRepository.length() > 0) {
      settings.setLocalRepository(altLocalRepository);
    }
    return settings;
  }

  // adds offline mode from system property
  private Settings enrichWithOfflineMode(Settings settings) {

    String goOffline = SecurityActions.getProperty(ALT_MAVEN_OFFLINE);
    if (goOffline != null && goOffline.length() > 0) {
      settings.setOffline(Boolean.valueOf(goOffline));
    }

    return settings;
  }
}
예제 #5
0
 /**
  * Creates a builder which has access to Maven system and current settings
  *
  * @param system the Maven system
  * @param settings Maven and resolver settings
  */
 MavenManagerBuilder(RepositorySystem system, Settings settings) {
   this.system = system;
   this.settings = settings;
   this.useLegacyLocalRepository =
       Boolean.parseBoolean(SecurityActions.getProperty(USE_LEGACY_REPO_KEY));
 }
예제 #6
0
/**
 * General utility methods used throughout the Infinispan code base.
 *
 * @author <a href="*****@*****.**">Brian Stansberry</a>
 * @author Galder Zamarreño
 * @since 4.0
 */
public final class Util {

  private static final boolean IS_ARRAYS_DEBUG = Boolean.getBoolean("infinispan.arrays.debug");
  private static final boolean IS_OSGI_CONTEXT;

  public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
  public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

  private static final Log log = LogFactory.getLog(Util.class);

  /**
   * Current Java vendor. This variable is later used to differentiate LRU implementations for
   * different java vendors.
   */
  private static final String javaVendor = SecurityActions.getProperty("java.vendor", "");

  static {
    boolean osgi = false;
    try {
      osgi = Util.class.getClassLoader() instanceof org.osgi.framework.BundleReference;
    } catch (NoClassDefFoundError ex) {
      // Ignore
    }
    IS_OSGI_CONTEXT = osgi;
  }

  /**
   * Loads the specified class using the passed classloader, or, if it is <code>null</code> the
   * Infinispan classes' classloader.
   *
   * <p>If loadtime instrumentation via GenerateInstrumentedClassLoader is used, this class may be
   * loaded by the bootstrap classloader.
   *
   * <p>If the class is not found, the {@link ClassNotFoundException} or {@link
   * NoClassDefFoundError} is wrapped as a {@link CacheConfigurationException} and is re-thrown.
   *
   * @param classname name of the class to load
   * @param cl the application classloader which should be used to load the class, or null if the
   *     class is always packaged with Infinispan
   * @return the class
   * @throws CacheConfigurationException if the class cannot be loaded
   */
  public static <T> Class<T> loadClass(String classname, ClassLoader cl) {
    try {
      return loadClassStrict(classname, cl);
    } catch (ClassNotFoundException e) {
      throw new CacheConfigurationException("Unable to instantiate class " + classname, e);
    }
  }

  /**
   * Tries to determine if the code is running in an OSGi context.
   *
   * @return true if an OSGi context is detected
   */
  public static boolean isOSGiContext() {
    return IS_OSGI_CONTEXT;
  }

  public static ClassLoader[] getClassLoaders(ClassLoader appClassLoader) {
    if (isOSGiContext()) {
      return new ClassLoader[] {
        appClassLoader, // User defined classes
        OsgiClassLoader
            .getInstance(), // OSGi bundle context needs to be on top of TCCL, system CL, etc.
        Util.class.getClassLoader(), // Infinispan classes (not always on TCCL [modular env])
        ClassLoader.getSystemClassLoader(), // Used when load time instrumentation is in effect
        Thread.currentThread().getContextClassLoader() // Used by jboss-as stuff
      };
    } else {
      return new ClassLoader[] {
        appClassLoader, // User defined classes
        Util.class.getClassLoader(), // Infinispan classes (not always on TCCL [modular env])
        ClassLoader.getSystemClassLoader(), // Used when load time instrumentation is in effect
        Thread.currentThread().getContextClassLoader() // Used by jboss-as stuff
      };
    }
  }

  /**
   * Loads the specified class using the passed classloader, or, if it is <code>null</code> the
   * Infinispan classes' classloader.
   *
   * <p>If loadtime instrumentation via GenerateInstrumentedClassLoader is used, this class may be
   * loaded by the bootstrap classloader.
   *
   * @param classname name of the class to load
   * @return the class
   * @param userClassLoader the application classloader which should be used to load the class, or
   *     null if the class is always packaged with Infinispan
   * @throws ClassNotFoundException if the class cannot be loaded
   */
  @SuppressWarnings("unchecked")
  public static <T> Class<T> loadClassStrict(String classname, ClassLoader userClassLoader)
      throws ClassNotFoundException {
    ClassLoader[] cls = getClassLoaders(userClassLoader);
    ClassNotFoundException e = null;
    NoClassDefFoundError ne = null;
    for (ClassLoader cl : cls) {
      if (cl == null) continue;

      try {
        return (Class<T>) Class.forName(classname, true, cl);
      } catch (ClassNotFoundException ce) {
        e = ce;
      } catch (NoClassDefFoundError ce) {
        ne = ce;
      }
    }

    if (e != null) throw e;
    else if (ne != null) {
      // Before we wrap this, make sure we appropriately log this.
      log.unableToLoadClass(classname, Arrays.toString(cls), ne);
      throw new ClassNotFoundException(classname, ne);
    } else throw new IllegalStateException();
  }

  public static InputStream getResourceAsStream(String resourcePath, ClassLoader userClassLoader) {
    if (resourcePath.startsWith("/")) {
      resourcePath = resourcePath.substring(1);
    }
    InputStream is = null;
    for (ClassLoader cl : getClassLoaders(userClassLoader)) {
      if (cl != null) {
        is = cl.getResourceAsStream(resourcePath);
        if (is != null) {
          break;
        }
      }
    }
    return is;
  }

  private static Method getFactoryMethod(Class<?> c) {
    for (Method m : c.getMethods()) {
      if (m.getName().equals("getInstance")
          && m.getParameterTypes().length == 0
          && Modifier.isStatic(m.getModifiers())) return m;
    }
    return null;
  }

  /**
   * Instantiates a class by first attempting a static <i>factory method</i> named
   * <tt>getInstance()</tt> on the class and then falling back to an empty constructor.
   *
   * <p>Any exceptions encountered are wrapped in a {@link CacheConfigurationException} and
   * rethrown.
   *
   * @param clazz class to instantiate
   * @return an instance of the class
   */
  public static <T> T getInstance(Class<T> clazz) {
    try {
      return getInstanceStrict(clazz);
    } catch (IllegalAccessException iae) {
      throw new CacheConfigurationException("Unable to instantiate class " + clazz.getName(), iae);
    } catch (InstantiationException ie) {
      throw new CacheConfigurationException("Unable to instantiate class " + clazz.getName(), ie);
    }
  }

  /**
   * Similar to {@link #getInstance(Class)} except that exceptions are propagated to the caller.
   *
   * @param clazz class to instantiate
   * @return an instance of the class
   * @throws IllegalAccessException
   * @throws InstantiationException
   */
  @SuppressWarnings("unchecked")
  public static <T> T getInstanceStrict(Class<T> clazz)
      throws IllegalAccessException, InstantiationException {
    // first look for a getInstance() constructor
    T instance = null;
    try {
      Method factoryMethod = getFactoryMethod(clazz);
      if (factoryMethod != null) instance = (T) factoryMethod.invoke(null);
    } catch (Exception e) {
      // no factory method or factory method failed.  Try a constructor.
      instance = null;
    }
    if (instance == null) {
      instance = clazz.newInstance();
    }
    return instance;
  }

  /**
   * Instantiates a class based on the class name provided. Instantiation is attempted via an
   * appropriate, static factory method named <tt>getInstance()</tt> first, and failing the
   * existence of an appropriate factory, falls back to an empty constructor.
   *
   * <p>Any exceptions encountered loading and instantiating the class is wrapped in a {@link
   * CacheConfigurationException}.
   *
   * @param classname class to instantiate
   * @return an instance of classname
   */
  public static <T> T getInstance(String classname, ClassLoader cl) {
    if (classname == null) throw new IllegalArgumentException("Cannot load null class!");
    Class<T> clazz = loadClass(classname, cl);
    return getInstance(clazz);
  }

  /**
   * Similar to {@link #getInstance(String, ClassLoader)} except that exceptions are propagated to
   * the caller.
   *
   * @param classname class to instantiate
   * @return an instance of classname
   * @throws ClassNotFoundException
   * @throws InstantiationException
   * @throws IllegalAccessException
   */
  public static <T> T getInstanceStrict(String classname, ClassLoader cl)
      throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    if (classname == null) throw new IllegalArgumentException("Cannot load null class!");
    Class<T> clazz = loadClassStrict(classname, cl);
    return getInstanceStrict(clazz);
  }

  /**
   * Clones parameter x of type T with a given Marshaller reference;
   *
   * @return a deep clone of an object parameter x
   */
  @SuppressWarnings("unchecked")
  public static <T> T cloneWithMarshaller(Marshaller marshaller, T x) {
    if (marshaller == null)
      throw new IllegalArgumentException("Cannot use null Marshaller for clone");

    byte[] byteBuffer;
    try {
      byteBuffer = marshaller.objectToByteBuffer(x);
      return (T) marshaller.objectFromByteBuffer(byteBuffer);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new CacheException(e);
    } catch (Exception e) {
      throw new CacheException(e);
    }
  }

  /** Prevent instantiation */
  private Util() {}

  /**
   * Null-safe equality test.
   *
   * @param a first object to compare
   * @param b second object to compare
   * @return true if the objects are equals or both null, false otherwise.
   */
  public static boolean safeEquals(Object a, Object b) {
    return (a == b) || (a != null && a.equals(b));
  }

  public static String prettyPrintTime(long time, TimeUnit unit) {
    return prettyPrintTime(unit.toMillis(time));
  }

  /**
   * {@link System#nanoTime()} is less expensive than {@link System#currentTimeMillis()} and better
   * suited to measure time intervals. It's NOT suited to know the current time, for example to be
   * compared with the time of other nodes.
   *
   * @return the value of {@link System#nanoTime()}, but converted in Milliseconds.
   */
  public static final long currentMillisFromNanotime() {
    return TimeUnit.MILLISECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS);
  }

  /**
   * Prints a time for display
   *
   * @param millis time in millis
   * @return the time, represented as millis, seconds, minutes or hours as appropriate, with suffix
   */
  public static String prettyPrintTime(long millis) {
    if (millis < 1000) return millis + " milliseconds";
    NumberFormat nf = NumberFormat.getNumberInstance();
    nf.setMaximumFractionDigits(2);
    double toPrint = ((double) millis) / 1000;
    if (toPrint < 300) {
      return nf.format(toPrint) + " seconds";
    }

    toPrint = toPrint / 60;

    if (toPrint < 120) {
      return nf.format(toPrint) + " minutes";
    }

    toPrint = toPrint / 60;

    return nf.format(toPrint) + " hours";
  }

  /**
   * Reads the given InputStream fully, closes the stream and returns the result as a byte array.
   *
   * @param is the stream to read
   * @return the read bytes
   * @throws java.io.IOException in case of stream read errors
   */
  public static byte[] readStream(InputStream is) throws IOException {
    try {
      ByteArrayOutputStream os = new ByteArrayOutputStream();
      byte[] buf = new byte[1024];
      int len;
      while ((len = is.read(buf)) != -1) {
        os.write(buf, 0, len);
      }
      return os.toByteArray();
    } finally {
      is.close();
    }
  }

  /**
   * Reads the given InputStream fully, closes the stream and returns the result as a String.
   *
   * @param is the stream to read
   * @return the UTF-8 string
   * @throws java.io.IOException in case of stream read errors
   */
  public static String read(InputStream is) throws IOException {
    try {
      final Reader reader = new InputStreamReader(is, "UTF-8");
      StringWriter writer = new StringWriter();
      char[] buf = new char[1024];
      int len;
      while ((len = reader.read(buf)) != -1) {
        writer.write(buf, 0, len);
      }
      return writer.toString();
    } finally {
      is.close();
    }
  }

  public static void close(Closeable cl) {
    if (cl == null) return;
    try {
      cl.close();
    } catch (Exception e) {
    }
  }

  public static void close(Socket s) {
    if (s == null) return;
    try {
      s.close();
    } catch (Exception e) {
    }
  }

  public static void close(Closeable... cls) {
    for (Closeable cl : cls) {
      close(cl);
    }
  }

  public static void close(Context ctx) {
    if (ctx == null) return;
    try {
      ctx.close();
    } catch (Exception e) {
    }
  }

  public static void flushAndCloseStream(OutputStream o) {
    if (o == null) return;
    try {
      o.flush();
    } catch (Exception e) {

    }

    try {
      o.close();
    } catch (Exception e) {

    }
  }

  public static void flushAndCloseOutput(ObjectOutput o) {
    if (o == null) return;
    try {
      o.flush();
    } catch (Exception e) {

    }

    try {
      o.close();
    } catch (Exception e) {

    }
  }

  public static String formatString(Object message, Object... params) {
    if (params.length == 0) return message == null ? "null" : message.toString();

    return String.format(message.toString(), params);
  }

  public static String toStr(Object o) {
    if (o instanceof byte[]) {
      return printArray((byte[]) o, false);
    } else if (o == null) {
      return "null";
    } else {
      return o.toString();
    }
  }

  public static <E> String toStr(Collection<E> collection) {
    if (collection == null) return "[]";

    Iterator<E> i = collection.iterator();
    if (!i.hasNext()) return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (; ; ) {
      E e = i.next();
      sb.append(e == collection ? "(this Collection)" : toStr(e));
      if (!i.hasNext()) return sb.append(']').toString();
      sb.append(", ");
    }
  }

  public static String printArray(byte[] array) {
    return printArray(array, false);
  }

  public static String printArray(byte[] array, boolean withHash) {
    if (array == null) return "null";

    int limit = 8;
    StringBuilder sb = new StringBuilder();
    sb.append("[B0x");
    if (array.length <= limit || IS_ARRAYS_DEBUG) {
      // Convert the entire byte array
      sb.append(toHexString(array));
      if (withHash) {
        sb.append(",h=");
        sb.append(Integer.toHexString(Arrays.hashCode(array)));
        sb.append(']');
      }
    } else {
      // Pick the first 8 characters and convert that part
      sb.append(toHexString(array, limit));
      sb.append("..[");
      sb.append(array.length);
      if (withHash) {
        sb.append("],h=");
        sb.append(Integer.toHexString(Arrays.hashCode(array)));
      }
      sb.append(']');
    }
    return sb.toString();
  }

  public static String toHexString(byte input[]) {
    return toHexString(input, input.length);
  }

  public static String toHexString(byte input[], int limit) {
    int i = 0;
    if (input == null || input.length <= 0) return null;

    char lookup[] = {
      '0', '1', '2', '3', '4', '5', '6', '7',
      '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };

    char[] result = new char[(input.length < limit ? input.length : limit) * 2];

    while (i < limit && i < input.length) {
      result[2 * i] = lookup[(input[i] >> 4) & 0x0F];
      result[2 * i + 1] = lookup[(input[i] & 0x0F)];
      i++;
    }
    return String.valueOf(result);
  }

  public static String padString(String s, int minWidth) {
    if (s.length() < minWidth) {
      StringBuilder sb = new StringBuilder(s);
      while (sb.length() < minWidth) sb.append(" ");
      return sb.toString();
    }
    return s;
  }

  private static String INDENT = "    ";

  public static String threadDump() {
    StringBuilder threadDump = new StringBuilder();
    ThreadMXBean threadMx = ManagementFactory.getThreadMXBean();
    if (threadMx.isObjectMonitorUsageSupported() && threadMx.isSynchronizerUsageSupported()) {
      // Print lock info if, and only if, both object monitor usage and synchronizer usage are
      // supported.
      dumpThreadInfo(threadDump, true, threadMx);
    } else {
      dumpThreadInfo(threadDump, false, threadMx);
    }
    return threadDump.toString();
  }

  private static void dumpThreadInfo(
      StringBuilder threadDump, boolean withLocks, ThreadMXBean threadMx) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String timestamp = dateFormat.format(new Date());
    threadDump.append(timestamp);
    threadDump.append("\nFull thread dump ");
    threadDump.append("\n");

    if (withLocks) {
      ThreadInfo[] threadInfos = threadMx.dumpAllThreads(true, true);
      for (ThreadInfo threadInfo : threadInfos) {
        printThreadInfo(threadInfo, threadDump);
        LockInfo[] syncs = threadInfo.getLockedSynchronizers();
        printLockInfo(syncs, threadDump);
      }
      threadDump.append("\n");
    } else {
      long[] threadIds = threadMx.getAllThreadIds();
      ThreadInfo[] threadInfos = threadMx.getThreadInfo(threadIds, Integer.MAX_VALUE);
      for (ThreadInfo threadInfo : threadInfos) printThreadInfo(threadInfo, threadDump);
    }
  }

  private static void printThreadInfo(ThreadInfo threadInfo, StringBuilder threadDump) {
    // Print thread information
    printThread(threadInfo, threadDump);
    // print stack trace with locks
    StackTraceElement[] stacktrace = threadInfo.getStackTrace();
    MonitorInfo[] monitors = threadInfo.getLockedMonitors();
    for (int i = 0; i < stacktrace.length; i++) {
      StackTraceElement ste = stacktrace[i];
      threadDump.append(INDENT + "at " + ste.toString());
      threadDump.append("\n");
      for (int j = 1; j < monitors.length; j++) {
        MonitorInfo mi = monitors[j];
        if (mi.getLockedStackDepth() == i) {
          threadDump.append(INDENT + "  - locked " + mi);
          threadDump.append("\n");
        }
      }
    }
    threadDump.append("\n");
  }

  private static void printLockInfo(LockInfo[] locks, StringBuilder threadDump) {
    threadDump.append(INDENT + "Locked synchronizers: count = " + locks.length);
    threadDump.append("\n");
    for (LockInfo li : locks) {
      threadDump.append(INDENT + "  - " + li);
      threadDump.append("\n");
    }
    threadDump.append("\n");
  }

  private static void printThread(ThreadInfo threadInfo, StringBuilder threadDump) {
    StringBuilder sb =
        new StringBuilder(
            "\""
                + threadInfo.getThreadName()
                + "\""
                + " nid="
                + threadInfo.getThreadId()
                + " state="
                + threadInfo.getThreadState());
    if (threadInfo.getLockName() != null && threadInfo.getThreadState() != Thread.State.BLOCKED) {
      String[] lockInfo = threadInfo.getLockName().split("@");
      sb.append("\n" + INDENT + "- waiting on <0x" + lockInfo[1] + "> (a " + lockInfo[0] + ")");
      sb.append("\n" + INDENT + "- locked <0x" + lockInfo[1] + "> (a " + lockInfo[0] + ")");
    } else if (threadInfo.getLockName() != null
        && threadInfo.getThreadState() == Thread.State.BLOCKED) {
      String[] lockInfo = threadInfo.getLockName().split("@");
      sb.append(
          "\n" + INDENT + "- waiting to lock <0x" + lockInfo[1] + "> (a " + lockInfo[0] + ")");
    }
    if (threadInfo.isSuspended()) sb.append(" (suspended)");

    if (threadInfo.isInNative()) sb.append(" (running in native)");

    threadDump.append(sb.toString());
    threadDump.append("\n");
    if (threadInfo.getLockOwnerName() != null) {
      threadDump.append(
          INDENT
              + " owned by "
              + threadInfo.getLockOwnerName()
              + " id="
              + threadInfo.getLockOwnerId());
      threadDump.append("\n");
    }
  }

  public static CacheException rewrapAsCacheException(Throwable t) {
    if (t instanceof CacheException) return (CacheException) t;
    else return new CacheException(t);
  }

  public static <T> Set<T> asSet(T... a) {
    if (a.length > 1) return new HashSet<T>(Arrays.<T>asList(a));
    else return Collections.singleton(a[0]);
  }

  /**
   * Prints the identity hash code of the object passed as parameter in an hexadecimal format in
   * order to safe space.
   */
  public static String hexIdHashCode(Object o) {
    return Integer.toHexString(System.identityHashCode(o));
  }

  static final String HEX_VALUES = "0123456789ABCDEF";

  public static String hexDump(byte[] buffer) {
    StringBuilder buf = new StringBuilder(buffer.length << 1);
    for (byte b : buffer) addHexByte(buf, b);

    return buf.toString();
  }

  public static String hexDump(ByteBuffer buffer) {
    byte[] data = new byte[buffer.remaining()];
    int pos = buffer.position();
    buffer.get(data);
    buffer.position(pos);
    StringBuilder buf = new StringBuilder(buffer.remaining() + 22);
    for (byte b : data) addHexByte(buf, b);

    return buf.toString();
  }

  private static void addHexByte(StringBuilder buf, byte b) {
    buf.append(HEX_VALUES.charAt((b & 0xF0) >> 4)).append(HEX_VALUES.charAt((b & 0x0F)));
  }

  public static Double constructDouble(Class<?> type, Object o) {
    if (type.equals(Long.class) || type.equals(long.class)) return Double.valueOf((Long) o);
    else if (type.equals(Double.class) || type.equals(double.class)) return (Double) o;
    else if (type.equals(Integer.class) || type.equals(int.class))
      return Double.valueOf((Integer) o);
    else if (type.equals(String.class)) return Double.valueOf((String) o);

    throw new IllegalStateException(
        String.format(
            "Expected a value that can be converted into a double: type=%s, value=%s", type, o));
  }

  /**
   * Applies the given hash function to the hash code of a given object, and then normalizes it to
   * ensure a positive value is always returned.
   *
   * @param object to hash
   * @param hashFct hash function to apply
   * @return a non-null, non-negative normalized hash code for a given object
   */
  public static int getNormalizedHash(Object object, Hash hashFct) {
    // make sure no negative numbers are involved.
    return hashFct.hash(object) & Integer.MAX_VALUE;
  }

  /**
   * Returns the size of each segment, given a number of segments.
   *
   * @param numSegments number of segments required
   * @return the size of each segment
   */
  public static int getSegmentSize(int numSegments) {
    return (int) Math.ceil((double) (1L << 31) / numSegments);
  }

  public static boolean isIBMJavaVendor() {
    return javaVendor.toLowerCase().contains("ibm");
  }

  public static String join(List<String> strings, String separator) {
    StringBuilder sb = new StringBuilder();
    boolean first = true;

    for (String string : strings) {
      if (!first) {
        sb.append(separator);
      } else {
        first = false;
      }
      sb.append(string);
    }

    return sb.toString();
  }

  /**
   * Returns a number such that the number is a power of two that is equal to, or greater than, the
   * number passed in as an argument. The smallest number returned will be 1, not 0.
   */
  public static int findNextHighestPowerOfTwo(int num) {
    if (num <= 0) return 1;
    int highestBit = Integer.highestOneBit(num);
    return num <= highestBit ? highestBit : highestBit << 1;
  }

  /**
   * A function that calculates hash code of a byte array based on its contents but using the given
   * size parameter as deliminator for the content.
   */
  public static int hashCode(byte[] bytes, int size) {
    int contentLimit = size;
    if (size > bytes.length) contentLimit = bytes.length;

    int hashCode = 1;
    for (int i = 0; i < contentLimit; i++) hashCode = 31 * hashCode + bytes[i];

    return hashCode;
  }

  /**
   * Prints {@link Subject}'s principals as a one-liner (as opposed to default Subject's <code>
   * toString()</code> method, which prints every principal on separate line).
   */
  public static String prettyPrintSubject(Subject subject) {
    return (subject == null)
        ? "null"
        : "Subject with principal(s): " + toStr(subject.getPrincipals());
  }
}