You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by bl...@apache.org on 2002/09/11 19:38:49 UTC
cvs commit: jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader ComponentClassLoader.java
bloritsch 2002/09/11 10:38:49
Added: container/src/java/org/apache/excalibur/container/classloader
ComponentClassLoader.java
Log:
add a generic ClassLoader that will assemble a list of components/services/blocks--there is no affinity to meta model library
Revision Changes Path
1.1 jakarta-avalon-excalibur/container/src/java/org/apache/excalibur/container/classloader/ComponentClassLoader.java
Index: ComponentClassLoader.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.lookup;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLStreamHandlerFactory;
/**
* 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
* <code>ClassLoader</code> behaves identically to the
* @link{java.net.URLClassLoader}
*
* @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
*/
public class ComponentClassLoader extends URLClassLoader
{
protected static final String AVALON = "Avalon";
protected static final String BLOCK = AVALON + "-Block";
protected static final String TYPE = "Type";
protected static final String SERVICE = "Service";
private final Set m_blocks;
private final Set m_types;
private final Set m_services;
/**
* Constructs a new <code>ComponentClassLoader</code> and extracts a list
* of services and components.
*/
public ComponentClassLoader( URL[] classPath )
{
this( classPath, null, null );
}
/**
* Constructs a new <code>ComponentClassLoader</code> and extracts a list
* of services and components.
*/
public ComponentClassLoader( URL[] classPath, ClassLoader parent )
{
this( classPath, parent, null );
}
/**
* Constructs a new <code>ComponentClassLoader</code> and extracts a list
* of services and components.
*/
public ComponentClassLoader( URL[] classPath,
ClassLoader parent,
URLStreamHandlerFactory urlHandlerFactory )
{
super( classPath, parent, urlHandlerFactory );
m_blocks = new HashSet();
m_types = new HashSet();
m_services = new HashSet();
for ( int i = 0; i < classPath.length; i++ )
{
scan( classPath[i] );
}
}
/**
* Expose the <code>addURL()</code> from the
* @link{java.net.URLClassLoader} publically. Please note that there is
* no facility to remove a URL from the ClassLoader.
*/
public void addURL( URL classPath )
{
super.addURL( classPath );
scan ( classPath );
}
/**
* Get an array of the block names. These are treated separately from
* the generic <code>Type</code>
*/
public String[] getBlocks()
{
return (String[]) m_blocks.toArray( new String[ m_blocks.size() ] );
}
/**
* Get an array of the type names. These are treated separately from
* the Phoenix specific <code>Block</code>
*/
public String[] getTypes()
{
return (String[]) m_types.toArray( new String[ m_types.size() ] );
}
/**
* Get an array of the service names.
*/
public String[] getServices()
{
return (String[]) m_services.toArray( new String[ m_services.size() ] );
}
/**
* The logic to look through the manifest entries in the JAR url passed
* in. It is used to populate the sets of Services, Types, and Blocks.
*/
protected void scan( URL jarLocation )
{
try
{
final JarURLConnection jar = (JarURLConnection)
new URL( "jar:" + jarLocation.toString() + "!/" ).openConnection();
final Map manifest = jar.getManifest().getEntries();
final Iterator it = manifest.keySet().iterator();
while ( it.hasNext() )
{
final String entry = (String) it.next();
final Attributes attributes = (Attributes)manifest.get( entry );
final Iterator attrIt = attributes.keySet().iterator();
while( attrIt.hasNext() )
{
final String attrName = (String) it.next();
if ( attrName.equals( BLOCK ) &&
attributes.getValue( attrName ).equals( "true" ) )
{
m_blocks.add( cleanName( attrName ) );
}
else if ( attrName.equals( AVALON ) )
{
final String attrVal = attributes.getValue( attrName );
if ( attrVal.equals( TYPE ) )
{
m_types.add( cleanName( attrName ) );
}
else if ( attrVal.equals( SERVICE ) )
{
m_types.add( cleanName( attrName ) );
}
else
{
// TODO: Handle error condition
}
}
}
}
}
catch ( IOException ioe )
{
// TODO: Handle error condition
}
}
/**
* Strips the ".class" ending off of a Type/Block/Service name.
*/
private final String cleanName( String name )
{
return name.substring( 0, name.indexOf( ".class" ) );
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>