Granfeldt_cp 2013-01-30 14:12:35 -08:00
parent ca2f82f06d
commit c48ad73f33
10 changed files with 1486 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,341 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Workflow.ComponentModel;
using Microsoft.IdentityManagement.WebUI.Controls;
using Microsoft.ResourceManagement.Workflow.Activities;
namespace Granfeldt.FIM.ActivityLibrary
{
class BaseActivitySettingsPart : ActivitySettingsPart
{
#region Utility Functions
/// <summary>
/// Create a TableRow that contains a label and a textbox.
/// </summary>
protected TableRow AddTableRowTextBox(String labelText, String controlID, int width, int maxLength, Boolean multiLine, String defaultValue)
{
TableRow row = new TableRow();
TableCell labelCell = new TableCell();
TableCell controlCell = new TableCell();
Label oLabel = new Label();
TextBox oText = new TextBox();
oLabel.Text = labelText;
oLabel.CssClass = base.LabelCssClass;
labelCell.Controls.Add(oLabel);
oText.ID = controlID;
oText.CssClass = base.TextBoxCssClass;
oText.Text = defaultValue;
oText.MaxLength = maxLength;
oText.Width = width;
if (multiLine)
{
oText.TextMode = TextBoxMode.MultiLine;
oText.Rows = System.Math.Min(6, (maxLength + 60) / 60);
oText.Wrap = true;
}
controlCell.Controls.Add(oText);
row.Cells.Add(labelCell);
row.Cells.Add(controlCell);
return row;
}
#region Lookup Action Dropdown
protected TableRow AddLookupActionDropDownList(String labelText, String controlID, int width, String defaultValue)
{
TableRow row = new TableRow();
TableCell labelCell = new TableCell();
TableCell controlCell = new TableCell();
// Add label
Label oLabel = new Label();
oLabel.Text = labelText;
oLabel.CssClass = base.LabelCssClass;
labelCell.Controls.Add(oLabel);
DropDownList ddl = new DropDownList();
ddl.ID = controlID;
ddl.Width = width;
ddl.Items.Add(new ListItem("Return first element", "")); // default is ''
ddl.Items.Add(new ListItem("Return last element", "RETURNLAST"));
ddl.Items.Add(new ListItem("Throw error and stop", "ERROR"));
ddl.SelectedValue = defaultValue;
controlCell.Controls.Add(ddl);
row.Cells.Add(labelCell);
row.Cells.Add(controlCell);
return row;
}
protected string GetLookupActionDropDownList(string dropDownListID)
{
string g = "";
DropDownList ddl = (DropDownList)this.FindControl(dropDownListID);
if (ddl != null)
{
if (!string.IsNullOrEmpty(ddl.SelectedValue))
g = ddl.SelectedValue.ToString();
}
else
Debugging.Log("Cannot find control with ID '" + dropDownListID + "'");
return g;
}
protected void SetLookupActionDropDownList(string dropDownListID, string value)
{
DropDownList ddl = (DropDownList)this.FindControl(dropDownListID);
if (ddl != null)
{
if (!string.IsNullOrEmpty(value))
ddl.SelectedValue = value;
}
else
Debugging.Log("Cannot find control with ID '" + dropDownListID + "'");
}
#endregion
#region Actor Dropdown
protected TableRow AddActorDropDownList(String labelText, String controlID, int width, String defaultValue)
{
TableRow row = new TableRow();
TableCell labelCell = new TableCell();
TableCell controlCell = new TableCell();
// Add label
Label oLabel = new Label();
oLabel.Text = labelText;
oLabel.CssClass = base.LabelCssClass;
labelCell.Controls.Add(oLabel);
DropDownList ddl = new DropDownList();
ddl.ID = controlID;
//ddl.CssClass = base.???cssclass
ddl.Width = width;
ListItem BuiltInSynchronizationAccount = new ListItem("Built-in Synchronization Account", WellKnownGuids.BuiltInSynchronizationAccount.ToString());
ListItem FIMServiceAccount = new ListItem("FIMServiceAccount", WellKnownGuids.FIMServiceAccount.ToString());
ListItem Anonymous = new ListItem("Anonymous", WellKnownGuids.Anonymous.ToString());
ddl.Items.Add(BuiltInSynchronizationAccount);
ddl.Items.Add(FIMServiceAccount);
ddl.Items.Add(Anonymous);
ddl.SelectedValue = defaultValue;
controlCell.Controls.Add(ddl);
row.Cells.Add(labelCell);
row.Cells.Add(controlCell);
return row;
}
protected string GetActorDropDownList(string dropDownListID)
{
string g = WellKnownGuids.FIMServiceAccount.ToString();
DropDownList ddl = (DropDownList)this.FindControl(dropDownListID);
if (ddl != null)
{
if (!string.IsNullOrEmpty(ddl.SelectedValue))
g = ddl.SelectedValue.ToString();
}
else
Debugging.Log("Cannot find control with ID '" + dropDownListID + "'");
return g;
}
protected void SetActorDropDownList(string dropDownListID, object Guid)
{
DropDownList ddl = (DropDownList)this.FindControl(dropDownListID);
if (ddl != null)
{
if (Guid != null)
ddl.SelectedValue = Guid.ToString();
}
else
Debugging.Log("Cannot find control with ID '" + dropDownListID + "'");
}
#endregion
protected TableRow AddCheckbox(String labelText, String controlID, bool defaultValue)
{
TableRow row = new TableRow();
TableCell labelCell = new TableCell();
TableCell controlCell = new TableCell();
// Add label
Label oLabel = new Label();
oLabel.Text = labelText;
oLabel.CssClass = base.LabelCssClass;
labelCell.Controls.Add(oLabel);
CheckBox cb = new CheckBox();
cb.ID = controlID;
cb.Checked = defaultValue;
controlCell.Controls.Add(cb);
row.Cells.Add(labelCell);
row.Cells.Add(controlCell);
return row;
}
protected bool GetCheckbox(string checkBoxID)
{
CheckBox checkBox = (CheckBox)this.FindControl(checkBoxID);
if (checkBox != null)
return checkBox.Checked;
else
return false;
}
protected void SetCheckbox(string checkBoxID, bool isChecked)
{
CheckBox checkBox = (CheckBox)this.FindControl(checkBoxID);
if (checkBox != null)
{
checkBox.Checked = isChecked;
}
}
protected string GetText(string textBoxID)
{
TextBox textBox = (TextBox)this.FindControl(textBoxID);
return textBox.Text ?? String.Empty;
}
protected void SetText(string textBoxID, string text)
{
TextBox textBox = (TextBox)this.FindControl(textBoxID);
if (textBox != null)
textBox.Text = text;
else
textBox.Text = "";
}
protected string[] GetTextArray(string textBoxId)
{
TextBox textBox = (TextBox)this.FindControl(textBoxId);
string[] words = textBox.Text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
return words ?? null;
}
protected void SetTextArray(string textBoxID, string[] text)
{
TextBox textBox = (TextBox)this.FindControl(textBoxID);
StringBuilder myBuilder = new StringBuilder();
foreach (string s in text)
{
if (!String.IsNullOrEmpty(s))
myBuilder.AppendLine(s);
}
string toInsert = myBuilder.ToString().TrimEnd('\r', '\n');
textBox.Text = toInsert;
}
//Set the text box to read mode or read/write mode
protected void SetCheckboxReadOnlyOption(string CheckBoxID, bool readOnly)
{
CheckBox checkBox = (CheckBox)this.FindControl(CheckBoxID);
checkBox.Enabled = !readOnly;
}
//Set the check box to read mode or read/write mode
protected void SetTextBoxReadOnlyOption(string textBoxID, bool readOnly)
{
TextBox textBox = (TextBox)this.FindControl(textBoxID);
textBox.Enabled = !readOnly;
}
protected void SetDropDownListDisabled(string dropDownListID, bool disabled)
{
DropDownList ddl = (DropDownList)this.FindControl(dropDownListID);
if (ddl != null)
{
ddl.Enabled = !disabled;
}
else
Debugging.Log("Cannot find control with ID '" + dropDownListID + "'");
}
#endregion
/// <summary>
/// Called when a user clicks the Save button in the Workflow Designer.
/// Returns an instance of the RequestLoggingActivity class that
/// has its properties set to the values entered into the text box controls
/// used in the UI of the activity.
/// </summary>
public override Activity GenerateActivityOnWorkflow(SequentialWorkflow workflow)
{
throw new NotImplementedException();
}
/// <summary>
/// Called by FIM when the UI for the activity must be reloaded.
/// It passes us an instance of our workflow activity so that we can
/// extract the values of the properties to display in the UI.
/// </summary>
public override void LoadActivitySettings(Activity activity)
{
throw new NotImplementedException();
}
/// <summary>
/// Saves the activity settings.
/// </summary>
public override ActivitySettingsPartData PersistSettings()
{
throw new NotImplementedException();
}
/// <summary>
/// Restores the activity settings in the UI
/// </summary>
public override void RestoreSettings(ActivitySettingsPartData data)
{
throw new NotImplementedException();
}
/// <summary>
/// Switches the activity between read only and read/write mode
/// </summary>
public override void SwitchMode(ActivitySettingsPartMode mode)
{
throw new NotImplementedException();
}
/// <summary>
/// Returns the activity name.
/// </summary>
public override string Title
{
get { throw new NotImplementedException(); }
}
/// <summary>
/// In general, this method should be used to validate information entered
/// by the user when the activity is added to a workflow in the Workflow
/// Designer.
/// We could add code to verify that the log file path already exists on
/// the server that is hosting the FIM Portal and check that the activity
/// has permission to write to that location. However, the code
/// would only check if the log file path exists when the
/// activity is added to a workflow in the workflow designer. This class
/// will not be used when the activity is actually run.
/// For this activity we will just return true.
/// </summary>
public override bool ValidateInputs()
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
namespace Granfeldt.FIM.ActivityLibrary
{
public class AttributeValue
{
//Constructors
/// <summary>
/// Creates a new instance of the object type AttributeValue.
/// </summary>
public AttributeValue()
{
this.IsResolved = false;
}
/// <summary>
/// Creates a new instance of the object type AttributeValue, and sets source and target attribute name.
/// </summary>
/// <param name="sourceAttributeName">Name of the source attribute.</param>
/// <param name="targetAttributeName">Name of the target attribute.</param>
public AttributeValue(string sourceAttributeName, string targetAttributeName)
{
this.SourceAttributeName = sourceAttributeName;
this.TargetAttributeName = targetAttributeName;
this.IsResolved = false;
}
//Fields
private object _sourceAttributeValue;
//Properties
public string SourceAttributeName { get; set; }
public object SourceAttributeValue
{
get
{
return this._sourceAttributeValue;
}
set
{
this._sourceAttributeValue = value;
this.IsResolved = true;
}
}
public string TargetAttributeName { get; set; }
public object TargetAttributeValue { get; set; }
public bool IsDelete { get; private set; }
/// <summary>
/// Indicates if the SourceAttributeName have been resolved.
/// This is set when SourceAttributeValue is set.
/// </summary>
public bool IsResolved { get; private set; }
/// <summary>
/// Tells if the SourceAttributeValue should be resolved from SourceAttributeName.
/// It is decided by testing if the SourceAttributeName contains a resolveable string.
/// </summary>
public bool ShouldResolve
{
get
{
if (this.IsResolved)
{
return false;
}
else
{
if (this.SourceAttributeName != null)
return this.SourceAttributeName.Trim().Contains("[//");
else
return false;
}
}
}
#region Methods
/// <summary>
/// Returns this AttributeValue as an UpdateRequestParameter used for updating resources in FIM.
/// </summary>
/// <param name="objectId">ObjectID of the resource being updated.</param>
/// <param name="isDelete">Tells the method what type of update to return.
/// If isDelete is true a UpdateMode is set to: Remove.
/// </param>
/// <returns></returns>
public UpdateRequestParameter ToUpdateRequestParameter(Guid objectId,bool isDelete)
{
if (!isDelete)
return new UpdateRequestParameter(objectId, this.TargetAttributeName, UpdateMode.Modify, FIMAttributeUtilities.FormatValue(this.SourceAttributeValue), false);
else
{
return new UpdateRequestParameter(objectId, this.TargetAttributeName, UpdateMode.Remove, this.TargetAttributeValue, false);
}
}
/// <summary>
/// Returns this AttributeValue as an UpdateRequestParameter used for updating resources in FIM, without specifying which object to update.
/// </summary>
/// <param name="isDelete">Tells the method what type of update to return.
/// If isDelete is true a UpdateMode is set to: Remove.</param>
/// <returns></returns>
public UpdateRequestParameter ToUpdateRequestParameter(bool isDelete)
{
if (!isDelete)
return new UpdateRequestParameter(this.TargetAttributeName, UpdateMode.Modify, FIMAttributeUtilities.FormatValue(this.SourceAttributeValue), false);
else
{
return new UpdateRequestParameter(this.TargetAttributeName, UpdateMode.Remove, this.TargetAttributeValue, false);
}
}
/// <summary>
/// Compares the source value with the supplied readValue parameter.
/// Also sets IsDelete to true or false
/// </summary>
/// <param name="readValue">A value to compare with the SourceValue.</param>
/// <returns></returns>
public virtual bool ShouldUpdate(object readValue)
{
// we need the original (non-converted) value if we are doing a removal as we must specify the original value (even a local date/time)
// object originalTargetValue = this.TargetAttributeValue;
object target = FIMAttributeUtilities.FormatValue(readValue);
object source = FIMAttributeUtilities.FormatValue(this.SourceAttributeValue);
return getShouldUpdate(target, source);
}
/// <summary>
/// Compares the Target attribute value with the existing source attribute value. If the source attribute value is not set,
/// it will be compared on as a null value.
/// </summary>
/// <returns>Result of compare</returns>
public virtual bool ShouldUpdate()
{
object target = FIMAttributeUtilities.FormatValue(this.TargetAttributeValue);
object source = FIMAttributeUtilities.FormatValue(this.SourceAttributeValue);
Debugging.Log(String.Format("Comparing source: {0} and target: {1}, containing the values: {2} / {3}", this.SourceAttributeName, this.TargetAttributeName, this.SourceAttributeValue, this.TargetAttributeValue));
bool result = getShouldUpdate(target, source);
Debugging.Log(String.Format("Comparison resulted in: {0}",result));
return result;
}
/// <summary>
/// Private method for comparing Source and Target attributes
/// </summary>
/// <param name="target">Taget value</param>
/// <param name="source">Source value</param>
/// <returns>Whether or not the target attribute should be updated.</returns>
private bool getShouldUpdate(object target, object source)
{
if (FIMAttributeUtilities.ValuesAreDifferent(source, target))
{
if (source == null)
{
// we are in a delete state
Debugging.Log(string.Format("Deleting value '{1}' from {0}", this.TargetAttributeName, target == null ? "(null)" : target));
this.IsDelete = true;
}
else
{
// we are in an update state
Debugging.Log(string.Format("Updating {0} from '{1}' to '{2}'", this.TargetAttributeName, target == null ? "(null)" : target, source));
this.IsDelete = false;
}
return true;
}
else
{
Debugging.Log(string.Format("No need to update {0}. Value is already {1}", this.TargetAttributeName, this.TargetAttributeValue == null ? "(null)" : this.TargetAttributeValue));
this.IsDelete = false;
return false;
}
}
/// <summary>
/// Sets the TargetAttributeValue on this AttributeValue based on the it's current TargetAttributeName.
/// </summary>
/// <param name="resource">the ResourceType object to pull the attribute value from.</param>
internal virtual void SetValues(ResourceType resource)
{
TargetAttributeValue = resource[this.TargetAttributeName] != null ? resource[this.TargetAttributeName] : null;
Debugging.Log(this.TargetAttributeName, this.TargetAttributeValue);
}
#endregion
}
}

View File

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
namespace Granfeldt.FIM.ActivityLibrary
{
public class AttributeValueCollection : ICollection<AttributeValue>
{
//Constructors
/// <summary>
/// Creates a new instance of AttributeValueCollection.
/// </summary>
public AttributeValueCollection()
{
this._attributeValues = new List<AttributeValue>();
}
/// <summary>
/// Creates a new instance of AttributeValueCollection that takes the ObjectID of the target resource.
/// </summary>
/// <param name="targetObjectID">ObjectID of the target resource</param>
public AttributeValueCollection(Guid targetObjectID)
{
this.TargetObjectID = targetObjectID;
this._attributeValues = new List<AttributeValue>();
}
//Fields
/// <summary>
/// List of all the AttributeValue objects in the collection.
/// </summary>
private List<AttributeValue> _attributeValues;
/// <summary>
/// Target resource that needs to be updates.
/// </summary>
private ResourceType _targetResource;
//Properties
public Guid TargetObjectID { get; set; }
public ResourceType TargetResource
{
get { return _targetResource; }
set
{
_targetResource = value;
PopulateAttributeValues();
}
}
/// <summary>
/// Gets all the AttributeValues in the collection, which contains differences between the source and the target value
/// </summary>
/// <returns>All changes in the collection to send to target.</returns>
public List<UpdateRequestParameter> Changes
{
get
{
List<UpdateRequestParameter> changes = new List<UpdateRequestParameter>();
foreach (AttributeValue a in _attributeValues)
{
Debugging.Log(a.TargetAttributeName, a.TargetAttributeValue);
if (a.ShouldUpdate())
{
changes.Add(a.ToUpdateRequestParameter(this.TargetObjectID, a.IsDelete));
}
}
return changes;
}
}
#region Methods
/// <summary>
/// Sets attribute values on all AttributeValue objects in the collection.
/// </summary>
private void PopulateAttributeValues()
{
foreach (AttributeValue val in _attributeValues)
{
val.SetValues(_targetResource);
}
}
#region ICollection implementation
public void Add(AttributeValue item)
{
this._attributeValues.Add(item);
}
public void Clear()
{
this._attributeValues.Clear();
}
public bool Contains(AttributeValue item)
{
return this._attributeValues.Contains(item);
}
public void CopyTo(AttributeValue[] array, int arrayIndex)
{
this._attributeValues.CopyTo(array, arrayIndex);
}
public int Count
{
get { return this._attributeValues.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(AttributeValue item)
{
return this._attributeValues.Remove(item);
}
public IEnumerator<AttributeValue> GetEnumerator()
{
return this._attributeValues.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
#endregion
}
}

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
namespace Granfeldt.FIM.ActivityLibrary
{
public class ConditionalAttributeValue : AttributeValue
{
//Constructors
public ConditionalAttributeValue(string conditionAttributeName)
{
this.ConditionAttributeName = conditionAttributeName;
}
public ConditionalAttributeValue(string sourceAttributeName, string targetAttributeName, string conditionAttributeName)
{
this.ConditionAttributeName = conditionAttributeName;
this.SourceAttributeName = sourceAttributeName;
this.TargetAttributeName = targetAttributeName;
}
public ConditionalAttributeValue(string sourceAttributeName, string targetAttributeName, string conditionAttributeName, bool updateOnConditionTrue)
{
this.ConditionAttributeName = conditionAttributeName;
this.UpdateOnTrue = updateOnConditionTrue;
this.SourceAttributeName = sourceAttributeName;
this.TargetAttributeName = targetAttributeName;
}
//Properties
public string ConditionAttributeName { get; set; }
public bool ConditionAttributeValue { get; private set; }
public bool UpdateOnTrue { get; set; }
/// <summary>
/// Compares the Target attribute value with the existing source attribute value. If the source attribute value is not set,
/// it will be compared on as a null value.
/// </summary>
/// <returns>Result of the comparison.</returns>
public override bool ShouldUpdate()
{
if (conditionsSatisfied())
{
return base.ShouldUpdate();
}
else
{
Debugging.Log(String.Format("Conditions not met. Because {0} has the value: {1}.",this.ConditionAttributeName,this.ConditionAttributeValue));
return false;
}
}
/// <summary>
/// Sets Source and Target values as well as conditional values.
/// </summary>
/// <param name="resource">resource object of the target to be updated.</param>
internal override void SetValues(ResourceType resource)
{
base.SetValues(resource);
this.SetConditionValue(resource);
}
/// <summary>
/// Private methods that determines if the conditions are met to allow the target to be updated.
/// </summary>
/// <returns>If conditions are met, it will return true, otherwise false.</returns>
private bool conditionsSatisfied()
{
if (UpdateOnTrue)
{
if (ConditionAttributeValue)
{
//True and True is True
return true;
}
else
{
return false;
}
}
else
{
if (!ConditionAttributeValue)
{
//False and False is true
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// Sets the ConditionAttributeValue, based on ConditionAttributeName and <paramref name="resource"/>.
/// </summary>
/// <param name="resource"></param>
private void SetConditionValue(ResourceType resource)
{
this.ConditionAttributeValue = resource[this.ConditionAttributeName] != null ? (bool)resource[this.ConditionAttributeName] : false;
Debugging.Log(String.Format("Condition set to: {0}", this.ConditionAttributeValue));
}
}
}

View File

@ -0,0 +1,164 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Threading;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Granfeldt.FIM.ActivityLibrary
{
public class WellKnownGuids
{
public static Guid BuiltInSynchronizationAccount = new Guid("fb89aefa-5ea1-47f1-8890-abe7797d6497");
public static Guid FIMServiceAccount = new Guid("e05d1f1b-3d5e-4014-baa6-94dee7d68c89");
public static Guid Anonymous = new Guid("b0b36673-d43b-4cfa-a7a2-aff14fd90522");
}
public static class Debugging
{
private static string DebugLogFilename = null;
private static Mutex loggingMutex = new Mutex();
static Debugging()
{
try
{
DebugLogFilename = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Granfeldt\FIM\Workflows", false).GetValue("DebugLogFilename", null).ToString();
DebugLogFilename = string.Format(DebugLogFilename, DateTime.Now);
}
catch
{
// we get here if key og hive doesn't exist
}
}
public static void Log(string s)
{
string message = string.Format("{0}: {1}", DateTime.Now, string.IsNullOrEmpty(s) ? "(null)" : s);
loggingMutex.WaitOne();
if (!string.IsNullOrEmpty(DebugLogFilename))
{
using (StreamWriter f = new StreamWriter(DebugLogFilename, true))
{
f.WriteLine(message);
}
}
loggingMutex.ReleaseMutex();
System.Diagnostics.Trace.WriteLine(string.Format("{0}: {1} - {2}", DateTime.Now, s, TraceRoutine("")));
}
public static void Log(string name, object value)
{
Log(string.Format("{0}: {1}", name, value != null ? value.ToString() : "(null)"));
}
public static void Log(Exception ex)
{
Log(string.Format("Error: {0}", ex.Message));
throw ex;
}
public static string TraceRoutine(string action)
{
StackTrace CallStack = new StackTrace();
int i = 0;
string StrOut = null;
for (i = CallStack.FrameCount - 1; i >= 1; i += -1)
{
if (StrOut != null)
{
StrOut += "->";
}
StrOut += CallStack.GetFrame(i).GetMethod().Name;
}
CallStack = null;
return string.Format("{0}: {1}", action, StrOut);
}
}
public static class FIMAttributeUtilities
{
/// <summary>
/// Returns a formatted value ready for committing to create/update resource built-in activity
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static object FormatValue(object value)
{
if (value == null)
return null;
if (value.GetType() == typeof(bool))
return value;
// if the source value is a date, we need to format the date for the update to take the value
DateTime outputDate;
if (DateTime.TryParse(value.ToString(), out outputDate))
{
value = outputDate.ToString("yyyy-MM-ddTHH:mm:ss.000");
return value;
}
// if it's a reference value, we need to remove leading urn:uuid text before later comparison
value = Regex.Replace(value.ToString(), "^urn:uuid:", "", RegexOptions.IgnoreCase);
return value;
}
/// <summary>
/// Returns true if the two values are different (FIM evaluation)
/// </summary>
/// <param name="sourceValue"></param>
/// <param name="targetValue"></param>
/// <returns></returns>
public static bool ValuesAreDifferent(object sourceValue, object targetValue)
{
if (targetValue == null || sourceValue == null)
{
if (targetValue != null || sourceValue != null)
{
return true;
}
else
{
return false;
}
}
else
{
if (!targetValue.ToString().Equals(sourceValue.ToString(), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else
{
return false;
}
}
}
}
public class StringUtilities
{
/// <summary>
/// Parses and splits the expression passed
/// </summary>
/// <param name="Expression">Expression to parse, i.e. [//Target/DisplayName] or [//WorkflowData/Password]</param>
/// <param name="Destination">Will hold the destination object type after parsing</param>
/// <param name="DestinationAttribute">Will hold the destination attribute after parsing</param>
/// <returns></returns>
public static void ExtractWorkflowExpression(string Expression, out string Destination, out string DestinationAttribute)
{
Regex regex = new Regex(@"^\[//(?<destination>\w+)/+?(?<destinationattribute>\w*[^]])", RegexOptions.IgnoreCase);
Destination = regex.Match(Expression).Result("${destination}");
DestinationAttribute = regex.Match(Expression).Result("${destinationattribute}");
}
}
}

View File

@ -0,0 +1,87 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
namespace Granfeldt.FIM.ActivityLibrary
{
public partial class FindResourcesActivity
{
#region Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
[System.Diagnostics.DebuggerNonUserCode]
private void InitializeComponent()
{
this.CanModifyActivities = true;
System.Workflow.ComponentModel.ActivityBind activitybind1 = new System.Workflow.ComponentModel.ActivityBind();
System.Workflow.ComponentModel.ActivityBind activitybind2 = new System.Workflow.ComponentModel.ActivityBind();
System.Workflow.ComponentModel.ActivityBind activitybind3 = new System.Workflow.ComponentModel.ActivityBind();
System.Workflow.ComponentModel.ActivityBind activitybind4 = new System.Workflow.ComponentModel.ActivityBind();
System.Workflow.ComponentModel.ActivityBind activitybind5 = new System.Workflow.ComponentModel.ActivityBind();
System.Workflow.ComponentModel.ActivityBind activitybind6 = new System.Workflow.ComponentModel.ActivityBind();
this.ReadEnumeratedResource = new System.Workflow.Activities.CodeActivity();
this.GenerateResourceIds = new System.Workflow.Activities.CodeActivity();
this.Enumerate = new Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity();
//
// readEnumeratedResource
//
this.ReadEnumeratedResource.Name = "ReadEnumeratedResource";
this.ReadEnumeratedResource.ExecuteCode += new System.EventHandler(this.ReadEnumeratedResource_ExecuteCode);
//
// GenerateResourceIds
//
this.GenerateResourceIds.Name = "GenerateResourceIds";
this.GenerateResourceIds.ExecuteCode += new System.EventHandler(this.GenerateResourceIds_ExecuteCode);
//
// Enumerate
//
this.Enumerate.Activities.Add(this.ReadEnumeratedResource);
activitybind1.Name = "FindResourcesActivity";
activitybind1.Path = "ActorId";
this.Enumerate.Name = "Enumerate";
activitybind2.Name = "FindResourcesActivity";
activitybind2.Path = "PageSize";
activitybind3.Name = "FindResourcesActivity";
activitybind3.Path = "Attributes";
activitybind4.Name = "FindResourcesActivity";
activitybind4.Path = "SortingAttributes";
activitybind5.Name = "FindResourcesActivity";
activitybind5.Path = "TotalResultsCount";
activitybind6.Name = "FindResourcesActivity";
activitybind6.Path = "XPathFilter";
this.Enumerate.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity.ActorIdProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind1)));
this.Enumerate.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity.PageSizeProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind2)));
this.Enumerate.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity.SelectionProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind3)));
this.Enumerate.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity.SortingAttributesProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind4)));
this.Enumerate.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity.TotalResultsCountProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind5)));
this.Enumerate.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity.XPathFilterProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind6)));
//
// FindResourcesActivity
//
this.Activities.Add(this.Enumerate);
this.Activities.Add(this.GenerateResourceIds);
this.Name = "FindResourcesActivity";
this.CanModifyActivities = false;
}
#endregion
private CodeActivity GenerateResourceIds;
private CodeActivity ReadEnumeratedResource;
private Microsoft.ResourceManagement.Workflow.Activities.EnumerateResourcesActivity Enumerate;
}
}

