001package org.nasdanika.html.flow; 002 003import java.util.Collections; 004import java.util.HashSet; 005import java.util.List; 006import java.util.Map; 007import java.util.Set; 008import java.util.function.BiConsumer; 009import java.util.function.Consumer; 010import java.util.stream.Collectors; 011 012import org.eclipse.emf.common.util.EList; 013import org.eclipse.emf.ecore.EClass; 014import org.eclipse.emf.ecore.EObject; 015import org.eclipse.emf.ecore.ETypedElement; 016import org.nasdanika.common.Context; 017import org.nasdanika.common.ProgressMonitor; 018import org.nasdanika.common.Util; 019import org.nasdanika.emf.EmfUtil; 020import org.nasdanika.flow.ArtifactParticipantResponsibility; 021import org.nasdanika.flow.FlowElement; 022import org.nasdanika.flow.FlowPackage; 023import org.nasdanika.flow.Participant; 024import org.nasdanika.flow.ParticipantResponsibility; 025import org.nasdanika.html.model.app.Action; 026import org.nasdanika.html.model.app.AppFactory; 027import org.nasdanika.html.model.app.SectionStyle; 028import org.nasdanika.html.model.bootstrap.BootstrapFactory; 029import org.nasdanika.html.model.bootstrap.Table; 030import org.nasdanika.html.model.bootstrap.TableCell; 031import org.nasdanika.html.model.bootstrap.TableHeader; 032import org.nasdanika.html.model.bootstrap.TableRow; 033import org.nasdanika.html.model.bootstrap.TableSection; 034import org.nasdanika.ncore.util.NamedElementComparator; 035 036public class ParticipantActionBuilder extends ServiceProviderActionBuilder<Participant> { 037 038 public ParticipantActionBuilder(Participant value, Context context) { 039 super(value, context); 040 } 041 042 @Override 043 protected Action buildAction( 044 Action action, 045 BiConsumer<EObject, Action> registry, 046 Consumer<org.nasdanika.common.Consumer<org.nasdanika.html.emf.EObjectActionResolver.Context>> resolveConsumer, 047 ProgressMonitor progressMonitor) throws Exception { 048 049 action = super.buildAction(action, registry, resolveConsumer, progressMonitor); 050 EList<EObject> children = action.getChildren(); 051 for (Participant element: getTarget().getChildren().values().stream().sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList())) { 052 children.add(createChildAction(element, registry, resolveConsumer, progressMonitor)); 053 } 054 055 return action; 056 } 057 058 @Override 059 protected List<ETypedElement> getProperties() { 060 List<ETypedElement> properties = super.getProperties(); 061 properties.add(FlowPackage.Literals.PARTICIPANT__ARTIFACTS); 062 properties.add(FlowPackage.Literals.PARTICIPANT__PARTICIPATES); 063 properties.add(FlowPackage.Literals.PARTICIPANT__RESOURCES); 064 properties.add(FlowPackage.Literals.PARTICIPANT__BASES); 065 properties.add(FlowPackage.Literals.PARTICIPANT__SPECIALIZATIONS); 066 return properties; 067 } 068 069 @Override 070 protected void resolve( 071 Action action, 072 org.nasdanika.html.emf.EObjectActionResolver.Context context, 073 ProgressMonitor progressMonitor) throws Exception { 074 super.resolve(action, context, progressMonitor); 075 076 // Responsibilities 077 EList<Action> sections = action.getSections(); 078 079 Set<EClass> groupKeys = new HashSet<>(); // For sections 080 081 Map<EClass, List<ParticipantResponsibility<?>>> responsibleGroup = Util.groupBy(getTarget().getResponsible(), EObject::eClass); 082 groupKeys.addAll(responsibleGroup.keySet()); 083 084 Map<EClass, List<ParticipantResponsibility<?>>> accountableGroup = Util.groupBy(getTarget().getAccountable(), EObject::eClass); 085 groupKeys.addAll(accountableGroup.keySet()); 086 087 Map<EClass, List<ParticipantResponsibility<?>>> consultedGroup = Util.groupBy(getTarget().getConsulted(), EObject::eClass); 088 groupKeys.addAll(consultedGroup.keySet()); 089 090 Map<EClass, List<ParticipantResponsibility<?>>> informedGroup = Util.groupBy(getTarget().getInformed(), EObject::eClass); 091 groupKeys.addAll(informedGroup.keySet()); 092 093 if (!groupKeys.isEmpty()) { 094 Action responsibilitiesAction = AppFactory.eINSTANCE.createAction(); 095 responsibilitiesAction.setText("Responsible"); 096 responsibilitiesAction.setSectionStyle(SectionStyle.HEADER); 097 sections.add(responsibilitiesAction); 098 EList<Action> rSections = responsibilitiesAction.getSections(); 099 for (EClass groupKey: groupKeys.stream().sorted(EmfUtil.ENAMED_ELEMENT_COMPARATOR).collect(Collectors.toList())) { 100 rSections.add(createResponsivilityGroupAction( 101 groupKey, 102 responsibleGroup.get(groupKey), 103 accountableGroup.get(groupKey), 104 consultedGroup.get(groupKey), 105 informedGroup.get(groupKey), 106 action, 107 context, 108 progressMonitor)); 109 } 110 } 111 112 } 113 114 private Action createResponsivilityGroupAction( 115 EClass typeKey, 116 List<ParticipantResponsibility<?>> responsible, 117 List<ParticipantResponsibility<?>> accountable, 118 List<ParticipantResponsibility<?>> consulted, 119 List<ParticipantResponsibility<?>> informed, 120 Action base, 121 org.nasdanika.html.emf.EObjectActionResolver.Context context, 122 ProgressMonitor progressMonitor) throws Exception { 123 124 Action groupAction = AppFactory.eINSTANCE.createAction(); 125 String groupName = typeKey.getName(); 126 if ("Activity".equals(groupName)) { 127 groupAction.setText("Activities"); 128 } else { 129 groupAction.setText(groupName + "s"); 130 } 131 132 if (typeKey == FlowPackage.Literals.ARTIFACT_PARTICIPANT_RESPONSIBILITY) { 133 groupAction.setText("Activity artifacts"); 134 Table responsibilitiesTable = BootstrapFactory.eINSTANCE.createTable(); 135 TableHeader header = BootstrapFactory.eINSTANCE.createTableHeader(); 136 responsibilitiesTable.setHeader(header); 137 TableRow headerRow = BootstrapFactory.eINSTANCE.createTableRow(); 138 header.getRows().add(headerRow); 139 EList<TableCell> headerRowCells = headerRow.getCells(); 140 for (String title: new String[] {"Activity", "Responsible", "Accountable", "Consulted", "Informed"}) { 141 TableCell headerCell = BootstrapFactory.eINSTANCE.createTableCell(); 142 headerCell.setHeader(true); 143 headerRowCells.add(headerCell); 144 headerCell.getContent().add(createText(title)); 145 } 146 147 // Group all by container. Sort containers For each container create a row 148 Set<EObject> flowElements = new HashSet<>(); // For sections 149 150 Map<EObject, List<ParticipantResponsibility<?>>> responsibleGroup = responsible == null ? Collections.emptyMap() : Util.groupBy(responsible, EObject::eContainer); 151 flowElements.addAll(responsibleGroup.keySet()); 152 153 Map<EObject, List<ParticipantResponsibility<?>>> accountableGroup = accountable == null ? Collections.emptyMap() : Util.groupBy(accountable, EObject::eContainer); 154 flowElements.addAll(accountableGroup.keySet()); 155 156 Map<EObject, List<ParticipantResponsibility<?>>> consultedGroup = consulted == null ? Collections.emptyMap() : Util.groupBy(consulted, EObject::eContainer); 157 flowElements.addAll(consultedGroup.keySet()); 158 159 Map<EObject, List<ParticipantResponsibility<?>>> informedGroup = informed == null ? Collections.emptyMap() : Util.groupBy(informed, EObject::eContainer); 160 flowElements.addAll(informedGroup.keySet()); 161 162 TableSection body = BootstrapFactory.eINSTANCE.createTableSection(); 163 responsibilitiesTable.setBody(body); 164 EList<TableRow> bodyRows = body.getRows(); 165 166 for (FlowElement<?> container: flowElements.stream().map(e -> (FlowElement<?>) e).sorted(FlowActionBuilder::compareFlowElements).collect(Collectors.toList())) { 167 TableRow containerRow = BootstrapFactory.eINSTANCE.createTableRow(); 168 bodyRows.add(containerRow); 169 170 TableCell containerCell = BootstrapFactory.eINSTANCE.createTableCell(); 171 containerRow.getCells().add(containerCell); 172 containerCell.getContent().add(renderValue(base, null, container, context, progressMonitor)); 173 174 TableCell responsibleCell = BootstrapFactory.eINSTANCE.createTableCell(); 175 containerRow.getCells().add(responsibleCell); 176 List<ParticipantResponsibility<?>> containerResponsible = responsibleGroup.get(container); 177 if (containerResponsible != null) { 178 buildResponsibilityCell(containerResponsible.stream().map(e -> ((ArtifactParticipantResponsibility) e).getArtifact()).sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList()), responsibleCell, base, context, progressMonitor); 179 } 180 181 TableCell accountableCell = BootstrapFactory.eINSTANCE.createTableCell(); 182 containerRow.getCells().add(accountableCell); 183 List<ParticipantResponsibility<?>> containerAccountable = accountableGroup.get(container); 184 if (containerAccountable != null) { 185 buildResponsibilityCell(containerAccountable.stream().map(e -> ((ArtifactParticipantResponsibility) e).getArtifact()).sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList()), accountableCell, base, context, progressMonitor); 186 } 187 188 TableCell consultedCell = BootstrapFactory.eINSTANCE.createTableCell(); 189 containerRow.getCells().add(consultedCell); 190 List<ParticipantResponsibility<?>> containerConsulted = consultedGroup.get(container); 191 if (containerConsulted != null) { 192 buildResponsibilityCell(containerConsulted.stream().map(e -> ((ArtifactParticipantResponsibility) e).getArtifact()).sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList()), consultedCell, base, context, progressMonitor); 193 } 194 195 TableCell informedCell = BootstrapFactory.eINSTANCE.createTableCell(); 196 containerRow.getCells().add(informedCell); 197 List<ParticipantResponsibility<?>> containerInformed = informedGroup.get(container); 198 if (containerInformed != null) { 199 buildResponsibilityCell(containerInformed.stream().map(e -> ((ArtifactParticipantResponsibility) e).getArtifact()).sorted(NamedElementComparator.INSTANCE).collect(Collectors.toList()), informedCell, base, context, progressMonitor); 200 } 201 202 } 203 204 groupAction.getContent().add(responsibilitiesTable); 205 } else { 206 Table responsibilitiesTable = BootstrapFactory.eINSTANCE.createTable(); 207 TableHeader header = BootstrapFactory.eINSTANCE.createTableHeader(); 208 responsibilitiesTable.setHeader(header); 209 TableRow headerRow = BootstrapFactory.eINSTANCE.createTableRow(); 210 header.getRows().add(headerRow); 211 EList<TableCell> headerRowCells = headerRow.getCells(); 212 for (String title: new String[] {"Responsible", "Accountable", "Consulted", "Informed"}) { 213 TableCell headerCell = BootstrapFactory.eINSTANCE.createTableCell(); 214 headerCell.setHeader(true); 215 headerRowCells.add(headerCell); 216 headerCell.getContent().add(createText(title)); 217 } 218 219 TableSection body = BootstrapFactory.eINSTANCE.createTableSection(); 220 responsibilitiesTable.setBody(body); 221 EList<TableRow> bodyRows = body.getRows(); 222 223 TableRow responsibilitiesRow = BootstrapFactory.eINSTANCE.createTableRow(); 224 bodyRows.add(responsibilitiesRow); 225 226 TableCell responsibleCell = BootstrapFactory.eINSTANCE.createTableCell(); 227 responsibilitiesRow.getCells().add(responsibleCell); 228 buildResponsibilityCell(responsible, responsibleCell, base, context, progressMonitor); 229 230 TableCell accountableCell = BootstrapFactory.eINSTANCE.createTableCell(); 231 responsibilitiesRow.getCells().add(accountableCell); 232 buildResponsibilityCell(accountable, accountableCell, base, context, progressMonitor); 233 234 TableCell consultedCell = BootstrapFactory.eINSTANCE.createTableCell(); 235 responsibilitiesRow.getCells().add(consultedCell); 236 buildResponsibilityCell(consulted, consultedCell, base, context, progressMonitor); 237 238 TableCell informedCell = BootstrapFactory.eINSTANCE.createTableCell(); 239 responsibilitiesRow.getCells().add(informedCell); 240 buildResponsibilityCell(informed, informedCell, base, context, progressMonitor); 241 242 groupAction.getContent().add(responsibilitiesTable); 243 } 244 245 return groupAction; 246 } 247 248 private void buildResponsibilityCell( 249 List<ParticipantResponsibility<?>> elements, 250 TableCell cell, 251 Action base, 252 org.nasdanika.html.emf.EObjectActionResolver.Context context, 253 ProgressMonitor progressMonitor) throws Exception { 254 255 if (elements != null && !elements.isEmpty()) { 256 cell.getContent().add(renderValue(base, null, elements, context, progressMonitor)); 257 } 258 259 } 260 261}