示例#1
0
		ActionData CreateTwoLevelTreeXOfY(int countFirstLevel, int countSecondLevel)
        {
            ActionData source = new ActionData();
            source.Tag = "firstfloor";
            for (int i = 0; i < countFirstLevel; i++)
            {
                ActionData children = new ActionData();
                children.Tag = i.ToString();
                //StreamWriter sw = new StreamWriter(children.Content);
                //sw.WriteLine("Hello Dave");
                //sw.Flush();
				children.DisplayName = "Hello Dave.txt";
				children.FileName = CreateFile("Hello Dave.txt");
                source.Nested.Add(children);
            }
            ActionData anotherLevel = new ActionData();
            anotherLevel.Tag = "2ndFloor";
            for (int i = 0; i < countSecondLevel; i++)
            {
                ActionData children = new ActionData();
                children.Tag = i.ToString();
				//StreamWriter sw = new StreamWriter(children.Content);
				//sw.WriteLine("Hello Dave");
				//sw.Flush();
				children.DisplayName = "Hello Dave.txt";
				children.FileName = CreateFile("Hello Dave.txt");
                anotherLevel.Nested.Add(children);
            }
            source.Nested.Add(anotherLevel);

            return source;
        }
示例#2
0
        /// <summary>
        /// Loads a node traversal path into a node. To create intricate trees, call
        /// multiple times with different paths(or the same even).
        /// The entries items are copied to the Tag field of the newly created nodes.
        /// </summary>
        /// <param name="root"></param>
        /// <param name="entries"></param>
        /// <param name="start"></param>
		void LoadIntoTree(ActionData root, object[] entries, int start)
        {
            for(int i = start; i < entries.Length; i++)
            {
                string s = entries[i].ToString();
                ActionData newItem = new ActionData();
                newItem.Tag = s;

                if (s.StartsWith("folder", StringComparison.InvariantCultureIgnoreCase))
                {
                    LoadIntoTree(newItem, entries, i + 1);
                    i = entries.Length;
                }
                else
                {
					newItem.DisplayName = "Hello Dave.txt";
					newItem.FileName = CreateFile("Hello Dave.txt");
                }
                root.Nested.Add(newItem);
                
            }
        }
示例#3
0
		/// <summary>
		/// This method searches for an Action corresponding to
		///     a) the required ResolvedAction <paramref name="resAction"/>
		///     b) the required ContentItem within <paramref name="item"/>
		/// 
		/// When given a flat list of ResolvedAction items, we need to find the corresponding action in the heirarchy beneath the 
		/// ContentItems, in order to use the properties that are specific to that Content.
		/// </summary>
		/// <param name="pro"> </param>
		/// <param name="item"></param>
		/// <param name="resAction"></param>
		/// <param name="folderAction"> </param>
		/// <returns></returns>
		private static PolicyResponseAction FindContentAction(PolicyResponseObject pro, ActionData item, ResolvedAction resAction, bool folderAction)
		{
			List<IContentItem> contents = new List<IContentItem>(resAction.ContentCollection);
			IContentItem content;
			if (!folderAction)
			{
				content = contents.Find(delegate(IContentItem temp)
				{
					return ((ContentItem) (temp)).File.ContentId == item.Underworld.ContentId;
				});
			}
			else
			{
				content = contents[0];
			}

			PolicyResponseAction pra = null;
			pra = GetActionOfTypeFromContentItem(pro, content, resAction.ResponseAction.Type);

			if (pra == null)
				Debug.Assert(false, "Should not get here - unless the ResolvedAction and the ActionData params were not related in the first place");

			return pra;
		}
