001package org.nasdanika.html.flow;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.List;
006import java.util.Map;
007import java.util.function.BiConsumer;
008import java.util.function.Consumer;
009import java.util.stream.Collectors;
010
011import org.eclipse.emf.common.util.EList;
012import org.eclipse.emf.common.util.EMap;
013import org.eclipse.emf.common.util.URI;
014import org.eclipse.emf.ecore.EObject;
015import org.eclipse.emf.ecore.EReference;
016import org.eclipse.emf.ecore.ETypedElement;
017import org.nasdanika.common.Context;
018import org.nasdanika.common.ProgressMonitor;
019import org.nasdanika.common.Util;
020import org.nasdanika.diagram.Diagram;
021import org.nasdanika.diagram.DiagramElement;
022import org.nasdanika.flow.Artifact;
023import org.nasdanika.flow.ArtifactParticipantResponsibility;
024import org.nasdanika.flow.FlowElement;
025import org.nasdanika.flow.FlowPackage;
026import org.nasdanika.flow.Participant;
027import org.nasdanika.flow.Relationship;
028import org.nasdanika.flow.Transition;
029import org.nasdanika.flow.util.ArtifactComponentDiagramGenerator;
030import org.nasdanika.html.emf.ColumnBuilder;
031import org.nasdanika.html.model.app.Action;
032import org.nasdanika.html.model.app.AppFactory;
033import org.nasdanika.html.model.app.SectionStyle;
034import org.nasdanika.html.model.bootstrap.BootstrapFactory;
035import org.nasdanika.html.model.bootstrap.Table;
036import org.nasdanika.html.model.bootstrap.TableCell;
037import org.nasdanika.html.model.bootstrap.TableHeader;
038import org.nasdanika.html.model.bootstrap.TableRow;
039import org.nasdanika.html.model.bootstrap.TableSection;
040import org.nasdanika.ncore.NcorePackage;
041import org.nasdanika.ncore.util.NamedElementComparator;
042
043public class ArtifactActionBuilder extends ParticipantResponsibilityActionBuilder<Artifact> {
044        
045        public ArtifactActionBuilder(Artifact value, Context context) {
046                super(value, context);
047        }
048                
049        @Override
050        protected Action buildAction(
051                        Action action,
052                        BiConsumer<EObject, Action> registry,
053                        Consumer<org.nasdanika.common.Consumer<org.nasdanika.html.emf.EObjectActionResolver.Context>> resolveConsumer,
054                        ProgressMonitor progressMonitor) throws Exception {
055                
056                action = super.buildAction(action, registry, resolveConsumer, progressMonitor);
057                EList<EObject> children = action.getChildren(); 
058                for (Artifact element: getTarget().getChildren().values().stream().sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList())) {
059                        children.add(createChildAction(element, registry, resolveConsumer, progressMonitor));
060                }
061                
062                return action;
063        }       
064        
065        @Override
066        protected List<ETypedElement> getProperties() {
067                List<ETypedElement> properties = super.getProperties();
068                properties.add(FlowPackage.Literals.ARTIFACT__INPUT_FOR);
069                properties.add(FlowPackage.Literals.ARTIFACT__OUTPUT_FOR);
070                properties.add(FlowPackage.Literals.ARTIFACT__REPOSITORIES);
071                properties.add(FlowPackage.Literals.ARTIFACT__USED_BY);
072                properties.add(FlowPackage.Literals.ARTIFACT__TEMPLATES);
073                properties.add(FlowPackage.Literals.ARTIFACT__INSTANCES);
074                return properties;
075        }
076                
077        @Override
078        protected void resolve(
079                        Action action, 
080                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
081                        ProgressMonitor progressMonitor) throws Exception {
082                
083                super.resolve(action, context, progressMonitor);
084                
085                EList<Action> sections = action.getSections();
086                Artifact semanticElement = getTarget();
087                if (!semanticElement.getPayloadFor().isEmpty()) {
088                        sections.add(createEReferenceAction(action, FlowPackage.Literals.ARTIFACT__PAYLOAD_FOR, context, progressMonitor));
089                }
090                
091                if (!semanticElement.getResponseFor().isEmpty()) {
092                        sections.add(createEReferenceAction(action, FlowPackage.Literals.ARTIFACT__RESPONSE_FOR, context, progressMonitor));
093                }
094                
095                
096                // Inbound
097                EList<Relationship> inboundRelationships = semanticElement.getInboundRelationships();
098                EMap<String, Relationship> outboundRelationships = semanticElement.getOutboundRelationships();
099                if (!(inboundRelationships.isEmpty() && outboundRelationships.isEmpty())) {
100                        Action rAction = AppFactory.eINSTANCE.createAction();
101                        rAction.setSectionStyle(SectionStyle.HEADER);
102                        rAction.setText("Relationships");
103                        sections.add(rAction);
104                        EList<Action> rSections = rAction.getSections();
105                        if (!inboundRelationships.isEmpty()) {
106                                rSections.add(createInboundRelationshipsAction(action, context, progressMonitor));
107                        }
108                        
109                        // Outbound
110                        if (!outboundRelationships.isEmpty()) {
111                                rSections.add(createOutboundRelationshipsAction(action, context, progressMonitor));
112                        }
113                }
114                
115                // Activity level responsibilities
116                EList<ArtifactParticipantResponsibility> responsibilities = semanticElement.getResponsibilities();
117                
118                if (!responsibilities.isEmpty()) {
119                        sections.add(createActivityResponsibilitiesAction(responsibilities, action, context, progressMonitor));
120                }
121                
122        }
123
124        private Action createActivityResponsibilitiesAction(
125                        EList<ArtifactParticipantResponsibility> responsibilities,
126                        Action base,
127                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
128                        ProgressMonitor progressMonitor) throws Exception {
129
130                Action responsibilitiesAction = AppFactory.eINSTANCE.createAction();                    
131                responsibilitiesAction.setText("Activity responsibilities");
132                
133                Table responsibilitiesTable = BootstrapFactory.eINSTANCE.createTable();
134                TableHeader header = BootstrapFactory.eINSTANCE.createTableHeader();
135                responsibilitiesTable.setHeader(header);
136                TableRow headerRow = BootstrapFactory.eINSTANCE.createTableRow();
137                header.getRows().add(headerRow);
138                EList<TableCell> headerRowCells = headerRow.getCells();
139                for (String title: new String[] {"Activity", "Responsible", "Accountable", "Consulted", "Informed"}) {
140                        TableCell headerCell = BootstrapFactory.eINSTANCE.createTableCell();
141                        headerCell.setHeader(true);
142                        headerRowCells.add(headerCell);
143                        headerCell.getContent().add(createText(title));
144                }
145                
146                // Group all by container. Sort containers For each container create a row              
147                Map<EObject, List<ArtifactParticipantResponsibility>> flowElementsMap = Util.groupBy(responsibilities, EObject::eContainer);
148
149                TableSection body = BootstrapFactory.eINSTANCE.createTableSection();
150                responsibilitiesTable.setBody(body);
151                EList<TableRow> bodyRows = body.getRows();
152                
153                for (FlowElement<?> container: flowElementsMap.keySet().stream().map(e -> (FlowElement<?>) e).sorted(FlowActionBuilder::compareFlowElements).collect(Collectors.toList())) {
154                        TableRow containerRow = BootstrapFactory.eINSTANCE.createTableRow();
155                        bodyRows.add(containerRow);
156
157                        TableCell containerCell = BootstrapFactory.eINSTANCE.createTableCell();
158                        containerRow.getCells().add(containerCell);
159                        containerCell.getContent().add(renderValue(base, null, container, context, progressMonitor));
160                        
161                        TableCell responsibleCell = BootstrapFactory.eINSTANCE.createTableCell();
162                        containerRow.getCells().add(responsibleCell);
163                        List<ArtifactParticipantResponsibility> containerResponsibilities = flowElementsMap.get(container);
164                        
165                        buildResponsibilityCell(
166                                        containerResponsibilities
167                                                .stream()
168                                                .map(ArtifactParticipantResponsibility::getResponsible)
169                                                .flatMap(Collection::stream)
170                                                .collect(Collectors.toSet()) // To remove duplicates
171                                                .stream()
172                                                .sorted(NamedElementComparator.INSTANCE)
173                                                .collect(Collectors.toList()),
174                                        responsibleCell,
175                                        base, 
176                                        context, 
177                                        progressMonitor);
178                        
179                        TableCell accountableCell = BootstrapFactory.eINSTANCE.createTableCell();
180                        containerRow.getCells().add(accountableCell);
181                        buildResponsibilityCell(
182                                        containerResponsibilities
183                                                .stream()
184                                                .map(ArtifactParticipantResponsibility::getAccountable)
185                                                .flatMap(Collection::stream)
186                                                .collect(Collectors.toSet()) // To remove duplicates
187                                                .stream()
188                                                .sorted(NamedElementComparator.INSTANCE)
189                                                .collect(Collectors.toList()),
190                                        accountableCell,
191                                        base, 
192                                        context, 
193                                        progressMonitor);
194                        
195                        TableCell consultedCell = BootstrapFactory.eINSTANCE.createTableCell();
196                        containerRow.getCells().add(consultedCell);
197                        buildResponsibilityCell(
198                                        containerResponsibilities
199                                                .stream()
200                                                .map(ArtifactParticipantResponsibility::getConsulted)
201                                                .flatMap(Collection::stream)
202                                                .collect(Collectors.toSet()) // To remove duplicates
203                                                .stream()
204                                                .sorted(NamedElementComparator.INSTANCE)
205                                                .collect(Collectors.toList()),
206                                        consultedCell,
207                                        base, 
208                                        context, 
209                                        progressMonitor);
210                        
211                        TableCell informedCell = BootstrapFactory.eINSTANCE.createTableCell();
212                        containerRow.getCells().add(informedCell);
213                        buildResponsibilityCell(
214                                        containerResponsibilities
215                                                .stream()
216                                                .map(ArtifactParticipantResponsibility::getInformed)
217                                                .flatMap(Collection::stream)
218                                                .collect(Collectors.toSet()) // To remove duplicates
219                                                .stream()
220                                                .sorted(NamedElementComparator.INSTANCE)
221                                                .collect(Collectors.toList()),
222                                        informedCell,
223                                        base, 
224                                        context, 
225                                        progressMonitor);
226                }
227                
228                responsibilitiesAction.getContent().add(responsibilitiesTable);
229                
230                return responsibilitiesAction;
231        }
232        
233        private void buildResponsibilityCell(
234                        List<Participant> elements,                     
235                        TableCell cell,
236                        Action base,
237                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
238                        ProgressMonitor progressMonitor) throws Exception {
239                
240                if (elements != null && !elements.isEmpty()) {
241                        cell.getContent().add(renderValue(base, null, elements, context, progressMonitor));
242                }
243                        
244        }
245        
246        // TODO - Sort by source 
247        private Action createEReferenceAction(
248                        Action action, 
249                        EReference eReference,
250                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
251                        ProgressMonitor progressMonitor) throws Exception {
252                Collection<ColumnBuilder<? super EObject>> columnBuilders = new ArrayList<>();
253                columnBuilders.add(new ColumnBuilder<EObject>() {
254                        
255                        @Override
256                        public void buildHeader(
257                                        TableCell header, 
258                                        Action base, 
259                                        ETypedElement typedElement,
260                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
261                                        ProgressMonitor progressMonitor)
262                                        throws Exception {
263                                header.getContent().add(createText("Source"));
264                        }
265                        
266                        @Override
267                        public void buildCell(
268                                        EObject rowElement, 
269                                        TableCell cell, 
270                                        Action base, 
271                                        ETypedElement typedElement,
272                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
273                                        ProgressMonitor progressMonitor)
274                                        throws Exception {
275                                cell.getContent().add(renderValue(base, typedElement, rowElement.eContainer().eContainer(), context, progressMonitor));                         
276                        }
277                });
278                
279                columnBuilders.add(new ColumnBuilder<EObject>() {
280                        
281                        @Override
282                        public void buildHeader(
283                                        TableCell header, 
284                                        Action base, 
285                                        ETypedElement typedElement,
286                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
287                                        ProgressMonitor progressMonitor)
288                                        throws Exception {
289                                header.getContent().add(createText("Key"));
290                        }
291                        
292                        @Override
293                        public void buildCell(
294                                        EObject rowElement, 
295                                        TableCell cell, 
296                                        Action base, 
297                                        ETypedElement typedElement,
298                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
299                                        ProgressMonitor progressMonitor)
300                                        throws Exception {
301                                EObject renderedValue = renderValue(base, typedElement, ((Map.Entry<?,?>) rowElement.eContainer()).getKey(), context, progressMonitor);
302                                if (renderedValue != null) {
303                                        cell.getContent().add(renderedValue);
304                                }
305                        }
306                });
307                
308                columnBuilders.add(new ColumnBuilder<EObject>() {
309                        
310                        @Override
311                        public void buildHeader(
312                                        TableCell header, 
313                                        Action base, 
314                                        ETypedElement typedElement,
315                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
316                                        ProgressMonitor progressMonitor)
317                                        throws Exception {
318                                header.getContent().add(createText("Target"));
319                        }
320                        
321                        @Override
322                        public void buildCell(
323                                        EObject rowElement, 
324                                        TableCell cell, 
325                                        Action base, 
326                                        ETypedElement typedElement,
327                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
328                                        ProgressMonitor progressMonitor)
329                                        throws Exception {
330                                EObject renderedValue = renderValue(base, typedElement, ((Transition) rowElement).getTarget(), context, progressMonitor);
331                                if (renderedValue != null) {
332                                        cell.getContent().add(renderedValue);
333                                }
334                        }
335                });
336
337                columnBuilders.add(new ColumnBuilder<EObject>() {
338                        
339                        @Override
340                        public void buildHeader(
341                                        TableCell header, 
342                                        Action base, 
343                                        ETypedElement typedElement,
344                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
345                                        ProgressMonitor progressMonitor)
346                                        throws Exception {
347                                header.getContent().add(createText("Name"));
348                        }
349                        
350                        @Override
351                        public void buildCell(
352                                        EObject rowElement, 
353                                        TableCell cell, 
354                                        Action base, 
355                                        ETypedElement typedElement,
356                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
357                                        ProgressMonitor progressMonitor)
358                                        throws Exception {
359                                EObject renderedValue = renderValue(base, typedElement, ((Transition) rowElement).getName(), context, progressMonitor);
360                                if (renderedValue != null) {
361                                        cell.getContent().add(renderedValue);
362                                }
363                        }
364                });
365
366                columnBuilders.add(new ColumnBuilder<EObject>() {
367                        
368                        @Override
369                        public void buildHeader(
370                                        TableCell header, 
371                                        Action base, 
372                                        ETypedElement typedElement,
373                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
374                                        ProgressMonitor progressMonitor)
375                                        throws Exception {
376                                header.getContent().add(createText("Documentation"));
377                        }
378                        
379                        @Override
380                        public void buildCell(
381                                        EObject rowElement, 
382                                        TableCell cell, 
383                                        Action base, 
384                                        ETypedElement typedElement,
385                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
386                                        ProgressMonitor progressMonitor)
387                                        throws Exception {
388                                EObject renderedValue = renderValue(base, typedElement, ((Transition) rowElement).getDocumentation(), context, progressMonitor);
389                                if (renderedValue != null) {
390                                        cell.getContent().add(renderedValue);
391                                }
392                        }
393                });
394                
395                return createTableAction(
396                                eReference,
397                                columnBuilders,
398                                action, 
399                                context, 
400                                progressMonitor);
401        }
402        
403        @Override
404        protected void populateRepresentation(
405                        Diagram representation, 
406                        Action action,
407                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
408                        ProgressMonitor progressMonitor) throws Exception {
409
410                ArtifactComponentDiagramGenerator artifactComponentDiagramGenerator = new ArtifactComponentDiagramGenerator() {
411                
412                        @Override
413                        protected String getArtifactLocation(Artifact semanticElement) {
414                                Action elementAction = context.getAction(semanticElement);
415                                if (elementAction == null) {
416                                        return null;
417                                }
418                                
419                                URI uri = context.resolve(elementAction, action);
420                                return uri == null ? null : uri.toString();
421                        }
422                        
423                        @Override
424                        protected String getArtifactTooltip(Artifact semanticElement) {
425                                Action elementAction = context.getAction(semanticElement);
426                                return elementAction == null ? null : elementAction.getDescription();
427                        }
428
429                        @Override
430                        protected DiagramElement createDiagramElement(
431                                        Artifact semanticElement,
432                                        Map<Artifact, DiagramElement> semanticMap, 
433                                        Artifact contextElement,
434                                        int depth) {
435                                
436                                DiagramElement ret = super.createDiagramElement(semanticElement, semanticMap, contextElement, depth);
437                                String text = ret.getText();
438                                int initialLineLength = 25;
439                                if (text != null && text.length() > initialLineLength) {
440                                        ret.setText(Util.wrap(text, initialLineLength, 2, "\\n"));
441                                }
442                                return ret;
443                        }
444                                                
445                };
446                
447                populateRepresentation(representation, artifactComponentDiagramGenerator);
448        }
449        
450        protected void populateRepresentation(Diagram representation, ArtifactComponentDiagramGenerator artifactComponentDiagramGenerator) {
451                artifactComponentDiagramGenerator.generateDiagram(getTarget(), representation);
452        }
453
454        private Action createInboundRelationshipsAction(
455                        Action action, 
456                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
457                        ProgressMonitor progressMonitor) throws Exception {
458                Collection<ColumnBuilder<? super EObject>> columnBuilders = new ArrayList<>();
459                columnBuilders.add(new ColumnBuilder<EObject>() {
460                        
461                        @Override
462                        public void buildHeader(
463                                        TableCell header, 
464                                        Action base, 
465                                        ETypedElement typedElement,
466                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
467                                        ProgressMonitor progressMonitor)
468                                        throws Exception {
469                                header.getContent().add(createText("Source"));
470                        }
471                        
472                        @Override
473                        public void buildCell(
474                                        EObject rowElement, 
475                                        TableCell cell, 
476                                        Action base, 
477                                        ETypedElement typedElement,
478                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
479                                        ProgressMonitor progressMonitor)
480                                        throws Exception {
481                                cell.getContent().add(renderValue(base, typedElement, rowElement.eContainer().eContainer(), context, progressMonitor));                         
482                        }
483                });
484                
485                columnBuilders.add(createColumnBuilder(NcorePackage.Literals.NAMED_ELEMENT__NAME));             
486                columnBuilders.add(createColumnBuilder(FlowPackage.Literals.PACKAGE_ELEMENT__DOCUMENTATION));           
487                
488                Action ret = AppFactory.eINSTANCE.createAction();
489                ret.setText("Inbound");
490                
491                Table table = buildTable(
492                                getTarget().getInboundRelationships(), 
493                                columnBuilders, 
494                                action, 
495                                FlowPackage.Literals.ARTIFACT__INBOUND_RELATIONSHIPS, 
496                                context, 
497                                progressMonitor);
498                
499                ret.getContent().add(table);
500                return ret;             
501        }
502        
503        private Action createOutboundRelationshipsAction(
504                        Action action, 
505                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
506                        ProgressMonitor progressMonitor) throws Exception {
507                Collection<ColumnBuilder<? super Map.Entry<String, Relationship>>> columnBuilders = new ArrayList<>();
508                columnBuilders.add(new ColumnBuilder<Map.Entry<String, Relationship>>() {
509                        
510                        @Override
511                        public void buildHeader(
512                                        TableCell header, 
513                                        Action base, 
514                                        ETypedElement typedElement,
515                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
516                                        ProgressMonitor progressMonitor)
517                                        throws Exception {
518                                header.getContent().add(createText("Key"));
519                        }
520                        
521                        @Override
522                        public void buildCell(
523                                        Map.Entry<String, Relationship> rowElement, 
524                                        TableCell cell, 
525                                        Action base, 
526                                        ETypedElement typedElement,
527                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
528                                        ProgressMonitor progressMonitor)
529                                        throws Exception {
530                                EObject renderedValue = renderValue(base, typedElement, rowElement.getKey(), context, progressMonitor);
531                                if (renderedValue != null) {
532                                        cell.getContent().add(renderedValue);
533                                }
534                        }
535                });
536                
537                columnBuilders.add(new ColumnBuilder<Map.Entry<String, Relationship>>() {
538                        
539                        @Override
540                        public void buildHeader(
541                                        TableCell header, 
542                                        Action base, 
543                                        ETypedElement typedElement,
544                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
545                                        ProgressMonitor progressMonitor)
546                                        throws Exception {
547                                header.getContent().add(createText("Target"));
548                        }
549                        
550                        @Override
551                        public void buildCell(
552                                        Map.Entry<String, Relationship> rowElement, 
553                                        TableCell cell, 
554                                        Action base, 
555                                        ETypedElement typedElement,
556                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
557                                        ProgressMonitor progressMonitor)
558                                        throws Exception {
559                                Relationship relationship = rowElement.getValue();
560                                EObject renderedValue = renderValue(base, typedElement, relationship.getTarget(), context, progressMonitor);
561                                if (renderedValue != null) {
562                                        cell.getContent().add(renderedValue);
563                                }
564                        }
565                });
566
567                columnBuilders.add(new ColumnBuilder<Map.Entry<String, Relationship>>() {
568                        
569                        @Override
570                        public void buildHeader(
571                                        TableCell header, 
572                                        Action base, 
573                                        ETypedElement typedElement,
574                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
575                                        ProgressMonitor progressMonitor)
576                                        throws Exception {
577                                header.getContent().add(createText("Name"));
578                        }
579                        
580                        @Override
581                        public void buildCell(
582                                        Map.Entry<String, Relationship> rowElement, 
583                                        TableCell cell, 
584                                        Action base, 
585                                        ETypedElement typedElement,
586                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
587                                        ProgressMonitor progressMonitor)
588                                        throws Exception {
589                                Relationship value = rowElement.getValue();
590                                EObject renderedValue = renderValue(base, typedElement, value.getName(), context, progressMonitor);
591                                if (renderedValue != null) {
592                                        cell.getContent().add(renderedValue);
593                                }
594                        }
595                });
596
597                columnBuilders.add(new ColumnBuilder<Map.Entry<String, Relationship>>() {
598                        
599                        @Override
600                        public void buildHeader(
601                                        TableCell header, 
602                                        Action base, 
603                                        ETypedElement typedElement,
604                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
605                                        ProgressMonitor progressMonitor)
606                                        throws Exception {
607                                header.getContent().add(createText("Documentation"));
608                        }
609                        
610                        @Override
611                        public void buildCell(
612                                        Map.Entry<String, Relationship> rowElement, 
613                                        TableCell cell, 
614                                        Action base, 
615                                        ETypedElement typedElement,
616                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
617                                        ProgressMonitor progressMonitor)
618                                        throws Exception {
619                                Relationship value = rowElement.getValue();
620                                EObject renderedValue = renderValue(base, typedElement, value.getDocumentation(), context, progressMonitor);
621                                if (renderedValue != null) {
622                                        cell.getContent().add(renderedValue);
623                                }
624                        }
625                });
626                
627                Action ret = AppFactory.eINSTANCE.createAction();
628                ret.setText("Outbound");
629                
630                Table table = buildTable(
631                                getTarget().getOutboundRelationships(), 
632                                columnBuilders, 
633                                action, 
634                                FlowPackage.Literals.ARTIFACT__OUTBOUND_RELATIONSHIPS, 
635                                context, 
636                                progressMonitor);
637                
638                ret.getContent().add(table);
639                return ret;             
640        }
641        
642        
643}