htsjdk.samtools.CustomReaderFactory Maven / Gradle / Ivy
/*
* The MIT License
*
* Copyright (c) 2013 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package htsjdk.samtools;
import htsjdk.samtools.util.Log;
import java.net.URL;
import java.net.URLClassLoader;
/**
* Factory for creating custom readers for accessing API based resources,
* e.g. ga4gh.
* The configuration is controlled via custom_reader property (@see Defaults).
* This allows injection of such readers from code bases outside HTSJDK.
*/
public class CustomReaderFactory {
private final static Log LOG = Log.getInstance(CustomReaderFactory.class);
/**
* Interface to be implemented by custom factory classes that register
* themselves with this factory and are loaded dynamically.
*/
public interface ICustomReaderFactory {
SamReader open(URL url);
}
private static final CustomReaderFactory DEFAULT_FACTORY;
private static CustomReaderFactory currentFactory;
private String urlPrefix = "";
private String factoryClassName = "";
private String jarFile = "";
private ICustomReaderFactory factory;
static {
DEFAULT_FACTORY = new CustomReaderFactory();
currentFactory = DEFAULT_FACTORY;
}
public static void setInstance(final CustomReaderFactory factory){
currentFactory = factory;
}
public static void resetToDefaultInstance() {
setInstance(DEFAULT_FACTORY);
}
public static CustomReaderFactory getInstance(){
return currentFactory;
}
/**
* Initializes factory based on the custom_reader property specification.
*/
private CustomReaderFactory() {
this(Defaults.CUSTOM_READER_FACTORY);
}
CustomReaderFactory(String cfg) {
final String[] cfgComponents = cfg.split(",");
if (cfgComponents.length < 2) {
return;
}
urlPrefix = cfgComponents[0].toLowerCase();
factoryClassName = cfgComponents[1];
if (cfgComponents.length > 2) {
jarFile = cfgComponents[2];
}
}
/**
* Lazily creates factory based on the configuration.
* @return null if creation fails, factory instance otherwise.
*/
private synchronized ICustomReaderFactory getFactory() {
if (factory == null) {
try {
Class clazz = null;
if (!jarFile.isEmpty()) {
LOG.info("Attempting to load factory class " + factoryClassName +
" from " + jarFile);
final URL jarURL = new URL("file:///"+jarFile);
clazz = Class.forName(factoryClassName, true,
new URLClassLoader (new URL[] { jarURL },
this.getClass().getClassLoader()));
} else {
LOG.info("Attempting to load factory class " + factoryClassName);
clazz = Class.forName(factoryClassName);
}
factory = (ICustomReaderFactory)clazz.newInstance();
LOG.info("Created custom factory for " + urlPrefix + " from " +
factoryClassName + " loaded from " + (jarFile.isEmpty() ?
" this jar" : jarFile));
} catch (Exception e) {
LOG.error(e);
return null;
}
}
return factory;
}
/**
* Check if the url is supposed to be handled by the custom factory and if so
* attempt to create reader via an instance of this custom factory.
*
* @return null if the url is not handled by this factory, SamReader otherwise.
*/
public SamReader maybeOpen(URL url) {
if (urlPrefix.isEmpty() ||
!url.toString().toLowerCase().startsWith(urlPrefix)) {
return null;
}
LOG.info("Attempting to open " + url + " with custom factory");
final ICustomReaderFactory factory = getFactory();
if (factory == null) {
return null;
}
return factory.open(url);
}
}