示例#4
0
		/// <summary>
		/// Executes actions specified in the PolicyResponseObject. Supports both file and folder based
		/// actions.
		/// </summary>
		/// <param name="pro">PolicyResponseObject with ResolvedActions and ContentItems</param>
		/// <param name="container">ContentItems in a hierarchy structure</param>
		/// <returns></returns>
		public IUniversalRequestObject ExecuteActions(IPolicyResponseObject pro, ref IContainer container)
		{
			MimeEngine mimeEngine = new MimeEngine();
			mimeEngine.ProgressCallback = _progressCallback;

			PolicyResponseObject realPro = pro as PolicyResponseObject;
			if (realPro == null)
				throw new PolicyEngineException("Invalid policy response object passed to the ActionExecuter");

			// for now just do this fudge - cull this at earliest opportunity Laku 25/07/07
			// the handling of the block and alert actions should be within the action processor
			if (ContainsBlockAction(realPro.ResolvedActionCollection))
			{
				container.Files.Clear();
				return CreateOutputUro(realPro, container);
			}

			#region process resolved actions
			// builds the master list of items into a hierarchy
			ActionData masterData = new ActionData(container, GetReadableContent);
			List<Guid> collections = new List<Guid>();

			PolicyResponseAction pra = null;
			ActionData workingSet = null;
			try
			{
				foreach (ResolvedAction resAction in pro.ResolvedActionCollection)
				{
					if (resAction.ContentCollection.Count <= 0)
						continue;
					pra = resAction.ResponseAction as PolicyResponseAction;
					if (pra.IsExceptionAction)
					{
						mimeEngine.ExceptionAction = pra;
						continue;
					}

					if (pra.Action.Capabilities.SupportsMime && !mimeEngine.Actions.ContainsKey(resAction))
					{
						mimeEngine.Actions[resAction] =
							GetActionOfTypeFromContentItem(realPro, resAction.ContentCollection[0], resAction.ResponseAction.Type).InternalProperties as ActionPropertySet;
						if (masterData.FileType == FileType.Email)
							continue;
					}

					collections.Clear();
					ActionData.GetAllCollectionId(masterData, collections);

					workingSet = new ActionData(masterData, new Predicate<ActionData>(delegate(ActionData item)
					{
						string supportedFileType = FileTypeToSupportedFileTypeString(item.FileType);

						if (item.FileType == FileType.Folder || item.FileType == FileType.Selection)
							return true;

						if (!pra.Action.SupportedFileCollection.Supports(supportedFileType))
							return false;

						if (item.Underworld != null && item.Underworld.Parent != null)
						{
							IFile parent = item.Underworld.Parent as IFile;
							if (parent != null && parent.FileType == FileType.ZIP)// && !pra.Action.SupportedFileCollection.Supports(".zip"))
								if (Array.IndexOf(pra.Action.SupportedFileCollection.UnsupportedFiles(), ".zip") >= 0)
									return false;
						}

						foreach (ContentItem ci in resAction.ContentCollection)
						{
							if (ci.File.UniqueIdentifier == item.Underworld.UniqueIdentifier &&
								pra.Action.SupportedFileCollection.Supports(supportedFileType))
							{
								return true;
							}
						}

						return false;
					}), GetReadableContent);

					if (ActionUtils.DoesActionSupportFolders((resAction.ResponseAction as PolicyResponseAction).Action))
					{
						//magic
						IActionProperty prop = null;
						ActionData firstLevelData = workingSet.Nested[0] as ActionData;

						if (workingSet.Nested.Count > 0)
							pra = FindContentAction(realPro, firstLevelData, resAction, true);

						bool bZipAllFolder = false;

						if (pra.InternalProperties.SystemProperties.TryGetValue("FileType", out prop))
						{
							if (workingSet.FileType == FileType.Email)
								prop.Value = ".email";
							else
							{
								prop.Value = ".fld";
								IActionProperty zipAttr = null;
								if (pra.InternalProperties.TryGetValue("ZIPAttachedFiles", out zipAttr) &&
									(bool) zipAttr.Value)
								{
									bZipAllFolder = true;
									if (workingSet.Nested.Count > 0)
										RemoveZipFilesInFolder(workingSet.Nested[0] as ActionData, pro, false);
								}
							}
						}

						ExecuteAction(pra, workingSet);
						if (masterData.Nested.Count > 0 && bZipAllFolder)
						{
							RemoveZipFilesInFolder(masterData.Nested[0] as ActionData, pro, true);
						}
					}
					else
					{
						foreach (ActionData item in workingSet.GetAllLeafs())
						{
							PolicyResponseAction actionToExecute = FindContentAction(realPro, item, resAction, false);

							ExecuteAction(actionToExecute, item);
						}
					}
					ActionData.Merge(masterData, workingSet, true);
					ActionData.PruneEmptyCollections(masterData, collections);
					pra.Executed = true;
				}

			}
			catch (AbortActionException abortThis)
			{
				// handle abort scenario
				PolicyActionException somethingWrong =
					new PolicyActionException(string.Format(CultureInfo.InvariantCulture, "Operation was aborted by action {0}", pra.Type), abortThis);

				somethingWrong.ExceptionHandling = ActionExceptionHandling.Abort;

				throw somethingWrong;
			}
			catch (Exception e)
			{
				throw CreateActionException(pra.Type, realPro, e, false);
			}
			#endregion

			if (masterData.Nested.Count != 0)
				container = ContentToPackedContainer(masterData);
			else
				container.Files.Clear();

			// Synchronise the URO with the changes to the attachments
			IUniversalRequestObject outputUro = CreateOutputUro(realPro, container);

			try
			{
				// The MIME actions will modify the URO directly            
				mimeEngine.ExecuteActions(outputUro);

				UniversalResponseObjectHelper.CopyProperties(outputUro, realPro.UniversalRequestObject);
				UniversalResponseObjectHelper.CopyRouting(outputUro, realPro.UniversalRequestObject);

			}
			catch (AbortActionException abortThis)
			{
				// handle abort scenario
				PolicyActionException somethingWrong =
					 new PolicyActionException(string.Format(CultureInfo.InvariantCulture, "Operation was aborted by action {0}", pra.Type), abortThis);

				somethingWrong.ExceptionHandling = ActionExceptionHandling.Abort;

				throw somethingWrong;
			}
			catch (Exception e)
			{
				throw CreateActionException(pra.Type, realPro, e, true);
			}

			return outputUro;
		}
示例#5
0
		private void ExecuteAction(PolicyResponseAction pra, ActionData item)
		{
			string displayName = null;
			if (item.Underworld != null)
			{
				displayName = item.Underworld.DisplayName;
			}
			else
			{
				item.Properties.TryGetValue("FileName", out displayName);
			}
			Logger.LogDebug("Pre-Execute: " + displayName);

			OnBeforeExecuteHandler(pra.Action.Name, item.DisplayName);
			try
			{
				Dictionary<string, string> streamProperties = item.Properties;

				item.FileName = pra.Action.Execute(item, pra.InternalProperties as ActionPropertySet);
				item.DisplayName = streamProperties["DisplayName"];
			}
			catch (Exception e)
			{
				OnAfterExecuteHandler(pra.Action.Name, item.DisplayName);
				if (e is AbortActionException)
				{
					throw;
				}
				string message = "ActionExecution: Exception on " + pra.Type + ". Message: " + e.Message;
				PolicyActionException pae = new PolicyActionException(message, e);
				pae.ContentId = displayName;
				throw pae;
			}
			OnAfterExecuteHandler(pra.Action.Name, item.DisplayName);
			Logger.LogDebug("Post-Execute: " + displayName);
		}
示例#6
0
		private bool RemoveZipFilesInFolder(ActionData data,
											IPolicyResponseObject pro,
											bool bRemoved)
		{
			if (data.FileType == FileType.Folder)
			{
				int i = 0;
				while (i < data.Nested.Count)
				{
					if (!RemoveZipFilesInFolder(data.Nested[i] as ActionData, pro, bRemoved))
						++i;
				}
			}
			else if (data.FileType == FileType.ZIP)
			{
				foreach (ResolvedAction resAction in pro.ResolvedActionCollection)
				{
					foreach (ContentItem ci in resAction.ContentCollection)
					{
						if (ContainedinPRO(data.Properties["FileName"], ci.File as File))
						{
							if (!bRemoved)
								return false;
							if (data.Parent.Nested.Count > 0)
							{
								data.Parent.Nested.Remove(data);
								return true;
							}
						}
					}
				}
				if (!bRemoved && data.Parent.Nested.Count > 0)
				{
					data.Parent.Nested.Remove(data);
					return true;
				}
			}
			return false;
		}
示例#7
0
		private void ExecuteAction(IUniversalRequestObject outputUro, IResolvedAction actionInfo, List<string> actionsApplied)
		{
			PolicyResponseAction resAction = actionInfo.ResponseAction as PolicyResponseAction;

			// ReSharper disable ConditionIsAlwaysTrueOrFalse
			if (outputUro == null || actionInfo == null || resAction == null)
			// ReSharper restore ConditionIsAlwaysTrueOrFalse
			{
				return;
			}

			IAction3 action = resAction.Action;
			IFile emailFile;
			using (Stream stream = GetMimeStream(outputUro))
			{
				emailFile = new File(stream, resAction.Type);
			}

			ActionData data = new ActionData(emailFile, GetReadableContent)
								{
									AttachmentFiles = outputUro.Attachments
								};

			Logger.LogDebug("Pre-Execute: MIME");
			Logger.LogDebug("ProcessActions: action " + resAction.Type); // shame no policySetInfo name

			OnBeforeExecuteHandler(resAction.Name, emailFile.FileName);

			if (!_emailActions[actionInfo].SystemProperties.ContainsKey("FileType"))
			{
				_emailActions[actionInfo].SystemProperties["FileType"] = new Action.ActionProperty("FileType", typeof(string),
																									PropertyDisplayType.TextBox,
																									true, false, ".email", true);
			}
			_emailActions[actionInfo].SystemProperties["FileType"].Value = ".email";

			using (Stream modifiedStream = action.ExecuteMime(data, _emailActions[actionInfo]))
			{
				if (null == modifiedStream)
				{
					throw new PolicyException("Invalid mime stream");
				}
				UpdateUroOriginalContentBytes(outputUro, modifiedStream);
			}

			foreach (RequestAttachment ra in outputUro.Attachments)
			{
				if (ra.File == null)
				{
					ra.File = new FCS.Lite.Interface.File(ra.FileName, ra.Name);
				}
			}

			bool isUserOverriden = resAction.InternalProperties.Modified;
			resAction.Executed = true;
			actionsApplied.Add(resAction.Name);

			Logger.LogDebug("Post-Execute: MIME");

			UpdateActionEntity(resAction, isUserOverriden);

			OnAfterExecuteHandler(resAction.Name, emailFile.FileName);
		}
示例#8
0
		public void ExecuteMime_Abort()
		{
			IActionWrapperClass wrapper = new IActionWrapperClass(new MimeOnlyAction());
			ActionData testData = new ActionData();
			testData.AttachmentFiles = new Collection<IRequestAttachment>();
			ActionPropertySet props = new ActionPropertySet();

			testData.Properties[IActionWrapperClass.ABORT] = bool.FalseString;

			Stream output = wrapper.ExecuteMime(testData, props);

			Assert.IsNotNull(output, "Although abort property was present, the value was not true.  Hence no exception expected.");

			testData.Properties[IActionWrapperClass.ABORT] = bool.TrueString;

			try
			{
				//execute
				output = wrapper.ExecuteMime(testData, props);
			}
			catch (AbortActionException)
			{
				Assert.IsTrue(true, "Expecting to arrive here when abort property was added");
				return;
			}

			Assert.Fail("Should have thrown an abort exception");
		}
示例#9
0
        public void MergeASpawnDeleteEmptyFolders()
        {
            //setup
            ActionData source = CreateTwoLevelTreeXOfY(5, 6);
            
            ActionData subTree = new ActionData(source, new Predicate<ActionData>(
                delegate(ActionData item)
                {
                    int id = 0;
                    if (int.TryParse(item.Tag.ToString(), out id))
                    {
                        if (id % 2 == 0)
                            return true;
                    }
                    return false;
                }
                ), null);
            subTree.Nested.Clear();

            //execute
            ActionData.Merge(source, subTree, true);

            //verify
            Assert.AreEqual(3, source.Nested.Count, "Incorrect number of children in source");
            //find one with folder
            int countFolders = 0;
            ActionData childFolder = null;
            foreach (ActionData item in source.Nested)
            {
                if (item.Nested.Count != 0)
                {
                    childFolder = item;
                    countFolders++;
                }
            }
            Assert.AreEqual(1, countFolders, "Only expecting one folder");
            Assert.AreEqual(3, childFolder.Nested.Count, "Nested folder has incorrect count");
        }
示例#10
0
		public void Execute_Abort()
		{
			IActionWrapperClass wrapper = new IActionWrapperClass(new BasicAction());
			ActionData testData = new ActionData();
			testData.Tag = "Execute_Abort.txt";
			testData.DisplayName = "Execute_Abort.txt";
			string file = CreateFile("Execute_Abort.txt");
			testData.FileName = file;
			testData.Properties["DisplayName"] = "Execute_Abort.txt";

			ActionPropertySet props = new ActionPropertySet();

			testData.Properties[IActionWrapperClass.ABORT] = bool.FalseString;
			string output = wrapper.Execute(testData, props);
			Assert.IsTrue(!String.IsNullOrEmpty(output) &&  System.IO.File.Exists(output) , "Although abort property was present, the value was not true.  Hence no exception expected.");
			testData.Properties[IActionWrapperClass.ABORT] = bool.TrueString;
			try
			{
				//execute
				testData.FileName = CreateFile("Execute_Abort.txt");
				output = wrapper.Execute(testData, props);
			}
			catch (AbortActionException)
			{
				Assert.IsTrue(true, "Expecting to arrive here when abort property was added");
				return;
			}

			Assert.Fail("Should have thrown an abort exception");
		}
示例#11
0
		public void Execute()
		{
			//setup
			IActionWrapperClass wrapper = new IActionWrapperClass(new BasicAction());
			ActionData testData = new ActionData();
			//testData.Content = new MemoryStream();
			testData.Tag = "Execute.txt";
			testData.DisplayName = "Execute.txt";
			string file = CreateFile("Execute.txt");
			testData.FileName = file;
			testData.Properties["DisplayName"] = "Execute.txt";

			ActionPropertySet props = new ActionPropertySet();
			
			//execute
			string output = wrapper.Execute(testData, props);
			Assert.IsTrue(output == file, "Input file and output file should be the same.");
			Assert.IsTrue(!String.IsNullOrEmpty(output) && System.IO.File.Exists(output));			
			Assert.AreEqual(1, int.Parse(testData.Properties["ExecuteCalled"]), "Execute should be called only once");
		}
示例#12
0
        public void IdPropertyMatchesContentId()
        {
            using (MemoryStream str = new MemoryStream(Encoding.Unicode.GetBytes("DummyContent")))
            {
                Workshare.Policy.Engine.File file = new Workshare.Policy.Engine.File(str, "DummyFile");

                file.ContentId = Guid.NewGuid().ToString();

                Predicate<IContainer> dummyContainerTest = delegate { return true; };
                ReadableContentRequest dummyRequestMethod = delegate { return null; };

                ActionData actionData = new ActionData( file,
                    dummyContainerTest, dummyRequestMethod);

                Assert.AreEqual(file.ContentId, actionData.Id.ToString(),
                                "Expect ActionData.Id to match fi.ContentId when passing a file object in ActionData constructor.");
            }
        }
示例#13
0
        public void NestedSubTree()
        {
            // setup
            object[] tree = new object[] { 1, 2, 3, 4, "folder1", 5, 6, 7, 8, 9, "folder2", "foobar", "hello", "you", "folder3", 12, 14 };
            object[] anotherLevel = new object[] { 4, 1, "folder12", 6 };
            object[] yal = new object[] { "folder5", "folder6", "folder7", 24, 26, 28 };
            ActionData root = new ActionData();
            root.Tag = "root";
            LoadIntoTree(root, tree, 0);
            LoadIntoTree(root, anotherLevel, 0);
            LoadIntoTree(root, yal, 0);
            Assert.AreEqual(9, root.Nested.Count, "should be 6 items and 3 folders");
            //execute

            ActionData subTree = new ActionData(root, new Predicate<ActionData>(delegate(ActionData item)
            {
                int i = 1;
                if (int.TryParse(item.Tag.ToString(), out i))
                {
                    if (i % 2 == 0)
                        return true;
                }

                return false;
            }), null);

            //verify
            foreach (ActionData data in root.GetAllLeafs())
            {
                int i = 1;
                if(int.TryParse(data.Tag.ToString(), out i))
                {
                    Assert.IsTrue(i % 2 > 0, "Incorrect item found in subtree: tag: {0}", data.Tag);
                }
            }
        }
