/* * ==================================================================== * Copyright (c) 2004-2012 TMate Software Ltd. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://svnkit.com/license.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * ==================================================================== */ package org.tmatesoft.svn.core.internal.wc; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.util.Collection; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import java.util.TreeSet; import org.tmatesoft.svn.core.SVNErrorCode; import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.internal.io.fs.repcache.IFSRepresentationCacheManagerFactory; import org.tmatesoft.svn.core.internal.io.svn.SVNAuthenticator; import org.tmatesoft.svn.core.internal.io.svn.SVNConnection; import org.tmatesoft.svn.core.internal.util.ISVNThreadPool; import org.tmatesoft.svn.core.internal.wc.admin.SVNAdminAreaFactory; import org.tmatesoft.svn.util.SVNDebugLog; import org.tmatesoft.svn.util.SVNLogType; /** * @version 1.3 * @author TMate Software Ltd. */ public class SVNClassLoader { private static final String SVNKIT_PROPERTIES = "svnkit.properties"; private static final String SVNKIT_PROPERTIES_PATH = "svnkit.properties.property"; private static final String DEFAULT_PROPERTIES = "svnkit.adminareafactory.1=org.tmatesoft.svn.core.internal.wc.admin.SVNAdminArea16Factory\n" + "svnkit.adminareafactory.2=org.tmatesoft.svn.core.internal.wc.admin.SVNAdminArea15Factory\n" + "svnkit.adminareafactory.3=org.tmatesoft.svn.core.internal.wc.admin.SVNAdminArea14Factory\n" + "svnkit.adminareafactory.4=org.tmatesoft.svn.core.internal.wc.admin.SVNXMLAdminAreaFactory\n" + "svnkit.repcachemanagerfactory.1=org.tmatesoft.svn.core.internal.io.fs.repcache.FSRepresentationCacheManagerFactory\n" + "svnkit.repcachemanagerfactory.2=org.tmatesoft.svn.core.internal.io.fs.repcache.FSEmptyRepresentationCacheManagerFactory\n" + "svnkit.saslauthenticator.1=org.tmatesoft.svn.core.internal.io.svn.sasl.SVNSaslAuthenticator\n" + "svnkit.saslauthenticator.2=org.tmatesoft.svn.core.internal.io.svn.SVNPlainAuthenticator\n" + "svnkit.threadpool.1=org.tmatesoft.svn.core.internal.util.SVNThreadPool\n" + "svnkit.threadpool.2=org.tmatesoft.svn.core.internal.util.SVNEmptyThreadPool\n"; public static ISVNThreadPool getThreadPool() { Collection threadPoolClasses = getAllClasses("svnkit.threadpool."); for (Iterator classesIter = threadPoolClasses.iterator(); classesIter.hasNext();) { Class threadPoolClass = (Class) classesIter.next(); Object object = null; try { object = threadPoolClass.newInstance(); } catch (Throwable th) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.FSFS, "Could not instantiate a thread pool class " + threadPoolClass.getName() + ": " + th.getMessage()); } if (object != null && object instanceof ISVNThreadPool) { return (ISVNThreadPool) object; } } return null; } public static Collection getAvailableAdminAreaFactories() { Collection instances = getAllClasses("svnkit.adminareafactory."); Collection factories = new TreeSet(); for (Iterator classesIter = instances.iterator(); classesIter.hasNext();) { Class adminAreaFactoryClass = (Class) classesIter.next(); Object object = null; try { object = adminAreaFactoryClass.newInstance(); } catch (Throwable th) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.WC, "Failed to instantiate an admin area factory class " + adminAreaFactoryClass.getName() + ": " + th.getMessage()); continue; } if (object != null && object instanceof SVNAdminAreaFactory) { factories.add(object); } } return factories; } public static SVNAuthenticator getSASLAuthenticator(SVNConnection connection) throws SVNException { Collection saslAuthenticatorClasses = getAllClasses("svnkit.saslauthenticator."); for (Iterator classesItera = saslAuthenticatorClasses.iterator(); classesItera.hasNext();) { Class saslAuthenticatorClass = (Class) classesItera.next(); Constructor constructor = null; try { constructor = saslAuthenticatorClass.getConstructor(new Class[] { SVNConnection.class }); } catch (Throwable th) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.NETWORK, "Failed to get constructor of a SASL authenticator (" + saslAuthenticatorClass.getName() + "): " + th.getMessage()); } if (constructor != null) { Object object = null; try { object = constructor.newInstance(new Object[] { connection }); } catch (Throwable th) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.NETWORK, "Failed to instantiate a SASL authenticator ( " + saslAuthenticatorClass.getName() + "): " + th.getMessage()); } if (object != null && object instanceof SVNAuthenticator) { return (SVNAuthenticator) object; } } } SVNErrorMessage err = SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "No SASL authenticator class found!"); SVNErrorManager.error(err, SVNLogType.NETWORK); return null; } public static IFSRepresentationCacheManagerFactory getFSRepresentationCacheManagerFactory() { Collection repCacheManagerFactoryClasses = getAllClasses("svnkit.repcachemanagerfactory."); for (Iterator classesIter = repCacheManagerFactoryClasses.iterator(); classesIter.hasNext();) { Class repCacheManagerFactoryClass = (Class) classesIter.next(); Object object = null; try { object = repCacheManagerFactoryClass.newInstance(); } catch (Throwable th) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.FSFS, "Could not instantiate a rep-cache manager class " + repCacheManagerFactoryClass.getName() + ": " + th.getMessage()); } if (object != null && object instanceof IFSRepresentationCacheManagerFactory) { return (IFSRepresentationCacheManagerFactory) object; } } return null; } private static Collection getAllClasses(String keyPrefix) { Collection classes = new LinkedList(); Map svnkitProps = SVNClassLoader.loadProperties(); for (Iterator svnkitPropsIter = svnkitProps.keySet().iterator(); svnkitPropsIter.hasNext();) { String key = (String) svnkitPropsIter.next(); if (key.startsWith(keyPrefix)) { String className = (String) svnkitProps.get(key); if (className == null) { continue; } Class clazz = null; try { clazz = SVNClassLoader.class.getClassLoader().loadClass(className); } catch (Throwable th) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.WC, "Failed to load class " + className + ": " + th.getMessage()); continue; } if (clazz == null) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.WC, "Failed to load class " + className); continue; } classes.add(clazz); } } return classes; } private static Map loadProperties() { Map finalProps = new TreeMap(); Properties props = new Properties(); InputStream resourceStream = new ByteArrayInputStream(DEFAULT_PROPERTIES.getBytes()); try { //1. first load default props props.load(resourceStream); } catch (IOException ioe) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.DEFAULT, "Failed to load default SVNKit properties: " + ioe.getMessage()); } String svnkitPropertiesResource = System.getProperty(SVNKIT_PROPERTIES_PATH, SVNKIT_PROPERTIES); try { //2. and 3. second try to locate a props file from a system property //if none found, use default name for the props file resourceStream = SVNClassLoader.class.getClassLoader().getResourceAsStream(svnkitPropertiesResource); if (resourceStream != null) { props.load(resourceStream); } } catch (IOException e) { SVNDebugLog.getDefaultLog().logFine(SVNLogType.DEFAULT, "Failed to load '" + svnkitPropertiesResource + "': " + e.getMessage()); } finally { SVNFileUtil.closeFile(resourceStream); } //4. try to iterate over possible keys and load values from //system properties with the same names //Properties finalProps = new Properties(); for (Iterator propNamesIter = props.keySet().iterator(); propNamesIter.hasNext();) { String key = (String) propNamesIter.next(); String value = props.getProperty(key); value = System.getProperty(key, value); //finalProps.setProperty(key, value); finalProps.put(key, value); } return finalProps; } }