using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Nintex.Workflow;
using Nintex.Workflow.Administration;
using Nintex.Workflow.Common;
using System.Reflection;
namespace CFSP.CustomActions.Features.WebApplication___Custom_Actions
{
[Guid("07607091-449b-422b-94e4-84e6d863eb9e")]
public class WebApplication___Custom_ActionsEventReceiver : SPFeatureReceiver
{
#region Events
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWebApplication parent = (SPWebApplication) properties.Feature.Parent;
AddCustomAction(parent, properties, "ReadFromPropertyBagAction.nwa");
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPWebApplication parent = (SPWebApplication) properties.Feature.Parent;
RemoveCustomAction(parent, properties,
"CFSP.CustomActions.ReadFromPropertyBag.ReadFromPropertyBagAdapter",
Assembly.GetExecutingAssembly().FullName);
}
#endregion
#region Methods
/// <summary>
/// Adds a nintex custom action to SharePoint
/// </summary>
/// <param name="parent"></param>
/// <param name="properties"></param>
/// <param name="pathToNWAFile"></param>
protected void AddCustomAction(SPWebApplication parent, SPFeatureReceiverProperties properties,
string pathToNWAFile)
{
// First step is register the action to the Nintex Workflow database
XmlDocument nwaXml = GetNWADefinition(properties, pathToNWAFile);
ActivityReference newActivityReference = ActivityReference.ReadFromNWA(nwaXml);
ActivityReference action = ActivityReferenceCollection.FindByAdapter(newActivityReference.AdapterType,
newActivityReference.AdapterAssembly);
if (action != null)
{
// update the details if the adapter already exists
ActivityReferenceCollection.UpdateActivity(action.ActivityId, newActivityReference.Name,
newActivityReference.Description, newActivityReference.Category,
newActivityReference.ActivityAssembly, newActivityReference.ActivityType,
newActivityReference.AdapterAssembly, newActivityReference.AdapterType,
newActivityReference.HandlerUrl, newActivityReference.ConfigPage,
newActivityReference.RenderBehaviour, newActivityReference.Icon, newActivityReference.ToolboxIcon,
newActivityReference.WarningIcon, newActivityReference.QuickAccess,
newActivityReference.ListTypeFilter);
}
else
{
ActivityReferenceCollection.AddActivity(newActivityReference.Name, newActivityReference.Description,
newActivityReference.Category, newActivityReference.ActivityAssembly,
newActivityReference.ActivityType, newActivityReference.AdapterAssembly,
newActivityReference.AdapterType, newActivityReference.HandlerUrl, newActivityReference.ConfigPage,
newActivityReference.RenderBehaviour, newActivityReference.Icon, newActivityReference.ToolboxIcon,
newActivityReference.WarningIcon, newActivityReference.QuickAccess,
newActivityReference.ListTypeFilter);
action = ActivityReferenceCollection.FindByAdapter(newActivityReference.AdapterType,
newActivityReference.AdapterAssembly);
}
// Second step is to modify the web.config file to allow use of the activity in declarative workflows
string activityTypeName = string.Empty;
string activityNamespace = string.Empty;
Utility.ExtractNamespaceAndClassName(action.ActivityType, out activityTypeName, out activityNamespace);
AuthorisedTypes.InstallAuthorizedWorkflowTypes(parent, action.ActivityAssembly, activityNamespace,
activityTypeName);
// Third step is to activate the action for the farm
ActivityActivationReference reference = new ActivityActivationReference(action.ActivityId, Guid.Empty,
Guid.Empty);
reference.AddOrUpdateActivationReference();
}
/// <summary>
/// Removes a nintex custom action from SharePoint
/// </summary>
/// <param name="parent"></param>
/// <param name="properties"></param>
/// <param name="adapterType"></param>
/// <param name="adapterAssembly"></param>
protected void RemoveCustomAction(SPWebApplication parent, SPFeatureReceiverProperties properties,
string adapterType, string adapterAssembly)
{
ActivityReference action = ActivityReferenceCollection.FindByAdapter(adapterType, adapterAssembly);
if (action != null)
{
// Remove the action definition from the workflow configuration database if the Feature is not activated elsewhere
if (!IsFeatureActivatedInAnyWebApp(parent, properties.Definition.Id))
ActivityReferenceCollection.RemoveAction(action.ActivityId);
string activityTypeName = string.Empty;
string activityNamespace = string.Empty;
Utility.ExtractNamespaceAndClassName(action.ActivityType, out activityTypeName, out activityNamespace);
// Remove the web.config entry
Collection<SPWebConfigModification> modifications = parent.WebConfigModifications;
foreach (SPWebConfigModification modification in modifications)
{
if (modification.Owner == AuthorisedTypes.OWNER_TOKEN)
// OWNER_TOKEN is the owner for any web config modification added by Nintex Workflow
{
if (IsAuthorizedTypeMatch(modification.Value, action.ActivityAssembly, activityTypeName,
activityNamespace))
{
modifications.Remove(modification);
parent.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
break;
}
}
}
}
}
private bool IsAuthorizedTypeMatch(string modification, string activityAssembly, string activityType,
string activityNamespace)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(modification);
if (doc.FirstChild.Name == "authorizedType")
{
return (doc.SelectSingleNode("//@TypeName").Value == activityType
&& doc.SelectSingleNode("//@Namespace").Value == activityNamespace
&& doc.SelectSingleNode("//@Assembly").Value == activityAssembly);
}
return false;
}
private bool IsFeatureActivatedInAnyWebApp(SPWebApplication thisWebApplication, Guid thisFeatureId)
{
SPWebService webService = SPWebService.ContentService;
if (webService == null)
throw new ApplicationException("Cannot access ContentService");
SPWebApplicationCollection webApps = webService.WebApplications;
foreach (SPWebApplication webApp in webApps)
{
if (webApp != thisWebApplication)
if (webApp.Features[thisFeatureId] != null)
return true;
}
return false;
}
private XmlDocument GetNWADefinition(SPFeatureReceiverProperties properties, string pathToNWAFile)
{
using (Stream stream = properties.Definition.GetFile(pathToNWAFile))
{
XmlDocument nwaXml = new XmlDocument();
nwaXml.Load(stream);
return nwaXml;
}
}
#endregion
}
}
using System.Collections.ObjectModel;
using System.IO;
using System.Runtime.InteropServices;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Nintex.Workflow;
using Nintex.Workflow.Administration;
using Nintex.Workflow.Common;
using System.Reflection;
namespace CFSP.CustomActions.Features.WebApplication___Custom_Actions
{
[Guid("07607091-449b-422b-94e4-84e6d863eb9e")]
public class WebApplication___Custom_ActionsEventReceiver : SPFeatureReceiver
{
#region Events
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWebApplication parent = (SPWebApplication) properties.Feature.Parent;
AddCustomAction(parent, properties, "ReadFromPropertyBagAction.nwa");
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPWebApplication parent = (SPWebApplication) properties.Feature.Parent;
RemoveCustomAction(parent, properties,
"CFSP.CustomActions.ReadFromPropertyBag.ReadFromPropertyBagAdapter",
Assembly.GetExecutingAssembly().FullName);
}
#endregion
#region Methods
/// <summary>
/// Adds a nintex custom action to SharePoint
/// </summary>
/// <param name="parent"></param>
/// <param name="properties"></param>
/// <param name="pathToNWAFile"></param>
protected void AddCustomAction(SPWebApplication parent, SPFeatureReceiverProperties properties,
string pathToNWAFile)
{
// First step is register the action to the Nintex Workflow database
XmlDocument nwaXml = GetNWADefinition(properties, pathToNWAFile);
ActivityReference newActivityReference = ActivityReference.ReadFromNWA(nwaXml);
ActivityReference action = ActivityReferenceCollection.FindByAdapter(newActivityReference.AdapterType,
newActivityReference.AdapterAssembly);
if (action != null)
{
// update the details if the adapter already exists
ActivityReferenceCollection.UpdateActivity(action.ActivityId, newActivityReference.Name,
newActivityReference.Description, newActivityReference.Category,
newActivityReference.ActivityAssembly, newActivityReference.ActivityType,
newActivityReference.AdapterAssembly, newActivityReference.AdapterType,
newActivityReference.HandlerUrl, newActivityReference.ConfigPage,
newActivityReference.RenderBehaviour, newActivityReference.Icon, newActivityReference.ToolboxIcon,
newActivityReference.WarningIcon, newActivityReference.QuickAccess,
newActivityReference.ListTypeFilter);
}
else
{
ActivityReferenceCollection.AddActivity(newActivityReference.Name, newActivityReference.Description,
newActivityReference.Category, newActivityReference.ActivityAssembly,
newActivityReference.ActivityType, newActivityReference.AdapterAssembly,
newActivityReference.AdapterType, newActivityReference.HandlerUrl, newActivityReference.ConfigPage,
newActivityReference.RenderBehaviour, newActivityReference.Icon, newActivityReference.ToolboxIcon,
newActivityReference.WarningIcon, newActivityReference.QuickAccess,
newActivityReference.ListTypeFilter);
action = ActivityReferenceCollection.FindByAdapter(newActivityReference.AdapterType,
newActivityReference.AdapterAssembly);
}
// Second step is to modify the web.config file to allow use of the activity in declarative workflows
string activityTypeName = string.Empty;
string activityNamespace = string.Empty;
Utility.ExtractNamespaceAndClassName(action.ActivityType, out activityTypeName, out activityNamespace);
AuthorisedTypes.InstallAuthorizedWorkflowTypes(parent, action.ActivityAssembly, activityNamespace,
activityTypeName);
// Third step is to activate the action for the farm
ActivityActivationReference reference = new ActivityActivationReference(action.ActivityId, Guid.Empty,
Guid.Empty);
reference.AddOrUpdateActivationReference();
}
/// <summary>
/// Removes a nintex custom action from SharePoint
/// </summary>
/// <param name="parent"></param>
/// <param name="properties"></param>
/// <param name="adapterType"></param>
/// <param name="adapterAssembly"></param>
protected void RemoveCustomAction(SPWebApplication parent, SPFeatureReceiverProperties properties,
string adapterType, string adapterAssembly)
{
ActivityReference action = ActivityReferenceCollection.FindByAdapter(adapterType, adapterAssembly);
if (action != null)
{
// Remove the action definition from the workflow configuration database if the Feature is not activated elsewhere
if (!IsFeatureActivatedInAnyWebApp(parent, properties.Definition.Id))
ActivityReferenceCollection.RemoveAction(action.ActivityId);
string activityTypeName = string.Empty;
string activityNamespace = string.Empty;
Utility.ExtractNamespaceAndClassName(action.ActivityType, out activityTypeName, out activityNamespace);
// Remove the web.config entry
Collection<SPWebConfigModification> modifications = parent.WebConfigModifications;
foreach (SPWebConfigModification modification in modifications)
{
if (modification.Owner == AuthorisedTypes.OWNER_TOKEN)
// OWNER_TOKEN is the owner for any web config modification added by Nintex Workflow
{
if (IsAuthorizedTypeMatch(modification.Value, action.ActivityAssembly, activityTypeName,
activityNamespace))
{
modifications.Remove(modification);
parent.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
break;
}
}
}
}
}
private bool IsAuthorizedTypeMatch(string modification, string activityAssembly, string activityType,
string activityNamespace)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(modification);
if (doc.FirstChild.Name == "authorizedType")
{
return (doc.SelectSingleNode("//@TypeName").Value == activityType
&& doc.SelectSingleNode("//@Namespace").Value == activityNamespace
&& doc.SelectSingleNode("//@Assembly").Value == activityAssembly);
}
return false;
}
private bool IsFeatureActivatedInAnyWebApp(SPWebApplication thisWebApplication, Guid thisFeatureId)
{
SPWebService webService = SPWebService.ContentService;
if (webService == null)
throw new ApplicationException("Cannot access ContentService");
SPWebApplicationCollection webApps = webService.WebApplications;
foreach (SPWebApplication webApp in webApps)
{
if (webApp != thisWebApplication)
if (webApp.Features[thisFeatureId] != null)
return true;
}
return false;
}
private XmlDocument GetNWADefinition(SPFeatureReceiverProperties properties, string pathToNWAFile)
{
using (Stream stream = properties.Definition.GetFile(pathToNWAFile))
{
XmlDocument nwaXml = new XmlDocument();
nwaXml.Load(stream);
return nwaXml;
}
}
#endregion
}
}
Comments
Post a Comment