All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xeustechnologies.jcl.AbstractClassLoader Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2015 Kamran Zafar
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xeustechnologies.jcl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xeustechnologies.jcl.exception.JclException; import org.xeustechnologies.jcl.exception.ResourceNotFoundException; import org.xeustechnologies.jcl.utils.Utils; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Abstract class loader that can load classes from different resources * * @author Kamran Zafar */ @SuppressWarnings("unchecked") public abstract class AbstractClassLoader extends ClassLoader { // we could use concurrent sorted set like ConcurrentSkipListSet here instead, which would be automatically sorted // and wouldn't require the lock. // But that was added in 1.6, and according to Maven we're targeting 1.5+. /** * Note that all iterations over this list *must* synchronize on it first! */ protected final List loaders = Collections.synchronizedList(new ArrayList()); private final ProxyClassLoader systemLoader = new SystemLoader(); private final ProxyClassLoader parentLoader = new ParentLoader(); private final ProxyClassLoader currentLoader = new CurrentLoader(); private final ProxyClassLoader threadLoader = new ThreadContextLoader(); private final ProxyClassLoader osgiBootLoader = new OsgiBootLoader(); /** * Build a new instance of AbstractClassLoader.java. * * @param parent parent class loader */ public AbstractClassLoader(ClassLoader parent) { super(parent); addDefaultLoader(); } /** * No arguments constructor */ public AbstractClassLoader() { super(); addDefaultLoader(); } protected void addDefaultLoader() { synchronized (loaders) { loaders.add(systemLoader); loaders.add(parentLoader); loaders.add(currentLoader); loaders.add(threadLoader); Collections.sort(loaders); } } public void addLoader(ProxyClassLoader loader) { synchronized (loaders) { loaders.add(loader); Collections.sort(loaders); } } /* * (non-Javadoc) * * @see java.lang.ClassLoader#loadClass(java.lang.String) */ @Override public Class loadClass(String className) throws ClassNotFoundException { return (loadClass(className, true)); } /** * Overrides the loadClass method to load classes from other resources, * JarClassLoader is the only subclass in this project that loads classes * from jar files * * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) */ @Override public Class loadClass(String className, boolean resolveIt) throws ClassNotFoundException { if (className == null || className.trim().equals("")) return null; Class clazz = null; // Check osgi boot delegation if (osgiBootLoader.isEnabled()) { clazz = osgiBootLoader.loadClass(className, resolveIt); } if (clazz == null) { synchronized (loaders) { for (ProxyClassLoader l : loaders) { if (l.isEnabled()) { clazz = l.loadClass(className, resolveIt); if (clazz != null) break; } } } } if (clazz == null) throw new ClassNotFoundException(className); return clazz; } /** * Overrides the getResource method to load non-class resources from other * sources, JarClassLoader is the only subclass in this project that loads * non-class resources from jar files * * @see java.lang.ClassLoader#getResource(java.lang.String) */ @Override public URL getResource(String name) { if (name == null || name.trim().equals("")) return null; URL url = null; // Check osgi boot delegation if (osgiBootLoader.isEnabled()) { url = osgiBootLoader.findResource(name); } if (url == null) { synchronized (loaders) { for (ProxyClassLoader l : loaders) { if (l.isEnabled()) { url = l.findResource(name); if (url != null) break; } } } } return url; } @Override public Enumeration getResources(String name) throws IOException { if (name == null || name.trim().equals("")) { return Collections.emptyEnumeration(); } Vector urlVector = new Vector(); URL url = null; // Check osgi boot delegation if (osgiBootLoader.isEnabled()) { url = osgiBootLoader.findResource(name); if (url != null) { urlVector.add(url); } } if (url == null) { synchronized (loaders) { for (ProxyClassLoader l : loaders) { if (l.isEnabled()) { url = l.findResource(name); if (url != null) { urlVector.add(url); } } } } } return urlVector.elements(); } /** * Overrides the getResourceAsStream method to load non-class resources from * other sources, JarClassLoader is the only subclass in this project that * loads non-class resources from jar files * * @see java.lang.ClassLoader#getResourceAsStream(java.lang.String) */ @Override public InputStream getResourceAsStream(String name) { if (name == null || name.trim().equals("")) return null; InputStream is = null; // Check osgi boot delegation if (osgiBootLoader.isEnabled()) { is = osgiBootLoader.loadResource(name); } if (is == null) { synchronized (loaders) { for (ProxyClassLoader l : loaders) { if (l.isEnabled()) { is = l.loadResource(name); if (is != null) break; } } } } return is; } /** * System class loader */ class SystemLoader extends ProxyClassLoader { private final Logger logger = LoggerFactory.getLogger(SystemLoader.class); public SystemLoader() { order = 50; enabled = Configuration.isSystemLoaderEnabled(); } @Override public Class loadClass(String className, boolean resolveIt) { Class result; try { result = findSystemClass(className); } catch (ClassNotFoundException e) { return null; } logger.debug("Returning system class " + className); return result; } @Override public InputStream loadResource(String name) { InputStream is = getSystemResourceAsStream(name); if (is != null) { logger.debug("Returning system resource " + name); return is; } return null; } @Override public URL findResource(String name) { URL url = getSystemResource(name); if (url != null) { logger.debug("Returning system resource " + name); return url; } return null; } } /** * Parent class loader */ class ParentLoader extends ProxyClassLoader { private final Logger logger = LoggerFactory.getLogger(ParentLoader.class); public ParentLoader() { order = 30; enabled = Configuration.isParentLoaderEnabled(); } @Override public Class loadClass(String className, boolean resolveIt) { Class result; try { result = getParent().loadClass(className); } catch (ClassNotFoundException e) { return null; } logger.debug("Returning class " + className + " loaded with parent classloader"); return result; } @Override public InputStream loadResource(String name) { InputStream is = getParent().getResourceAsStream(name); if (is != null) { logger.debug("Returning resource " + name + " loaded with parent classloader"); return is; } return null; } @Override public URL findResource(String name) { URL url = getParent().getResource(name); if (url != null) { logger.debug("Returning resource " + name + " loaded with parent classloader"); return url; } return null; } } /** * Current class loader */ class CurrentLoader extends ProxyClassLoader { private final Logger logger = LoggerFactory.getLogger(CurrentLoader.class); public CurrentLoader() { order = 20; enabled = Configuration.isCurrentLoaderEnabled(); } @Override public Class loadClass(String className, boolean resolveIt) { Class result; try { result = getClass().getClassLoader().loadClass(className); } catch (ClassNotFoundException e) { return null; } logger.debug("Returning class " + className + " loaded with current classloader"); return result; } @Override public InputStream loadResource(String name) { InputStream is = getClass().getClassLoader().getResourceAsStream(name); if (is != null) { logger.debug("Returning resource " + name + " loaded with current classloader"); return is; } return null; } @Override public URL findResource(String name) { URL url = getClass().getClassLoader().getResource(name); if (url != null) { logger.debug("Returning resource " + name + " loaded with current classloader"); return url; } return null; } } /** * Current class loader */ class ThreadContextLoader extends ProxyClassLoader { private final Logger logger = LoggerFactory.getLogger(ThreadContextLoader.class); public ThreadContextLoader() { order = 40; enabled = Configuration.isThreadContextLoaderEnabled(); } @Override public Class loadClass(String className, boolean resolveIt) { Class result; try { result = Thread.currentThread().getContextClassLoader().loadClass(className); } catch (ClassNotFoundException e) { return null; } logger.debug("Returning class " + className + " loaded with thread context classloader"); return result; } @Override public InputStream loadResource(String name) { InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name); if (is != null) { logger.debug("Returning resource " + name + " loaded with thread context classloader"); return is; } return null; } @Override public URL findResource(String name) { URL url = Thread.currentThread().getContextClassLoader().getResource(name); if (url != null) { logger.debug("Returning resource " + name + " loaded with thread context classloader"); return url; } return null; } } /** * Osgi boot loader */ public final class OsgiBootLoader extends ProxyClassLoader { private final Logger logger = LoggerFactory.getLogger(OsgiBootLoader.class); private boolean strictLoading; private String[] bootDelagation; private static final String JAVA_PACKAGE = "java."; public OsgiBootLoader() { enabled = Configuration.isOsgiBootDelegationEnabled(); strictLoading = Configuration.isOsgiBootDelegationStrict(); bootDelagation = Configuration.getOsgiBootDelegation(); order = 0; } @Override public Class loadClass(String className, boolean resolveIt) { Class clazz = null; if (enabled && isPartOfOsgiBootDelegation(className)) { clazz = getParentLoader().loadClass(className, resolveIt); if (clazz == null && strictLoading) { throw new JclException(new ClassNotFoundException("JCL OSGi Boot Delegation: Class " + className + " not found.")); } logger.debug("Class " + className + " loaded via OSGi boot delegation."); } return clazz; } @Override public InputStream loadResource(String name) { InputStream is = null; if (enabled && isPartOfOsgiBootDelegation(name)) { is = getParentLoader().loadResource(name); if (is == null && strictLoading) { throw new ResourceNotFoundException("JCL OSGi Boot Delegation: Resource " + name + " not found."); } logger.debug("Resource " + name + " loaded via OSGi boot delegation."); } return is; } @Override public URL findResource(String name) { URL url = null; if (enabled && isPartOfOsgiBootDelegation(name)) { url = getParentLoader().findResource(name); if (url == null && strictLoading) { throw new ResourceNotFoundException("JCL OSGi Boot Delegation: Resource " + name + " not found."); } logger.debug("Resource " + name + " loaded via OSGi boot delegation."); } return url; } /** * Check if the class/resource is part of OSGi boot delegation * * @param resourceName * @return */ private boolean isPartOfOsgiBootDelegation(String resourceName) { if (resourceName.startsWith(JAVA_PACKAGE)) return true; String[] bootPkgs = bootDelagation; if (bootPkgs != null) { for (String bc : bootPkgs) { Pattern pat = Pattern.compile(Utils.wildcardToRegex(bc), Pattern.CASE_INSENSITIVE); Matcher matcher = pat.matcher(resourceName); if (matcher.find()) { return true; } } } return false; } public boolean isStrictLoading() { return strictLoading; } public void setStrictLoading(boolean strictLoading) { this.strictLoading = strictLoading; } public String[] getBootDelagation() { return bootDelagation; } public void setBootDelagation(String[] bootDelagation) { this.bootDelagation = bootDelagation; } } public ProxyClassLoader getSystemLoader() { return systemLoader; } public ProxyClassLoader getParentLoader() { return parentLoader; } public ProxyClassLoader getCurrentLoader() { return currentLoader; } public ProxyClassLoader getThreadLoader() { return threadLoader; } public ProxyClassLoader getOsgiBootLoader() { return osgiBootLoader; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy