001/* 002 * Copyright (c) 2016-2017 Chris K Wensel <chris@wensel.net>. All Rights Reserved. 003 * Copyright (c) 2007-2017 Xplenty, Inc. All Rights Reserved. 004 * 005 * Project and contact information: http://www.cascading.org/ 006 * 007 * This file is part of the Cascading project. 008 * 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 */ 021 022package cascading.provider; 023 024import java.net.URL; 025 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028 029/** 030 * Class ProviderLoader is the base class for loading various "provider" types. 031 * <p> 032 * This loader can optinally load a provider implementation within its own ClassLoader using the 033 * {@link ChildFirstURLClassLoader}. 034 * 035 * @see FactoryLoader 036 * @see ServiceLoader 037 */ 038public class ProviderLoader<Provider> 039 { 040 private static final Logger LOG = LoggerFactory.getLogger( ServiceLoader.class ); 041 URL libraryURL; 042 String[] exclusions; 043 044 ClassLoader classLoader; 045 046 public ProviderLoader() 047 { 048 } 049 050 public ProviderLoader( String[] exclusions, URL libraryURL ) 051 { 052 this.exclusions = exclusions; 053 this.libraryURL = libraryURL; 054 } 055 056 public Provider createProvider( String className ) 057 { 058 // test for ant style token escapes 059 if( className == null || className.isEmpty() ) 060 return null; 061 062 if( className.startsWith( "@" ) && className.endsWith( "@" ) ) 063 { 064 LOG.warn( "invalid classname: {}", className ); 065 return null; 066 } 067 068 try 069 { 070 Class<Provider> type = (Class<Provider>) getClassLoader().loadClass( className ); 071 072 return type.newInstance(); 073 } 074 catch( ClassNotFoundException exception ) 075 { 076 LOG.error( "unable to find service class: {}, with exception: {}", className, exception ); 077 } 078 catch( IllegalAccessException exception ) 079 { 080 LOG.error( "unable to instantiate service class: {}, with exception: {}", className, exception ); 081 } 082 catch( InstantiationException exception ) 083 { 084 LOG.error( "unable to instantiate service class: {}, with exception: {}", className, exception ); 085 } 086 087 return null; 088 } 089 090 private synchronized ClassLoader getClassLoader() 091 { 092 if( classLoader != null ) 093 return classLoader; 094 095 if( libraryURL == null ) 096 { 097 classLoader = Thread.currentThread().getContextClassLoader(); 098 } 099 else 100 { 101 LOG.info( "loading services from library: {}", libraryURL ); 102 103 classLoader = new ChildFirstURLClassLoader( exclusions, libraryURL ); 104 } 105 106 return classLoader; 107 } 108 }