001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.runtime;
011
012import java.util.function.Function;
013
014/**
015 * A {@code Loader} just encapsulate a {@code ClassLoader}. The class implements
016 * {@code java.util.function.Function<String, Class<?>>} so that a loader can be directly mapped to a stream of the
017 * names of the classes to load. Moreover, the {@code ClassNotFoundException} is catched to return
018 * {@code null}, allowing a more "flowing" use. For instance:
019 * <pre class="listing"><code class="lang-java" data-lang="java">
020 * Loader loader = new Loader(this.getClass().getClassLoader());
021 * Stream.of("java.lang.String", "gololang.Tuple", "foo.bar.Baz", "java.util.LinkedList")
022 *     .map(loader)
023 *     .filter(java.util.Objects::nonNull)
024 *     .map(klass -> dealWithTheClass(klass))
025 * </code></pre>
026 */
027public final class Loader implements Function<String, Class<?>> {
028  private final ClassLoader loader;
029
030  Loader(ClassLoader loader) {
031    this.loader = loader;
032  }
033
034  /**
035   * Create a loader using the {@code ClassLoader} of the given class
036   *
037   * @param klass the class whose {@code ClassLoader} to use
038   * @return a {@code Loader}
039   * */
040  public static Loader forClass(Class<?> klass) {
041    return new Loader(klass.getClassLoader());
042  }
043
044  /**
045   * Load the given class.
046   * <p>
047   * This only delegates to the underlying class loader, but returns {@code null} instead
048   * of throwing a {@code ClassNotFoundException} exception.
049   *
050   * @return the class if load succeed, {@code null} otherwise.
051   */
052  public Class<?> load(String name) {
053    try {
054      return loader.loadClass(name);
055    } catch (ClassNotFoundException e) {
056      return null;
057    }
058  }
059
060  /**
061   * Just delegate to {@link #load(java.lang.String)} to implement {@code Function}.
062   *
063   * @see #load(java.lang.String)
064   */
065  @Override
066  public Class<?> apply(String name) {
067    return load(name);
068  }
069}
070
071