/// <summary> /// The CALDAV:calendar-multiget REPORT is used to retrieve specific calendar object resources from within a /// collection, if the Request-URI is a collection, or to retrieve a specific calendar object resource, if the /// Request-URI is a calendar object resource. This report is similar to the CALDAV:calendar-query REPORT /// (see Section 7.8), except that it takes a list of DAV:href elements, instead of a CALDAV:filter element, to /// determine which calendar object resources to return /// </summary> /// <returns></returns> private async Task CalendarMultiget(IXMLTreeStructure xmlBody, HttpContext httpContext) { // take the first prop node to know the data that // should ne returned IXMLTreeStructure propNode; xmlBody.GetChildAtAnyLevel("prop", out propNode); //take the href nodes. Contain the direction of the resources files that //are requested var hrefs = xmlBody.Children.Where(node => node.NodeName == "href").Select(href => href.Value); var result = new Dictionary <string, string>(); // process the requested resources foreach (var href in hrefs) { var fs = new FileSystemManagement(); var resourceContent = await fs.GetCalendarObjectResource(href); result.Add(href, resourceContent); } await ReportResponseBuilder(result .Select( x => new KeyValuePair <string, VCalendar>(x.Key, string.IsNullOrEmpty(x.Value) ? null : VCalendar.Parse(x.Value))), propNode, httpContext); }
/// <summary> /// The CALDAV:calendar-query REPORT performs a search for all calendar object resources that match a /// specified filter. The response of this report will contain all the WebDAV properties and calendar object /// resource data specified in the request. In the case of the CALDAV:calendar-data XML element, one can /// explicitly specify the calendar components and properties that should be returned in the calendar object /// resource data that matches the filter. /// </summary> /// <param name="xmlDoc">The body of the request.</param> /// <param name="collectionURl"></param> /// <param name="httpContext"></param> /// <returns></returns> public async Task CalendarQuery(IXMLTreeStructure xmlDoc, string collectionURl, HttpContext httpContext) { IFileSystemManagement fs = new FileSystemManagement(); // take the first prop node to know the data that // should ne returned IXMLTreeStructure propNode; xmlDoc.GetChildAtAnyLevel("prop", out propNode); //get the filters to be applied IXMLTreeStructure componentFilter; xmlDoc.GetChildAtAnyLevel("filter", out componentFilter); var userResources = new Dictionary <string, string>(); await fs.GetAllCalendarObjectResource(collectionURl, userResources); var userCalendars = userResources.ToDictionary(userResource => userResource.Key, userResource => VCalendar.Parse(userResource.Value)); //apply the filters to the calendars var filteredCalendars = userCalendars.Where(x => x.Value.FilterResource(componentFilter)); await ReportResponseBuilder(filteredCalendars, propNode, httpContext); }
/// <summary> /// Apply a text-match filter to the given value. /// </summary> /// <param name="propertyValue">The property value where to apply the filter.</param> /// <param name="filter">The filter to apply.</param> /// <returns>True if pass the filter, false otherwise.</returns> private static bool TextMatchFilter(this string propertyValue, IXMLTreeStructure filter) { var negateCond = false; string negCondStr; //if the filter contains a negate condition attr then take it if (filter.Attributes.TryGetValue("negate-condition", out negCondStr)) { negateCond = negCondStr == "yes"; } bool result; //add the default collation if the node doesnt contains one. if (!filter.Attributes.ContainsKey("collation")) { filter.Attributes["collation"] = "i;ascii-casemap"; } switch (filter.Attributes["collation"]) { case "i;octet": var propValueOctet = Encoding.ASCII.GetBytes(propertyValue); var filterValueOctet = Encoding.ASCII.GetBytes(filter.Value); result = ApplyTextFilter(propValueOctet, filterValueOctet); return(negateCond ? !result : result); case "i;ascii-casemap": var propValueAscii = propertyValue.Select(x => (int)x).ToArray(); var filterValueAscii = filter.Value.Select(x => (int)x).ToArray(); result = ApplyTextFilter(propValueAscii, filterValueAscii); return(negateCond ? !result : result); default: throw new NotImplementedException("Implement the error for return"); } }
/// <summary> /// Apply a filter to the param of the property with name /// equal the given param /// </summary> /// <param name="property"></param> /// <param name="filters"></param> /// <returns>True if the param pass the filters, false otherwise.</returns> private static bool ParamFilter(this IComponentProperty property, IXMLTreeStructure filters) { var paramName = filters.Attributes["name"]; var param = property.PropertyParameters.First(x => x.Name == paramName); if (param == null) { return(false); } foreach (var filter in filters.Children) { switch (filter.NodeName) { case "text-match": var result = param.Value.TextMatchFilter(filter); if (!result) { return(false); } break; default: throw new NotImplementedException(@"The filter {filter.NodeName} is not implemented yet."); } } return(true); }
/// <summary> /// Take the calendar that passed the filter and /// create the multi-status xml. /// </summary> /// <param name="resources">The resources to be returned</param> /// <param name="calDataNode"> /// THis is the node with name ="prop" /// When used in a calendaring REPORT request, the CALDAV:calendar-data XML /// element specifies which parts of calendar object resources need to be returned in the /// response.If the CALDAV:calendar-data XML element doesn't contain any /// CALDAV:comp element, calendar object resources will be returned in their entirety. /// </param> /// <param name="httpContext"></param> /// <returns>The string representation of the multi-status Xml with the results.</returns> public async Task ReportResponseBuilder(IEnumerable <KeyValuePair <string, VCalendar> > resources, IXMLTreeStructure calDataNode, HttpContext httpContext) { var multistatusNode = new XmlTreeStructure("multistatus", "DAV:") { Namespaces = new Dictionary <string, string> { { "D", "DAV:" }, { "C", "urn:ietf:params:xml:ns:caldav" } } }; //take the node that specified the comp and properties //to return foreach (var resource in resources) { IXMLTreeStructure statusNode; //each returned resource has is own response and nodes var responseNode = new XmlTreeStructure("response", "DAV:"); var hrefNode = new XmlTreeStructure("href", "DAV:"); var href = resource.Key[0] != '/' ? "/" + resource.Key : resource.Key; hrefNode.AddValue(href); //href is a child pf response responseNode.AddChild(hrefNode); //if the resource is null it was not foound so // add an error status if (resource.Value == null) { statusNode = new XmlTreeStructure("status", "DAV:"); statusNode.AddValue("HTTP/1.1 404 Not Found"); responseNode.AddChild(statusNode); } else { var propstatNode = new XmlTreeStructure("propstat", "DAV:"); //that the requested data var propStats = await ProccessPropNode(calDataNode, resource); foreach (var propStat in propStats) { responseNode.AddChild(propStat); } } multistatusNode.AddChild(responseNode); } var responseText = multistatusNode.ToString(); var responseBytes = Encoding.UTF8.GetBytes(responseText); httpContext.Response.ContentLength = responseBytes.Length; await httpContext.Response.Body.WriteAsync(responseBytes, 0, responseBytes.Length); }
private async Task <bool> BuiltResponseForSet(string url, string calendarResourceId, bool errorOccurred, IXMLTreeStructure setTree, IXMLTreeStructure response) { //For each property it is tried to remove, if not possible change the error occured to true and //continue setting dependency error to the rest. var prop = setTree.GetChild("prop"); var errorStack = new Stack <string>(); foreach (var property in prop.Children) { var propstat = new XmlTreeStructure("propstat", "DAV:"); var stat = new XmlTreeStructure("status", "DAV:"); var resProp = new XmlTreeStructure("prop", "DAV:"); resProp.AddChild(new XmlTreeStructure(property.NodeName, property.MainNamespace)); propstat.AddChild(stat); propstat.AddChild(resProp); response.AddChild(propstat); if (errorOccurred) { stat.Value = "HTTP/1.1 424 Failed Dependency"; } else { //Try to modify the specified property if it exist, if not try to create it //gets an error message from the stack in case of problems. errorOccurred = !(calendarResourceId != null ? await _resourceRespository.CreateOrModifyProperty(url, property.NodeName, property.MainNamespace, GetValueFromRealProperty(property), errorStack, false) : await _collectionRespository.CreateOrModifyProperty(url, property.NodeName, property.MainNamespace, GetValueFromRealProperty(property), errorStack, false)); //collection.CreateOrModifyProperty(property.NodeName, property.MainNamespace, // GetValueFromRealProperty(property), errorStack)); if (errorOccurred && errorStack.Count > 0) { stat.Value = errorStack.Pop(); } else { stat.Value = "HTTP/1.1 200 OK"; //db.SaveChanges(); } } } return(errorOccurred); }
private async Task <bool> BuiltResponseForRemove(string url, string calendarResourceId, bool errorOccurred, IXMLTreeStructure removeTree, IXMLTreeStructure response) { //For each property it is tried to remove, if not possible change the error occured to true and //continue setting dependency error to the rest. var prop = removeTree.GetChild("prop"); var errorStack = new Stack <string>(); foreach (var property in prop.Children) { //The structure for the response does not change. //It is constructed with a propstat and the value is never showed in the prop element. var propstat = new XmlTreeStructure("propstat", "DAV:"); var stat = new XmlTreeStructure("status", "DAV:"); var resProp = new XmlTreeStructure("prop", "DAV:"); propstat.AddChild(stat); propstat.AddChild(resProp); resProp.AddChild(new XmlTreeStructure(property.NodeName, property.MainNamespace)); response.AddChild(propstat); //If an error occurred previously the stat if 424 Failed Dependency. if (errorOccurred) { stat.Value = "HTTP/1.1 424 Failed Dependency"; } else { //Try to remove the specified property, gets an error message from the stack in case of problems. errorOccurred = !(calendarResourceId != null ? await _resourceRespository.RemoveProperty(url, new KeyValuePair <string, string>(property.NodeName, property.MainNamespace), errorStack) : await _collectionRespository.RemoveProperty(url, new KeyValuePair <string, string>(property.NodeName, property.MainNamespace), errorStack)); //collection.RemoveProperty(property.NodeName, property.MainNamespace, errorStack)); if (errorOccurred && errorStack.Count > 0) { stat.Value = errorStack.Pop(); } else { stat.Value = "HTTP/1.1 200 OK"; // db.SaveChanges(); } } } return(errorOccurred); }
/// <summary> /// The filters have to be applied in an specific component, property /// or param of a property. This method go deep in the calCOmponents following the /// treeStructure of the filter till it get the component where to apply the filter. /// </summary> /// <param name="container">The container of the components.</param> /// <param name="treeStructure">The IXMLTree where is the filter.</param> /// <param name="filter">Return The XmlTreeStructure node that contains the filter.</param> /// <param name="component">The final component where to apply the filter.</param> /// <returns>True if found the component, false otherwise.</returns> public static bool ComponentSeeker(this ICalendarComponentsContainer container, IXMLTreeStructure treeStructure, out IXMLTreeStructure filter, out ICalendarComponent component) { filter = null; component = null; while (true) { ICalendarComponent comp = null; IXMLTreeStructure compNode = null; treeStructure.GetChildAtAnyLevel("comp-filter", out compNode); if (compNode == null) { //if the filter doesn't has a child with comp-filter name //and the name of the current container is the same if (((ICalendarObject)container).Name == treeStructure.Attributes["name"]) { filter = treeStructure; component = container as ICalendarComponent; return(true); } else { return(false); } } var compName = compNode.Attributes["name"]; //if the container doesn't has a calComponent with the desired compName //then return false if (!container.CalendarComponents.ContainsKey(compName)) { return(false); } //take the comp with the desired name comp = container.CalendarComponents[compName].First(); var componentsContainer = comp as ICalendarComponentsContainer; //if the the filter has more components and the container has more calendarComp //then go deeper if (componentsContainer != null && compNode.Children.Any(x => x.NodeName == "comp-filter")) { container = componentsContainer; treeStructure = compNode; continue; } //if not then apply the filter in the comp component = comp; filter = compNode; return(true); } }
public async Task AclPrincipalPropSet(IXMLTreeStructure body, HttpResponse response) { //take the requested properties from the body // of the request IXMLTreeStructure propNode; //first take the node container of the property names body.GetChildAtAnyLevel("prop", out propNode); //take the children of the node, these are the proeprties var requestedProperties = propNode.Children.Select(x => new KeyValuePair <string, string>(x.NodeName, x.MainNamespace)); var colUrl = ""; //Take the resource with the href == to the given url //TODO: should the href property be store in a property? var resource = await _resourceRepository.GetAsync(colUrl); //take the string representation of the acl property //this property is stored in xml format so is needed to //be parsed to xml var aclProperty = resource.Properties.First(x => x.Name == "acl"); var aclXmlProperty = XDocument.Parse(aclProperty.Value); //take the href of the principals of the property var principalsURLs = aclXmlProperty.Elements("principal") .Select(x => x.Descendants("href").FirstOrDefault()); var principals = new Dictionary <Principal, IEnumerable <Property> >(); //take all the principals with its url equal to the givens foreach (var pUrl in principalsURLs) { var principal = _principalRepository.Get(pUrl.Value); if (principal != null) { principals.Add(principal, null); } } //take the requested properties from the principals foreach (var principal in principals) { principals[principal.Key] = principal.Key.TakeProperties(requestedProperties); } await WriteBody(response, principals); }
public void TakingCurrentUserPrivilegeSet() { var principal = new Principal { PrincipalURL = "principals/users/principal1" }; var aclProperty = PropertyCreation.CreateAclPropertyForUserCollections(principal.PrincipalURL); var permissions = principal.GetCurrentUserPermissions(aclProperty); IXMLTreeStructure child = null; Assert.Equal(permissions.NodeName, "current-user-privilege-set"); Assert.True(permissions.GetChildAtAnyLevel("read", out child)); Assert.True(permissions.GetChildAtAnyLevel("write", out child)); }
/// <summary> /// Extract all property names and property namespace from a prop element of a propfind body. /// </summary> /// <param name="propFindTree"></param> /// <returns></returns> private List <KeyValuePair <string, string> > ExtractPropertiesNameMainNS(IXMLTreeStructure propFindTree) { var retList = new List <KeyValuePair <string, string> >(); IXMLTreeStructure props; if (propFindTree.GetChildAtAnyLevel("prop", out props)) { retList.AddRange( props.Children.Select( child => new KeyValuePair <string, string>(child.NodeName, string.IsNullOrEmpty(child.MainNamespace) ? "DAV:" : child.MainNamespace))); } return(retList); }
/// <summary> /// The DAV:principal-match REPORT is used to identify all members (at /// any depth) of the collection identified by the Request-URI that are /// principals and that match the current user. /// So it takes the resources of the collection and see wich ones match /// the given principal. This is done comparing the principal's email /// of the resource with the email of the given principal. /// </summary> /// <returns></returns> public async Task PrincipalMatch(IXMLTreeStructure body, string principalEmail, string href, HttpResponse response) { //take the collection with the given href var col = _collectionRepository.Get(href); //if the collection doesnt exit then return an error if (col == null) { await ReturnError(response, "Not Found", 404, href); } //take all the resources from the collection. //var colResources = col.CalendarResources.Where(x=>x.) }
/// <summary> /// Return the string representation of the VCALENDAR object /// with just the given properties and components. /// </summary> /// <param name="calData">Properties and components to print.</param> /// <returns></returns> public string ToString(IXMLTreeStructure calData) { var strBuilder = new StringBuilder(); strBuilder.AppendLine("BEGIN:VCALENDAR"); ///take the first node in the tree that contains VCALENDAR in the /// attr "name" var vCal = calData.Children.Where(x => x.NodeName == "comp"). First(x => x.Attributes.ContainsValue("VCALENDAR")); ///take the name of the properties in VCALENDAR that have to be /// returned var propToReturn = vCal.Children .Where(x => x.NodeName == "prop") .SelectMany(x => x.Attributes.Values); ///take those properties from the VCalendar object foreach (var property in Properties.Values.Where(x => propToReturn.Contains(x.Name))) { strBuilder.Append(property); } ///take the desired calendar component names from the tree var compToReturn = vCal.Children.Where(x => x.NodeName == "comp"). SelectMany(x => x.Attributes.Values); ///take the calendar components from the VCALENDAR object foreach (var component in CalendarComponents.Where(comp => compToReturn.Contains(comp.Key))) { ///take the properties of the current component that are in the /// node of the tree with name = to the current component. var properties = vCal.Children.Where(x => x.NodeName == "comp") .First(x => x.Attributes.ContainsValue(component.Key)) .Children.SelectMany(x => x.Attributes.Values); ///take the string representation of the current cal component /// and all the requested properties strBuilder.Append(component.Value.First().ToString(properties)); } strBuilder.AppendLine("END:VCALENDAR"); return(strBuilder.ToString()); }
/// <summary> /// Apply different filters to the given calendar. /// </summary> /// <param name="calendar">THe calendar to apply the filter.</param> /// <param name="filterTree">The filter container. The node in the xml with name = "filter"</param> /// <returns>True if the calendar pass the filter, false otherwise</returns> public static bool FilterResource(this VCalendar calendar, IXMLTreeStructure filterTree) { //first get the component in the calendar where to apply the filter. IXMLTreeStructure filtersContainer; ICalendarComponent component; //take the first node with "comp-filter" name, // this is the node with name="VCALENDAR" filterTree.GetChildAtAnyLevel("comp-filter", out filterTree); //get the component and filter in the position of the first component // required by the filter that is a child of VCALENDAR if (!ComponentSeeker(calendar, filterTree, out filtersContainer, out component)) { return(false); //if the container doesn't have the requested comp then return false; } foreach (var filter in filtersContainer.Children) { switch (filter.NodeName) { case "prop-filter": var result = component.PropertyFilter(filter); if (!result) { return(false); } break; case "time-range": result = component.ApplyTimeFilter(filter); if (!result) { return(false); } break; default: throw new NotImplementedException($"The filter with name{filter.NodeName} isn't implemented yet"); } } return(true); }
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously public async Task PrincipalPropertySearch(IXMLTreeStructure body, HttpRequest request, HttpResponse response) #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously { throw new NotImplementedException(); }
/// <summary> /// Apply the time-filter to the /// </summary> /// <param name="resources"></param> /// <param name="start"></param> /// <param name="end"></param> /// <param name="filter"></param> /// <returns></returns> public static Dictionary <string, VCalendar> TimeFilter(this Dictionary <string, VCalendar> resources, DateTime start, DateTime end, IXMLTreeStructure filter) { foreach (var resource in resources) { var compNode = filter.GetChild("comp-filter"); var compName = compNode.Attributes["name"]; if (resource.Value.CalendarComponents.ContainsKey(compName)) { } else { continue; } } return(null); }
/// <summary> /// Take the prop node that specified the properties and /// component that are requested, extract this data from /// the system and the VCalendar and return the container /// node with this data. /// </summary> /// <param name="incomPropNode"> /// This node contains the requested data. Is the first prop node /// of the calendar-query. /// </param> /// <param name="resource">The calendar where to extract the data.</param> /// <returns>Return the prop node that contains the requested data</returns> private async Task <List <IXMLTreeStructure> > ProccessPropNode(IXMLTreeStructure incomPropNode, KeyValuePair <string, VCalendar> resource) { var output = new List <IXMLTreeStructure>(); var resPropertiesOk = new List <XmlTreeStructure>(); var resPropertiesNotExist = new List <XmlTreeStructure>(); var href = resource.Key[0] != '/' ? "/" + resource.Key : resource.Key; var calResource = _resourceRepository.Get(href); foreach (var prop in incomPropNode.Children) { //create an instance of a XMlTreeStrucure with the same name and //ns that the requested var currentPropNode = new XmlTreeStructure(prop.NodeName, prop.MainNamespace); switch (prop.NodeName) { //if the requested prop is calendar data then take the content of the //resource case "calendar-data": //see if the calendar-data describes pros to take // if does then take them if not take it all currentPropNode.AddValue(prop.Children.Any() ? resource.Value.ToString(prop) : resource.Value.ToString()); resPropertiesOk.Add(currentPropNode); break; //if not try to take the property from the resource's properties default: var currentProperty = calResource.Properties.FirstOrDefault(p => p.Name == prop.NodeName); currentPropNode.AddValue(currentProperty != null ? currentProperty.PropertyRealValue() : ""); if (currentProperty != null) { resPropertiesOk.Add(currentPropNode); } else { resPropertiesNotExist.Add(currentPropNode); } break; } } #region Adding nested propOK //This procedure has been explained in another method. //Here the retrieve properties are grouped. var propstatOK = new XmlTreeStructure("propstat", "DAV:"); var propOk = new XmlTreeStructure("prop", "DAV:"); //Here i add all properties to the prop. foreach (var property in resPropertiesOk) { propOk.AddChild(property); } propstatOK.AddChild(propOk); #endregion #region Adding nested status OK var statusOK = new XmlTreeStructure("status", "DAV:"); statusOK.AddValue("HTTP/1.1 200 OK"); propstatOK.AddChild(statusOK); #endregion #region Adding nested propWrong //Here the properties that could not be retrieved are grouped. var propstatWrong = new XmlTreeStructure("propstat", "DAV:"); var propWrong = new XmlTreeStructure("prop", "DAV:"); //Here i add all properties to the prop. foreach (var property in resPropertiesNotExist) { propWrong.AddChild(property); } propstatWrong.AddChild(propWrong); #endregion #region Adding nested status Not Found var statusWrong = new XmlTreeStructure("status", "DAV:"); statusWrong.AddValue("HTTP/1.1 400 Not Found"); propstatWrong.AddChild(statusWrong); #endregion #region Adding responseDescription when wrong //Here i add an description for explain the errors. //This should be aplied in all method with an similar structure but for the moment is only used here. //However this is not required. var responseDescrpWrong = new XmlTreeStructure("responsedescription", "DAV:"); responseDescrpWrong.AddValue("The properties doesn't exist"); propstatWrong.AddChild(responseDescrpWrong); #endregion if (resPropertiesOk.Any()) { output.Add(propstatOK); } if (resPropertiesNotExist.Any()) { output.Add(propstatWrong); } return(output); }
/// <summary> /// Apply the time filter to the given component as /// defined in 9.9 CALDAV:time-range XML Element. /// </summary> /// <param name="component">The component where to apply the filter.</param> /// <param name="filter">The filter to apply.</param> /// <returns>True if the component pass the filter, false otherwise.</returns> private static bool ApplyTimeFilter(this ICalendarComponent component, IXMLTreeStructure filter) { DateTime?start; DateTime?end; //get the start and time attributes of the filter. if (filter.Attributes.ContainsKey("start")) { filter.Attributes["start"].ToDateTime(out start); } else //if not then assign infinite { start = DateTime.MinValue; } if (filter.Attributes.ContainsKey("end")) { filter.Attributes["end"].ToDateTime(out end); } else //if not then assign -infinite { end = DateTime.MaxValue; } //Get the DTSTART of the component. var compDTSTART = component.GetComponentProperty("DTSTART") == null ? DateTime.MaxValue : ((IValue <DateTime>)component.GetComponentProperty("DTSTART")).Value; //if the component contains RRULES then expand the dts IEnumerable <DateTime> expandedDates = null; if (component.MultipleValuesProperties.ContainsKey("RRULE")) { expandedDates = compDTSTART.ExpandTime(component.GetMultipleCompProperties("RRULE").Select( x => ((IValue <Recur>)x).Value).ToList()); } if (expandedDates == null) { expandedDates = new List <DateTime> { compDTSTART } } ; if (component is VEvent) { return(component.ApplyTimeFilterToVEVENT(start.Value, end.Value, expandedDates)); } if (component is VTodo) { return(component.ApplyTimeFilterToVTODO(start.Value, end.Value, expandedDates)); } if (component is VJournal) { throw new NotImplementedException("The doesn't support the VJOURNALs yet."); } if (component is VFreebusy) { return(component.ApplyTimeFilterToVFREEBUSY(start.Value, end.Value)); } if (component is VAlarm) { return(component.ApplyTimeFilterToVALARM(start.Value, end.Value)); } return(false); }
/// <summary> /// Apply the given filters to to a property in the cal component. /// </summary> /// <param name="component">The component where to apply the filters.</param> /// <param name="filter">Filters container.</param> /// <returns>True if the component pass the filters, false otherwise.</returns> private static bool PropertyFilter(this ICalendarComponent component, IXMLTreeStructure filter) { //take the property where to apply the filter. var propName = filter.Attributes["name"]; //if the comp doesn't has the desired prop return false //iterate over the filters, if one is false then //returns false //this is gonna be use for the ATTENDEE and RRULE // properties foreach (var propFilter in filter.Children) { var result = false; IComponentProperty propValue; List <IComponentProperty> propMultiValues; switch (propFilter.NodeName) { case "text-match": //have to check this line in each of the cases because the //"is not defined" if (component.Properties.TryGetValue(propName, out propValue)) { result = propValue.StringValue.TextMatchFilter(propFilter); } else if (component.MultipleValuesProperties.TryGetValue(propName, out propMultiValues)) { result = propMultiValues.Any(x => x.StringValue.TextMatchFilter(propFilter)); } if (!result) { return(false); } break; case "param-filter": if (component.Properties.TryGetValue(propName, out propValue)) { result = propValue.ParamFilter(propFilter); } else if (component.MultipleValuesProperties.TryGetValue(propName, out propMultiValues)) { result = propMultiValues.Any(x => x.ParamFilter(propFilter)); } if (!result) { return(false); } break; case "is-not-defined": //if the component has a single prop with the given na,e // return false if (component.Properties.ContainsKey(propName)) { return(false); } //else if contains a multiple property with the given name // returns false if (component.GetMultipleCompProperties(propName) != null) { return(false); } break; default: throw new NotImplementedException( $"THe property filter {propFilter.NodeName} is not implemented"); } } return(true); }
/// <summary> /// This method only functionality is to take the string representation of a property without /// the first line, witch is the template for xml. /// </summary> /// <param name="property"></param> /// <returns></returns> private string GetValueFromRealProperty(IXMLTreeStructure property) { var temp = property.ToString(); return(temp.Replace(@"<?xml version=""1.0"" encoding=""utf-8""?>", "").TrimStart()); }