/// <summary>
		/// 	Embeds the parameter.
		/// </summary>
		/// <param name="ic"> The ic. </param>
		/// <param name="pr"> The pr. </param>
		/// <param name="tc"> The tc. </param>
		/// <param name="t"> The t. </param>
		/// <remarks>
		/// </remarks>
		private void EmbedParameter(string ic, XElement pr, string tc, ThemaDescriptor t) {
			var code = t.Substitute(pr.Id());
			if (Context.ParameterIndex.ContainsKey(code)) {
				ReplaceParameter(pr, code);
			}
			else {
				var message = "item " + tc + "/" + ic + " references non-existed parameter " + code;
				if (Context.Project.NonResolvedParameterIsError) {
					AddError(
						ErrorLevel.Error,
						message,
						"TE2201",
						null,
						pr.Describe().File,
						pr.Describe().Line
						);
					UserLog.Error(message);
					return;
				}
				AddError(
					ErrorLevel.Warning,
					message,
					"TW2201",
					null,
					pr.Describe().File,
					pr.Describe().Line
					);
				UserLog.Warn(message);
				pr.Remove();
			}
		}
		/// <summary>
		/// 	Cleanups the specified thema.
		/// </summary>
		/// <param name="thema"> The thema. </param>
		/// <param name="key"> The key. </param>
		/// <remarks>
		/// </remarks>
		private static void Cleanup(ThemaDescriptor thema, string key) {
			if (thema.IsGroupActive(key)) {
				return;
			}
			foreach (var p in thema.ResolvedParameters.Keys.ToArray().Where(p => p.EndsWith(key))) {
				thema.ResolvedParameters.Remove(p);
			}
		}
		/// <summary>
		/// 	Nots the match cluster.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		private bool NotMatchCluster(ThemaDescriptor t) {
			var proceed = false;
			if (t.IsWorking) {
				var cl = ComplexStringHelper.Parse(t.GetParam("cluster"));
				proceed = !cl.Any(c => Context.Project.Clusters.Contains(c.Key));
			}
			return proceed;
		}
		/// <summary>
		/// 	Resolves the specified td.
		/// </summary>
		/// <param name="td"> The td. </param>
		/// <param name="key"> The key. </param>
		/// <param name="src"> The SRC. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		protected virtual string Resolve(ThemaDescriptor td, string key, string src = null) {
			var val = td.GetParam(key, src);
			if (0 != val.IndexOf('@') && -1 == val.IndexOf("${", StringComparison.InvariantCulture)) {
				return val;
			}
			val = Doreplace(td, val, src);
			td.ResolvedParameters[key] = val;
			return val;
		}
		/// <summary>
		/// 	Resolves the use sets.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <param name="i"> The i. </param>
		/// <param name="c"> The c. </param>
		/// <remarks>
		/// </remarks>
		private void ResolveUseSets(ThemaDescriptor t, XElement i, string c) {
			foreach (var ac in i.Elements(Context.Project.ImportSubsetElementName).ToArray()) {
				var code = ac.Id();
				if (null != t) {
					code = t.Substitute(code, c, true);
				}
				if (code.IsEmpty()) {
					continue;
				}
				if (Context.SubsetIndex.ContainsKey(code)) {
					ac.ReplaceWith(ResolveSubset(code));
				}
				else {
					var message = "item " + (null == t ? i.Id() : t.Code) + "/" + c + " references non-existed subset " + code;
					if (Context.Project.NonResolvedSubsetIsError) {
						AddError(
							ErrorLevel.Error,
							message,
							"TE2101",
							null,
							i.Describe().File,
							i.Describe().Line
							);
						UserLog.Error(message);
						return;
					}
					AddError(
						ErrorLevel.Warning,
						message,
						"TW2101",
						null,
						i.Describe().File,
						i.Describe().Line
						);
					UserLog.Warn(message);
					ac.Remove();
				}
			}
		}
		/// <summary>
		/// 	Internals the process.
		/// </summary>
		/// <remarks>
		/// </remarks>
		protected override void InternalProcess() {
			var processed = 1;
			var themaidx = 100;
			while (processed > 0) {
				processed = 0;
				foreach (var file in Context.SourceFiles) {
					if (!Context.SourceFileXml.ContainsKey(file)) {
						continue;
					}
					var xml = Context.SourceFileXml[file];
					foreach (var e in xml.Elements().ToArray()) {
						var code = e.Id();
						if (code.IsEmpty()) {
							continue;
						}

						if (e.Name.LocalName != "thema" && e.Name.LocalName != "library" && !Context.Themas.ContainsKey(e.Name.LocalName)) {
							continue;
						}
						LogCreateRecreate(file, code);
						var d = new ThemaDescriptor();
						d.ResolvedParameters["fileidx"] = themaidx.ToString(CultureInfo.InvariantCulture);
						d.Code = code;
						d.Fullsource = e;
						if (e.Name.LocalName == "library") {
							d.SelfParameters["library"] = "true";
						}
						else if (e.Name.LocalName != "thema") {
							d.Imports.Add(e.Name.LocalName);
						}
						Context.Themas[code] = d;
						processed++;
						e.Remove();
						themaidx += 10;
					}
				}
			}
		}
Example #7
0
		/// <summary>
		/// 	Generates the specified t.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		public XElement Generate(ThemaDescriptor t) {
			var result = new XElement("thema");
			foreach (var p in SaveAbleParameterKeys(t)) {
				result.Add(new XAttribute(p, t.ResolvedParameters[p]));
			}
			var imports = t.Imports.ConcatString();
			if (imports.IsNotEmpty()) {
				result.Add(new XElement("imports", t.Imports.ConcatString()));
			}
			XElement tmp;
			foreach (var link in t.Links) {
				result.Add(tmp = new XElement("link",
				                              new XAttribute("type", link.Type.Code),
				                              new XAttribute("target", link.TargetCode)
					                 ));
				if (link.Value.IsNotEmpty()) {
					tmp.Add(new XAttribute("value", link.Value));
				}
			}
			foreach (var link in t.BackLinks) {
				result.Add(tmp = new XElement("backlink",
				                              new XAttribute("type", link.Type.Code),
				                              new XAttribute("source", link.SourceCode)
					                 ));
				if (link.Value.IsNotEmpty()) {
					tmp.Add(new XAttribute("value", link.Value));
				}
			}
			foreach (var i in t.Items) {
				i.Value.SetAttributeValue("code", i.Key);
				i.Value.SetAttributeValue("id", i.Key);
				result.Add(i.Value);
			}
			result.Add(t.Fullsource.Elements());
			return result;
		}
		/// <summary>
		/// 	Resolves the structure and org nodes.
		/// </summary>
		/// <param name="orgnodes"> The orgnodes. </param>
		/// <param name="themas"> The themas. </param>
		/// <remarks>
		/// </remarks>
		public void ResolveStructureAndOrgNodes(OrgNodeCollection orgnodes, ThemaDescriptor[] themas) {
			BindProcessIns();
			if (null != orgnodes) {
				BindOrgNodes(orgnodes);
			}
			if (null != themas) {
				BindThemas(themas);
			}
		}
		/// <summary>
		/// 	Makeerrors the specified r.
		/// </summary>
		/// <param name="r"> The r. </param>
		/// <param name="t"> The t. </param>
		/// <param name="ic"> The ic. </param>
		/// <param name="desc"> The desc. </param>
		/// <param name="error"> The error. </param>
		/// <param name="code"> The code. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		private bool Makeerror(XNode r, ThemaDescriptor t, string ic, XmlExtensions.XmlElementDescriptor desc, string error,
		                       int code) {
			r.Remove();
			var message = string.Format("error in uselib resolution in {0}/{1} {2}:{3} - {4}", t.Code, ic, desc.File,
			                            desc.Line,
			                            error);
			var ecprefix = "WRLIBR0";
			var level = ErrorLevel.Warning;
			if (Context.Project.NonResolvedLibraryIsError) {
				ecprefix = "ERLIBR0";
				level = ErrorLevel.Error;
			}
			var ecode = ecprefix + code;
			AddError(level, message, ecode, null, desc.File, desc.Line);
			if (ErrorLevel.Error == level) {
				UserLog.Error(message);
			}
			else {
				UserLog.Warn(message);
			}
			return ErrorLevel.Error == level;
		}
Example #10
0
		/// <summary>
		/// 	Saves the able parameter keys.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		private IEnumerable<string> SaveAbleParameterKeys(ThemaDescriptor t) {
			return t.ResolvedParameters.Keys
				.OrderBy(x =>
					{
						if (Context.Project.AttributeOrder.Contains(x)) {
							return
								Context.Project.AttributeOrder.IndexOf(x).ToString("0000");
						}
						return "ZZZ_" + x;
					}).ToArray()
				.Where(p => null == Context.Project.NonSaveParameters ||
				            null == Context.Project.NonSaveParameters.FirstOrDefault(
					            x => Regex.IsMatch(p, x, RegexOptions.Compiled)));
		}
		/// <summary>
		/// 	Doreplaces the specified td.
		/// </summary>
		/// <param name="td"> The td. </param>
		/// <param name="val"> The val. </param>
		/// <param name="src"> The SRC. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		protected string Doreplace(ThemaDescriptor td, string val, string src) {
			Match m;
			if (0 == val.IndexOf('@') && (m = _atregex.Match(val)).Success) {
				val = Resolve(td, m.Groups[1].Value, src);
			}
			else {
				val = _inregex.Replace(val, i => Resolve(td, i.Groups[1].Value));
			}
			return val;
		}
		/// <summary>
		/// 	Resolves the specified td.
		/// </summary>
		/// <param name="td"> The td. </param>
		/// <param name="key"> The key. </param>
		/// <param name="src"> The SRC. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		protected override string Resolve(ThemaDescriptor td, string key, string src = null) {
			return td.GetParam(key, src);
		}
		/// <summary>
		/// 	Nons the inheritable parameter.
		/// </summary>
		/// <param name="thema"> The thema. </param>
		/// <param name="rp"> The rp. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		private bool NonInheritableParameter(ThemaDescriptor thema, KeyValuePair<string, string> rp) {
			if (-1 != Context.Project.NonInheritableParameters.IndexOf(rp.Key)) {
				return true;
			}
			if (!thema.IsGeneric && rp.Key.EndsWith(".")) {
				return true;
			}
			return rp.Key.StartsWith("__PLUS__") || rp.Key.StartsWith("__MUNIS__");
		}
		/// <summary>
		/// 	Resolves the parameters.
		/// </summary>
		/// <param name="thema"> The thema. </param>
		/// <remarks>
		/// </remarks>
		private void ResolveParameters(ThemaDescriptor thema) {
			if (thema.ParametersResolved) {
				return;
			}
			// cluster is must-be property, if no imports and self setted, set it as DEFAULT
			if (thema.Imports.Count == 0) {
				thema.ResolvedParameters["cluster"] = "DEFAULT";
			}
			foreach (var importthema in thema.Imports.Select(import => Context.Themas[import])) {
				ResolveParameters(importthema);
				foreach (var rp in importthema.ResolvedParameters.Where(rp => !NonInheritableParameter(thema, rp))) {
					thema.ResolvedParameters[rp.Key] = rp.Value;
				}
			}
			foreach (
				var sp in
					thema.SelfParameters.OrderBy(
						x => x.Key.StartsWith("__PLUS__") ? "ZZ0" + x.Key : (x.Key.StartsWith("__MINUS__") ? "ZZ1" + x.Key : x.Key))) {
				var complex = new Complex(sp.Key);
				if ("" == complex.Type) {
					thema.ResolvedParameters[sp.Key] = sp.Value;
				}
				else {
					var current = "";
					if (thema.ResolvedParameters.ContainsKey(complex.Name)) {
						current = thema.ResolvedParameters[complex.Name];
					}
					current = complex.Type == "+"
						          ? ComplexStringHelper.Set(current, sp.Value)
						          : ComplexStringHelper.Remove(current, sp.Value);
					thema.ResolvedParameters[complex.Name] = current;
				}
			}
			if (thema.IsGeneric) {
				foreach (var p in thema.ResolvedParameters.Keys.ToArray()) {
					if (!p.EndsWith(".")) {
						continue;
					}
					var v = thema.ResolvedParameters[p];
					thema.ResolvedParameters.Remove(p);
					thema.ResolvedParameters[p.Substring(0, p.Length - 1) + thema.Index] = v;
				}

				foreach (var p in thema.ResolvedParameters.Keys.ToArray()) {
					var val = thema.ResolvedParameters[p];
					if (ThemaDescriptor.Atregex.IsMatch(val) && val.EndsWith(".")) {
						thema.ResolvedParameters[p] = val.Substring(0, val.Length - 1) + thema.Index;
					}
					else if (val.Contains("${")) {
						thema.ResolvedParameters[p] = ThemaDescriptor.Inregex.Replace(val, m =>
							{
								var v = m.Groups[1].Value;

								if (v == "@") {
									return thema.Index;
								}
								if (!v.EndsWith(".")) {
									return m.Value;
								}
								return
									"${" + v.Substring(0, v.Length - 1) +
									thema.Index + "}";
							});
					}
				}
			}

			thema.ParametersResolved = true;
		}
		/// <summary>
		/// 	Renders the group.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <param name="visited"> The visited. </param>
		/// <remarks>
		/// </remarks>
		private void RenderGroup(ThemaDescriptor t, ICollection<ThemaDescriptor> visited) {
			visited.Add(t);
			_current.Add(
				new XElement("tr",
				             new XAttribute("class", "group  level_0"),
				             new XElement("td", ++_rowcount),
				             new XElement("td", t.EffectiveIndex),
				             new XElement("td", new XElement("a",
				                                             new XAttribute("href",
				                                                            "view-source:file:///" + _folder + "/" + t.Code +
				                                                            ".thema.bxl"),
				                                             new XAttribute("target", "_blank"),
				                                             t.Code)),
				             new XElement("td", new XAttribute("class", "name"), t.Name),
				             new XElement("td", new XAttribute("class", "cluster"), t.Cluster),
				             new XElement("td", new XAttribute("class", "processes"), t.EcoProcess),
				             new XElement("td", new XAttribute("class", "roles"), t.Role),
				             new XElement("td", t.File),
				             new XElement("td", t.Line),
				             new XElement("td", new XAttribute("colspan", 10))
					)
				);
			var roots =
				Context.Themas.Values.Where(x => x.GroupCode == t.Code && x.ParentCode.IsEmpty()).OrderBy(
					x => string.Format("{0:000000} {1}", x.EffectiveIndex, x.Code)).ToArray();
			foreach (var r in roots) {
				RenderThema(r, visited, 1);
			}
		}
		/// <summary>
		/// 	Renders the thema.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <param name="visited"> The visited. </param>
		/// <param name="level"> The level. </param>
		/// <remarks>
		/// </remarks>
		private void RenderThema(ThemaDescriptor t, ICollection<ThemaDescriptor> visited, int level) {
			if (visited.Contains(t)) {
				return;
			}
			visited.Add(t);
			_current.Add(
				new XElement("tr",
				             new XAttribute("class", "thema level_" + level),
				             new XElement("td", ++_rowcount),
				             new XElement("td", t.EffectiveIndex),
				             new XElement("td", new XElement("a",
				                                             new XAttribute("href",
				                                                            "view-source:file:///" + _folder + "/" + t.Code +
				                                                            ".thema.bxl"),
				                                             new XAttribute("target", "_blank"),
				                                             t.Code)),
				             new XElement("td", new XAttribute("class", "name"), t.Name),
				             new XElement("td", new XAttribute("class", "cluster"), t.Cluster),
				             new XElement("td", new XAttribute("class", "processes"), t.EcoProcess),
				             new XElement("td", new XAttribute("class", "roles"), t.Role),
				             new XElement("td", t.File),
				             new XElement("td", t.Line),
				             new XElement("td", BuildSpec(t)),
				             new XElement("td", t.GroupCode),
				             new XElement("td", t.ParentCode),
				             new XElement("td", GetContent(t))
					)
				);
			var child =
				Context.Themas.Values.Where(x => x.ParentCode == t.Code).OrderBy(
					x => string.Format("{0:000000} {1}", x.EffectiveIndex, x.Code)).ToArray();
			foreach (var r in child) {
				RenderThema(r, visited, level + 1);
			}
		}
		/// <summary>
		/// 	Gets the content.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		private static IEnumerable<XNode> GetContent(ThemaDescriptor t) {
			return t.Items.Select(e => new XText(e.Key + "; ")).OfType<XNode>();
		}
		/// <summary>
		/// 	Binds the themas.
		/// </summary>
		/// <param name="themas"> The themas. </param>
		/// <remarks>
		/// </remarks>
		private void BindThemas(ThemaDescriptor[] themas) {
			foreach (var process in Index.Values) {
				foreach (var tr in process.ThemaRefs) {
					tr.ContainingProcess = process;
					var thema = themas.FirstOrDefault(x => x.Code == tr.Code && x.IsWorking);
					if (null == thema) {
						EmptyReferences.Add(tr);
					}
					else {
						tr.Thema = thema;
					}
				}
			}
		}
		/// <summary>
		/// 	Builds the spec.
		/// </summary>
		/// <param name="t"> The t. </param>
		/// <returns> </returns>
		/// <remarks>
		/// </remarks>
		private static IEnumerable<XNode> BuildSpec(ThemaDescriptor t) {
			if (!t.IsLibrary) {
				yield break;
			}
			yield return new XText("Библиотека");
			yield return new XElement("br");
		}