示例#14
0
		public ActionData(IContainer ic, Predicate<IContainer> venn, ReadableContentRequest readContentDelegate)
			: this()
		{
			myIC = ic as File;
			filename = ic.FileName;

			RetrieveContent = readContentDelegate;
			if (myIC == null && ic is Workshare.FCS.Lite.Interface.File)
			{
				myIC = new File(ic as Workshare.FCS.Lite.Interface.File);
			}

			if (!string.IsNullOrEmpty(myIC.ContentId))
			{
				try
				{
					uniqueID = new Guid(myIC.ContentId);
				}
				catch (System.FormatException fe)
				{
					Logger.LogInfo(fe);
				}
			}

			PopulateStream();
			foreach (IContainer c in ic.Files)
			{
				if (!venn(c) && c.Files.Count == 0)
					continue;

				ActionData childNode = new ActionData(c, venn, readContentDelegate);
				childNode.parent = this;
				nested.Add(childNode);
			}
		}
示例#15
0
		public void ExecuteMime()
		{
			//setup
			IActionWrapperClass wrapper = new IActionWrapperClass(new MimeOnlyAction());
			ActionData testData = new ActionData();
			testData.AttachmentFiles = new Collection<IRequestAttachment>();
			ActionPropertySet props = new ActionPropertySet();
			//execute
			Stream output = wrapper.ExecuteMime(testData, props);

			//verify
			StreamReader sr = new StreamReader(output);
			string exeOutput = sr.ReadToEnd().TrimEnd('\r', '\n');

			Assert.AreEqual(typeof(MimeOnlyAction).FullName, exeOutput, "Expecting full typename to be written to the stream");
			Assert.AreEqual(1, int.Parse(testData.Properties["ExecuteCalled"]), "Execute should be called only once");
		}
示例#16
0
		/// <summary>
		/// This creates a subtree rooted at root containing all the nodes of
		/// root for which the Predicate returns true. root is modified such that
		/// the nodes (if not containers) are deleted from it.
		/// </summary>
		/// <param name="root">source tree</param>
		/// <param name="venn">node evaluation function</param>
		public ActionData(IActionData3 node, Predicate<ActionData> venn, ReadableContentRequest readContentDelegate)
			: this()
		{
			ActionData root = node as ActionData;
			if (root == null)
				return;
			myIC = root.myIC;
			rawContent = root.rawContent;
			streamProperties = root.streamProperties;
			tag = root.tag;
			RetrieveContent = readContentDelegate;
			filename = root.filename;
			displayname = root.displayname;

			List<ActionData> toRemove = new List<ActionData>();
			uniqueID = root.uniqueID;

			foreach (ActionData c in root.Nested)
			{
				if (!venn(c) && c.nested.Count == 0)
					continue;
				if (c.nested.Count == 0)
					toRemove.Add(c);
				ActionData reassignedChild = new ActionData(c, venn, readContentDelegate);
				Nested.Add(reassignedChild);
				reassignedChild.parent = this;
			}
			foreach (ActionData c in toRemove)
			{
				root.Nested.Remove(c);
			}
		}
示例#17
0
        public void CreatingAContentSubTree()
        {
            //setup
            ActionData source = CreateTwoLevelTreeXOfY(4, 3);
            
            //execute
            ActionData newSubTree = new ActionData(source, new Predicate<ActionData>(
                delegate(ActionData item)
                {
                    if (item.Tag.ToString().Equals("2"))
                        return true;
                    return false;
                }), null);

            //verify
            Assert.AreEqual(4, source.Nested.Count, "Incorrect number in subtree");
            Assert.AreEqual(source.Id, newSubTree.Id, "subtree not pegged at root.");
            Assert.AreEqual(2, newSubTree.Nested.Count, "Incorrect number of child items in new tree.");
            Assert.AreEqual((source.Nested[3] as ActionData).Id, (newSubTree.Nested[1] as ActionData).Id, "Incorrect folder level.");
            //TODO: verify the trees are disjoint
        }