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