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.Predicate;
008import java.util.stream.Collectors;
009
010import org.eclipse.emf.common.util.EList;
011import org.eclipse.emf.common.util.URI;
012import org.eclipse.emf.ecore.EObject;
013import org.eclipse.emf.ecore.ETypedElement;
014import org.nasdanika.common.Context;
015import org.nasdanika.common.ProgressMonitor;
016import org.nasdanika.common.Util;
017import org.nasdanika.diagram.Diagram;
018import org.nasdanika.diagram.DiagramElement;
019import org.nasdanika.flow.Call;
020import org.nasdanika.flow.FlowElement;
021import org.nasdanika.flow.FlowPackage;
022import org.nasdanika.flow.Participant;
023import org.nasdanika.flow.Transition;
024import org.nasdanika.flow.util.FlowStateDiagramGenerator;
025import org.nasdanika.html.emf.ColumnBuilder;
026import org.nasdanika.html.model.app.Action;
027import org.nasdanika.html.model.bootstrap.TableCell;
028import org.nasdanika.ncore.NamedElement;
029import org.nasdanika.ncore.NcorePackage;
030import org.nasdanika.ncore.util.NamedElementComparator;
031
032public class FlowElementActionBuilder<T extends FlowElement<?>> extends ParticipantResponsibilityActionBuilder<T> {
033        
034        public FlowElementActionBuilder(T value, Context context) {
035                super(value, context);
036        }
037                
038        @Override
039        protected List<ETypedElement> getProperties() {
040                List<ETypedElement> properties = super.getProperties();
041                properties.add(FlowPackage.Literals.FLOW_ELEMENT__INPUT_ARTIFACTS);
042                properties.add(FlowPackage.Literals.FLOW_ELEMENT__OUTPUT_ARTIFACTS);
043                properties.add(FlowPackage.Literals.FLOW_ELEMENT__PARTICIPANTS);
044                properties.add(FlowPackage.Literals.FLOW_ELEMENT__RESOURCES);
045                return properties;
046        }
047        
048        @SuppressWarnings("unchecked")
049        @Override
050        protected Object getTypedElementValue(ETypedElement typedElement) throws Exception {
051                Object value = super.getTypedElementValue(typedElement);
052                if (value instanceof Collection && (
053                                typedElement == FlowPackage.Literals.FLOW_ELEMENT__INPUT_ARTIFACTS 
054                                || typedElement == FlowPackage.Literals.FLOW_ELEMENT__OUTPUT_ARTIFACTS 
055                                || typedElement == FlowPackage.Literals.FLOW_ELEMENT__PARTICIPANTS
056                                || typedElement == FlowPackage.Literals.FLOW_ELEMENT__RESOURCES)) {
057                        return ((Collection<NamedElement>) value).stream().sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList());
058                }
059                return value;
060        }
061        
062        @Override
063        protected void resolve(
064                        Action action, 
065                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
066                        ProgressMonitor progressMonitor) throws Exception {
067                
068                super.resolve(action, context, progressMonitor);
069                
070                // Inputs
071                EList<Action> sections = action.getSections();
072                if (!getTarget().getInputs().isEmpty()) {
073                        sections.add(createInputsAction(action, context, progressMonitor));
074                }
075                
076                // Outputs
077                if (!getTarget().getOutputs().isEmpty()) {
078                        sections.add(createOutputsAction(action, context, progressMonitor));
079                }
080                
081                // Invocations
082                if (!getTarget().getInvocations().isEmpty()) {
083                        sections.add(createInvocationsAction(action, context, progressMonitor));
084                }
085                
086                // Calls
087                if (!getTarget().getCalls().isEmpty()) {
088                        sections.add(createCallsAction(action, context, progressMonitor));
089                }
090                
091                // Artifact participant responsibilities
092                if (!getTarget().getArtifactResponsibilities().isEmpty()) {
093                        sections.add(createArtifactResponsibilitiesAction(action, context, progressMonitor));                   
094                }
095        }
096        
097        @Override
098        protected void populateRepresentation(
099                        Diagram representation, 
100                        Action action,
101                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
102                        ProgressMonitor progressMonitor)
103                        throws Exception {
104                
105                FlowStateDiagramGenerator flowStateDiagramGenerator = new FlowStateDiagramGenerator() {
106                
107                        @Override
108                        protected String getFlowElementLocation(FlowElement<?> flowElement) {
109                                Action elementAction = context.getAction(flowElement);
110                                if (elementAction == null) {
111                                        return null;
112                                }
113                                
114                                URI uri = context.resolve(elementAction, action);
115                                return uri == null ? null : uri.toString();
116                        }
117                        
118                        @Override
119                        protected String getFlowElementTooltip(FlowElement<?> flowElement) {
120                                Action elementAction = context.getAction(flowElement);
121                                return elementAction == null ? null : elementAction.getDescription();
122                        }
123                        
124                        @Override
125                        protected String getParticipantLocation(Participant participant) {
126                                Action elementAction = context.getAction(participant);
127                                if (elementAction == null) {
128                                        return null;
129                                }
130                                
131                                URI uri = context.resolve(elementAction, action);
132                                return uri == null ? null : uri.toString();
133                        }
134                        
135                        @Override
136                        protected String getParticipantTooltip(Participant participant) {
137                                Action elementAction = context.getAction(participant);
138                                return elementAction == null ? null : elementAction.getDescription();
139                        }
140                        
141                        /**
142                         * Wraps text
143                         */
144                        @Override
145                        protected DiagramElement createDiagramElement(
146                                        FlowElement<?> flowElement,
147                                        Map<FlowElement<?>, DiagramElement> semanticMap, 
148                                        FlowElement<?> contextElement,
149                                        Predicate<FlowElement<?>> partitionPredicate,
150                                        int depth) {
151                                
152                                DiagramElement ret = super.createDiagramElement(flowElement, semanticMap, contextElement, partitionPredicate, depth);
153                                String text = ret.getText();
154                                int initialLineLength = 25;
155                                if (text != null && text.length() > initialLineLength) {
156                                        ret.setText(Util.wrap(text, initialLineLength, 2, "\\n"));
157                                }
158                                return ret;
159                        }
160                        
161                };
162                
163                populateRepresentation(representation, flowStateDiagramGenerator);
164        }
165
166        protected void populateRepresentation(Diagram representation, FlowStateDiagramGenerator flowStateDiagramGenerator) {
167                flowStateDiagramGenerator.generateDiagram(getTarget(), representation, null);
168        }
169
170        private Action createInputsAction(
171                        Action action, 
172                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
173                        ProgressMonitor progressMonitor) throws Exception {
174                Collection<ColumnBuilder<? super EObject>> columnBuilders = new ArrayList<>();
175                columnBuilders.add(new ColumnBuilder<EObject>() {
176                        
177                        @Override
178                        public void buildHeader(
179                                        TableCell header, 
180                                        Action base, 
181                                        ETypedElement typedElement,
182                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
183                                        ProgressMonitor progressMonitor)
184                                        throws Exception {
185                                header.getContent().add(createText("Source"));
186                        }
187                        
188                        @Override
189                        public void buildCell(
190                                        EObject rowElement, 
191                                        TableCell cell, 
192                                        Action base, 
193                                        ETypedElement typedElement,
194                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
195                                        ProgressMonitor progressMonitor)
196                                        throws Exception {
197                                cell.getContent().add(renderValue(base, typedElement, rowElement.eContainer().eContainer(), context, progressMonitor));                         
198                        }
199                });
200                
201                columnBuilders.add(createColumnBuilder(NcorePackage.Literals.NAMED_ELEMENT__NAME));             
202                columnBuilders.add(createColumnBuilder(FlowPackage.Literals.PACKAGE_ELEMENT__DOCUMENTATION));           
203                columnBuilders.add(createColumnBuilder(FlowPackage.Literals.TRANSITION__PAYLOAD));
204                
205                return createTableAction(
206                                FlowPackage.Literals.FLOW_ELEMENT__INPUTS,
207                                columnBuilders,
208                                action, 
209                                context, 
210                                progressMonitor);
211        }
212        
213        private Action createOutputsAction(
214                        Action action, 
215                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
216                        ProgressMonitor progressMonitor) throws Exception {
217                Collection<ColumnBuilder<? super EObject>> columnBuilders = new ArrayList<>();
218                columnBuilders.add(new ColumnBuilder<EObject>() {
219                        
220                        @Override
221                        public void buildHeader(
222                                        TableCell header, 
223                                        Action base, 
224                                        ETypedElement typedElement,
225                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
226                                        ProgressMonitor progressMonitor)
227                                        throws Exception {
228                                header.getContent().add(createText("Key"));
229                        }
230                        
231                        @Override
232                        public void buildCell(
233                                        EObject rowElement, 
234                                        TableCell cell, 
235                                        Action base, 
236                                        ETypedElement typedElement,
237                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
238                                        ProgressMonitor progressMonitor)
239                                        throws Exception {
240                                EObject renderedValue = renderValue(base, typedElement, ((Map.Entry<?,?>) rowElement).getKey(), context, progressMonitor);
241                                if (renderedValue != null) {
242                                        cell.getContent().add(renderedValue);
243                                }
244                        }
245                });
246                
247                columnBuilders.add(new ColumnBuilder<EObject>() {
248                        
249                        @Override
250                        public void buildHeader(
251                                        TableCell header, 
252                                        Action base, 
253                                        ETypedElement typedElement,
254                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
255                                        ProgressMonitor progressMonitor)
256                                        throws Exception {
257                                header.getContent().add(createText("Target"));
258                        }
259                        
260                        @Override
261                        public void buildCell(
262                                        EObject rowElement, 
263                                        TableCell cell, 
264                                        Action base, 
265                                        ETypedElement typedElement,
266                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
267                                        ProgressMonitor progressMonitor)
268                                        throws Exception {
269                                Transition transition = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
270                                EObject renderedValue = renderValue(base, typedElement, transition.getTarget(), context, progressMonitor);
271                                if (renderedValue != null) {
272                                        cell.getContent().add(renderedValue);
273                                }
274                        }
275                });
276
277                columnBuilders.add(new ColumnBuilder<EObject>() {
278                        
279                        @Override
280                        public void buildHeader(
281                                        TableCell header, 
282                                        Action base, 
283                                        ETypedElement typedElement,
284                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
285                                        ProgressMonitor progressMonitor)
286                                        throws Exception {
287                                header.getContent().add(createText("Name"));
288                        }
289                        
290                        @Override
291                        public void buildCell(
292                                        EObject rowElement, 
293                                        TableCell cell, 
294                                        Action base, 
295                                        ETypedElement typedElement,
296                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
297                                        ProgressMonitor progressMonitor)
298                                        throws Exception {
299                                Transition value = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
300                                EObject renderedValue = renderValue(base, typedElement, value.getName(), context, progressMonitor);
301                                if (renderedValue != null) {
302                                        cell.getContent().add(renderedValue);
303                                }
304                        }
305                });
306
307                columnBuilders.add(new ColumnBuilder<EObject>() {
308                        
309                        @Override
310                        public void buildHeader(
311                                        TableCell header, 
312                                        Action base, 
313                                        ETypedElement typedElement,
314                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
315                                        ProgressMonitor progressMonitor)
316                                        throws Exception {
317                                header.getContent().add(createText("Documentation"));
318                        }
319                        
320                        @Override
321                        public void buildCell(
322                                        EObject rowElement, 
323                                        TableCell cell, 
324                                        Action base, 
325                                        ETypedElement typedElement,
326                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
327                                        ProgressMonitor progressMonitor)
328                                        throws Exception {
329                                Transition value = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
330                                EObject renderedValue = renderValue(base, typedElement, value.getDocumentation(), 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("Payload"));
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                                Transition value = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
360                                EObject renderedValue = renderValue(base, typedElement, value.getPayload(), context, progressMonitor);
361                                if (renderedValue != null) {
362                                        cell.getContent().add(renderedValue);                           
363                                }
364                        }
365                });
366                
367                return createTableAction(
368                                FlowPackage.Literals.FLOW_ELEMENT__OUTPUTS,
369                                columnBuilders,
370                                action, 
371                                context, 
372                                progressMonitor);
373        }
374
375        private Action createInvocationsAction(
376                        Action action, 
377                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
378                        ProgressMonitor progressMonitor) throws Exception {
379                Collection<ColumnBuilder<? super EObject>> columnBuilders = new ArrayList<>();
380                columnBuilders.add(new ColumnBuilder<EObject>() {
381                        
382                        @Override
383                        public void buildHeader(
384                                        TableCell header, 
385                                        Action base, 
386                                        ETypedElement typedElement,
387                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
388                                        ProgressMonitor progressMonitor)
389                                        throws Exception {
390                                header.getContent().add(createText("Source"));
391                        }
392                        
393                        @Override
394                        public void buildCell(
395                                        EObject rowElement, 
396                                        TableCell cell, 
397                                        Action base, 
398                                        ETypedElement typedElement,
399                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
400                                        ProgressMonitor progressMonitor)
401                                        throws Exception {
402                                cell.getContent().add(renderValue(base, typedElement, rowElement.eContainer().eContainer(), context, progressMonitor));                         
403                        }
404                });
405                
406                columnBuilders.add(createColumnBuilder(NcorePackage.Literals.NAMED_ELEMENT__NAME));             
407                columnBuilders.add(createColumnBuilder(FlowPackage.Literals.PACKAGE_ELEMENT__DOCUMENTATION));           
408                columnBuilders.add(createColumnBuilder(FlowPackage.Literals.TRANSITION__PAYLOAD));
409                columnBuilders.add(createColumnBuilder(FlowPackage.Literals.CALL__RESPONSE));
410                
411                return createTableAction(
412                                FlowPackage.Literals.FLOW_ELEMENT__INVOCATIONS,
413                                columnBuilders,
414                                action, 
415                                context, 
416                                progressMonitor);
417        }
418        
419        private Action createCallsAction(
420                        Action action, 
421                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
422                        ProgressMonitor progressMonitor) throws Exception {
423                Collection<ColumnBuilder<? super EObject>> columnBuilders = new ArrayList<>();
424                columnBuilders.add(new ColumnBuilder<EObject>() {
425                        
426                        @Override
427                        public void buildHeader(
428                                        TableCell header, 
429                                        Action base, 
430                                        ETypedElement typedElement,
431                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
432                                        ProgressMonitor progressMonitor)
433                                        throws Exception {
434                                header.getContent().add(createText("Key"));
435                        }
436                        
437                        @Override
438                        public void buildCell(
439                                        EObject rowElement, 
440                                        TableCell cell, 
441                                        Action base, 
442                                        ETypedElement typedElement,
443                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
444                                        ProgressMonitor progressMonitor)
445                                        throws Exception {
446                                EObject renderedValue = renderValue(base, typedElement, ((Map.Entry<?,?>) rowElement).getKey(), context, progressMonitor);
447                                if (renderedValue != null) {
448                                        cell.getContent().add(renderedValue);
449                                }
450                        }
451                });
452                
453                columnBuilders.add(new ColumnBuilder<EObject>() {
454                        
455                        @Override
456                        public void buildHeader(
457                                        TableCell header, 
458                                        Action base, 
459                                        ETypedElement typedElement,
460                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
461                                        ProgressMonitor progressMonitor)
462                                        throws Exception {
463                                header.getContent().add(createText("Target"));
464                        }
465                        
466                        @Override
467                        public void buildCell(
468                                        EObject rowElement, 
469                                        TableCell cell, 
470                                        Action base, 
471                                        ETypedElement typedElement,
472                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
473                                        ProgressMonitor progressMonitor)
474                                        throws Exception {
475                                Transition transition = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
476                                EObject renderedValue = renderValue(base, typedElement, transition.getTarget(), context, progressMonitor);
477                                if (renderedValue != null) {
478                                        cell.getContent().add(renderedValue);
479                                }
480                        }
481                });
482
483                columnBuilders.add(new ColumnBuilder<EObject>() {
484                        
485                        @Override
486                        public void buildHeader(
487                                        TableCell header, 
488                                        Action base, 
489                                        ETypedElement typedElement,
490                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
491                                        ProgressMonitor progressMonitor)
492                                        throws Exception {
493                                header.getContent().add(createText("Name"));
494                        }
495                        
496                        @Override
497                        public void buildCell(
498                                        EObject rowElement, 
499                                        TableCell cell, 
500                                        Action base, 
501                                        ETypedElement typedElement,
502                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
503                                        ProgressMonitor progressMonitor)
504                                        throws Exception {
505                                Transition value = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
506                                EObject renderedValue = renderValue(base, typedElement, value.getName(), context, progressMonitor);
507                                if (renderedValue != null) {
508                                        cell.getContent().add(renderedValue);
509                                }
510                        }
511                });
512
513                columnBuilders.add(new ColumnBuilder<EObject>() {
514                        
515                        @Override
516                        public void buildHeader(
517                                        TableCell header, 
518                                        Action base, 
519                                        ETypedElement typedElement,
520                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
521                                        ProgressMonitor progressMonitor)
522                                        throws Exception {
523                                header.getContent().add(createText("Documentation"));
524                        }
525                        
526                        @Override
527                        public void buildCell(
528                                        EObject rowElement, 
529                                        TableCell cell, 
530                                        Action base, 
531                                        ETypedElement typedElement,
532                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
533                                        ProgressMonitor progressMonitor)
534                                        throws Exception {
535                                Transition value = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
536                                EObject renderedValue = renderValue(base, typedElement, value.getDocumentation(), context, progressMonitor);
537                                if (renderedValue != null) {
538                                        cell.getContent().add(renderedValue);
539                                }
540                        }
541                });
542
543                columnBuilders.add(new ColumnBuilder<EObject>() {
544                        
545                        @Override
546                        public void buildHeader(
547                                        TableCell header, 
548                                        Action base, 
549                                        ETypedElement typedElement,
550                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
551                                        ProgressMonitor progressMonitor)
552                                        throws Exception {
553                                header.getContent().add(createText("Request"));
554                        }
555                        
556                        @Override
557                        public void buildCell(
558                                        EObject rowElement, 
559                                        TableCell cell, 
560                                        Action base, 
561                                        ETypedElement typedElement,
562                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
563                                        ProgressMonitor progressMonitor)
564                                        throws Exception {
565                                Transition value = (Transition) ((Map.Entry<?,?>) rowElement).getValue();
566                                EObject renderedValue = renderValue(base, typedElement, value.getPayload(), context, progressMonitor);
567                                if (renderedValue != null) {
568                                        cell.getContent().add(renderedValue);                           
569                                }
570                        }
571                });
572
573                columnBuilders.add(new ColumnBuilder<EObject>() {
574                        
575                        @Override
576                        public void buildHeader(
577                                        TableCell header, 
578                                        Action base, 
579                                        ETypedElement typedElement,
580                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
581                                        ProgressMonitor progressMonitor)
582                                        throws Exception {
583                                header.getContent().add(createText("Response"));
584                        }
585                        
586                        @Override
587                        public void buildCell(
588                                        EObject rowElement, 
589                                        TableCell cell, 
590                                        Action base, 
591                                        ETypedElement typedElement,
592                                        org.nasdanika.html.emf.EObjectActionResolver.Context context, 
593                                        ProgressMonitor progressMonitor)
594                                        throws Exception {
595                                Call value = (Call) ((Map.Entry<?,?>) rowElement).getValue();
596                                EObject renderedValue = renderValue(base, typedElement, value.getResponse(), context, progressMonitor);
597                                if (renderedValue != null) {
598                                        cell.getContent().add(renderedValue);                           
599                                }
600                        }
601                });
602                
603                return createTableAction(
604                                FlowPackage.Literals.FLOW_ELEMENT__CALLS,
605                                columnBuilders,
606                                action, 
607                                context, 
608                                progressMonitor);
609        }
610        
611        
612        private Action createArtifactResponsibilitiesAction(
613                        Action action, 
614                        org.nasdanika.html.emf.EObjectActionResolver.Context context,
615                        ProgressMonitor progressMonitor) throws Exception {
616                
617                return createTableAction(
618                                FlowPackage.Literals.FLOW_ELEMENT__ARTIFACT_RESPONSIBILITIES,
619                                action, 
620                                context, 
621                                progressMonitor,
622                                FlowPackage.Literals.ARTIFACT_PARTICIPANT_RESPONSIBILITY__ARTIFACT,
623                                FlowPackage.Literals.PARTICIPANT_RESPONSIBILITY__RESPONSIBLE,
624                                FlowPackage.Literals.PARTICIPANT_RESPONSIBILITY__ACCOUNTABLE,
625                                FlowPackage.Literals.PARTICIPANT_RESPONSIBILITY__CONSULTED,
626                                FlowPackage.Literals.PARTICIPANT_RESPONSIBILITY__INFORMED,
627                                NcorePackage.Literals.MODEL_ELEMENT__DESCRIPTION);
628        }
629        
630}