///
/// 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 System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using JetBrains.Omea.Base;
using JetBrains.Omea.OpenAPI;
using Microsoft.Win32;
using RSSPlugin;
using Syndication.Extensibility;
namespace JetBrains.Omea.RSSPlugin
{
///
/// Loads and manages the plugins implementing the IBlogExtension interface.
///
internal class BlogExtensionManager
{
private readonly ArrayList _blogExtensions = new ArrayList();
private const string _extensionKey = @"Software\JetBrains\Omea\BlogExtensions";
public void LoadExtensions()
{
Core.ActionManager.RegisterContextMenuActionGroup( "BlogExtensions", "Blog This", ListAnchor.Last );
Core.ActionManager.RegisterContextMenuActionGroup( "BlogExtensionsConfigure", "Blog This", ListAnchor.Last );
Core.ActionManager.RegisterContextMenuAction( new ConfigureExtensionsAction(), "BlogExtensionsConfigure",
ListAnchor.Last, "Configure Extensions...", null, "RSSItem", null );
string pluginPath = Path.Combine( Application.StartupPath, "plugins" );
if ( Directory.Exists( pluginPath ) )
{
foreach( string fileName in Directory.GetFiles( pluginPath, "*.dll" ) )
{
string pluginFileName = Path.Combine( pluginPath, fileName );
LoadExtension( pluginFileName );
}
}
RegistryKey regKey = Registry.CurrentUser.CreateSubKey( _extensionKey );
foreach( string valueName in regKey.GetValueNames() )
{
string path = (string) regKey.GetValue( valueName );
LoadExtension( path );
}
regKey.Close();
}
private BlogExtensionData LoadExtension( string fileName )
{
Type[] pluginTypes;
try
{
Assembly pluginAssembly = Assembly.LoadFrom( fileName );
pluginTypes = pluginAssembly.GetExportedTypes();
}
catch( Exception e )
{
Trace.WriteLine( e.ToString() );
return null;
}
// search for IPlugin instances
foreach( Type aType in pluginTypes )
{
foreach( Type intfType in aType.GetInterfaces() )
{
if ( intfType == typeof(IBlogExtension) )
{
IBlogExtension extension;
try
{
extension = (IBlogExtension) Activator.CreateInstance( aType );
}
catch( Exception ex )
{
if ( ex is TargetInvocationException )
{
ex = (ex as TargetInvocationException).InnerException;
}
DialogResult dr = MessageBox.Show( Core.MainWindow,
"Exception when initializing weblog posting extension " + fileName +
":\r\n" + ex.Message + "\r\nWould you like to uninstall the extension?",
Core.ProductFullName, MessageBoxButtons.YesNo );
if ( dr == DialogResult.Yes )
{
UninstallExtensionFile( fileName );
}
return null;
}
IAction extAction = RegisterBlogExtensionAction( extension );
BlogExtensionData extData = new BlogExtensionData( fileName, extension, extAction );
_blogExtensions.Add( extData );
return extData;
}
}
}
return null;
}
internal BlogExtensionData InstallExtension( string fileName )
{
BlogExtensionData extData = LoadExtension( fileName );
if ( extData == null )
{
return null;
}
RegUtil.CreateSubKey( Registry.CurrentUser, _extensionKey );
RegUtil.SetValue( Registry.CurrentUser, _extensionKey, Path.GetFileNameWithoutExtension( fileName ), fileName );
return extData;
}
internal void UninstallExtension( BlogExtensionData extData )
{
UninstallExtensionFile( extData.FileName );
Core.ActionManager.UnregisterContextMenuAction( extData.Action );
_blogExtensions.Remove( extData );
}
private static void UninstallExtensionFile( string fileName )
{
RegistryKey regKey = Registry.CurrentUser.OpenSubKey( _extensionKey, true );
foreach( string valueName in regKey.GetValueNames() )
{
string path = (string) regKey.GetValue( valueName );
if ( path == fileName )
{
regKey.DeleteValue( valueName );
break;
}
}
}
private static IAction RegisterBlogExtensionAction( IBlogExtension extension )
{
BlogExtensionAction extAction = new BlogExtensionAction( extension );
Core.ActionManager.RegisterContextMenuAction( extAction, "BlogExtensions", ListAnchor.Last,
extension.DisplayName, null, "RSSItem", null );
return extAction;
}
internal IEnumerable BlogExtensions
{
get { return _blogExtensions; }
}
}
internal class BlogExtensionData
{
private readonly string _fileName;
private readonly IBlogExtension _blogExtension;
private readonly IAction _action;
public BlogExtensionData( string fileName, IBlogExtension blogExtension, IAction extAction )
{
_fileName = fileName;
_blogExtension = blogExtension;
_action = extAction;
}
public string FileName
{
get { return _fileName; }
}
public IBlogExtension BlogExtension
{
get { return _blogExtension; }
}
public IAction Action
{
get { return _action; }
}
}
internal class BlogExtensionAction: ActionOnSingleResource
{
private readonly IBlogExtension _extension;
public BlogExtensionAction( IBlogExtension extension )
{
_extension = extension;
}
public override void Execute( IActionContext context )
{
IResource item = context.SelectedResources [0];
IResource feed = item.GetLinkProp( -Props.RSSItem );
// Submit the item, show the editing UI if needed
BlogExtensionComposer.Compose( _extension, item, feed );
}
}
internal class ConfigureExtensionsAction: SimpleAction
{
public override void Execute( IActionContext context )
{
Core.UIManager.ShowOptionsDialog( "Internet", "Feeds" );
}
}
}