/// <summary> /// Constructs a new diagram instance /// </summary> /// <param name="xNode">The XML node which is the root for this diagram instance</param> public BpmnDiagram(XElement xNode) { Plane = null; Children = new Dictionary <BpmnDiagram, BpmnElement>(); Styles = new Dictionary <string, BpmnLabelStyle>(); Id = ""; Documentation = ""; Resolution = ""; // Get name, if it exists Name = BpmnNM.GetAttributeValue(xNode, BpmnNM.Bpmn, BpmnDiConstants.NameAttribute); // Name Diagram "Unnamed", if it has no name (for choosing, if file contains multiple diagrams) if (string.IsNullOrEmpty(Name)) { Name = "Unnamed Diagram"; } // Get id, if it exists Id = BpmnNM.GetAttributeValue(xNode, BpmnNM.Bpmn, BpmnDiConstants.IdAttribute); // Get documentation, if it exists Documentation = BpmnNM.GetAttributeValue(xNode, BpmnNM.Bpmn, BpmnDiConstants.DocumentationAttribute); // Get resolution, if it exists Resolution = BpmnNM.GetAttributeValue(xNode, BpmnNM.Bpmn, BpmnDiConstants.ResolutionAttribute); }
/// <summary> /// Constructs a new shape instance /// </summary> /// <param name="xShape">The XML element which represents this shape</param> /// <param name="elements">Dictionary of all bpmn elements from this file parsing</param> public BpmnShape(XElement xShape, IDictionary <string, BpmnElement> elements) { HasLabel = false; LabelBounds = new RectD(0, 0, 0, 0); X = 0; Y = 0; Height = 30; Width = 30; // Get and Link the corresponding element BpmnElement element; Element = elements.TryGetValue(BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.BpmnElementAttribute), out element) ? element : null; // If there is no element, skip if (Element == null) { return; } // Get the id Id = BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.IdAttribute); // Get all additional Attributes IsHorizontal = Convert.ToBoolean(BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.IsHorizontalAttribute)); IsExpanded = BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.IsExpandedAttribute); IsMarkerVisible = Convert.ToBoolean(BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.IsMarkerVisibleAttribute)); IsMessageVisible = Convert.ToBoolean(BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.IsMessageVisibleAttribute)); ChoreographyActivityShape = BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.ChoreographyActivityShapeAttribute); switch (BpmnNM.GetAttributeValue(xShape, BpmnNM.BpmnDi, BpmnDiConstants.ParticipantBandKindAttribute)) { case "top_non_initiating": PartBandKind = ParticipantBandKind.TopNonInitiating; break; case "top_initiating": PartBandKind = ParticipantBandKind.TopInitiating; break; case "middle_non_initiating": PartBandKind = ParticipantBandKind.MiddleNonInitiating; break; case "middle_initiating": PartBandKind = ParticipantBandKind.MiddleInitiating; break; case "bottom_non_initiating": PartBandKind = ParticipantBandKind.BottomNonInitiating; break; case "bottom_initiating": PartBandKind = ParticipantBandKind.BottomInitiating; break; } }
/// <summary> /// Constructs a new plane instance /// </summary> /// <param name="xNode">The XML element which represents this plane</param> /// <param name="elements">Dictionary of all bpmn elements from this file parsing</param> public BpmnPlane(XElement xNode, IDictionary <string, BpmnElement> elements) { ListOfEdges = new List <BpmnEdge>(); ListOfShapes = new List <BpmnShape>(); // A BPMNPlane only has one bpmnElement and no further attributes BpmnElement element; Element = elements.TryGetValue(BpmnNM.GetAttributeValue(xNode, BpmnNM.BpmnDi, BpmnDiConstants.BpmnElementAttribute), out element) ? element : null; }
/// <summary> /// Add a label and its bounds to the edge /// </summary> /// <param name="xBounds">The XML element of the label bounds</param> public void AddLabel(XElement xBounds) { HasLabel = true; if (xBounds == null) { return; } // If there are bounds, set standard values, first. double labelX = 0; double labelY = 0; double labelWidth = 100; double labelHeight = 20; var attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.XAttribute); if (attr != null) { labelX = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.YAttribute); if (attr != null) { labelY = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.HeightAttribute); if (attr != null) { labelHeight = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.WidthAttribute); if (attr != null) { labelWidth = double.Parse(attr, CultureInfo.InvariantCulture); } // In case, the label sizes were set to 0 if (labelWidth < 1 || labelHeight < 1) { var text = Element.Label; var preferredSize = CalculatePreferredSize(text); labelWidth = preferredSize.Width; labelHeight = preferredSize.Height; } LabelBounds = new RectD(labelX, labelY, labelWidth, labelHeight); }
/// <summary> /// Adds a waypoint to the edge /// </summary> /// <param name="xWaypoint">The waypoint to add</param> public void AddWayPoint(XElement xWaypoint) { double x = 0; double y = 0; var attr = BpmnNM.GetAttributeValue(xWaypoint, BpmnNM.Di, BpmnDiConstants.XAttribute); if (attr != null) { x = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xWaypoint, BpmnNM.Di, BpmnDiConstants.YAttribute); if (attr != null) { y = double.Parse(attr, CultureInfo.InvariantCulture); } var tuple = new PointD(x, y); Waypoints.Add(tuple); }
/// <summary> /// Adds the bound of this shape /// </summary> /// <param name="xBounds">XML element representing the bounds</param> public void AddBounds(XElement xBounds) { var attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.XAttribute); if (attr != null) { X = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.YAttribute); if (attr != null) { Y = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.HeightAttribute); if (attr != null) { Height = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xBounds, BpmnNM.Dc, BpmnDiConstants.WidthAttribute); if (attr != null) { Width = double.Parse(attr, CultureInfo.InvariantCulture); } //Check for size 0 if (Height == 0) { Height = 30; } if (Width == 0) { Width = 30; } }
/// <summary> /// Constructs an instance of <see cref="DefaultLabelStyle"/> representing this Style /// </summary> /// <param name="xStyle">The XML Element to be converted into this style</param> public BpmnLabelStyle(XElement xStyle) { Id = null; Font = "Arial"; Size = 0; IsBold = false; IsItalic = false; IsUnderline = false; IsStrikeThrough = false; Id = BpmnNM.GetAttributeValue(xStyle, BpmnNM.Dc, BpmnDiConstants.IdAttribute); // Parse Values of the Label Style var xFont = BpmnNM.GetElement(xStyle, BpmnNM.Dc, BpmnDiConstants.FontElement); if (xFont != null) { Font = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.NameAttribute); var attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.SizeAttribute); if (attr != null) { Size = float.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsBoldAttribute); if (attr != null) { IsBold = bool.Parse(attr); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsItalicAttribute); if (attr != null) { IsItalic = bool.Parse(attr); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsUnderlineAttribute); if (attr != null) { IsUnderline = bool.Parse(attr); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsStrikeThroughAttribute); if (attr != null) { IsStrikeThrough = bool.Parse(attr); } } LabelStyle = new DefaultLabelStyle { StringFormat = { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center } }; var fontStyle = FontStyle.Regular; // Set Boldness if (IsBold) { fontStyle |= FontStyle.Bold; } // Set Italic if (IsItalic) { fontStyle |= FontStyle.Italic; } // Set Underline if (IsUnderline) { fontStyle |= FontStyle.Underline; } // Set StrikeThrough if (IsStrikeThrough) { fontStyle |= FontStyle.Strikeout; } LabelStyle.Font = new Font(Font, Size > 0 ? Size : LabelTextSize, fontStyle, GraphicsUnit.Pixel); LabelStyle.StringFormat.FormatFlags &= ~StringFormatFlags.NoWrap; }
/// <summary> /// Constructs a new edge instance /// </summary> /// <param name="xEdge">The XML element which represents this edge</param> /// <param name="elements">Dictionary of all bpmn elements from this file parsing</param> public BpmnEdge(XElement xEdge, IDictionary <string, BpmnElement> elements) { Waypoints = new List <PointD>(); HasLabel = false; LabelBounds = new RectD(0, 0, 0, 0); Source = null; Target = null; MessageVisibleK = MessageVisibleKind.Unspecified; // Get id Id = BpmnNM.GetAttributeValue(xEdge, BpmnNM.BpmnDi, BpmnDiConstants.IdAttribute); // Get and link element if (BpmnNM.GetAttributeValue(xEdge, BpmnNM.BpmnDi, BpmnDiConstants.BpmnElementAttribute) != null) { BpmnElement element; Element = elements.TryGetValue(BpmnNM.GetAttributeValue(xEdge, BpmnNM.BpmnDi, BpmnDiConstants.BpmnElementAttribute), out element) ? element : null; } // If there is no element, skip if (Element == null) { return; } // Source and target elements can be specified as attribute of the element // or as children of the element (in data associations). BpmnElement source; string sourceRef; BpmnElement target; string targetRef; // Getting source element id var sourceVar = Element.Source; if (sourceVar != null) { sourceRef = sourceVar; } else { sourceRef = Element.LoadSourceFromChild(); } // Getting and linking source element if (elements.TryGetValue(sourceRef, out source)) { Source = source; } // Getting target element id var targetVar = Element.Target; if (targetVar != null) { targetRef = targetVar; } else { targetRef = Element.LoadTargetFromChild(); } // Getting and linking target element if (elements.TryGetValue(targetRef, out target)) { Target = target; } switch (BpmnNM.GetAttributeValue(xEdge, BpmnNM.BpmnDi, BpmnDiConstants.MessageVisibleKindAttribute)) { case "non_initiating": MessageVisibleK = MessageVisibleKind.NonInitiating; break; case "initiating": MessageVisibleK = MessageVisibleKind.Initiating; break; default: MessageVisibleK = MessageVisibleKind.Unspecified; break; } }
/// <summary> /// Parse all bpmn shapes and bpmn edges and their associations and attributes from one <see cref="BpmnPlane"/> /// </summary> /// <param name="xNode">The XML node to start with</param> private BpmnPlane BuildPlane(XElement xNode) { var plane = new BpmnPlane(xNode, Elements); if (plane.Element == null) { return(null); } // All Shapes foreach (var xChild in BpmnNM.GetElements(xNode, BpmnNM.BpmnDi, BpmnDiConstants.BpmnShapeElement)) { var shape = new BpmnShape(xChild, Elements); if (shape.Element != null) { plane.AddShape(shape); } else { Messages.Add("Error in parsing shape " + (shape.Id) + ", could not find corresponding BPMNElement."); continue; } // Shapes usually define their bounds shape.AddBounds(BpmnNM.GetElement(xChild, BpmnNM.Dc, BpmnDiConstants.BoundsElement)); // Shapes can have a BPMNLabel as child var bpmnLabel = BpmnNM.GetElement(xChild, BpmnNM.BpmnDi, BpmnDiConstants.BpmnLabelElement); if (bpmnLabel != null) { // Label bounds var bounds = BpmnNM.GetElement(bpmnLabel, BpmnNM.Dc, BpmnDiConstants.BoundsElement); shape.AddLabel(bounds); // BpmnLabelStyle shape.LabelStyle = BpmnNM.GetAttributeValue(bpmnLabel, BpmnNM.BpmnDi, BpmnDiConstants.LabelStyleAttribute); } } foreach (var xChild in BpmnNM.GetElements(xNode, BpmnNM.BpmnDi, BpmnDiConstants.BpmnEdgeElement)) { var edge = new BpmnEdge(xChild, Elements); if (edge.Element != null) { plane.AddEdge(edge); } else { Messages.Add("Error in parsing edge " + (edge.Id) + ", could not find corresponding BPMNElement."); continue; } // Edges define 2 or more Waypoints foreach (var waypoint in BpmnNM.GetElements(xChild, BpmnNM.Di, BpmnDiConstants.WaypointElement)) { edge.AddWayPoint(waypoint); } // Edges can have a BPMNLabel as child var bpmnLabel = BpmnNM.GetElement(xChild, BpmnNM.BpmnDi, BpmnDiConstants.BpmnLabelElement); if (bpmnLabel != null) { // Label bounds var bounds = BpmnNM.GetElement(bpmnLabel, BpmnNM.Dc, BpmnDiConstants.BoundsElement); edge.AddLabel(bounds); // BpmnLabelStyle edge.LabelStyle = BpmnNM.GetAttributeValue(bpmnLabel, BpmnNM.BpmnDi, BpmnDiConstants.LabelStyleAttribute); } } return(plane); }
/// <summary> /// Class for BPMNElement objects /// </summary> /// <param name="xNode">The XML Node to turn into a BpmnElement</param> public BpmnElement(XElement xNode) { Children = new List <BpmnElement>(); ForeignChildren = new List <XNode>(); Attributes = new Dictionary <string, string>(); //Initialize blank Label Label = ""; // Parsing all Attributes foreach (var attribute in BpmnNM.AttributesInNamespace(xNode.Attributes(), BpmnNM.Bpmn)) { var localName = attribute.Name.LocalName; switch (localName) { case BpmnDiConstants.IdAttribute: Id = attribute.Value; break; case BpmnDiConstants.NameAttribute: Label = attribute.Value; break; case BpmnDiConstants.SourceRefAttribute: Source = attribute.Value; break; case BpmnDiConstants.TargetRefAttribute: Target = attribute.Value; break; case BpmnDiConstants.ProcessRefAttribute: Process = attribute.Value; break; case BpmnDiConstants.CalledElementAttribute: case BpmnDiConstants.CalledChoreographyRefAttribute: CalledElement = attribute.Value; break; default: Attributes.Add(localName, attribute.Value); break; } } Value = xNode.Value; Name = xNode.Name.LocalName; switch (Name) { case BpmnDiConstants.GroupElement: Label = BpmnNM.GetAttributeValue(xNode, BpmnNM.Bpmn, BpmnDiConstants.CategoryValueRefAttribute); break; case BpmnDiConstants.TextAnnotationElement: var element = BpmnNM.GetElement(xNode, BpmnNM.Bpmn, BpmnDiConstants.TextElement); if (element != null) { Label = element.Value; } break; } }
/// <summary> /// Constructs an instance of <see cref="DefaultLabelStyle"/> representing this Style /// </summary> /// <param name="xStyle">The XML Element to be converted into this style</param> public BpmnLabelStyle(XElement xStyle) { Id = null; Font = "Arial"; Size = 0; IsBold = false; IsItalic = false; IsUnderline = false; IsStrikeThrough = false; Id = BpmnNM.GetAttributeValue(xStyle, BpmnNM.Dc, BpmnDiConstants.IdAttribute); // Parse Values of the Label Style var xFont = BpmnNM.GetElement(xStyle, BpmnNM.Dc, BpmnDiConstants.FontElement); if (xFont != null) { Font = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.NameAttribute); var attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.SizeAttribute); if (attr != null) { Size = double.Parse(attr, CultureInfo.InvariantCulture); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsBoldAttribute); if (attr != null) { IsBold = bool.Parse(attr); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsItalicAttribute); if (attr != null) { IsItalic = bool.Parse(attr); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsUnderlineAttribute); if (attr != null) { IsUnderline = bool.Parse(attr); } attr = BpmnNM.GetAttributeValue(xFont, BpmnNM.Dc, BpmnDiConstants.IsStrikeThroughAttribute); if (attr != null) { IsStrikeThrough = bool.Parse(attr); } } LabelStyle = new DefaultLabelStyle { TextAlignment = TextAlignment.Center, VerticalTextAlignment = VerticalAlignment.Center }; var fontStyle = FontStyles.Normal; var fontWeight = FontWeights.Normal; // Set text size if (Size > 0) { LabelStyle.TextSize = Size; } else { LabelStyle.TextSize = LabelTextSize; } // Set Boldness if (IsBold) { fontWeight = FontWeights.Bold; } // Set Italic if (IsItalic) { fontStyle = FontStyles.Italic; } LabelStyle.Typeface = new Typeface(new FontFamily(Font), fontStyle, fontWeight, FontStretches.Normal); LabelStyle.TextDecorations = new TextDecorationCollection(); // Set Underline if (IsUnderline) { LabelStyle.TextDecorations.Add(TextDecorations.Underline); } // Set StrikeThrough if (IsStrikeThrough) { LabelStyle.TextDecorations.Add(TextDecorations.Strikethrough); } LabelStyle.TextWrapping = TextWrapping.Wrap; }