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 io.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 final 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  private 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}