public static OrderByNode CreateOrderByNode(XElement element, Tree tree)
        {
            if (element.Name == TreeMarkupConstants.Namespace + "Field")
            {
                XAttribute nameAttribute = element.Attribute("FieldName");
                XAttribute directionAttribute = element.Attribute("Direction");

                if (nameAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "FieldName");
                    return null;
                }

                return new FieldOrderByNode
                {
                    XPath = element.GetXPath(),
                    FieldName = nameAttribute.Value,                    
                    Direction = directionAttribute.GetValueOrDefault("ascending")
                };
            }
            else
            {
                throw new InvalidOperationException(string.Format("OrderBy node {0} not supported", element.Name));
            }
        }
Example #2
0
 /// <summary>
 /// Creates a new srcML location object
 /// </summary>
 /// <param name="element">The srcML element that this location refers to</param>
 /// <param name="fileName">The filename</param>
 /// <param name="isReferenceLocation">true if this is a reference location; false otherwise</param>
 public SrcMLLocation(XElement element, string fileName, bool isReferenceLocation) {
     if(element == null) throw new ArgumentNullException("element");
     this.SourceFileName = fileName;
     this.StartingLineNumber = element.GetSrcLineNumber();
     this.StartingColumnNumber = element.GetSrcLinePosition();
     this.XPath = element.GetXPath(false);
     this.IsReference = isReferenceLocation;
     SetEndingLocation(element);
 }
Example #3
0
 protected Definition(XElement element, string fileName)
     : this()
 {
     if (null == element)
         throw new ArgumentNullException("element");
     this.FileName = fileName;
     this.LineNumber = element.GetSrcLineNumber();
     this.XPath = element.GetXPath(false);
     this.Xml = element;
     this.ElementXName = element.Name.ToString();
 }
Example #4
0
 /// <summary>
 /// Creates a new srcML location object
 /// </summary>
 /// <param name="element">The srcML element that this location refers to</param>
 /// <param name="fileUnit">The file unit that contains
 /// <paramref name="element"/></param>
 /// <param name="isReferenceLocation">true if this is a reference location; false
 /// otherwise</param>
 public SrcMLLocation(XElement element, XElement fileUnit, bool isReferenceLocation) {
     if(element == null)
         throw new ArgumentNullException("element");
     if(fileUnit == null)
         throw new ArgumentNullException("fileUnit");
     this.SourceFileName = SrcMLElement.GetFileNameForUnit(fileUnit);
     this.StartingLineNumber = element.GetSrcLineNumber();
     this.StartingColumnNumber = element.GetSrcLinePosition();
     this.XPath = element.GetXPath();
     this.IsReference = isReferenceLocation;
     SetEndingLocation(element);
 }
 public static Elem Create(XElement element, int source)
 {
     var kv = element.GetBestKeyValueInfo();
     var res = new Elem
     {
         LineNumber = element.LineNumber(),
         Element = element,
         KeyValueInfo = kv,
         Source = source,
         XPath = element.GetXPath(kv),
     };
     return res;
 }
