001/**
002 * Copyright 2010-2016 Boxfuse GmbH
003 * <p/>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p/>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p/>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.avaje.classpath.scanner.internal;
017
018import org.slf4j.Logger;
019import org.slf4j.LoggerFactory;
020
021/**
022 * Detects whether certain features are available or not.
023 */
024public class EnvironmentDetection {
025
026  private static final Logger LOG = LoggerFactory.getLogger(EnvironmentDetection.class);
027
028  /**
029   * The ClassLoader to use.
030   */
031  private ClassLoader classLoader;
032
033  /**
034   * Creates a new FeatureDetector.
035   *
036   * @param classLoader The ClassLoader to use.
037   */
038  public EnvironmentDetection(ClassLoader classLoader) {
039    this.classLoader = classLoader;
040  }
041
042  /**
043   * Flag indicating availability of JBoss VFS v2.
044   */
045  private Boolean jbossVFSv2;
046
047  /**
048   * Flag indicating availability of JBoss VFS v3.
049   */
050  private Boolean jbossVFSv3;
051
052  /**
053   * Flag indicating availability of the OSGi framework classes.
054   */
055  private Boolean osgi;
056
057  /**
058   * Checks whether JBoss VFS v2 is available.
059   *
060   * @return {@code true} if it is, {@code false if it is not}
061   */
062  public boolean isJBossVFSv2() {
063    if (jbossVFSv2 == null) {
064      jbossVFSv2 = isPresent("org.jboss.virtual.VFS", classLoader);
065      LOG.trace("... JBoss VFS v2 available: {}", jbossVFSv2);
066    }
067
068    return jbossVFSv2;
069  }
070
071  /**
072   * Checks whether JBoss VFS is available.
073   *
074   * @return {@code true} if it is, {@code false if it is not}
075   */
076  public boolean isJBossVFSv3() {
077    if (jbossVFSv3 == null) {
078      jbossVFSv3 = isPresent("org.jboss.vfs.VFS", classLoader);
079      LOG.trace("... JBoss VFS v3 available: {}", jbossVFSv3);
080    }
081
082    return jbossVFSv3;
083  }
084
085  /**
086   * Checks if OSGi framework is available.
087   *
088   * @return {@code true} if it is, {@code false if it is not}
089   */
090  public boolean isOsgi() {
091    if (osgi == null) {
092      osgi = isPresent("org.osgi.framework.Bundle", classLoader);
093      LOG.trace("... OSGi framework available: {}", osgi);
094    }
095
096    return osgi;
097  }
098
099  /**
100   * Return true if the runtime is Andriod.
101   */
102  public static boolean isAndroid() {
103    return "Android Runtime".equals(System.getProperty("java.runtime.name"));
104  }
105
106  /**
107   * Determine whether the {@link Class} identified by the supplied name is present
108   * and can be loaded. Will return {@code false} if either the class or
109   * one of its dependencies is not present or cannot be loaded.
110   *
111   * @param className   the name of the class to check
112   * @param classLoader The ClassLoader to use.
113   * @return whether the specified class is present
114   */
115  protected static boolean isPresent(String className, ClassLoader classLoader) {
116    try {
117      classLoader.loadClass(className);
118      return true;
119    } catch (Throwable ex) {
120      // Class or one of its dependencies is not present...
121      return false;
122    }
123  }
124}