///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using JetBrains.Omea.ResourceStore;
using JetBrains.Omea.ResourceTools;
using Microsoft.Win32;
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Windows.Forms;
using JetBrains.Omea.OpenAPI;
using System.IO;
using System.Xml;
using JetBrains.DataStructures;
namespace JetBrains.Omea.Plugins
{
///
/// Plugins singleton loader.
/// Loads plugin assemblies enumerated in the 'Plugins' reg key.
/// Afterwards plugins may be enumerated as instances of IPlugin
///
class PluginInterfaces : PluginLoader, IPluginLoader
{
public void RegisterResourceTextProvider( string resType, IResourceTextProvider provider )
{
if ( resType == null )
{
lock( _genericResourceTextProviders )
{
_genericResourceTextProviders.Add( provider );
}
}
else
{
ArrayList providerList = (ArrayList) _resourceTextProviders [resType];
if ( providerList == null )
{
providerList = new ArrayList();
_resourceTextProviders [resType] = providerList;
}
lock( providerList )
{
providerList.Add( provider );
}
}
}
public bool HasTypedTextProvider( string resType )
{
#region Preconditions
if( resType == null )
throw new ArgumentNullException( "PluginLoader -- Input resource type can not be null." );
#endregion Preconditions
ArrayList providerList = (ArrayList) _resourceTextProviders[ resType ];
return (providerList != null);
}
public void InvokeResourceTextProviders( IResource res, IResourceTextConsumer consumer )
{
#region Preconditions
if ( res == null )
throw new ArgumentNullException( "PluginLoader -- Resource is null." );
if ( consumer == null )
throw new ArgumentNullException( "PluginLoader -- IResourceTextConsumer is null." );
#endregion Preconditions
bool isSuccess = true;
ArrayList providerList = (ArrayList) _resourceTextProviders [res.Type];
if ( providerList != null )
{
lock( providerList )
{
foreach( IResourceTextProvider provider in providerList )
{
IResourceTextIndexingPermitter permitter = provider as IResourceTextIndexingPermitter;
if( permitter != null && !permitter.CanIndexResource( res ) )
{
return;
}
}
}
}
lock( _genericResourceTextProviders )
{
foreach( IResourceTextProvider provider in _genericResourceTextProviders )
{
IResourceTextIndexingPermitter permitter = provider as IResourceTextIndexingPermitter;
if( permitter != null && !permitter.CanIndexResource( res ) )
{
return;
}
}
}
if ( providerList != null )
{
lock( providerList )
{
foreach( IResourceTextProvider provider in providerList )
{
isSuccess = isSuccess && provider.ProcessResourceText( res, consumer );
}
}
}
lock( _genericResourceTextProviders )
{
foreach( IResourceTextProvider provider in _genericResourceTextProviders )
{
isSuccess = isSuccess && provider.ProcessResourceText( res, consumer );
}
}
if( !isSuccess )
consumer.RejectResult();
}
public void RegisterResourceUIHandler( string resType, IResourceUIHandler handler )
{
#region Preconditions
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
{
throw new ArgumentException( "Invalid resource type '" + resType + "'", "resType" );
}
#endregion
_resourceUIHandlerHash [resType] = handler;
}
public IResourceUIHandler GetResourceUIHandler( string resType )
{
return (IResourceUIHandler) _resourceUIHandlerHash [resType];
}
public IResourceUIHandler GetResourceUIHandler( IResource res )
{
return (IResourceUIHandler) GetHandlerFromMap( res, _resourceUIHandlerHash );
}
public void RegisterResourceDragDropHandler( string resType, IResourceDragDropHandler handler )
{
#region Preconditions
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
throw new ArgumentException( "Invalid resource type \"" + resType + "\".", "resType" );
#endregion Preconditions
lock( _resourceDragDropHandlerHash )
{
// Check if a handler is already registered
IResourceDragDropHandler existing = _resourceDragDropHandlerHash[ resType ] as IResourceDragDropHandler;
if( existing != null )
{
// The handler's registered; if it's already a composite one, add a new handler to it
// If it's a simple handler, create a new composite of the old and new ones
ResourceDragDropCompositeHandler composite = existing as ResourceDragDropCompositeHandler;
if( composite != null )
composite.AddHandler( handler );
else
_resourceDragDropHandlerHash[ resType ] = new ResourceDragDropCompositeHandler( existing, handler );
}
else // There were no handler yet, just write the raw unwrapped handler
_resourceDragDropHandlerHash[ resType ] = handler;
}
}
public IResourceDragDropHandler GetResourceDragDropHandler( IResource res )
{
lock(_resourceDragDropHandlerHash)
return (IResourceDragDropHandler) GetHandlerFromMap( res, _resourceDragDropHandlerHash );
}
public IResourceDragDropHandler GetResourceDragDropHandler( string resType )
{
lock(_resourceDragDropHandlerHash)
return (IResourceDragDropHandler) _resourceDragDropHandlerHash [resType];
}
public void RegisterResourceRenameHandler( string resType, IResourceRenameHandler handler )
{
#region Preconditions
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
{
throw new ArgumentException( "Invalid resource type '" + resType + "'", "resType" );
}
#endregion Preconditions
_resourceRenameHandlerHash [resType] = handler;
}
public IResourceRenameHandler GetResourceRenameHandler( IResource res )
{
return (IResourceRenameHandler) GetHandlerFromMap( res, _resourceRenameHandlerHash );
}
private static object GetHandlerFromMap( IResource res, HashMap handlerMap )
{
if ( res == null || Core.ResourceStore == null )
return null;
object handler = handlerMap [res.Type];
if ( handler == null )
{
foreach( int linkTypeId in res.GetLinkTypeIds() )
{
if ( Core.ResourceStore.PropTypes [linkTypeId].HasFlag( PropTypeFlags.SourceLink ) )
{
IResource source = res.GetLinkProp( linkTypeId );
if ( source != null ) // the link may be reverse
{
handler = handlerMap [source.Type];
}
}
}
}
return handler;
}
public void RegisterResourceThreadingHandler( string resType, IResourceThreadingHandler handler )
{
_threadingHandler.AddHandler( resType, handler );
}
public void RegisterResourceThreadingHandler( int propId, IResourceThreadingHandler handler )
{
_threadingHandler.AddHandler( propId, handler );
}
public void RegisterDefaultThreadingHandler( string resType, int replyProp )
{
_threadingHandler.AddHandler( resType, new DefaultThreadingHandler( replyProp ) );
}
public IResourceThreadingHandler GetResourceThreadingHandler( string resType )
{
return _threadingHandler.GetHandler( resType );
}
public IResourceThreadingHandler CompositeThreadingHandler
{
get { return _threadingHandler; }
}
public IResourceDisplayer GetResourceDisplayer( string resType )
{
return (IResourceDisplayer) _resourceDisplayerHash [ resType ];
}
public void RegisterResourceDisplayer( string resType, IResourceDisplayer displayer )
{
_resourceDisplayerHash [ resType ] = displayer;
}
public void RegisterNewspaperProvider( string resType, INewspaperProvider provider )
{
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
throw new ArgumentException( "Resource type '" + resType + "' does not exist", "resType" );
_newspaperProviders [resType] = provider;
}
public INewspaperProvider GetNewspaperProvider( string resType )
{
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
throw new ArgumentException( "Resource type '" + resType + "' does not exist", "resType" );
return (INewspaperProvider) _newspaperProviders [ resType ];
}
public void RegisterResourceDeleter( string resType, IResourceDeleter deleter )
{
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
throw new ArgumentException( "Resource type '" + resType + "' does not exist", "resType" );
_resourceDeleters [ resType ] = deleter;
}
public IResourceDeleter GetResourceDeleter( string resType )
{
if ( !Core.ResourceStore.ResourceTypes.Exist( resType ) )
throw new ArgumentException( "Resource type '" + resType + "' does not exist", "resType" );
return (IResourceDeleter) _resourceDeleters [resType];
}
public IStreamProvider GetStreamProvider( string resType )
{
return (IStreamProvider) _streamProviderHash [ resType ];
}
public void RegisterStreamProvider( string resType, IStreamProvider provider )
{
_streamProviderHash [ resType ] = provider;
}
public void RegisterResourceSerializer( string resType, IResourceSerializer serializer )
{
_resourceSerializers[ resType ] = serializer;
}
public IResourceSerializer GetResourceSerializer( string resType )
{
return (IResourceSerializer) _resourceSerializers [ resType ];
}
public void RegisterViewsConstructor( IViewsConstructor constructor )
{
if( _viewsConstructors.IndexOf( constructor ) == -1 )
_viewsConstructors.Add( constructor );
}
public ArrayList GetViewsConstructors()
{
return _viewsConstructors;
}
private HashMap _resourceUIHandlerHash = new HashMap();
private HashMap _resourceDragDropHandlerHash = new HashMap();
private HashMap _resourceRenameHandlerHash = new HashMap();
private HashMap _resourceDisplayerHash = new HashMap();
private HashMap _streamProviderHash = new HashMap();
private HashMap _resourceTextProviders = new HashMap(); // resource type -> ArrayList
private HashMap _resourceSerializers = new HashMap(); // resource type -> IResourceSerializer
private HashMap _resourceDeleters = new HashMap(); // resource type -> IResourceDeleter
private HashMap _newspaperProviders = new HashMap(); // resource type -> INewspaperProvider
private ArrayList _genericResourceTextProviders = new ArrayList();
private ArrayList _viewsConstructors = new ArrayList();
private CompositeThreadingHandler _threadingHandler = new CompositeThreadingHandler();
}
}