/// <summary> /// Build name from captured part values. /// </summary> /// <param name="pattern"></param> /// <param name="parts"></param> /// <returns>Built name, or null if one of the required parts were not found.</returns> public static string Print(this ILinePattern pattern, IReadOnlyDictionary <string, string> parts) { // Count chars int length = 0; foreach (ILinePatternPart part in pattern.AllParts) { if (part.Text != null) { length += part.Text.Length; } else { string value = null; if (parts.TryGetValue(part.Identifier, out value) && !string.IsNullOrEmpty(value)) { length += part.PrefixSeparator.Length + part.PostfixSeparator.Length + value.Length; } else if (part.Required) { return(null); } } } // Put together string // .. without StringBuilder, there needs to be efficiencies since this may be called frequently. int ix = 0; char[] chars = new char[length]; foreach (ILinePatternPart part in pattern.AllParts) { if (part.Text != null) { part.Text.CopyTo(0, chars, ix, part.Text.Length); ix += part.Text.Length; } else { string value = null; if (parts.TryGetValue(part.Identifier, out value)) { if (string.IsNullOrEmpty(value)) { if (part.Required) { return(null); } else { continue; } } part.PrefixSeparator.CopyTo(0, chars, ix, part.PrefixSeparator.Length); ix += part.PrefixSeparator.Length; value.CopyTo(0, chars, ix, value.Length); ix += value.Length; part.PostfixSeparator.CopyTo(0, chars, ix, part.PostfixSeparator.Length); ix += part.PostfixSeparator.Length; } } } return(new string(chars)); }
/// <summary> /// Create tree structure from source of flat key values. /// </summary> /// <param name="lines"></param> /// <param name="groupingPolicy"></param> /// <param name="parameterInfos"></param> /// <returns>tree root ""</returns> public static LineTree Create(IEnumerable <ILine> lines, ILinePattern groupingPolicy, IParameterInfos parameterInfos) { LineTree root = new LineTree(new LinePart(LineAppender.NonResolving, null)); root.AddRange(lines, groupingPolicy, parameterInfos); return(root); }
/// <summary> /// Construct regular expression with half filled parameters /// </summary> /// <param name="pattern"></param> /// <param name="filledParameters"></param> /// <returns></returns> public static Regex BuildRegex(this ILinePattern pattern, IReadOnlyDictionary <string, string> filledParameters) { string pattern_text = pattern.BuildRegexString(filledParameters); RegexOptions options = RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture; if (filledParameters == null || filledParameters.Count == 0) { options |= RegexOptions.Compiled; } return(new Regex(pattern_text, options)); }
private void OnMultiLinePatternSelectionChanged(LinePattern selected) { isChangingMultipleAttributes = true; using (frame.Project.Undo.UndoFrame) { for (int i = 0; i < selectedObjects.Count; ++i) { ILinePattern ilp = selectedObjects[i] as ILinePattern; if (ilp != null) { ilp.LinePattern = selected; } } } isChangingMultipleAttributes = false; MultiChangeDone(); }
public LinePatternSelectionProperty(string ResourceID, LinePatternList linePatternList, ILinePattern iLinePattern, bool includeUndefined) { this.linePatternList = linePatternList; resourceId = ResourceID; LinePattern select = iLinePattern.LinePattern; if (includeUndefined) { choices = new string[linePatternList.Count + 1]; for (int i = 0; i < linePatternList.Count; ++i) { choices[i + 1] = linePatternList[i].Name; } string undef = StringTable.GetString("LinePattern.Undefined"); // sollte es den Namen schon geben, werden solange - davor und dahintergemacht, bis es den Namen mehr gibt while (linePatternList.Find(undef) != null) { undef = "-" + undef + "-"; } choices[0] = undef; if (select != null) { base.selectedText = select.Name; } else { base.selectedText = undef; } } else { choices = new string[linePatternList.Count]; for (int i = 0; i < linePatternList.Count; ++i) { choices[i] = linePatternList[i].Name; } if (select != null) { base.selectedText = select.Name; } } this.iLinePattern = iLinePattern; toWatch = iLinePattern as IGeoObject; }
/// <summary> /// Match against string or filename. /// </summary> /// <param name="pattern"></param> /// <param name="text"></param> /// <param name="filledParameters"></param> /// <returns>match object</returns> public static ILinePatternMatch Match(this ILinePattern pattern, string text, IReadOnlyDictionary <string, string> filledParameters = null) { bool hasFilledParameters = false; if (filledParameters != null && filledParameters.Count > 0) { foreach (var kp in filledParameters) { if (kp.Value != null) { hasFilledParameters = true; break; } } } Regex regex = hasFilledParameters ? pattern.Regex : pattern.BuildRegex(filledParameters); System.Text.RegularExpressions.Match match = regex.Match(text); LinePatternMatch _match = new LinePatternMatch(pattern); if (match.Success) { foreach (ILinePatternPart part in pattern.CaptureParts) { string prefilled_value; if (hasFilledParameters && filledParameters.TryGetValue(part.Identifier, out prefilled_value)) { _match.PartValues[part.CaptureIndex] = prefilled_value; } else { Group g = match.Groups[part.Identifier]; if (g.Success) { _match.PartValues[part.CaptureIndex] = g.Value; } } } } return(_match); }
/// <summary> /// Test if <paramref name="parameters"/> fill all required parameters of <paramref name="pattern"/>. /// </summary> /// <param name="pattern"></param> /// <param name="parameters"></param> /// <param name="allParts">if true tests if all capture parts match, if false, if non-optional parts match</param> /// <returns></returns> public static bool TestSuccess(this ILinePattern pattern, IReadOnlyDictionary <string, string> parameters, bool allParts) { if (parameters == null) { return(false); } foreach (var part in pattern.CaptureParts) { if (!allParts && !part.Required) { continue; } string value; if (!parameters.TryGetValue(part.Identifier, out value)) { return(false); } if (value == null) { return(false); } } return(true); }
/// <summary> /// Checks whether an <see cref="IGeoObject"/> is accepted by this filter. /// To realize custom filters, override this method. /// </summary> /// <param name="go">The object beeing tested</param> /// <returns>true if accepted, fale otherwise</returns> public virtual bool Accept(IGeoObject go) { // jetzt so implementiert: wenn ein Attribut verlangt wird und ein Objekt nicht das // passende Interface hat, dann wird es nicht akzeptiert // wenn z.B. der Layer eines Objektes null ist, dann wird dieses von keinem Filter anerkannt if (acceptedLayers.Count > 0) { ILayer ilayer = go as ILayer; if (ilayer == null) { return(false); } if (ilayer.Layer == null) { return(false); } if (!acceptedLayers.ContainsKey(ilayer.Layer)) { return(false); } } if (acceptedColorDefs.Count > 0) { IColorDef iColorDef = go as IColorDef; if (iColorDef == null) { return(false); } if (iColorDef.ColorDef == null) { return(false); } if (!acceptedColorDefs.ContainsKey(iColorDef.ColorDef)) { return(false); } } if (acceptedLineWidths.Count > 0) { ILineWidth iLineWidth = go as ILineWidth; if (iLineWidth == null) { return(false); } if (iLineWidth.LineWidth == null) { return(false); } if (!acceptedLineWidths.ContainsKey(iLineWidth.LineWidth)) { return(false); } } if (acceptedLinePatterns.Count > 0) { ILinePattern iLinePattern = go as ILinePattern; if (iLinePattern == null) { return(false); } if (iLinePattern.LinePattern == null) { return(false); } if (!acceptedLinePatterns.ContainsKey(iLinePattern.LinePattern)) { return(false); } } if (acceptedDimensionStyles.Count > 0) { IDimensionStyle iDimensionStyle = go as IDimensionStyle; if (iDimensionStyle == null) { return(false); } if (iDimensionStyle.DimensionStyle == null) { return(false); } if (!acceptedDimensionStyles.ContainsKey(iDimensionStyle.DimensionStyle)) { return(false); } } if (acceptedHatchStyles.Count > 0) { IHatchStyle iHatchStyle = go as IHatchStyle; if (iHatchStyle == null) { return(false); } if (iHatchStyle.HatchStyle == null) { return(false); } if (!acceptedHatchStyles.ContainsKey(iHatchStyle.HatchStyle)) { return(false); } } if (acceptedTypes.Count > 0) { if (!acceptedTypes.ContainsKey(go.GetType())) { return(false); } } return(true); }
/// <summary> /// Create abstract file source. /// </summary> /// <param name="path"></param> /// <param name="filePattern"></param> public FilePatternSource(string path, ILinePattern filePattern) { this.Path = path ?? throw new ArgumentNullException(nameof(path)); this.FilePattern = filePattern ?? throw new ArgumentNullException(nameof(FilePattern)); }
public void InitMultiAttributeSelection() { if (multiLinePattern == null) { return; } LinePattern commonLinePattern = null; bool linePatternValid = true; for (int i = 0; i < selectedObjects.Count; ++i) { ILinePattern ilp = selectedObjects[i] as ILinePattern; if (linePatternValid && ilp != null) { if (commonLinePattern == null) { commonLinePattern = ilp.LinePattern; } else { linePatternValid = (ilp.LinePattern != null) && (commonLinePattern == ilp.LinePattern); } } } if (linePatternValid && commonLinePattern != null) { multiLinePattern.SetSelection(frame.Project.LinePatternList.FindIndex(commonLinePattern)); } else { multiLinePattern.SetSelection(-1); } LineWidth commonLineWidth = null; bool lineWidthValid = true; for (int i = 0; i < selectedObjects.Count; ++i) { ILineWidth ilp = selectedObjects[i] as ILineWidth; if (lineWidthValid && ilp != null) { if (commonLineWidth == null) { commonLineWidth = ilp.LineWidth; } else { lineWidthValid = (ilp.LineWidth != null) && (commonLineWidth == ilp.LineWidth); } } } if (lineWidthValid && commonLineWidth != null) { multiLineWidth.SetSelection(frame.Project.LineWidthList.FindIndex(commonLineWidth)); } else { multiLineWidth.SetSelection(-1); } Layer commonLayer = null; bool LayerValid = true; for (int i = 0; i < selectedObjects.Count; ++i) { ILayer ily = selectedObjects[i] as ILayer; if (LayerValid && ily != null) { if (commonLayer == null) { commonLayer = ily.Layer; } else { LayerValid = (ily.Layer != null) && (commonLayer == ily.Layer); } } } if (LayerValid && commonLayer != null) { multiLayer.SetSelection(frame.Project.LayerList.FindIndex(commonLayer)); } else { multiLayer.SetSelection(-1); } ColorDef commonColorDef = null; bool ColorDefValid = true; for (int i = 0; i < selectedObjects.Count; ++i) { IColorDef ily = selectedObjects[i] as IColorDef; if (ColorDefValid && ily != null) { if (commonColorDef == null) { commonColorDef = ily.ColorDef; } else { ColorDefValid = (ily.ColorDef != null) && (commonColorDef == ily.ColorDef); } } } if (ColorDefValid && commonColorDef != null) { multiColorDef.SetSelection(frame.Project.ColorList.FindIndex(commonColorDef)); } else { multiColorDef.SetSelection(-1); } Style commonStyle = null; bool StyleValid = true; for (int i = 0; i < selectedObjects.Count; ++i) { IStyle ily = selectedObjects[i] as IStyle; if (StyleValid && ily != null) { if (commonStyle == null) { commonStyle = ily.Style; } else { StyleValid = (ily.Style != null) && (commonStyle == ily.Style); } } } if (StyleValid && commonStyle != null) { multiStyle.SetSelection(frame.Project.StyleList.FindIndex(commonStyle)); } else { multiStyle.SetSelection(-1); } }
/// <summary> /// Add an enumeration of key,value pairs. Each key will constructed a new node. /// /// If <paramref name="groupingRule"/> the nodes are laid out in the order occurance of name pattern parts. /// /// For example grouping pattern "{Type}/{Culture}{anysection}{Key}" would order nodes as following: /// <code> /// "type:MyController": { /// "key:Success": "Success", /// "culture:en:key:Success": "Success", /// } /// </code> /// /// Non-capture parts such as "/" in pattern "{Section}/{Culture}", specify separator of tree node levels. /// /// </summary> /// <param name="tree"></param> /// <param name="lines"></param> /// <param name="groupingRule"></param> /// <param name="parameterInfos"></param> /// <returns></returns> public static ILineTree AddRange(this ILineTree tree, IEnumerable <ILine> lines, ILinePattern groupingRule, IParameterInfos parameterInfos) // Todo separate to sortRule + groupingRule { // Use another method //if (groupingRule == null) { node.AddRange(lines); return node; } StructList16 <ILineParameter> parameters = new StructList16 <ILineParameter>(null); foreach (var line in lines) { parameters.Clear(); line.GetParameterParts(ref parameters); parameterListSorter.Reverse(ref parameters); // Key for the current level. ILine levelKey = null; // Build levels with this collection List <ILine> key_levels = new List <ILine>(); // Visit both lists concurrently ILineParameter next_parameter = default; if (groupingRule != null) { foreach (var part in groupingRule.AllParts) { // Is not a capture part if (part.CaptureIndex < 0) { // Non-capture part has "/", go to next level. eg. "{nn}/{nn}" if (part.Text != null && part.Text.Contains("/")) { if (levelKey != null) { key_levels.Add(levelKey); } levelKey = null; } // Next part continue; } // Capture part has "/" in prefix, start next level if (levelKey != null && part.PrefixSeparator.Contains("/")) { if (levelKey != null) { key_levels.Add(levelKey); } levelKey = null; } // Look ahead to see if there is a parameter that matches this capture part int next_parameter_ix = -1; for (int ix = 0; ix < parameters.Count; ix++) { // Copy next_parameter = parameters[ix]; // Already added before if (next_parameter.ParameterName == null) { continue; } // Get name string parameter_name = next_parameter.ParameterName; // Parameter matches the name in the pattern's capture part if (parameter_name == part.ParameterName) { next_parameter_ix = ix; break; } // Matches with "anysection" //IParameterInfo info; //if (part.ParameterName == "anysection" && ParameterInfos.Default.TryGetValue(parameter_name, out info) && info.IsSection) { next_parameter_ix = ix; break; } } // No matching parameter for this capture part if (next_parameter_ix < 0) { continue; } // This part is canonical, hint, or parameter. if (!next_parameter.IsNonCanonicalKey(parameterInfos)) { // There (may be) are other canonical parts between part_ix and next_part_is. We have to add them here. for (int ix = 0; ix < next_parameter_ix; ix++) { // Copy ILineParameter parameter = parameters[ix]; // Has been added before if ((parameter.ParameterName == null) || parameter.IsNonCanonicalKey(parameterInfos)) { continue; } // Append to level's key levelKey = LineAppender.NonResolving.Create(levelKey, LineArgument.ToArgument(parameter)); // Mark handled parameters[ix] = unused; } } // Append to level's key levelKey = LineAppender.NonResolving.Create(levelKey, LineArgument.ToArgument(next_parameter)); // Mark handled parameters[next_parameter_ix] = unused; // Yield level if (part.PostfixSeparator.Contains("/")) { key_levels.Add(levelKey); levelKey = null; } } } // Append rest of the parameters for (int ix = 0; ix < parameters.Count; ix++) { // Copy ILineParameter parameter = parameters[ix]; if (parameter.ParameterName != null && parameter.ParameterName != "String") { levelKey = LineAppender.NonResolving.Create(levelKey, LineArgument.ToArgument(parameter)); } } // yield levelKey if (levelKey != null) { key_levels.Add(levelKey); levelKey = null; } // Yield line tree.AddRecursive(key_levels, line.GetString()); key_levels.Clear(); parameters.Clear(); } return(tree); }
/// <summary> /// Construct new match. /// </summary> /// <param name="pattern"></param> public LinePatternMatch(ILinePattern pattern) { this.Pattern = pattern; this.PartValues = new string[pattern.CaptureParts.Length]; }
/// <summary> /// Build regex pattern that captures same parts from filename string. /// /// For example "localization{-Culture}.ini" translates to regex "localization(-(?<Culture>.*))?.ini". /// This can be matched against filename "localization-en.ini" with group m.Group["Culture"].Value == "en". /// </summary> /// <paramref name="pattern"/> /// <paramref name="filledParameters"/>> /// <returns>regex</returns> public static string BuildRegexString(this ILinePattern pattern, IReadOnlyDictionary <string, string> filledParameters, BuildRegexFlags flags = BuildRegexFlags.All) { StringBuilder sb = new StringBuilder(); sb.Append('^'); for (int i = 0; i < pattern.AllParts.Length; i++) { ILinePatternPart part = pattern.AllParts[i]; // Add regular part if (part.Text != null) { sb.Append(Escape(part.Text, flags, BuildRegexFlags.Escape_NonPart)); continue; } string prefilled_value; if (filledParameters != null && filledParameters.TryGetValue(part.Identifier, out prefilled_value) && prefilled_value != null) { if (part.PrefixSeparator != null) { sb.Append(Escape(part.PrefixSeparator, flags, BuildRegexFlags.Escape_Prefix)); } sb.Append(Escape(prefilled_value, flags, BuildRegexFlags.Escape_Identifier)); if (part.PostfixSeparator != null) { sb.Append(Escape(part.PostfixSeparator, flags, BuildRegexFlags.Escape_Postfix)); } } else { sb.Append("("); if (part.PrefixSeparator != null) { sb.Append(Escape(part.PrefixSeparator, flags, BuildRegexFlags.Escape_Prefix)); } sb.Append("(?<"); sb.Append(Escape(part.Identifier, flags, BuildRegexFlags.Escape_Identifier)); sb.Append('>'); // Append type specific pattern Regex part_pattern = part.Regex; string pattern_text = part_pattern.ToString(); int start = 0, end = pattern_text.Length; if (pattern_text.Length > 0 && pattern_text[start] == '^') { start++; } if (pattern_text.Length > 0 && pattern_text[end - 1] == '$') { end--; } if (start < end) { sb.Append(pattern_text.Substring(start, end - start)); } sb.Append(')'); if (part.PostfixSeparator != null) { sb.Append(Escape(part.PostfixSeparator, flags, BuildRegexFlags.Escape_Postfix)); } sb.Append(")"); if (!part.Required) { sb.Append('?'); } } } sb.Append('$'); return(sb.ToString()); }
/// <summary> /// Builds name from captured part values. /// </summary> /// <param name="pattern"></param> /// <param name="partValues"></param> /// <returns>Built name, or null if one of the required parts were not found.</returns> public static string Print(this ILinePattern pattern, IEnumerable <string> partValues) { // Count chars int length = 0; IEnumerator <string> partValuesEtor = partValues.GetEnumerator(); foreach (ILinePatternPart part in pattern.AllParts) { if (part.Text != null) { length += part.Text.Length; } else { if (!partValuesEtor.MoveNext()) { return(null); } string value = partValuesEtor.Current; if (value != null) { length += part.PrefixSeparator.Length + part.PostfixSeparator.Length + value.Length; } } } // Put together string // .. without StringBuilder, there needs to be efficiencies since this may be called frequently. int ix = 0; char[] chars = new char[length]; partValuesEtor.Reset(); foreach (ILinePatternPart part in pattern.AllParts) { if (part.Text != null) { part.Text.CopyTo(0, chars, ix, part.Text.Length); ix += part.Text.Length; } else { if (!partValuesEtor.MoveNext()) { return(null); } string value = partValuesEtor.Current; if (value == null) { if (part.Required) { return(null); } else { continue; } } part.PrefixSeparator.CopyTo(0, chars, ix, part.PrefixSeparator.Length); ix += part.PrefixSeparator.Length; value.CopyTo(0, chars, ix, value.Length); ix += value.Length; part.PostfixSeparator.CopyTo(0, chars, ix, part.PostfixSeparator.Length); ix += part.PostfixSeparator.Length; } } return(new string(chars)); }
/// <summary> /// Match parameters of an object and convert into a string. /// </summary> /// <param name="pattern"></param> /// <param name="key"></param> /// <returns>match as string or null</returns> public static string MatchToString(this ILinePattern pattern, ILine key) { ILinePatternMatch match = pattern.Match(key); return(pattern.Print(match.PartValues)); }
/// <summary> /// Create abstract file source. /// </summary> /// <param name="fileFormat"></param> /// <param name="path"></param> /// <param name="filePattern"></param> /// <param name="lineFormat"></param> public LineFilePatternSource(ILineFileFormat fileFormat, string path, ILinePattern filePattern, ILineFormat lineFormat) : base(path, filePattern) { this.FileFormat = fileFormat ?? throw new ArgumentNullException(nameof(fileFormat)); this.LineFormat = lineFormat; }
/// <summary> /// Create comparer to <paramref name="pattern"/>. /// </summary> /// <param name="pattern"></param> public LinePatternMatchComparer(ILinePattern pattern) { this.Pattern = pattern ?? throw new ArgumentNullException(nameof(pattern)); }
/// <summary> /// Create abstract file source. /// </summary> /// <param name="assembly"></param> /// <param name="resourcePattern"></param> public EmbeddedPatternSource(Assembly assembly, ILinePattern resourcePattern) { this.Assembly = assembly ?? throw new ArgumentNullException(nameof(assembly)); this.ResourcePattern = resourcePattern ?? throw new ArgumentNullException(nameof(resourcePattern)); }