View File

@ -0,0 +1,192 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Workflow.Activities;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
using Microsoft.ResourceManagement.Workflow.Activities;
namespace Granfeldt.FIM.ActivityLibrary
{
[Designer(typeof(ActivityDesigner), typeof(IDesigner))]
public partial class FindResourcesActivity : SequenceActivity
{
public FindResourcesActivity()
{
EnumeratedResources = new List<ResourceType>();
InitializeComponent();
}
#region Public Fields
public static DependencyProperty EnumeratedResourcesProperty = DependencyProperty.Register("EnumeratedResources", typeof(List<ResourceType>), typeof(FindResourcesActivity));
public static DependencyProperty EnumeratedResourceIDsProperty = DependencyProperty.Register("EnumeratedResourceIDs", typeof(Guid[]), typeof(FindResourcesActivity));
public static DependencyProperty ActorIdProperty = DependencyProperty.Register("ActorId", typeof(System.Guid), typeof(FindResourcesActivity));
public static DependencyProperty PageSizeProperty = DependencyProperty.Register("PageSize", typeof(System.Int32), typeof(FindResourcesActivity));
public static DependencyProperty AttributesProperty = DependencyProperty.Register("Attributes", typeof(System.String[]), typeof(FindResourcesActivity));
public static DependencyProperty SortingAttributesProperty = DependencyProperty.Register("SortingAttributes", typeof(Microsoft.ResourceManagement.WebServices.WSEnumeration.SortingAttribute[]), typeof(FindResourcesActivity));
public static DependencyProperty TotalResultsCountProperty = DependencyProperty.Register("TotalResultsCount", typeof(System.Int32), typeof(FindResourcesActivity));
public static DependencyProperty XPathFilterProperty = DependencyProperty.Register("XPathFilter", typeof(System.String), typeof(FindResourcesActivity));
#endregion
#region Public Properties
[Description("EnumeratedResource")]
[Category("Result")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public List<ResourceType> EnumeratedResources
{
get { return (List<ResourceType>)base.GetValue(FindResourcesActivity.EnumeratedResourcesProperty); }
set { base.SetValue(FindResourcesActivity.EnumeratedResourcesProperty, value); }
}
[DescriptionAttribute("EnumeratedResourceIDs")]
[CategoryAttribute("Result")]
[BrowsableAttribute(true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public Guid[] EnumeratedResourceIDs
{
get
{
return ((Guid[])(base.GetValue(FindResourcesActivity.EnumeratedResourceIDsProperty)));
}
set
{
base.SetValue(FindResourcesActivity.EnumeratedResourceIDsProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Input")]
public Guid ActorId
{
get
{
return ((System.Guid)(base.GetValue(FindResourcesActivity.ActorIdProperty)));
}
set
{
base.SetValue(FindResourcesActivity.ActorIdProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Input")]
public Int32 PageSize
{
get
{
return ((int)(base.GetValue(FindResourcesActivity.PageSizeProperty)));
}
set
{
base.SetValue(FindResourcesActivity.PageSizeProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Input")]
public String[] Attributes
{
get
{
return ((string[])(base.GetValue(FindResourcesActivity.AttributesProperty)));
}
set
{
base.SetValue(FindResourcesActivity.AttributesProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Input")]
public Microsoft.ResourceManagement.WebServices.WSEnumeration.SortingAttribute[] SortingAttributes
{
get
{
return ((Microsoft.ResourceManagement.WebServices.WSEnumeration.SortingAttribute[])(base.GetValue(FindResourcesActivity.SortingAttributesProperty)));
}
set
{
base.SetValue(FindResourcesActivity.SortingAttributesProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Misc")]
public Int32 TotalResultsCount
{
get
{
return ((int)(base.GetValue(FindResourcesActivity.TotalResultsCountProperty)));
}
set
{
base.SetValue(FindResourcesActivity.TotalResultsCountProperty, value);
}
}
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Input")]
public String XPathFilter
{
get
{
return ((string)(base.GetValue(FindResourcesActivity.XPathFilterProperty)));
}
set
{
base.SetValue(FindResourcesActivity.XPathFilterProperty, value);
}
}
#endregion
#region Code
/// <summary>
/// This function is called by the enumerateactivity for each result returned.
/// We'll put each result into the EnumeratedResources list for later processing
/// and passing on to other activities
/// </summary>
private void ReadEnumeratedResource_ExecuteCode(object sender, EventArgs e)
{
// If the EnumeratedGuids list is not instantiated do so now
if (this.EnumeratedResources == null) this.EnumeratedResources = new List<ResourceType>();
// Instantiate the result and verify that it is not null
ResourceType result = EnumerateResourcesActivity.GetCurrentIterationItem((CodeActivity)sender) as ResourceType;
if (result != null)
{
EnumeratedResources.Add(result);
}
}
/// <summary>
/// This function populates the list of objectID's that maybe
/// passed on to other activities
/// </summary>
private void GenerateResourceIds_ExecuteCode(object sender, EventArgs e)
{
List<Guid> resourceGuids = new List<Guid>(this.EnumeratedResources.Count);
foreach (ResourceType resource in this.EnumeratedResources)
{
resourceGuids.Add(resource.ObjectID.GetGuid());
}
this.EnumeratedResourceIDs = resourceGuids.ToArray();
}
#endregion
}
}

View File

@ -0,0 +1,114 @@
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Reflection;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
namespace Granfeldt.FIM.ActivityLibrary
{
public partial class UpdateSingleValueAttributeAsNeededActivity
{
#region Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
[System.Diagnostics.DebuggerNonUserCode]
[System.CodeDom.Compiler.GeneratedCode("", "")]
private void InitializeComponent()
{
this.CanModifyActivities = true;
System.Workflow.Activities.CodeCondition codecondition1 = new System.Workflow.Activities.CodeCondition();
System.Workflow.ComponentModel.ActivityBind activitybind1 = new System.Workflow.ComponentModel.ActivityBind();
System.Workflow.ComponentModel.ActivityBind activitybind2 = new System.Workflow.ComponentModel.ActivityBind();
this.UpdateResource = new Microsoft.ResourceManagement.Workflow.Activities.UpdateResourceActivity();
this.NoBranch = new System.Workflow.Activities.IfElseBranchActivity();
this.YesBranch = new System.Workflow.Activities.IfElseBranchActivity();
this.IsUpdateNeeded = new System.Workflow.Activities.IfElseActivity();
this.ReadResource = new Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity();
this.SetupReadTarget = new System.Workflow.Activities.CodeActivity();
//
// UpdateResource
//
this.UpdateResource.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000");
this.UpdateResource.ApplyAuthorizationPolicy = false;
this.UpdateResource.Name = "UpdateResource";
this.UpdateResource.ResourceId = new System.Guid("00000000-0000-0000-0000-000000000000");
this.UpdateResource.UpdateParameters = null;
//
// NoBranch
//
this.NoBranch.Name = "NoBranch";
//
// YesBranch
//
this.YesBranch.Activities.Add(this.UpdateResource);
codecondition1.Condition += new System.EventHandler<System.Workflow.Activities.ConditionalEventArgs>(this.TargetUpdateNeeded_Condition);
this.YesBranch.Condition = codecondition1;
this.YesBranch.Name = "YesBranch";
//
// IsUpdateNeeded
//
this.IsUpdateNeeded.Activities.Add(this.YesBranch);
this.IsUpdateNeeded.Activities.Add(this.NoBranch);
this.IsUpdateNeeded.Name = "IsUpdateNeeded";
//
// ReadResource
//
this.ReadResource.ActorId = new System.Guid("00000000-0000-0000-0000-000000000000");
this.ReadResource.Description = "Reads the current target";
this.ReadResource.Name = "ReadResource";
activitybind1.Name = "UpdateSingleValueAttributeAsNeededActivity";
activitybind1.Path = "TargetResource";
activitybind2.Name = "UpdateSingleValueAttributeAsNeededActivity";
activitybind2.Path = "TargetId";
this.ReadResource.SelectionAttributes = null;
this.ReadResource.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity.ResourceProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind1)));
this.ReadResource.SetBinding(Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity.ResourceIdProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind2)));
//
// SetupReadTarget
//
this.SetupReadTarget.Name = "SetupReadTarget";
this.SetupReadTarget.ExecuteCode += new System.EventHandler(this.SetupReadTarget_ExecuteCode);
//
// UpdateSingleValueAttributeAsNeededActivity
//
this.Activities.Add(this.SetupReadTarget);
this.Activities.Add(this.ReadResource);
this.Activities.Add(this.IsUpdateNeeded);
this.Name = "UpdateSingleValueAttributeAsNeededActivity";
this.CanModifyActivities = false;
}
#endregion
private CodeActivity SetupReadTarget;
private IfElseBranchActivity NoBranch;
private IfElseBranchActivity YesBranch;
private IfElseActivity IsUpdateNeeded;
private Microsoft.ResourceManagement.Workflow.Activities.UpdateResourceActivity UpdateResource;
private Microsoft.ResourceManagement.Workflow.Activities.ReadResourceActivity ReadResource;
}
}

View File

@ -0,0 +1,166 @@
// January 17, 2013 | Soren Granfeldt
// - initial version
// January 22, 2013 | Soren Granfeldt
// - added additional code to handle comparison of date, booleans and reference types
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Linq;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.Runtime;
using Microsoft.ResourceManagement.WebServices.WSResourceManagement;
using Microsoft.ResourceManagement.Workflow.Activities;
using System.Text.RegularExpressions;
namespace Granfeldt.FIM.ActivityLibrary
{
public partial class UpdateSingleValueAttributeAsNeededActivity : SequenceActivity
{
#region Properties
public static DependencyProperty NewValueProperty = DependencyProperty.Register("NewValue", typeof(object), typeof(UpdateSingleValueAttributeAsNeededActivity));
[Description("New value to write (or null for delete)")]
[Category("NewValue Category")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public object NewValue
{
get
{
return ((object)(base.GetValue(UpdateSingleValueAttributeAsNeededActivity.NewValueProperty)));
}
set
{
base.SetValue(UpdateSingleValueAttributeAsNeededActivity.NewValueProperty, value);
}
}
public static DependencyProperty AttributeNameProperty = DependencyProperty.Register("AttributeName", typeof(string), typeof(UpdateSingleValueAttributeAsNeededActivity));
[Description("Name of attribute to update")]
[Category("AttributeName Category")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string AttributeName
{
get
{
return ((string)(base.GetValue(UpdateSingleValueAttributeAsNeededActivity.AttributeNameProperty)));
}
set
{
base.SetValue(UpdateSingleValueAttributeAsNeededActivity.AttributeNameProperty, value);
}
}
public static DependencyProperty TargetIdProperty = DependencyProperty.Register("TargetId", typeof(System.Guid), typeof(Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity));
[Description("The ID of the object to update")]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Parameters")]
public Guid TargetId
{
get
{
return ((System.Guid)(base.GetValue(Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity.TargetIdProperty)));
}
set
{
base.SetValue(Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity.TargetIdProperty, value);
}
}
public static DependencyProperty TargetResourceProperty = DependencyProperty.Register("TargetResource", typeof(Microsoft.ResourceManagement.WebServices.WSResourceManagement.ResourceType), typeof(Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity));
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[BrowsableAttribute(true)]
[CategoryAttribute("Parameters")]
public ResourceType TargetResource
{
get
{
return ((Microsoft.ResourceManagement.WebServices.WSResourceManagement.ResourceType)(base.GetValue(Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity.TargetResourceProperty)));
}
set
{
base.SetValue(Granfeldt.FIM.ActivityLibrary.UpdateSingleValueAttributeAsNeededActivity.TargetResourceProperty, value);
}
}
public static DependencyProperty ActorIdProperty = DependencyProperty.Register("ActorId", typeof(System.Guid), typeof(UpdateSingleValueAttributeAsNeededActivity));
[Description("ID of the actor updating the target object")]
[Category("ActorId Category")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public System.Guid ActorId
{
get
{
return ((System.Guid)(base.GetValue(UpdateSingleValueAttributeAsNeededActivity.ActorIdProperty)));
}
set
{
base.SetValue(UpdateSingleValueAttributeAsNeededActivity.ActorIdProperty, value);
}
}
#endregion
public UpdateSingleValueAttributeAsNeededActivity()
{
InitializeComponent();
}
private void TargetUpdateNeeded_Condition(object sender, ConditionalEventArgs e)
{
List<UpdateRequestParameter> updateParameters = new List<UpdateRequestParameter>();
e.Result = false;
object CurrentValue = TargetResource[this.AttributeName];
object convertedSourceValue = FIMAttributeUtilities.FormatValue(CurrentValue);
object convertedNewValue = FIMAttributeUtilities.FormatValue(this.NewValue);
if (FIMAttributeUtilities.ValuesAreDifferent(convertedSourceValue, convertedNewValue))
{
e.Result = true;
// if the new value is null then remove current value.
// otherwise, update attribute to new value
updateParameters.Add(new UpdateRequestParameter(this.AttributeName, this.NewValue == null ? UpdateMode.Remove : UpdateMode.Modify, this.NewValue == null ? CurrentValue : convertedNewValue));
UpdateResource.ActorId = this.ActorId;
UpdateResource.ResourceId = this.TargetId;
UpdateResource.UpdateParameters = updateParameters.ToArray();
if (this.NewValue == null)
{
Debugging.Log(string.Format("Removing existing value '{0}' from {1}", CurrentValue, this.AttributeName));
}
else
{
Debugging.Log(string.Format("Updating {0} from '{1}' to '{2}'", this.AttributeName, CurrentValue == null ? "(null)" : CurrentValue, this.NewValue == null ? "(null)" : this.NewValue));
}
}
else
{
Debugging.Log(string.Format("No need to update {0}. Value is already '{1}'", this.AttributeName, convertedNewValue));
}
}
private void SetupReadTarget_ExecuteCode(object sender, EventArgs e)
{
ReadResource.ActorId = this.ActorId;
ReadResource.ResourceId = this.TargetId;
ReadResource.SelectionAttributes = new string[] { this.AttributeName };
}
}
}