Example #6
0
 internal static Dictionary<Tuple<string, string>, string> MakeLocalDictionary(SrcMLDataContext db, XElement fileUnit)
 {
     var pathToFileUnit = fileUnit.GetXPath(false);
     var scopes = from scope in db.ValidScopes
                  where scope.Definition.DefinitionTypeId == DefinitionType.DeclarationVariable
                  where scope.XPath.StartsWith(pathToFileUnit)
                  let declaration = scope.Definition as VariableDeclaration
                  select new KeyValuePair<Tuple<string, string>, string>(
                      Tuple.Create(scope.XPath, declaration.DeclarationName),
                      declaration.VariableTypeName
                  );
     var scopeMap = scopes.ToDictionary(x => x.Key, x => x.Value);
     return scopeMap;
 }
        private static bool MatchesLocalVariable(SrcMLDataContext db, VariableDeclaration def, XElement use)
        {
            if (def.IsGlobal ?? false)
                return false;

            if (def.DeclarationName != use.Value)
                return false;
            
            var useXPath = use.GetXPath(false);
            var validScopes = from scope in db.ValidScopes
                              where scope.DefinitionId == def.Id
                              select scope;
            foreach (var scope in validScopes)
            {
                if (useXPath.StartsWith(scope.XPath))
                    return true;
            }

            var method = (from ancestor in use.Ancestors()
                          where ContainerNames.MethodDefinitions.Any(mn => mn == ancestor.Name)
                          select ancestor).FirstOrDefault();
            var classNameFromMethod = SrcMLHelper.GetClassNameForMethod(method);

            if (null == classNameFromMethod)
            {
                return false;
            }

            var classDef = from scope in def.ValidScopes.OfType<TypeDefinition>()
                           where scope.TypeName == classNameFromMethod.Value
                           select scope;
            if (classDef.Any())
            {
                return true;
            }

            return false;
        }
        private static bool GetAttributeNotNull(XElement element, string attributeName, List<PackageFragmentValidationResult> validationSummary, out XAttribute attribute)
        {
            attribute = element.Attribute(attributeName);

            if (attribute != null) return true;

            validationSummary.Add(new PackageFragmentValidationResult(PackageFragmentValidationResultType.Fatal, 
                "MissingAttribute '{0}'. XPath: '{1}' ".FormatWith(attributeName, element.GetXPath())));

            return false;
        }
        public static FilterNode CreateFilterNode(XElement filterElement, Tree tree)
        {
            if (filterElement.Name == TreeMarkupConstants.Namespace + "ParentIdFilter")
            {
                XAttribute parentTypeAttribute = filterElement.Attribute("ParentType");
                XAttribute referenceFieldNameAttribute = filterElement.Attribute("ReferenceFieldName");

                if (parentTypeAttribute == null)
                {
                    tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.Common.MissingAttribute", "ParentType");
                    return null;
                }

                if (referenceFieldNameAttribute == null)
                {
                    tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.Common.MissingAttribute", "ReferenceFieldName");
                    return null;
                }                
                

                Type parentInterfaceType = TypeManager.TryGetType(parentTypeAttribute.Value);
                if (parentInterfaceType == null)
                {
                    tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.Common.UnknownInterfaceType", parentTypeAttribute.Value);
                    return null;
                }

                return new ParentIdFilterNode
                {
                    XPath = filterElement.GetXPath(),
                    Id = tree.BuildProcessContext.FilterIdCounter++,
                    ParentFilterType = parentInterfaceType,
                    ReferenceFieldName = referenceFieldNameAttribute.Value
                };
            }

            if (filterElement.Name == TreeMarkupConstants.Namespace + "FieldFilter")
            {
                XAttribute fieldNameAttribute = filterElement.Attribute("FieldName");
                XAttribute fieldValueAttribute = filterElement.Attribute("FieldValue");
                XAttribute operatorValueAttribute = filterElement.Attribute("Operator");

                if (fieldNameAttribute == null)
                {
                    tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.Common.MissingAttribute", "FieldName");
                    return null;
                }

                if (fieldValueAttribute == null)
                {
                    tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.Common.MissingAttribute", "FieldValue");
                    return null;
                }

                FieldFilterNodeOperator filterOperator;
                string operatorValue = operatorValueAttribute.GetValueOrDefault("equal");
                switch (operatorValue)
                {
                    case "equal":
                        filterOperator = FieldFilterNodeOperator.Equal;
                        break;

                    case "inequal":
                        filterOperator = FieldFilterNodeOperator.Inequal;
                        break;

                    case "lesser":
                        filterOperator = FieldFilterNodeOperator.Lesser;
                        break;

                    case "greater":
                        filterOperator = FieldFilterNodeOperator.Greater;
                        break;

                    case "lesserequal":
                        filterOperator = FieldFilterNodeOperator.LesserEqual;
                        break;

                    case "greaterequal":
                        filterOperator = FieldFilterNodeOperator.GreaterEqual;
                        break;

                    default:                        
                        tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.FieldFilter.UnknownOperatorName", operatorValue);
                        return null;
                }

                return new FieldFilterNode
                {
                    XPath = filterElement.GetXPath(),
                    Id = tree.BuildProcessContext.FilterIdCounter++,
                    FieldName = fieldNameAttribute.Value,
                    FieldValue = fieldValueAttribute.Value,
                    Operator = filterOperator
                };
            }

            if (filterElement.Name == TreeMarkupConstants.Namespace + "FunctionFilter")
            {
                XElement functionMarkupElement = filterElement.Element((XNamespace)FunctionTreeConfigurationNames.NamespaceName + FunctionTreeConfigurationNames.FunctionTagName);

                if (functionMarkupElement == null)
                {
                    tree.AddValidationError(filterElement.GetXPath(), "TreeValidationError.FunctionFilter.MissingFunctionMarkup");
                    return null;
                }

                return new FunctionFilterNode()
                {
                    XPath = filterElement.GetXPath(),
                    Id = tree.BuildProcessContext.FilterIdCounter++,
                    FunctionMarkup = functionMarkupElement
                };
            }

            throw new NotImplementedException("ValidationError");
        }
        private static void AnalyzeRun(XElement run, List<XElement> attList, List<string> notes, FormattingMetrics formattingMetrics, string uri)
        {
            var runText = run.Elements()
                .Where(e => e.Name == W.t || e.Name == W.delText)
                .Select(t => (string)t)
                .StringConcatenate();
            if (runText.Length == 0)
            {
                formattingMetrics.ZeroLengthText++;
                return;
            }
            var rPr = run.Element(W.rPr);
            if (rPr == null)
            {
                formattingMetrics.RunWithoutRprCount++;
                notes.Add(PtUtils.MakeValidXml(string.Format("Error in part {0}: run without rPr at {1}", uri, run.GetXPath())));
                rPr = new XElement(W.rPr);
            }
            FormattingAssembler.CharStyleAttributes csa = new FormattingAssembler.CharStyleAttributes(null, rPr);
            var fontTypeArray = runText
                .Select(ch => FormattingAssembler.DetermineFontTypeFromCharacter(ch, csa))
                .ToArray();
            var distinctFontTypeArray = fontTypeArray
                .Distinct()
                .ToArray();
            var distinctFonts = distinctFontTypeArray
                .Select(ft =>
                {
                    return GetFontFromFontType(csa, ft);
                })
                .Distinct();
            var languages = distinctFontTypeArray
                .Select(ft =>
                {
                    if (ft == FormattingAssembler.FontType.Ascii)
                        return csa.LatinLang;
                    if (ft == FormattingAssembler.FontType.CS)
                        return csa.BidiLang;
                    if (ft == FormattingAssembler.FontType.EastAsia)
                        return csa.EastAsiaLang;
                    //if (ft == FormattingAssembler.FontType.HAnsi)
                    return csa.LatinLang;
                })
                .Select(l =>
                {
                    if (l == "" || l == null)
                        return /* "Dflt:" + */ CultureInfo.CurrentCulture.Name;
                    return l;
                })
                //.Where(l => l != null && l != "")
                .Distinct();
            if (languages.Any(l => !formattingMetrics.Languages.Contains(l)))
                formattingMetrics.Languages = formattingMetrics.Languages.Concat(languages).Distinct().ToList();
            var multiFontRun = distinctFonts.Count() > 1;
            if (multiFontRun)
            {
                formattingMetrics.MultiFontRun++;

                formattingMetrics.AsciiCharCount += fontTypeArray.Where(ft => ft == FormattingAssembler.FontType.Ascii).Count();
                formattingMetrics.CSCharCount += fontTypeArray.Where(ft => ft == FormattingAssembler.FontType.CS).Count();
                formattingMetrics.EastAsiaCharCount += fontTypeArray.Where(ft => ft == FormattingAssembler.FontType.EastAsia).Count();
                formattingMetrics.HAnsiCharCount += fontTypeArray.Where(ft => ft == FormattingAssembler.FontType.HAnsi).Count();
            }
            else
            {
                switch (fontTypeArray[0])
                {
                    case FormattingAssembler.FontType.Ascii:
                        formattingMetrics.AsciiCharCount += runText.Length;
                        formattingMetrics.AsciiRunCount++;
                        break;
                    case FormattingAssembler.FontType.CS:
                        formattingMetrics.CSCharCount += runText.Length;
                        formattingMetrics.CSRunCount++;
                        break;
                    case FormattingAssembler.FontType.EastAsia:
                        formattingMetrics.EastAsiaCharCount += runText.Length;
                        formattingMetrics.EastAsiaRunCount++;
                        break;
                    case FormattingAssembler.FontType.HAnsi:
                        formattingMetrics.HAnsiCharCount += runText.Length;
                        formattingMetrics.HAnsiRunCount++;
                        break;
                }
            }
        }
        /// <summary>
        /// Transforms a target configsection file by applying the "Locator" and "Transform" attributes in the supplied source xml element
        /// </summary>
        /// <remarks>
        /// For example, if this method were supplied an XDocument created from the configsection file "connectionstrings.config" and 
        /// an xml element with a name attribute of "Titan", a Transform attribute of "SetAttributes", and a Locator attribute of "Match(name)"
        /// the method would search the XDocument for a match based on the "name" attribute and then set all its' attributes to match those 
        /// of the provided xml element.   The available Transform and Locator values conform to those provided by the Microsoft XML Document Transform
        /// (http://schemas.microsoft.com/XML-Document-Transform).
        /// </remarks>
        /// <param name="targetDoc"></param>
        /// <param name="sourceElement"></param>
        private void Transform(ref XDocument targetDoc, XElement sourceElement)
        {
            var xpath = sourceElement.GetXPath();
            var locatorAction = sourceElement.Attributes()
                .Where(x => x.Name.LocalName == "Locator")
                .Select(x => x.Value)
                .SingleOrDefault();

            var transformAction = sourceElement.Attributes()
                .Where(x => x.Name.LocalName == "Transform")
                .Select(x => x.Value)
                .SingleOrDefault();

            if (transformAction == null)
                throw new Exception(
                    "If you want two config files merged, you need to state which XML nodes should be merged and how they should be merged.  Environment specific config file must have a \"Transform\" attribute on at least one XML node for a config merge operation to occur.");

            var transformActionXPath = GetXPathFromTransformAction(transformAction);
            var transformAttributeList = GetAttributeListFromTransformAction(transformAction);

            if (locatorAction != null) {
                if (locatorAction.StartsWith("Match("))
                    xpath = AddMatchFilter(xpath, sourceElement, locatorAction);
                else if (locatorAction.StartsWith("Condition("))
                    xpath = AddConditionFilter(xpath, locatorAction);
                else if (locatorAction.StartsWith("XPath("))
                    xpath = AddXPathFilter(locatorAction);
            }

            var targetNodes = targetDoc.XPathSelectElements(xpath).ToList();
            var targetSiblings = new List<XElement>();

            var sanitizedSourceElement = new XElement(sourceElement);
            sanitizedSourceElement.Attributes()
                .Where(x => x.Name.NamespaceName == "http://schemas.microsoft.com/XML-Document-Transform")
                .Remove();

            switch (transformAction) {
                case "Replace":
                    if (targetNodes.Count > 0) {
                        targetNodes[0] = sourceElement;
                    }
                    break;

                case "Remove":
                    if (targetNodes.Count > 0) {
                        targetNodes[0].Remove();
                    }
                    break;

                case "RemoveAll":
                    targetNodes[0].Parent.RemoveNodes();
                    break;

                case "Insert":
                    var parentxpath = xpath.Remove(xpath.LastIndexOf('/'));
                    var targetParentNodes = targetDoc.XPathSelectElements(parentxpath).ToList();
                    foreach (XElement parentNode in targetParentNodes) {
                        parentNode.Add(sanitizedSourceElement);
                    }
                    break;

                case "SetAttributes":
                    if (transformAttributeList.Count == 0) {
                        // find the attributes with the "xdt" namespace (i.e. "Locator" and "Transform")
                        var sourceAttributes = sourceElement.Attributes()
                            .Where(x => x.Name.NamespaceName != "http://schemas.microsoft.com/XML-Document-Transform")
                            .Select(x => x)
                            .ToList();

                        foreach (XElement targetNode in targetNodes) {
                            foreach (var att in sourceAttributes) {
                                if (att.Name.LocalName != "xdt") {
                                    if (targetNode.Attribute(att.Name.LocalName) == null)
                                        targetNode.Add(new XAttribute(att.Name.LocalName, att.Value));
                                    else
                                        targetNode.Attribute(att.Name.LocalName).Value = att.Value;
                                }
                            }
                        }
                    }
                    else {
                        foreach (XElement targetNode in targetNodes) {
                            foreach (var name in transformAttributeList) {
                                if (name != "xdt") {
                                    if (targetNode.Attribute(name) == null)
                                        targetNode.Add(new XAttribute(sourceElement.Attribute(name).Name, sourceElement.Attribute(name).Value));
                                    else
                                        targetNode.Attribute(name).Value = sourceElement.Attribute(name).Value;
                                }
                            }
                        }
                    }
                    break;

                case "RemoveAttributes":
                    if (transformAttributeList.Count == 0) {
                        foreach (XElement node in targetNodes) {
                            node.RemoveAttributes();
                        }
                    }
                    else {
                        foreach (XElement node in targetNodes) {
                            foreach (var name in transformAttributeList) {
                                node.Attribute(name).Remove();
                            }
                        }
                    }
                    break;

                case "InsertAfter":
                    targetSiblings = targetDoc.XPathSelectElements(transformActionXPath).ToList();
                    foreach (var sibling in targetSiblings) {
                        sibling.AddAfterSelf(sanitizedSourceElement);
                    }
                    break;

                case "InsertBefore":
                    targetSiblings = targetDoc.XPathSelectElements(transformActionXPath).ToList();
                    foreach (var sibling in targetSiblings) {
                        sibling.AddBeforeSelf(sanitizedSourceElement);
                    }
                    break;

                default:
                    break;
            }
        }
        public static ActionLocation GetActionLocation(XElement element, Tree tree, ActionLocation defaultActionLocation = null)
        {
            XAttribute locationAttribute = element.Attribute("Location");

            if (locationAttribute == null) return ActionLocation.OtherPrimaryActionLocation;

            switch (locationAttribute.Value)
            {
                case "Add":
                    return ActionLocation.AddPrimaryActionLocation;

                case "Edit":
                    return ActionLocation.EditPrimaryActionLocation;

                case "Delete":
                    return ActionLocation.DeletePrimaryActionLocation;

                case "Other":
                    return ActionLocation.OtherPrimaryActionLocation;

                default:
                    if (defaultActionLocation != null) return defaultActionLocation;

                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.WrongLocationValue", locationAttribute.Value);

                    return ActionLocation.OtherPrimaryActionLocation;
            }
        }
        public static List<PermissionType> GetPermissionTypes(XElement element, Tree tree, List<PermissionType> defaultPermissionTypes = null)
        {
            XAttribute permissionTypesAttribute = element.Attribute("PermissionTypes");
            if ((permissionTypesAttribute == null) && (defaultPermissionTypes != null)) return defaultPermissionTypes;

            string permissionTypesString = permissionTypesAttribute.GetValueOrDefault("read");

            string[] permissionTypesStrings = permissionTypesString.Split(',');

            var permissionTypes = new List<PermissionType>();
            foreach (string permission in permissionTypesStrings)
            {                
                PermissionType permissionType;
                if (Enum.TryParse<PermissionType>(permission.Trim(), true, out permissionType) == false)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.WrongPermissionValue", permission.Trim());
                    
                    continue;
                }

                permissionTypes.Add(permissionType);
            }

            return permissionTypes;
        }
        public static ActionNode CreateActionNode(XElement element, Tree tree)
        {
            if (element.Name == TreeMarkupConstants.Namespace + "AddDataAction")
            {
                GenericAddDataActionNode actionNode = new GenericAddDataActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultAddDataResourceName, StringResourceSystemFacade.GetString("Composite.C1Console.Trees", "GenericAddDataAction.DefaultLabel"), ActionLocation.AddPrimaryActionLocation, DefaultAddPermissionTypes);

                XAttribute typeAttribute = element.Attribute("Type");
                XAttribute customFormMarkupAttribute = element.Attribute("CustomFormMarkupPath");

                if (typeAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "Type");
                }
                else
                {
                    actionNode.InterfaceType = TypeManager.TryGetType(typeAttribute.Value);
                    if (actionNode.InterfaceType == null) tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.UnknownInterfaceType", typeAttribute.Value);
                }

                actionNode.CustomFormMarkupPath = customFormMarkupAttribute.GetValueOrDefault(null);

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "EditDataAction")
            {
                GenericEditDataActionNode actionNode = new GenericEditDataActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultEditDataResourceName, StringResourceSystemFacade.GetString("Composite.C1Console.Trees", "GenericEditDataAction.DefaultLabel"), ActionLocation.EditPrimaryActionLocation, DefaultEditPermissionTypes);

                XAttribute customFormMarkupAttribute = element.Attribute("CustomFormMarkupPath");

                actionNode.CustomFormMarkupPath = customFormMarkupAttribute.GetValueOrDefault(null);

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "DeleteDataAction")
            {
                GenericDeleteDataActionNode actionNode = new GenericDeleteDataActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultDeleteDataResourceName, StringResourceSystemFacade.GetString("Composite.C1Console.Trees", "GenericDeleteDataAction.DefaultLabel"), ActionLocation.DeletePrimaryActionLocation, DefaultDeletePermissionTypes);

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "DuplicateDataAction")
            {
                GenericDuplicateDataActionNode actionNode = new GenericDuplicateDataActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultDuplicateDataResourceName, StringResourceSystemFacade.GetString("Composite.C1Console.Trees", "GenericDuplicateDataAction.DefaultLabel"), ActionLocation.OtherPrimaryActionLocation, DefaultDuplicatePermissionTypes);

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "ReportFunctionAction")
            {
                ReportFunctionActionNode actionNode = new ReportFunctionActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultReportFunctionResourceName);

                XAttribute documentLabelAttribute = element.Attribute("DocumentLabel");
                XAttribute documentIconAttribute = element.Attribute("DocumentIcon");

                XElement functionMarkupElement = element.Element((XNamespace)FunctionTreeConfigurationNames.NamespaceName + FunctionTreeConfigurationNames.FunctionTagName);
                if (functionMarkupElement == null) tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingFunctionMarkup");
                actionNode.FunctionMarkup = functionMarkupElement;

                actionNode.DocumentLabel = documentLabelAttribute.GetValueOrDefault(actionNode.Label);
                if (documentIconAttribute != null)
                {
                    actionNode.DocumentIcon = FactoryHelper.GetIcon(documentIconAttribute.Value);
                }
                else
                {
                    actionNode.DocumentIcon = actionNode.Icon;
                }

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "MessageBoxAction")
            {
                MessageBoxActionNode actionNode = new MessageBoxActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultMessageBoxResourceName);

                XAttribute messageBoxTitleAttribute = element.Attribute("MessageBoxTitle");
                XAttribute messageBoxMessageAttribute = element.Attribute("MessageBoxMessage");

                if (messageBoxTitleAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "MessageBoxTitle");
                }
                else
                {
                    actionNode.Title = messageBoxTitleAttribute.Value;
                }

                if (messageBoxMessageAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "MessageBoxMessage");
                }
                else
                {
                    actionNode.Message = messageBoxMessageAttribute.Value;
                }

                XAttribute dialogTypeAttribute = element.Attribute("MessageDialogType");
                string dialogTypeValue = dialogTypeAttribute.GetValueOrDefault("message");
                switch (dialogTypeValue)
                {
                    case "message": 
                        actionNode.DialogType = DialogType.Message;
                        break;

                    case "question":
                        actionNode.DialogType = DialogType.Question;
                        break;

                    case "warning":
                        actionNode.DialogType = DialogType.Warning;
                        break;

                    case "error":
                        actionNode.DialogType = DialogType.Error;
                        break;

                    default:
                        tree.AddValidationError(element.GetXPath(), "TreeValidationError.MessageBoxAction.UnknownDialogType", dialogTypeValue);
                        break;
                }

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "CustomUrlAction")
            {
                CustomUrlActionNode actionNode = new CustomUrlActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultCustomUrlResourceName);

                XAttribute urlAttribute = element.Attribute("Url");
                XAttribute viewLabelAttribute = element.Attribute("ViewLabel");
                XAttribute viewToolTipAttribute = element.Attribute("ViewToolTip");
                XAttribute viewIconAttribute = element.Attribute("ViewIcon");

                IEnumerable<XElement> postParameterElements = element.Elements(TreeMarkupConstants.Namespace + "PostParameters");
                XElement postParametersElement = null;
                if (postParameterElements.Count() == 1)
                {
                    postParametersElement = element.Element(TreeMarkupConstants.Namespace + "PostParameters");
                }
                else if (postParameterElements.Count() > 1)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.CustomUrlAction.TooManyPostParameterElements", "PostParameters");
                }

                if (urlAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "Url");
                }
                else
                {
                    actionNode.Url = urlAttribute.Value;
                }

                actionNode.ViewLabel = viewLabelAttribute.GetValueOrDefault(actionNode.Label);
                actionNode.ViewToolTip = viewToolTipAttribute.GetValueOrDefault(actionNode.ToolTip);
                actionNode.ViewIcon = FactoryHelper.GetIcon(viewIconAttribute.GetValueOrDefault(DefaultCustomUrlResourceName));

                bool urlIsAbsolute = actionNode.Url != null && actionNode.Url.Contains("://");

                XAttribute viewTypeAttribute = element.Attribute("ViewType");
                string viewTypeValue = viewTypeAttribute.GetValueOrDefault(urlIsAbsolute ? "externalview" : "documentview");
                switch (viewTypeValue)
                {
                    case "externalview":
                        actionNode.ViewType = CustomUrlActionNodeViewType.ExternalView;
                        break;

                    case "genericview":
                        actionNode.ViewType = CustomUrlActionNodeViewType.GenericView;
                        break;

                    case "pagebrowser":
                        actionNode.ViewType = CustomUrlActionNodeViewType.PageBrowser;
                        break;

                    case "filedownload":
                        actionNode.ViewType = CustomUrlActionNodeViewType.FileDownload;
                        break;

                    case "documentview":
                        actionNode.ViewType = CustomUrlActionNodeViewType.DocumentView;
                        break;

                    default:
                        tree.AddValidationError(element.GetXPath(), "TreeValidationError.CustomUrlAction.UnknownViewType", viewTypeValue);
                        break;
                }

                actionNode.PostParameters = new Dictionary<string, string>();
                if (postParametersElement != null)
                {
                    foreach (XElement parameterElement in postParametersElement.Elements(TreeMarkupConstants.Namespace + "Parameter"))
                    {
                        XAttribute keyAttribute = parameterElement.Attribute("Key");
                        XAttribute valueAttribute = parameterElement.Attribute("Value");

                        if (keyAttribute == null)
                        {
                            tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "Key");
                            continue;
                        }
                        else if (string.IsNullOrWhiteSpace(keyAttribute.Value))
                        {
                            tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.WrongAttributeValue", "Key");
                            continue;                            
                        }

                        if (valueAttribute == null)
                        {
                            tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "Value");
                            continue;
                        }

                        actionNode.PostParameters.Add(keyAttribute.Value, valueAttribute.Value);
                    }
                }

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "ConfirmAction")
            {
                ConfirmActionNode actionNode = new ConfirmActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultConfirmResourceName);

                XAttribute confirmTitleAttribute = element.Attribute("ConfirmTitle");
                XAttribute confirmMessageAttribute = element.Attribute("ConfirmMessage");

                if (confirmTitleAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "ConfirmTitle");
                }
                else
                {
                    actionNode.ConfirmTitle = confirmTitleAttribute.Value;
                }

                if (confirmMessageAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "ConfirmMessage");
                }
                else
                {
                    actionNode.ConfirmMessage = confirmMessageAttribute.Value;
                }

                XElement functionMarkupElement = element.Element((XNamespace)FunctionTreeConfigurationNames.NamespaceName + FunctionTreeConfigurationNames.FunctionTagName);
                if (functionMarkupElement == null) tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingFunctionMarkup");
                actionNode.FunctionMarkup = functionMarkupElement;

                XAttribute refreshTreeAttribute = element.Attribute("RefreshTree");
                string refreshTreeAttributeValue = refreshTreeAttribute.GetValueOrDefault("false").ToLowerInvariant();
                if (refreshTreeAttributeValue == "true")
                {
                    actionNode.RefreshTree = true;
                }
                else
                {
                    actionNode.RefreshTree = false;
                }                

                return actionNode;
            }
            else if (element.Name == TreeMarkupConstants.Namespace + "WorkflowAction")
            {
                WorkflowActionNode actionNode = new WorkflowActionNode();
                InitializeWithCommonValue(element, tree, actionNode, DefaultWorkflowResourceName);

                XAttribute workflowTypeAttribute = element.Attribute("WorkflowType");                

                if (workflowTypeAttribute == null)
                {
                    tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "ConfirmTitle");
                }
                else
                {
                    actionNode.WorkflowType = TypeManager.TryGetType(workflowTypeAttribute.Value);
                    if (actionNode.WorkflowType == null) tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.UnknownInterfaceType", workflowTypeAttribute.Value);
                }
                
                return actionNode;
            }
            else
            {
                tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.UnknownElement", element.Name);

                return null;
            }
        }
        private static void InitializeWithCommonValue(XElement element, Tree tree, ActionNode actionNode, string defaultIconName, string defaultLabelName = null, ActionLocation defaultActionLocation = null, List<PermissionType> defaultPermissionTypes = null)
        {
            XAttribute labelAttribute = element.Attribute("Label");
            XAttribute toolTipAttribute = element.Attribute("ToolTip");
            XAttribute iconAttribute = element.Attribute("Icon");

            if ((defaultLabelName == null) && (labelAttribute == null)) tree.AddValidationError(element.GetXPath(), "TreeValidationError.Common.MissingAttribute", "Label");

            actionNode.XPath = element.GetXPath();
            actionNode.Id = tree.BuildProcessContext.ActionIdCounter++;
            actionNode.Label = labelAttribute.GetValueOrDefault(defaultLabelName);
            actionNode.ToolTip = toolTipAttribute.GetValueOrDefault(actionNode.Label);
            actionNode.Icon = FactoryHelper.GetIcon(iconAttribute.GetValueOrDefault(defaultIconName));
            actionNode.Location = GetActionLocation(element, tree, defaultActionLocation);
            if (defaultPermissionTypes != null)
            {
                actionNode.PermissionTypes = defaultPermissionTypes;
            }
            else
            {
                actionNode.PermissionTypes = GetPermissionTypes(element, tree);
            }
        }
        private static string GetXPath(XElement element)
        {
            var parentDefinition = element.Annotation<TypeDefinition>();
            var xpath = element.GetXPath(false);
            if (null == parentDefinition || xpath.StartsWith("/src:unit[@filename=", StringComparison.OrdinalIgnoreCase))
                return xpath;

            var parts = new List<string>(xpath.Substring(1).Split('/'));
            parts[0] = parentDefinition.XPath;

            return string.Join("/", parts);
        }