Return-Path: Delivered-To: apmail-jakarta-avalon-cvs-archive@apache.org Received: (qmail 98701 invoked from network); 18 Sep 2002 22:45:39 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 18 Sep 2002 22:45:39 -0000 Received: (qmail 6383 invoked by uid 97); 18 Sep 2002 22:46:22 -0000 Delivered-To: qmlist-jakarta-archive-avalon-cvs@jakarta.apache.org Received: (qmail 6367 invoked by uid 97); 18 Sep 2002 22:46:22 -0000 Mailing-List: contact avalon-cvs-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon CVS List" Reply-To: "Avalon Developers List" Delivered-To: mailing list avalon-cvs@jakarta.apache.org Received: (qmail 6356 invoked by uid 97); 18 Sep 2002 22:46:21 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Date: 18 Sep 2002 22:45:34 -0000 Message-ID: <20020918224534.11217.qmail@icarus.apache.org> From: bloritsch@apache.org To: jakarta-avalon-excalibur-cvs@apache.org Subject: cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader DirectoryChangeListener.java DirectoryClassManager.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N bloritsch 2002/09/18 15:45:34 Added: container/src/java/org/apache/excalibur/container/classloader DirectoryChangeListener.java DirectoryClassManager.java Log: add ClassLoaderManager so that we can manage a directory of reloadable jars Revision Changes Path 1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/DirectoryChangeListener.java Index: DirectoryChangeListener.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.excalibur.container.classloader; import java.io.File; /** * The DirectoryChangeListener lets the DirectoryClassManager notify an * external class if the directory changed. * * @author Berin Loritsch */ public interface DirectoryChangeListener { void directoryChanged( File dir, JarEntries oldEntries, JarEntries newEntries ); } 1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/DirectoryClassManager.java Index: DirectoryClassManager.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE.txt file. */ package org.apache.excalibur.container.classloader; import java.net.URL; import java.io.InputStream; import java.io.IOException; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Timer; import java.util.TimerTask; /** * A ClassLoader that lists all the entries of a particular type. Using * this classloader we can resolve all the Avalon types and services, * and iterate through the list. In all other ways, this * ClassLoader behaves identically to the * @link{java.net.URLClassLoader} * * @author Berin Loritsch */ public class DirectoryClassManager { private final static long RECHECK_PERIOD = 60 * 1000; // One minute private final ClassLoader m_parentClassLoader; private final Map m_classLoaders; private final Map m_modifiedMap; private final Timer m_timer; private final File m_rootDir; private DirectoryChangeListener m_listener = null; public DirectoryClassManager( String path ) throws IOException { this( new File( path ) ); } public DirectoryClassManager( File rootDir ) throws IOException { this( rootDir, Thread.currentThread().getContextClassLoader() ); } public DirectoryClassManager( File rootDir, ClassLoader parent ) throws IOException { if ( rootDir.isFile() ) { throw new IOException( "The File object passed in must be a directory" ); } m_rootDir = rootDir; File[] entries = rootDir.listFiles(); m_parentClassLoader = parent; m_classLoaders = new HashMap( entries.length ); m_modifiedMap = new HashMap( entries.length ); m_classLoaders.put( m_rootDir, new ComponentClassLoader( new URL[] { m_rootDir.toURL() }, m_parentClassLoader ) ); m_modifiedMap.put( m_rootDir, new Long( m_rootDir.lastModified() ) ); for ( int i = 0; i < entries.length; i++ ) { if ( entries[i].isFile() ) { m_classLoaders.put( entries[i], new ComponentClassLoader( new URL[] { entries[i].toURL() }, m_parentClassLoader ) ); m_modifiedMap.put( entries[i], new Long( entries[i].lastModified() ) ); } } m_timer = new Timer( true ); m_timer.scheduleAtFixedRate( new DCMTimerTask(), RECHECK_PERIOD, RECHECK_PERIOD ); } public void setListener( DirectoryChangeListener listener ) { m_listener = listener; } public Class loadClass( String className ) throws ClassNotFoundException { Iterator it = m_classLoaders.values().iterator(); Class klass = null; while ( it.hasNext() && klass == null) { ClassLoader loader = (ClassLoader) it.next(); try { klass = loader.loadClass( className ); } catch ( Exception e ) { // ignore } } if ( null == klass ) { throw new ClassNotFoundException( className ); } return klass; } public URL getResource( String path ) { Iterator it = m_classLoaders.values().iterator(); URL resource = null; while ( it.hasNext() && resource == null) { ClassLoader loader = (ClassLoader) it.next(); try { resource = loader.getResource( path ); } catch ( Exception e ) { // ignore } } return resource; } public InputStream getResourceAsStream( String path ) throws IOException { return getResource( path ).openConnection().getInputStream(); } protected void finalize() { m_timer.cancel(); } private final class DCMTimerTask extends TimerTask { public void run() { try { Iterator it = m_modifiedMap.keySet().iterator(); while ( it.hasNext() ) { File curFile = (File) it.next(); long lastModified = curFile.lastModified(); if ( lastModified > ( (Long) m_modifiedMap.get( curFile ) ).longValue() ) { ComponentClassLoader loader = (ComponentClassLoader) m_classLoaders.get( curFile ); JarEntries oldEntries = loader.getEntries(); loader = new ComponentClassLoader( new URL[] { curFile.toURL() }, m_parentClassLoader ); m_classLoaders.put( curFile, loader ); JarEntries newEntries = loader.getEntries(); if ( null != m_listener ) { m_listener.directoryChanged( curFile, oldEntries, newEntries ); } } } } catch ( Exception e ) { // ignore for now } } } } -- To unsubscribe, e-mail: For additional commands, e-mail: