/// <summary> /// Emits the node/edge/internal class object attribute initialization code in graph exporting /// for an attribute of internal class object type with the given value into the stream writer. /// </summary> private static void EmitAttributeInitialization(MainGraphExportContext mainGraphContext, IAttributeBearer owner, AttributeType attrType, object value, INamedGraph graph, StreamWriter sw) { if (owner is IGraphElement) { String persistentName = graph.GetElementName((IGraphElement)owner); sw.Write("@(\"{0}\").{1} = ", persistentName, attrType.Name); } else { String persistentName = mainGraphContext.GetOrAssignPersistentName((IObject)owner); sw.Write("@@(\"{0}\").{1} = ", persistentName, attrType.Name); } StringBuilder deferredInits = new StringBuilder(); if (value == null) { sw.Write("null"); } else if (value is IObject) { IObject obj = (IObject)value; EmitObjectFetchingOrCreation(mainGraphContext, obj.Type, obj, graph, sw, deferredInits); } else // container { EmitAttribute(mainGraphContext, attrType, value, graph, sw, deferredInits); } sw.WriteLine(); sw.Write(deferredInits); }
private static void AddGraphAttributes(MainGraphExportContext mainExportContext, StreamWriter writer) { foreach (KeyValuePair <string, GraphExportContext> kvp in mainExportContext.nameToContext) { GraphExportContext context = kvp.Value; GRSExport.EmitSubgraphAttributes(mainExportContext, context, writer); } }
/// <summary> /// Exports the given graph to the file given by the stream writer in grs format. /// Any errors will be reported by exception. /// Returns the graph export context of the main graph. /// </summary> /// <param name="graph">The graph to export. Must be a named graph.</param> /// <param name="sw">The stream writer of the file to export into. The stream writer is not closed automatically.</param> /// <param name="modelPathPrefix">Path to the model.</param> /// <param name="nonewgraph">If true, the new graph command is not emitted.</param> /// <param name="typesToAttributesToSkip">Gives a dictionary with type names containing a dictionary with attribute names that are not to be emitted</param> public static MainGraphExportContext ExportYouMustCloseStreamWriter(INamedGraph graph, StreamWriter sw, string modelPathPrefix, bool noNewGraph, Dictionary <String, Dictionary <String, String> > typesToAttributesToSkip) { MainGraphExportContext mainGraphContext = new MainGraphExportContext(graph); mainGraphContext.graphToContext[mainGraphContext.graph] = mainGraphContext; mainGraphContext.nameToContext[mainGraphContext.name] = mainGraphContext; mainGraphContext.modelPathPrefix = modelPathPrefix; mainGraphContext.noNewGraph = noNewGraph; if (typesToAttributesToSkip != null) { mainGraphContext.typesToAttributesToSkip = new Dictionary <string, Dictionary <string, string> >(); foreach (KeyValuePair <String, Dictionary <String, String> > typeContainingAttributeToSkip in typesToAttributesToSkip) { mainGraphContext.typesToAttributesToSkip.Add(typeContainingAttributeToSkip.Key, new Dictionary <string, string>()); foreach (KeyValuePair <String, String> attributeToSkip in typeContainingAttributeToSkip.Value) { mainGraphContext.typesToAttributesToSkip[typeContainingAttributeToSkip.Key].Add(attributeToSkip.Key, null); } } } sw.WriteLine("# begin of graph \"{0}\" saved by GrsExport", mainGraphContext.name); sw.WriteLine(); bool subgraphAdded = ExportSingleGraph(mainGraphContext, mainGraphContext, sw); if (subgraphAdded) { restart: foreach (KeyValuePair <string, GraphExportContext> kvp in mainGraphContext.nameToContext) { GraphExportContext context = kvp.Value; if (!context.isExported) { subgraphAdded = ExportSingleGraph(mainGraphContext, context, sw); if (subgraphAdded) { goto restart; } } } foreach (KeyValuePair <string, GraphExportContext> kvp in mainGraphContext.nameToContext) { GraphExportContext context = kvp.Value; EmitSubgraphAttributes(mainGraphContext, context, sw); } sw.WriteLine("in \"" + mainGraphContext.name + "\""); // after import in main graph } sw.WriteLine("# end of graph \"{0}\" saved by GrsExport", mainGraphContext.name); sw.WriteLine(); return(mainGraphContext); }
private static bool IsAttributeToBeSkipped(MainGraphExportContext mainGraphContext, AttributeType attrType) { if (mainGraphContext.typesToAttributesToSkip != null && mainGraphContext.typesToAttributesToSkip.ContainsKey(attrType.OwnerType.PackagePrefixedName) && mainGraphContext.typesToAttributesToSkip[attrType.OwnerType.PackagePrefixedName].ContainsKey(attrType.Name)) { return(true); } return(false); }
private static void EmitObjectFetchingOrCreation(MainGraphExportContext mainGraphContext, ObjectType objType, IObject obj, INamedGraph graph, StreamWriter sw, StringBuilder deferredInits) { if (mainGraphContext.HasPersistentName(obj)) { sw.Write("@@(\"{0}\")", mainGraphContext.GetOrAssignPersistentName(obj)); } else { EmitObjectCreation(mainGraphContext, objType, obj, graph, sw, deferredInits); } }
void EmitObjectAttributeAssignmentCreatingAsNeeded(IObject owner, AttributeType attrType, MainGraphExportContext mainExportContext, RecordingState recordingState) { if (!mainExportContext.HasPersistentName(owner)) { StringBuilder deferredInits = new StringBuilder(); GRSExport.EmitObjectCreation(mainExportContext, owner.Type, owner, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(); recordingState.writer.Write(deferredInits.ToString()); } recordingState.writer.Write("@@(\"" + mainExportContext.GetOrAssignPersistentName((IObject)owner) + "\")." + attrType.Name + " = "); }
public static void EmitSubgraphAttributes(MainGraphExportContext mainGraphContext, GraphExportContext context, StreamWriter sw) { if (context.areGraphAttributesExported) { return; } sw.WriteLine("in \"" + context.name + "\""); foreach (INode node in context.graph.Nodes) { foreach (AttributeType attrType in node.Type.AttributeTypes) { if (IsAttributeToBeSkipped(mainGraphContext, attrType)) { continue; } if (!IsGraphUsedInAttribute(attrType)) { continue; } object value = node.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(node), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } foreach (IEdge edge in node.Outgoing) { foreach (AttributeType attrType in edge.Type.AttributeTypes) { if (IsAttributeToBeSkipped(mainGraphContext, attrType)) { continue; } if (!IsGraphUsedInAttribute(attrType)) { continue; } object value = edge.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(edge), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } } } context.areGraphAttributesExported = true; }
public static bool AddSubgraphAsNeeded(MainGraphExportContext mainGraphContext, INamedGraph graph) { if (graph != null && !mainGraphContext.graphToContext.ContainsKey(graph)) { GraphExportContext subgraphContext = new GraphExportContext(mainGraphContext, graph); mainGraphContext.graphToContext[graph] = subgraphContext; mainGraphContext.nameToContext[subgraphContext.name] = subgraphContext; return(true); } else { return(false); } }
public GraphExportContext(MainGraphExportContext mainGraphContext, INamedGraph graph) { this.graph = graph; this.mainGraphContext = mainGraphContext ?? (MainGraphExportContext)this; if(this.mainGraphContext.nameToContext.ContainsKey(graph.Name)) { int id = 0; while(this.mainGraphContext.nameToContext.ContainsKey(graph.Name + "_" + id.ToString())) { ++id; } this.name = graph.Name + "_" + id.ToString(); } else this.name = graph.Name; }
public GraphExportContext(MainGraphExportContext mainGraphContext, INamedGraph graph) { this.graph = graph; this.mainGraphContext = mainGraphContext ?? (MainGraphExportContext)this; if (this.mainGraphContext.nameToContext.ContainsKey(graph.Name)) { int id = 0; while (this.mainGraphContext.nameToContext.ContainsKey(graph.Name + "_" + id.ToString())) { ++id; } this.name = graph.Name + "_" + id.ToString(); } else { this.name = graph.Name; } }
/// <summary> /// Exports the given graph to the file given by the stream writer in grs format. /// Any errors will be reported by exception. /// Returns the graph export context of the main graph. /// </summary> /// <param name="graph">The graph to export. Must be a named graph.</param> /// <param name="sw">The stream writer of the file to export into. The stream writer is not closed automatically.</param> /// <param name="modelPathPrefix">Path to the model.</param> public static MainGraphExportContext ExportYouMustCloseStreamWriter(INamedGraph graph, StreamWriter sw, string modelPathPrefix) { MainGraphExportContext mainGraphContext = new MainGraphExportContext(graph); mainGraphContext.graphToContext[mainGraphContext.graph] = mainGraphContext; mainGraphContext.nameToContext[mainGraphContext.name] = mainGraphContext; mainGraphContext.modelPathPrefix = modelPathPrefix; sw.WriteLine("# begin of graph \"{0}\" saved by GrsExport", mainGraphContext.name); sw.WriteLine(); bool subgraphAdded = ExportSingleGraph(mainGraphContext, mainGraphContext, sw); if (subgraphAdded) { restart: foreach (KeyValuePair <string, GraphExportContext> kvp in mainGraphContext.nameToContext) { GraphExportContext context = kvp.Value; if (!context.isExported) { subgraphAdded = ExportSingleGraph(mainGraphContext, context, sw); if (subgraphAdded) { goto restart; } } } foreach (KeyValuePair <string, GraphExportContext> kvp in mainGraphContext.nameToContext) { GraphExportContext context = kvp.Value; EmitSubgraphAttributes(mainGraphContext, context, sw); } sw.WriteLine("in \"" + mainGraphContext.name + "\""); // after import in main graph } sw.WriteLine("# end of graph \"{0}\" saved by GrsExport", mainGraphContext.name); sw.WriteLine(); return(mainGraphContext); }
private bool AddSubgraphsAsNeeded(MainGraphExportContext mainExportContext, IGraphElement element, AttributeType attrType, Object value, StreamWriter writer) { if (!GRSExport.IsGraphUsedInAttribute(attrType)) { return(false); } if (value == null) { return(false); } if (!(value is INamedGraph)) { return(false); } bool wasAdded = GRSExport.AddSubgraphAsNeeded(mainExportContext, (INamedGraph)value); if (wasAdded) { restart: foreach (KeyValuePair <string, GraphExportContext> kvp in mainExportContext.nameToContext) { GraphExportContext context = kvp.Value; if (!context.isExported) { wasAdded = GRSExport.ExportSingleGraph(mainExportContext, context, writer); if (wasAdded) { goto restart; } } } AddGraphAttributes(mainExportContext, writer); writer.WriteLine("in \"" + mainExportContext.graphToContext[graph].name + "\" # after emitting new subgraph for attribute"); return(true); } return(false); }
public static void EmitObjectCreation(MainGraphExportContext mainGraphContext, ObjectType objType, IObject obj, INamedGraph graph, StreamWriter sw, StringBuilder deferredInits) { sw.Write("new {0}@(% = \"{1}\"", objType.PackagePrefixedName, mainGraphContext.GetOrAssignPersistentName(obj)); foreach (AttributeType attrType in objType.AttributeTypes) { if (IsInternalClassObjectUsedInAttribute(attrType)) { continue; } sw.Write(", {0} = ", attrType.Name); EmitAttribute(mainGraphContext, attrType, obj.GetAttribute(attrType.Name), graph, sw, deferredInits); } sw.Write(")"); ++mainGraphContext.numInternalClassObjects; foreach (AttributeType attrType in objType.AttributeTypes) { if (!IsInternalClassObjectUsedInAttribute(attrType)) { continue; } object value = obj.GetAttribute(attrType.Name); MemoryStream memStream = new MemoryStream(); StreamWriter deferredSw = new StreamWriter(memStream); EmitAttributeInitialization(mainGraphContext, obj, attrType, value, graph, deferredSw); deferredSw.Flush(); memStream.Seek(0, SeekOrigin.Begin); byte[] buffer = new byte[memStream.Length]; int read = memStream.Read(buffer, 0, (int)memStream.Length); String deferred = System.Text.Encoding.UTF8.GetString(buffer); deferredInits.Append(deferred); } }
public void StartRecording(string filename) { if (!recordings.ContainsKey(filename)) { if (recordings.Count == 0) { SubscribeEvents(); } StreamWriter writer = null; if (filename.EndsWith(".gz", StringComparison.InvariantCultureIgnoreCase)) { FileStream filewriter = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.Write); writer = new StreamWriter(new GZipStream(filewriter, CompressionMode.Compress)); } else { writer = new StreamWriter(filename); } String pathPrefix = ""; if (filename.LastIndexOf("/") != -1 || filename.LastIndexOf("\\") != -1) { int lastIndex = filename.LastIndexOf("/"); if (lastIndex == -1) { lastIndex = filename.LastIndexOf("\\"); } pathPrefix = filename.Substring(0, lastIndex + 1); } MainGraphExportContext mainGraphContext = GRSExport.ExportYouMustCloseStreamWriter(graph, writer, pathPrefix, false, null); recordings.Add(new KeyValuePair <string, RecordingState>(filename, new RecordingState(writer, mainGraphContext))); } }
/// <summary> /// Type needed for enum, otherwise null ok. /// Graph needed for node/edge, otherwise null ok. /// Main graph context needed to get access to the graph -> env dictionary for subgraph. /// </summary> public static void EmitAttributeValue(MainGraphExportContext mainGraphContext, object value, AttributeType type, INamedGraph graph, StreamWriter sw, StringBuilder deferredInits) { switch (type.Kind) { case AttributeKind.ByteAttr: sw.Write(((sbyte)value).ToString() + "Y"); return; case AttributeKind.ShortAttr: sw.Write(((short)value).ToString() + "S"); return; case AttributeKind.IntegerAttr: sw.Write(((int)value).ToString()); return; case AttributeKind.LongAttr: sw.Write(((long)value).ToString() + "L"); return; case AttributeKind.BooleanAttr: sw.Write(((bool)value).ToString()); return; case AttributeKind.StringAttr: if (value == null) { sw.Write("\"\""); } else { sw.Write("\"" + ((string)value).Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""); } return; case AttributeKind.FloatAttr: sw.Write(((float)value).ToString(System.Globalization.CultureInfo.InvariantCulture) + "f"); return; case AttributeKind.DoubleAttr: sw.Write(((double)value).ToString(System.Globalization.CultureInfo.InvariantCulture)); return; case AttributeKind.ObjectAttr: sw.Write(graph.Model.Serialize(value, type, graph)); return; case AttributeKind.GraphAttr: if (value != null && mainGraphContext != null && mainGraphContext.graphToContext != null) { sw.Write("\"" + mainGraphContext.graphToContext[(INamedGraph)value].name + "\""); } else { sw.Write("null"); } return; case AttributeKind.EnumAttr: sw.Write(type.EnumType.PackagePrefixedName + "::" + type.EnumType[(int)value].Name); return; case AttributeKind.NodeAttr: case AttributeKind.EdgeAttr: if (value != null) { sw.Write("@(\"" + graph.GetElementName((IGraphElement)value) + "\")"); } else { sw.Write("null"); } return; case AttributeKind.InternalClassObjectAttr: if (value != null) { IObject obj = (IObject)value; EmitObjectFetchingOrCreation(mainGraphContext, obj.Type, obj, graph, sw, deferredInits); } else { sw.Write("null"); } return; default: throw new Exception("Unsupported attribute kind in export"); } }
/// <summary> /// Type needed for enum, otherwise null ok. /// Graph needed for node/edge, otherwise null ok. /// Main graph context needed to get access to the graph -> env dictionary for subgraph. /// </summary> public static String ToString(MainGraphExportContext mainGraphContext, object value, AttributeType type, INamedGraph graph) { switch (type.Kind) { case AttributeKind.ByteAttr: return(((sbyte)value).ToString() + "Y"); case AttributeKind.ShortAttr: return(((short)value).ToString() + "S"); case AttributeKind.IntegerAttr: return(((int)value).ToString()); case AttributeKind.LongAttr: return(((long)value).ToString() + "L"); case AttributeKind.BooleanAttr: return(((bool)value).ToString()); case AttributeKind.StringAttr: if (value == null) { return("\"\""); } else { return("\"" + ((string)value).Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""); } case AttributeKind.FloatAttr: return(((float)value).ToString(System.Globalization.CultureInfo.InvariantCulture) + "f"); case AttributeKind.DoubleAttr: return(((double)value).ToString(System.Globalization.CultureInfo.InvariantCulture)); case AttributeKind.ObjectAttr: return(graph.Model.Serialize(value, type, graph)); case AttributeKind.GraphAttr: if (value != null && mainGraphContext != null && mainGraphContext.graphToContext != null) { return("\"" + mainGraphContext.graphToContext[(INamedGraph)value].name + "\""); } else { return("null"); } case AttributeKind.EnumAttr: return(type.EnumType.PackagePrefixedName + "::" + type.EnumType[(int)value].Name); case AttributeKind.NodeAttr: case AttributeKind.EdgeAttr: if (value != null) { return("\"" + graph.GetElementName((IGraphElement)value) + "\""); } else { return("null"); } default: throw new Exception("Unsupported attribute kind in export"); } }
/// <summary> /// Emits the attribute value as code /// for an attribute of the given type with the given value into the stream writer /// Main graph context is needed to get access to the graph -> env dictionary. /// </summary> public static void EmitAttribute(MainGraphExportContext mainGraphContext, AttributeType attrType, object value, INamedGraph graph, StreamWriter sw) { if (attrType.Kind == AttributeKind.SetAttr) { IDictionary set = (IDictionary)value; sw.Write("{0}{{", attrType.GetKindName()); bool first = true; foreach (DictionaryEntry entry in set) { if (first) { sw.Write(ToString(mainGraphContext, entry.Key, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry.Key, attrType.ValueType, graph)); } } sw.Write("}"); } else if (attrType.Kind == AttributeKind.MapAttr) { IDictionary map = (IDictionary)value; sw.Write("{0}{{", attrType.GetKindName()); bool first = true; foreach (DictionaryEntry entry in map) { if (first) { sw.Write(ToString(mainGraphContext, entry.Key, attrType.KeyType, graph) + "->" + ToString(mainGraphContext, entry.Value, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry.Key, attrType.KeyType, graph) + "->" + ToString(mainGraphContext, entry.Value, attrType.ValueType, graph)); } } sw.Write("}"); } else if (attrType.Kind == AttributeKind.ArrayAttr) { IList array = (IList)value; sw.Write("{0}[", attrType.GetKindName()); bool first = true; foreach (object entry in array) { if (first) { sw.Write(ToString(mainGraphContext, entry, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry, attrType.ValueType, graph)); } } sw.Write("]"); } else if (attrType.Kind == AttributeKind.DequeAttr) { IDeque deque = (IDeque)value; sw.Write("{0}]", attrType.GetKindName()); bool first = true; foreach (object entry in deque) { if (first) { sw.Write(ToString(mainGraphContext, entry, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry, attrType.ValueType, graph)); } } sw.Write("["); } else { sw.Write("{0}", ToString(mainGraphContext, value, attrType, graph)); } }
/// <summary> /// Emits the node/edge attribute initialization code in graph exporting /// for an attribute of the given type with the given value into the stream writer. /// </summary> private static void EmitAttributeInitialization(MainGraphExportContext mainGraphContext, AttributeType attrType, object value, INamedGraph graph, StreamWriter sw) { sw.Write(", {0} = ", attrType.Name); EmitAttribute(mainGraphContext, attrType, value, graph, sw); }
private static bool AddSubgraphAsNeeded(MainGraphExportContext mainGraphContext, IGraphElement elem, AttributeType attrType) { if(attrType.Kind == AttributeKind.GraphAttr) return AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)elem.GetAttribute(attrType.Name)); bool graphAdded = false; if(attrType.Kind == AttributeKind.SetAttr || attrType.Kind == AttributeKind.MapAttr || attrType.Kind == AttributeKind.ArrayAttr || attrType.Kind == AttributeKind.DequeAttr) { if(attrType.ValueType.Kind == AttributeKind.GraphAttr) { if(attrType.Kind == AttributeKind.SetAttr) { IDictionary set = (IDictionary)elem.GetAttribute(attrType.Name); foreach(DictionaryEntry entry in set) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Key); } } else if(attrType.Kind == AttributeKind.MapAttr) { IDictionary map = (IDictionary)elem.GetAttribute(attrType.Name); foreach(DictionaryEntry entry in map) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Value); } } else if(attrType.Kind == AttributeKind.ArrayAttr) { IList array = (IList)elem.GetAttribute(attrType.Name); foreach(object entry in array) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry); } } else if(attrType.Kind == AttributeKind.DequeAttr) { IDeque deque = (IDeque)elem.GetAttribute(attrType.Name); foreach(object entry in deque) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry); } } } } if(attrType.Kind == AttributeKind.MapAttr) { if(attrType.KeyType.Kind == AttributeKind.GraphAttr) { IDictionary map = (IDictionary)elem.GetAttribute(attrType.Name); foreach(DictionaryEntry entry in map) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Key); } } } return graphAdded; }
/// <summary> /// Event handler for IGraph.OnChangingNodeAttribute and IGraph.OnChangingEdgeAttribute. /// </summary> /// <param name="element">The node or edge whose attribute is changed.</param> /// <param name="attrType">The type of the attribute to be changed.</param> /// <param name="changeType">The type of the change which will be made.</param> /// <param name="newValue">The new value of the attribute, if changeType==Assign. /// Or the value to be inserted/removed if changeType==PutElement/RemoveElement on set. /// Or the new map pair value to be inserted if changeType==PutElement on map. /// Or the new value to be inserted/added if changeType==PutElement on array. /// Or the new value to be assigned to the given position if changeType==AssignElement on array.</param> /// <param name="keyValue">The map pair key to be inserted/removed if changeType==PutElement/RemoveElement on map. /// The array index to be removed/written to if changeType==RemoveElement/AssignElement on array.</param> void ChangingAttribute(IGraphElement element, AttributeType attrType, AttributeChangeType changeType, Object newValue, Object keyValue) { foreach (RecordingState recordingState in recordings.Values) { MainGraphExportContext mainExportContext = recordingState.mainExportContext; AddSubgraphsAsNeeded(mainExportContext, element, attrType, newValue, recordingState.writer); AddSubgraphsAsNeeded(mainExportContext, element, attrType, keyValue, recordingState.writer); switch (changeType) { case AttributeChangeType.Assign: recordingState.writer.Write("@(\"" + graph.GetElementName(element) + "\")." + attrType.Name + " = "); GRSExport.EmitAttribute(mainExportContext, attrType, newValue, graph, recordingState.writer); recordingState.writer.WriteLine(); break; case AttributeChangeType.PutElement: recordingState.writer.Write("@(\"" + graph.GetElementName(element) + "\")." + attrType.Name); switch (attrType.Kind) { case AttributeKind.SetAttr: recordingState.writer.Write(".add("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.WriteLine(")"); break; case AttributeKind.MapAttr: recordingState.writer.Write(".add("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, attrType.KeyType, graph)); recordingState.writer.Write(", "); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.WriteLine(")"); break; case AttributeKind.ArrayAttr: if (keyValue == null) { recordingState.writer.Write(".add("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.WriteLine(")"); } else { recordingState.writer.Write(".add("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.Write(", "); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph)); recordingState.writer.WriteLine(")"); } break; case AttributeKind.DequeAttr: if (keyValue == null) { recordingState.writer.Write(".add("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.WriteLine(")"); } else { recordingState.writer.Write(".add("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.Write(", "); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph)); recordingState.writer.WriteLine(")"); } break; default: throw new Exception("Wrong attribute type for attribute change type"); } break; case AttributeChangeType.RemoveElement: recordingState.writer.Write("@(\"" + graph.GetElementName(element) + "\")." + attrType.Name); switch (attrType.Kind) { case AttributeKind.SetAttr: recordingState.writer.Write(".rem("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); recordingState.writer.WriteLine(")"); break; case AttributeKind.MapAttr: recordingState.writer.Write(".rem("); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, attrType.KeyType, graph)); recordingState.writer.WriteLine(")"); break; case AttributeKind.ArrayAttr: recordingState.writer.Write(".rem("); if (keyValue != null) { recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph)); } recordingState.writer.WriteLine(")"); break; case AttributeKind.DequeAttr: recordingState.writer.Write(".rem("); if (keyValue != null) { recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph)); } recordingState.writer.WriteLine(")"); break; default: throw new Exception("Wrong attribute type for attribute change type"); } break; case AttributeChangeType.AssignElement: recordingState.writer.Write("@(\"" + graph.GetElementName(element) + "\")." + attrType.Name); switch (attrType.Kind) { case AttributeKind.ArrayAttr: recordingState.writer.Write("["); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph)); recordingState.writer.Write("] = "); recordingState.writer.WriteLine(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); break; case AttributeKind.DequeAttr: recordingState.writer.Write("["); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph)); recordingState.writer.Write("] = "); recordingState.writer.WriteLine(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); break; case AttributeKind.MapAttr: recordingState.writer.Write("["); recordingState.writer.Write(GRSExport.ToString(mainExportContext, keyValue, attrType.KeyType, graph)); recordingState.writer.Write("] = "); recordingState.writer.WriteLine(GRSExport.ToString(mainExportContext, newValue, attrType.ValueType, graph)); break; default: throw new Exception("Wrong attribute type for attribute change type"); } break; default: throw new Exception("Unknown attribute change type"); } } }
public static bool ExportSingleGraph(MainGraphExportContext mainGraphContext, GraphExportContext context, StreamWriter sw) { bool subgraphAdded = false; if(context.modelPathPrefix != null) sw.WriteLine("new graph \"" + context.modelPathPrefix + context.graph.Model.ModelName + "\" \"" + context.name + "\""); else sw.WriteLine("add new graph \"" + context.name + "\""); // emit nodes int numNodes = 0; foreach(INode node in context.graph.Nodes) { sw.Write("new :{0}($ = \"{1}\"", node.Type.PackagePrefixedName, context.graph.GetElementName(node)); foreach(AttributeType attrType in node.Type.AttributeTypes) { if(IsNodeOrEdgeUsedInAttribute(attrType)) { context.nodeOrEdgeUsedInAttribute = true; continue; } if(IsGraphUsedInAttribute(attrType)) { context.subgraphUsedInAttribute = true; subgraphAdded |= AddSubgraphAsNeeded(mainGraphContext, node, attrType); continue; } object value = node.GetAttribute(attrType.Name); EmitAttributeInitialization(mainGraphContext, attrType, value, context.graph, sw); } sw.WriteLine(")"); numNodes++; } if(context.modelPathPrefix != null) sw.WriteLine("# total number of nodes: {0}", numNodes); else sw.WriteLine("# total number of nodes in subgraph {0}: {1}", context.name, numNodes); sw.WriteLine(); // emit edges int numEdges = 0; foreach(INode node in context.graph.Nodes) { foreach(IEdge edge in node.Outgoing) { sw.Write("new @(\"{0}\") - :{1}($ = \"{2}\"", context.graph.GetElementName(node), edge.Type.PackagePrefixedName, context.graph.GetElementName(edge)); foreach(AttributeType attrType in edge.Type.AttributeTypes) { if(IsNodeOrEdgeUsedInAttribute(attrType)) { context.nodeOrEdgeUsedInAttribute = true; continue; } if(IsGraphUsedInAttribute(attrType)) { context.subgraphUsedInAttribute = true; subgraphAdded |= AddSubgraphAsNeeded(mainGraphContext, edge, attrType); continue; } object value = edge.GetAttribute(attrType.Name); // TODO: Add support for null values, as the default initializers could assign non-null values! if(value != null) { EmitAttributeInitialization(mainGraphContext, attrType, value, context.graph, sw); } } sw.WriteLine(") -> @(\"{0}\")", context.graph.GetElementName(edge.Target)); numEdges++; } } if(context.modelPathPrefix != null) sw.WriteLine("# total number of edges: {0}", numEdges); else sw.WriteLine("# total number of edges in subgraph {0}: {1}", context.name, numEdges); sw.WriteLine(); // emit node/edge valued attributes if(context.nodeOrEdgeUsedInAttribute) { foreach(INode node in context.graph.Nodes) { foreach(AttributeType attrType in node.Type.AttributeTypes) { if(!IsNodeOrEdgeUsedInAttribute(attrType)) continue; if(IsGraphUsedInAttribute(attrType)) continue; object value = node.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(node), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } foreach(IEdge edge in node.Outgoing) { foreach(AttributeType attrType in edge.Type.AttributeTypes) { if(!IsNodeOrEdgeUsedInAttribute(attrType)) continue; if(IsGraphUsedInAttribute(attrType)) continue; object value = edge.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(edge), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } } } } if(!context.subgraphUsedInAttribute) context.areGraphAttributesExported = true; context.isExported = true; return subgraphAdded; }
public RecordingState(StreamWriter writer, MainGraphExportContext mainExportContext) { this.writer = writer; this.mainExportContext = mainExportContext; }
private bool AddSubgraphsAsNeeded(MainGraphExportContext mainExportContext, IGraphElement element, AttributeType attrType, Object value, StreamWriter writer) { if(!GRSExport.IsGraphUsedInAttribute(attrType)) return false; if(value == null) return false; if(!(value is INamedGraph)) return false; bool wasAdded = GRSExport.AddSubgraphAsNeeded(mainExportContext, (INamedGraph)value); if(wasAdded) { restart: foreach(KeyValuePair<string, GraphExportContext> kvp in mainExportContext.nameToContext) { GraphExportContext context = kvp.Value; if(!context.isExported) { wasAdded = GRSExport.ExportSingleGraph(mainExportContext, context, writer); if(wasAdded) goto restart; } } AddGraphAttributes(mainExportContext, writer); writer.WriteLine("in \"" + mainExportContext.graphToContext[graph].name + "\" # after emitting new subgraph for attribute"); return true; } return false; }
private static void AddGraphAttributes(MainGraphExportContext mainExportContext, StreamWriter writer) { foreach(KeyValuePair<string, GraphExportContext> kvp in mainExportContext.nameToContext) { GraphExportContext context = kvp.Value; GRSExport.EmitSubgraphAttributes(mainExportContext, context, writer); } }
/// <summary> /// Type needed for enum, otherwise null ok. /// Graph needed for node/edge, otherwise null ok. /// Main graph context needed to get access to the graph -> env dictionary for subgraph. /// </summary> public static String ToString(MainGraphExportContext mainGraphContext, object value, AttributeType type, INamedGraph graph) { switch(type.Kind) { case AttributeKind.ByteAttr: return ((sbyte)value).ToString()+"Y"; case AttributeKind.ShortAttr: return ((short)value).ToString()+"S"; case AttributeKind.IntegerAttr: return ((int)value).ToString(); case AttributeKind.LongAttr: return ((long)value).ToString()+"L"; case AttributeKind.BooleanAttr: return ((bool)value).ToString(); case AttributeKind.StringAttr: if(value == null) return "\"\""; else return "\"" + ((string)value).Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""; case AttributeKind.FloatAttr: return ((float)value).ToString(System.Globalization.CultureInfo.InvariantCulture)+"f"; case AttributeKind.DoubleAttr: return ((double)value).ToString(System.Globalization.CultureInfo.InvariantCulture); case AttributeKind.ObjectAttr: return graph.Model.Serialize(value, type, graph); case AttributeKind.GraphAttr: if(value != null && mainGraphContext != null && mainGraphContext.graphToContext != null) return "\"" + mainGraphContext.graphToContext[(INamedGraph)value].name + "\""; else return "null"; case AttributeKind.EnumAttr: return type.EnumType.PackagePrefixedName + "::" + type.EnumType[(int)value].Name; case AttributeKind.NodeAttr: case AttributeKind.EdgeAttr: if(value != null) return "\"" + graph.GetElementName((IGraphElement)value) + "\""; else return "null"; default: throw new Exception("Unsupported attribute kind in export"); } }
/// <summary> /// Emits the attribute value as code /// for an attribute of the given type with the given value into the stream writer /// Main graph context is needed to get access to the graph -> env dictionary. /// </summary> public static void EmitAttribute(MainGraphExportContext mainGraphContext, AttributeType attrType, object value, INamedGraph graph, StreamWriter sw) { if(attrType.Kind==AttributeKind.SetAttr) { IDictionary set=(IDictionary)value; sw.Write("{0}{{", attrType.GetKindName()); bool first = true; foreach(DictionaryEntry entry in set) { if(first) { sw.Write(ToString(mainGraphContext, entry.Key, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry.Key, attrType.ValueType, graph)); } } sw.Write("}"); } else if(attrType.Kind==AttributeKind.MapAttr) { IDictionary map=(IDictionary)value; sw.Write("{0}{{", attrType.GetKindName()); bool first = true; foreach(DictionaryEntry entry in map) { if(first) { sw.Write(ToString(mainGraphContext, entry.Key, attrType.KeyType, graph) + "->" + ToString(mainGraphContext, entry.Value, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry.Key, attrType.KeyType, graph) + "->" + ToString(mainGraphContext, entry.Value, attrType.ValueType, graph)); } } sw.Write("}"); } else if(attrType.Kind == AttributeKind.ArrayAttr) { IList array = (IList)value; sw.Write("{0}[", attrType.GetKindName()); bool first = true; foreach(object entry in array) { if(first) { sw.Write(ToString(mainGraphContext, entry, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry, attrType.ValueType, graph)); } } sw.Write("]"); } else if(attrType.Kind == AttributeKind.DequeAttr) { IDeque deque = (IDeque)value; sw.Write("{0}]", attrType.GetKindName()); bool first = true; foreach(object entry in deque) { if(first) { sw.Write(ToString(mainGraphContext, entry, attrType.ValueType, graph)); first = false; } else { sw.Write("," + ToString(mainGraphContext, entry, attrType.ValueType, graph)); } } sw.Write("["); } else { sw.Write("{0}", ToString(mainGraphContext, value, attrType, graph)); } }
/// <summary> /// Event handler for IGraph.OnChangingNodeAttribute and IGraph.OnChangingEdgeAttribute and IGraph.OnChangingObjectAttribute. /// </summary> /// <param name="owner">The node or edge or object whose attribute is changed.</param> /// <param name="attrType">The type of the attribute to be changed.</param> /// <param name="changeType">The type of the change which will be made.</param> /// <param name="newValue">The new value of the attribute, if changeType==Assign. /// Or the value to be inserted/removed if changeType==PutElement/RemoveElement on set. /// Or the new map pair value to be inserted if changeType==PutElement on map. /// Or the new value to be inserted/added if changeType==PutElement on array. /// Or the new value to be assigned to the given position if changeType==AssignElement on array.</param> /// <param name="keyValue">The map pair key to be inserted/removed if changeType==PutElement/RemoveElement on map. /// The array index to be removed/written to if changeType==RemoveElement/AssignElement on array.</param> void ChangingAttribute(IAttributeBearer owner, AttributeType attrType, AttributeChangeType changeType, object newValue, object keyValue) { foreach (RecordingState recordingState in recordings.Values) { MainGraphExportContext mainExportContext = recordingState.mainExportContext; StringBuilder deferredInits = new StringBuilder(); AddSubgraphsAsNeeded(mainExportContext, owner, attrType, newValue, recordingState.writer); AddSubgraphsAsNeeded(mainExportContext, owner, attrType, keyValue, recordingState.writer); switch (changeType) { case AttributeChangeType.Assign: if (owner is IGraphElement) { recordingState.writer.Write("@(\"" + graph.GetElementName((IGraphElement)owner) + "\")." + attrType.Name + " = "); } else { EmitObjectAttributeAssignmentCreatingAsNeeded((IObject)owner, attrType, mainExportContext, recordingState); } StringBuilder sb = new StringBuilder(); GRSExport.EmitAttribute(mainExportContext, attrType, newValue, graph, recordingState.writer, sb); recordingState.writer.WriteLine(); recordingState.writer.Write(sb.ToString()); break; case AttributeChangeType.PutElement: if (owner is IGraphElement) { recordingState.writer.Write("@(\"" + graph.GetElementName((IGraphElement)owner) + "\")." + attrType.Name); } else { EmitObjectAttributeAssignmentCreatingAsNeeded((IObject)owner, attrType, mainExportContext, recordingState); } switch (attrType.Kind) { case AttributeKind.SetAttr: recordingState.writer.Write(".add("); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); break; case AttributeKind.MapAttr: recordingState.writer.Write(".add("); GRSExport.EmitAttributeValue(mainExportContext, keyValue, attrType.KeyType, graph, recordingState.writer, deferredInits); recordingState.writer.Write(", "); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); break; case AttributeKind.ArrayAttr: if (keyValue == null) { recordingState.writer.Write(".add("); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); } else { recordingState.writer.Write(".add("); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.Write(", "); GRSExport.EmitAttributeValue(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); } break; case AttributeKind.DequeAttr: if (keyValue == null) { recordingState.writer.Write(".add("); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); } else { recordingState.writer.Write(".add("); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.Write(", "); GRSExport.EmitAttributeValue(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); } break; default: throw new Exception("Wrong attribute type for attribute change type"); } break; case AttributeChangeType.RemoveElement: if (owner is IGraphElement) { recordingState.writer.Write("@(\"" + graph.GetElementName((IGraphElement)owner) + "\")." + attrType.Name); } else { EmitObjectAttributeAssignmentCreatingAsNeeded((IObject)owner, attrType, mainExportContext, recordingState); } switch (attrType.Kind) { case AttributeKind.SetAttr: recordingState.writer.Write(".rem("); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); break; case AttributeKind.MapAttr: recordingState.writer.Write(".rem("); GRSExport.EmitAttributeValue(mainExportContext, keyValue, attrType.KeyType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(")"); break; case AttributeKind.ArrayAttr: recordingState.writer.Write(".rem("); if (keyValue != null) { GRSExport.EmitAttributeValue(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph, recordingState.writer, deferredInits); } recordingState.writer.WriteLine(")"); break; case AttributeKind.DequeAttr: recordingState.writer.Write(".rem("); if (keyValue != null) { GRSExport.EmitAttributeValue(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph, recordingState.writer, deferredInits); } recordingState.writer.WriteLine(")"); break; default: throw new Exception("Wrong attribute type for attribute change type"); } break; case AttributeChangeType.AssignElement: if (owner is IGraphElement) { recordingState.writer.Write("@(\"" + graph.GetElementName((IGraphElement)owner) + "\")." + attrType.Name); } else { EmitObjectAttributeAssignmentCreatingAsNeeded((IObject)owner, attrType, mainExportContext, recordingState); } switch (attrType.Kind) { case AttributeKind.ArrayAttr: recordingState.writer.Write("["); GRSExport.EmitAttributeValue(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph, recordingState.writer, deferredInits); recordingState.writer.Write("] = "); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(); break; case AttributeKind.DequeAttr: recordingState.writer.Write("["); GRSExport.EmitAttributeValue(mainExportContext, keyValue, new AttributeType(null, null, AttributeKind.IntegerAttr, null, null, null, null, null, null, typeof(int)), graph, recordingState.writer, deferredInits); recordingState.writer.Write("] = "); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(); break; case AttributeKind.MapAttr: recordingState.writer.Write("["); GRSExport.EmitAttributeValue(mainExportContext, keyValue, attrType.KeyType, graph, recordingState.writer, deferredInits); recordingState.writer.Write("] = "); GRSExport.EmitAttributeValue(mainExportContext, newValue, attrType.ValueType, graph, recordingState.writer, deferredInits); recordingState.writer.WriteLine(); break; default: throw new Exception("Wrong attribute type for attribute change type"); } break; default: throw new Exception("Unknown attribute change type"); } recordingState.writer.Write(deferredInits.ToString()); } }
public static bool AddSubgraphAsNeeded(MainGraphExportContext mainGraphContext, INamedGraph graph) { if(graph!=null && !mainGraphContext.graphToContext.ContainsKey(graph)) { GraphExportContext subgraphContext = new GraphExportContext(mainGraphContext, graph); mainGraphContext.graphToContext[graph] = subgraphContext; mainGraphContext.nameToContext[subgraphContext.name] = subgraphContext; return true; } else return false; }
private static bool AddSubgraphAsNeeded(MainGraphExportContext mainGraphContext, IGraphElement elem, AttributeType attrType) { if (attrType.Kind == AttributeKind.GraphAttr) { return(AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)elem.GetAttribute(attrType.Name))); } bool graphAdded = false; if (attrType.Kind == AttributeKind.SetAttr || attrType.Kind == AttributeKind.MapAttr || attrType.Kind == AttributeKind.ArrayAttr || attrType.Kind == AttributeKind.DequeAttr) { if (attrType.ValueType.Kind == AttributeKind.GraphAttr) { if (attrType.Kind == AttributeKind.SetAttr) { IDictionary set = (IDictionary)elem.GetAttribute(attrType.Name); foreach (DictionaryEntry entry in set) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Key); } } else if (attrType.Kind == AttributeKind.MapAttr) { IDictionary map = (IDictionary)elem.GetAttribute(attrType.Name); foreach (DictionaryEntry entry in map) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Value); } } else if (attrType.Kind == AttributeKind.ArrayAttr) { IList array = (IList)elem.GetAttribute(attrType.Name); foreach (object entry in array) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry); } } else if (attrType.Kind == AttributeKind.DequeAttr) { IDeque deque = (IDeque)elem.GetAttribute(attrType.Name); foreach (object entry in deque) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry); } } } } if (attrType.Kind == AttributeKind.MapAttr) { if (attrType.KeyType.Kind == AttributeKind.GraphAttr) { IDictionary map = (IDictionary)elem.GetAttribute(attrType.Name); foreach (DictionaryEntry entry in map) { graphAdded |= AddSubgraphAsNeeded(mainGraphContext, (INamedGraph)entry.Key); } } } return(graphAdded); }
public static void EmitSubgraphAttributes(MainGraphExportContext mainGraphContext, GraphExportContext context, StreamWriter sw) { if(context.areGraphAttributesExported) return; sw.WriteLine("in \"" + context.name + "\""); foreach(INode node in context.graph.Nodes) { foreach(AttributeType attrType in node.Type.AttributeTypes) { if(!IsGraphUsedInAttribute(attrType)) continue; object value = node.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(node), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } foreach(IEdge edge in node.Outgoing) { foreach(AttributeType attrType in edge.Type.AttributeTypes) { if(!IsGraphUsedInAttribute(attrType)) continue; object value = edge.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(edge), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } } } context.areGraphAttributesExported = true; }
public static bool ExportSingleGraph(MainGraphExportContext mainGraphContext, GraphExportContext context, StreamWriter sw) { bool subgraphAdded = false; if (context.modelPathPrefix != null) { sw.WriteLine("new graph \"" + context.modelPathPrefix + context.graph.Model.ModelName + "\" \"" + context.name + "\""); } else { sw.WriteLine("add new graph \"" + context.name + "\""); } // emit nodes int numNodes = 0; foreach (INode node in context.graph.Nodes) { sw.Write("new :{0}($ = \"{1}\"", node.Type.PackagePrefixedName, context.graph.GetElementName(node)); foreach (AttributeType attrType in node.Type.AttributeTypes) { if (IsNodeOrEdgeUsedInAttribute(attrType)) { context.nodeOrEdgeUsedInAttribute = true; continue; } if (IsGraphUsedInAttribute(attrType)) { context.subgraphUsedInAttribute = true; subgraphAdded |= AddSubgraphAsNeeded(mainGraphContext, node, attrType); continue; } object value = node.GetAttribute(attrType.Name); EmitAttributeInitialization(mainGraphContext, attrType, value, context.graph, sw); } sw.WriteLine(")"); numNodes++; } if (context.modelPathPrefix != null) { sw.WriteLine("# total number of nodes: {0}", numNodes); } else { sw.WriteLine("# total number of nodes in subgraph {0}: {1}", context.name, numNodes); } sw.WriteLine(); // emit edges int numEdges = 0; foreach (INode node in context.graph.Nodes) { foreach (IEdge edge in node.Outgoing) { sw.Write("new @(\"{0}\") - :{1}($ = \"{2}\"", context.graph.GetElementName(node), edge.Type.PackagePrefixedName, context.graph.GetElementName(edge)); foreach (AttributeType attrType in edge.Type.AttributeTypes) { if (IsNodeOrEdgeUsedInAttribute(attrType)) { context.nodeOrEdgeUsedInAttribute = true; continue; } if (IsGraphUsedInAttribute(attrType)) { context.subgraphUsedInAttribute = true; subgraphAdded |= AddSubgraphAsNeeded(mainGraphContext, edge, attrType); continue; } object value = edge.GetAttribute(attrType.Name); // TODO: Add support for null values, as the default initializers could assign non-null values! if (value != null) { EmitAttributeInitialization(mainGraphContext, attrType, value, context.graph, sw); } } sw.WriteLine(") -> @(\"{0}\")", context.graph.GetElementName(edge.Target)); numEdges++; } } if (context.modelPathPrefix != null) { sw.WriteLine("# total number of edges: {0}", numEdges); } else { sw.WriteLine("# total number of edges in subgraph {0}: {1}", context.name, numEdges); } sw.WriteLine(); // emit node/edge valued attributes if (context.nodeOrEdgeUsedInAttribute) { foreach (INode node in context.graph.Nodes) { foreach (AttributeType attrType in node.Type.AttributeTypes) { if (!IsNodeOrEdgeUsedInAttribute(attrType)) { continue; } if (IsGraphUsedInAttribute(attrType)) { continue; } object value = node.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(node), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } foreach (IEdge edge in node.Outgoing) { foreach (AttributeType attrType in edge.Type.AttributeTypes) { if (!IsNodeOrEdgeUsedInAttribute(attrType)) { continue; } if (IsGraphUsedInAttribute(attrType)) { continue; } object value = edge.GetAttribute(attrType.Name); sw.Write("@(\"{0}\").{1} = ", context.graph.GetElementName(edge), attrType.Name); EmitAttribute(mainGraphContext, attrType, value, context.graph, sw); sw.Write("\n"); } } } } if (!context.subgraphUsedInAttribute) { context.areGraphAttributesExported = true; } context.isExported = true; return(subgraphAdded); }
/// <summary> /// Exports the given graph to the file given by the stream writer in grs format. /// Any errors will be reported by exception. /// Returns the graph export context of the main graph. /// </summary> /// <param name="graph">The graph to export. Must be a named graph.</param> /// <param name="sw">The stream writer of the file to export into. The stream writer is not closed automatically.</param> /// <param name="modelPathPrefix">Path to the model.</param> public static MainGraphExportContext ExportYouMustCloseStreamWriter(INamedGraph graph, StreamWriter sw, string modelPathPrefix) { MainGraphExportContext mainGraphContext = new MainGraphExportContext(graph); mainGraphContext.graphToContext[mainGraphContext.graph] = mainGraphContext; mainGraphContext.nameToContext[mainGraphContext.name] = mainGraphContext; mainGraphContext.modelPathPrefix = modelPathPrefix; sw.WriteLine("# begin of graph \"{0}\" saved by GrsExport", mainGraphContext.name); sw.WriteLine(); bool subgraphAdded = ExportSingleGraph(mainGraphContext, mainGraphContext, sw); if(subgraphAdded) { restart: foreach(KeyValuePair<string, GraphExportContext> kvp in mainGraphContext.nameToContext) { GraphExportContext context = kvp.Value; if(!context.isExported) { subgraphAdded = ExportSingleGraph(mainGraphContext, context, sw); if(subgraphAdded) goto restart; } } foreach(KeyValuePair<string, GraphExportContext> kvp in mainGraphContext.nameToContext) { GraphExportContext context = kvp.Value; EmitSubgraphAttributes(mainGraphContext, context, sw); } sw.WriteLine("in \"" + mainGraphContext.name + "\""); // after import in main graph } sw.WriteLine("# end of graph \"{0}\" saved by GrsExport", mainGraphContext.name); sw.WriteLine(); return mainGraphContext; }