// Copyright 2003-2004 The Apache Software Foundation
//
// 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.
namespace Apache.Avalon.Composition.Model.Default
{
using System;
using System.Reflection;
using System.Collections;
using Apache.Avalon.Framework;
using Apache.Avalon.Meta;
using Apache.Avalon.Meta.Builder;
using Apache.Avalon.Repository;
using Apache.Avalon.Composition.Data;
using Apache.Avalon.Composition.Model;
/// A repository for services, types and profiles.
///
///
/// Avalon Development Team
///
/// $Revision: 1.2 $ $Date: 2004/02/29 18:07:17 $
///
public class Scanner : AbstractLogEnabled
{
///
/// The type builder.
///
TypeDescriptorBuilder m_builder = new TypeDescriptorBuilder();
///
/// The service builder. NOTE: Not being used by now.
///
ServiceBuilder m_serviceBuilder = new ServiceBuilder();
//===================================================================
// constructor
//===================================================================
/// Creation of a new scanner.
/// The scanner is responsible for scanning suppied Assemblies for
/// service and types.
///
/// the logging channel
///
/// the classloader
///
public Scanner(ILogger logger)
{
EnableLogging(logger);
}
/// Scan the supplied url for Service and Type defintions.
/// the URL array to scan
///
/// the map to populate with types as keys and
/// and packaged profiles as values
///
/// a list to be populated with service descriptors
///
public virtual void Scan( Uri[] uris, IList types, IList services)
{
foreach(Uri item in uris)
{
ScanUri(item, types, services);
}
}
/// Add a URL to the classpath.
/// the URL to add to the repository
///
private void ScanUri(Uri uri, IList types, IList services)
{
if (Logger.IsDebugEnabled)
{
String message = "scanner.scanning";
Logger.Debug(message);
}
Assembly assembly = Assembly.LoadFrom( uri.LocalPath );
ScanAssembly( assembly, types, services );
}
///
///
///
///
///
///
private void ScanAssembly( Assembly assembly, IList types, IList services )
{
foreach(Type type in assembly.GetExportedTypes())
{
ScanType( type, types, services );
}
}
private void ScanType(Type targetType, IList types, IList services)
{
if (targetType.IsDefined( typeof(AvalonComponentAttribute), true ))
{
AddType(targetType, types);
}
}
private void AddType(Type targetType, IList types)
{
TypeDescriptor descriptor = m_builder.CreateTypeDescriptor( targetType );
try
{
VerifyType(descriptor, targetType);
if (Logger.IsDebugEnabled)
{
String message = "type added " + descriptor.ToString();
Logger.Debug(message);
}
types.Add(descriptor);
}
catch (System.ApplicationException)
{
if (Logger.IsWarnEnabled)
{
String warning = "Type verification failed for " + descriptor.ToString();
Logger.Warn(warning);
}
}
catch (System.Exception e)
{
if (Logger.IsWarnEnabled)
{
String warning = "Unexpected error in type verification: " + descriptor.ToString();
Logger.Warn(warning, e);
}
}
}
///
/// Verify the intergrity of the supplied type.
///
///
/// the type to verify
///
///
/// the implementation class
///
///
/// Exception if an verification failure occurs
///
private void VerifyType(TypeDescriptor typeDesc, System.Type type)
{
// TODO: VerifyType
}
}
}