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
018/**
019 * Detects whether certain features are available or not.
020 */
021public class EnvironmentDetection {
022
023  /**
024   * The ClassLoader to use.
025   */
026  private final ClassLoader classLoader;
027
028  /**
029   * Creates a new FeatureDetector.
030   *
031   * @param classLoader The ClassLoader to use.
032   */
033  public EnvironmentDetection(ClassLoader classLoader) {
034    this.classLoader = classLoader;
035  }
036
037  /**
038   * Flag indicating availability of JBoss VFS v2.
039   */
040  private Boolean jbossVFSv2;
041
042  /**
043   * Flag indicating availability of JBoss VFS v3.
044   */
045  private Boolean jbossVFSv3;
046
047  /**
048   * Flag indicating availability of the OSGi framework classes.
049   */
050  private Boolean osgi;
051
052  /**
053   * Checks whether JBoss VFS v2 is available.
054   *
055   * @return {@code true} if it is, {@code false if it is not}
056   */
057  public boolean isJBossVFSv2() {
058    if (jbossVFSv2 == null) {
059      jbossVFSv2 = isPresent("org.jboss.virtual.VFS", classLoader);
060      ScanLog.log.trace("JBossVFSv2 {}", jbossVFSv2);
061    }
062
063    return jbossVFSv2;
064  }
065
066  /**
067   * Checks whether JBoss VFS is available.
068   *
069   * @return {@code true} if it is, {@code false if it is not}
070   */
071  public boolean isJBossVFSv3() {
072    if (jbossVFSv3 == null) {
073      jbossVFSv3 = isPresent("org.jboss.vfs.VFS", classLoader);
074      ScanLog.log.trace("JBossVFSv3 {}", jbossVFSv3);
075    }
076
077    return jbossVFSv3;
078  }
079
080  /**
081   * Checks if OSGi framework is available.
082   *
083   * @return {@code true} if it is, {@code false if it is not}
084   */
085  public boolean isOsgi() {
086    if (osgi == null) {
087      osgi = isPresent("org.osgi.framework.Bundle", classLoader);
088      ScanLog.log.trace("OSGi {}", osgi);
089    }
090
091    return osgi;
092  }
093
094  /**
095   * Return true if the runtime is Andriod.
096   */
097  public static boolean isAndroid() {
098    return "Android Runtime".equals(System.getProperty("java.runtime.name"));
099  }
100
101  /**
102   * Determine whether the {@link Class} identified by the supplied name is present
103   * and can be loaded. Will return {@code false} if either the class or
104   * one of its dependencies is not present or cannot be loaded.
105   *
106   * @param className   the name of the class to check
107   * @param classLoader The ClassLoader to use.
108   * @return whether the specified class is present
109   */
110  private static boolean isPresent(String className, ClassLoader classLoader) {
111    try {
112      classLoader.loadClass(className);
113      return true;
114    } catch (Throwable ex) {
115      // Class or one of its dependencies is not present...
116      return false;
117    }
118  }
119}