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); }
/// <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; }
private PolicyActionException CreateActionException(string action, PolicyResponseObject response, Exception e, bool forceNew) { string message = "ActionExecution: Exception on " + action + ". Message: " + e.Message; Logger.LogDebug(message); #if DEBUG Logger.LogDebug(PolicyResponseLogHelper.GetDisplayNames(response)); #endif PolicyActionException exception = (forceNew ? null : e as PolicyActionException); if (exception == null) { exception = new PolicyActionException(message, e); } exception.Action = action; exception.ExceptionHandling = (BlockOnException(response) ? ActionExceptionHandling.Block : ActionExceptionHandling.Prompt); return exception; }