Skip to content

Commit d10e822

Browse files
authored
Make element name extension element in case of new line optional (#3951)
1 parent 754287e commit d10e822

File tree

17 files changed

+143
-40
lines changed

17 files changed

+143
-40
lines changed

modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BaseBpmnXMLConverter.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,13 @@ public void convertToBpmnModel(XMLStreamReader xtr, BpmnModel model, Process act
164164
}
165165
}
166166

167-
public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel model) throws Exception {
167+
public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel model, BpmnXMLConverterOptions options) throws Exception {
168168
xtw.writeStartElement(getXMLElementName());
169169
boolean didWriteExtensionStartElement = false;
170170
writeDefaultAttribute(ATTRIBUTE_ID, baseElement.getId(), xtw);
171171
if (baseElement instanceof FlowElement) {
172172
String name = ((FlowElement) baseElement).getName();
173-
if (!BpmnXMLUtil.containsNewLine(name)) {
173+
if (!(options.isSaveElementNameWithNewLineInExtensionElement() && BpmnXMLUtil.containsNewLine(name))) {
174174
writeDefaultAttribute(ATTRIBUTE_NAME, name, xtw);
175175
}
176176
}
@@ -226,7 +226,9 @@ public void convertToXML(XMLStreamWriter xtw, BaseElement baseElement, BpmnModel
226226
xtw.writeEndElement();
227227
}
228228

229-
didWriteExtensionStartElement = BpmnXMLUtil.writeElementNameExtensionElement(flowElement, didWriteExtensionStartElement, xtw);
229+
if (options.isSaveElementNameWithNewLineInExtensionElement()) {
230+
didWriteExtensionStartElement = BpmnXMLUtil.writeElementNameExtensionElement(flowElement, didWriteExtensionStartElement, xtw);
231+
}
230232
}
231233

232234
didWriteExtensionStartElement = writeExtensionChildElements(baseElement, didWriteExtensionStartElement, xtw);

modules/flowable-bpmn-converter/src/main/java/org/flowable/bpmn/converter/BpmnXMLConverter.java

+18-4
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ public class BpmnXMLConverter implements BpmnXMLConstants {
116116
protected List<String> userTaskFormTypes;
117117
protected List<String> startEventFormTypes;
118118

119+
protected BpmnXMLConverterOptions options = new BpmnXMLConverterOptions();
120+
119121
protected BpmnEdgeParser bpmnEdgeParser = new BpmnEdgeParser();
120122
protected BpmnShapeParser bpmnShapeParser = new BpmnShapeParser();
121123
protected DefinitionsParser definitionsParser = new DefinitionsParser();
@@ -204,6 +206,14 @@ public static void addConverter(BaseBpmnXMLConverter converter, Class<? extends
204206
convertersToXMLMap.put(elementType, converter);
205207
}
206208

209+
public BpmnXMLConverterOptions getBpmnXmlConverterOptions() {
210+
return options;
211+
}
212+
213+
public void setBpmnXmlConverterOptions(BpmnXMLConverterOptions options) {
214+
this.options = options;
215+
}
216+
207217
public void setClassloader(ClassLoader classloader) {
208218
this.classloader = classloader;
209219
}
@@ -581,7 +591,9 @@ protected void createXML(FlowElement flowElement, BpmnModel model, XMLStreamWrit
581591

582592
xtw.writeAttribute(ATTRIBUTE_ID, subProcess.getId());
583593
if (StringUtils.isNotEmpty(subProcess.getName())) {
584-
xtw.writeAttribute(ATTRIBUTE_NAME, subProcess.getName());
594+
if (!(options.isSaveElementNameWithNewLineInExtensionElement() && BpmnXMLUtil.containsNewLine(subProcess.getName()))) {
595+
xtw.writeAttribute(ATTRIBUTE_NAME, subProcess.getName());
596+
}
585597
} else {
586598
xtw.writeAttribute(ATTRIBUTE_NAME, "subProcess");
587599
}
@@ -619,7 +631,9 @@ protected void createXML(FlowElement flowElement, BpmnModel model, XMLStreamWrit
619631

620632
boolean didWriteExtensionStartElement = FlowableListenerExport.writeListeners(subProcess, false, xtw);
621633

622-
didWriteExtensionStartElement = BpmnXMLUtil.writeElementNameExtensionElement(subProcess, didWriteExtensionStartElement, xtw);
634+
if (options.isSaveElementNameWithNewLineInExtensionElement()) {
635+
didWriteExtensionStartElement = BpmnXMLUtil.writeElementNameExtensionElement(subProcess, didWriteExtensionStartElement, xtw);
636+
}
623637

624638
didWriteExtensionStartElement = BpmnXMLUtil.writeExtensionElements(subProcess, didWriteExtensionStartElement, model.getNamespaces(), xtw);
625639
if (didWriteExtensionStartElement) {
@@ -656,7 +670,7 @@ protected void createXML(FlowElement flowElement, BpmnModel model, XMLStreamWrit
656670
throw new XMLException("No converter for " + flowElement.getClass() + " found");
657671
}
658672

659-
converter.convertToXML(xtw, flowElement, model);
673+
converter.convertToXML(xtw, flowElement, model, options);
660674
}
661675
}
662676

@@ -668,6 +682,6 @@ protected void createXML(Artifact artifact, BpmnModel model, XMLStreamWriter xtw
668682
throw new XMLException("No converter for " + artifact.getClass() + " found");
669683
}
670684

671-
converter.convertToXML(xtw, artifact, model);
685+
converter.convertToXML(xtw, artifact, model, options);
672686
}
673687
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.bpmn.converter;
14+
15+
public class BpmnXMLConverterOptions {
16+
17+
protected boolean saveElementNameWithNewLineInExtensionElement = false;
18+
19+
public boolean isSaveElementNameWithNewLineInExtensionElement() {
20+
return saveElementNameWithNewLineInExtensionElement;
21+
}
22+
23+
public void setSaveElementNameWithNewLineInExtensionElement(boolean saveElementNameWithNewLineInExtensionElement) {
24+
this.saveElementNameWithNewLineInExtensionElement = saveElementNameWithNewLineInExtensionElement;
25+
}
26+
}

modules/flowable-bpmn-converter/src/test/java/org/flowable/editor/language/xml/NameWithNewLineTest.java

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import static org.flowable.bpmn.constants.BpmnXMLConstants.ATTRIBUTE_ELEMENT_NAME;
1717

1818
import org.flowable.bpmn.model.BpmnModel;
19-
import org.flowable.bpmn.model.ExtensionElement;
2019
import org.flowable.bpmn.model.FlowElement;
2120
import org.flowable.bpmn.model.SubProcess;
2221
import org.flowable.editor.language.xml.util.BpmnXmlConverterTest;

modules/flowable-bpmn-converter/src/test/java/org/flowable/editor/language/xml/util/XmlTestUtils.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,18 @@ public static BpmnModel readXmlExportAndReadAgain(String resource) {
3131
}
3232

3333
public static BpmnModel exportAndReadXMLFile(BpmnModel model) {
34-
byte[] xml = new BpmnXMLConverter().convertToXML(model);
35-
return new BpmnXMLConverter().convertToBpmnModel(new InputStreamSource(new ByteArrayInputStream(xml)), true, false, "UTF-8");
34+
byte[] xml = getBpmnXMLConverter().convertToXML(model);
35+
return getBpmnXMLConverter().convertToBpmnModel(new InputStreamSource(new ByteArrayInputStream(xml)), true, false, "UTF-8");
3636
}
3737

3838
public static BpmnModel readXMLFile(String resource) {
39-
return new BpmnXMLConverter().convertToBpmnModel(new ClasspathStreamResource(resource), true, false);
39+
return getBpmnXMLConverter().convertToBpmnModel(new ClasspathStreamResource(resource), true, false);
40+
}
41+
42+
private static BpmnXMLConverter getBpmnXMLConverter() {
43+
BpmnXMLConverter converter = new BpmnXMLConverter();
44+
converter.getBpmnXmlConverterOptions().setSaveElementNameWithNewLineInExtensionElement(true);
45+
return converter;
4046
}
4147

4248
protected static class ClasspathStreamResource implements InputStreamProvider {

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/CmmnXmlConverter.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ public class CmmnXmlConverter implements CmmnXmlConstants {
9191

9292
protected static Map<String, BaseCmmnXmlConverter> elementConverters = new HashMap<>();
9393

94+
protected CmmnXmlConverterOptions options = new CmmnXmlConverterOptions();
95+
9496
protected ClassLoader classloader;
9597

9698
static {
@@ -295,7 +297,7 @@ public byte[] convertToXML(CmmnModel model, String encoding) {
295297

296298
Stage planModel = caseModel.getPlanModel();
297299

298-
PlanItemDefinitionExport.writePlanItemDefinition(model, planModel, xtw);
300+
PlanItemDefinitionExport.writePlanItemDefinition(model, planModel, xtw, options);
299301

300302
// end case element
301303
xtw.writeEndElement();
@@ -719,6 +721,14 @@ protected void processAssociations(CmmnModel cmmnModel) {
719721
}
720722
}
721723

724+
public CmmnXmlConverterOptions getCmmnXmlConverterOptions() {
725+
return options;
726+
}
727+
728+
public void setCmmnXmlConverterOptions(CmmnXmlConverterOptions options) {
729+
this.options = options;
730+
}
731+
722732
public void setClassloader(ClassLoader classloader) {
723733
this.classloader = classloader;
724734
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* Licensed under the Apache License, Version 2.0 (the "License");
2+
* you may not use this file except in compliance with the License.
3+
* You may obtain a copy of the License at
4+
*
5+
* http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software
8+
* distributed under the License is distributed on an "AS IS" BASIS,
9+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
* See the License for the specific language governing permissions and
11+
* limitations under the License.
12+
*/
13+
package org.flowable.cmmn.converter;
14+
15+
public class CmmnXmlConverterOptions {
16+
17+
protected boolean saveElementNameWithNewLineInExtensionElement = false;
18+
19+
public boolean isSaveElementNameWithNewLineInExtensionElement() {
20+
return saveElementNameWithNewLineInExtensionElement;
21+
}
22+
23+
public void setSaveElementNameWithNewLineInExtensionElement(boolean saveElementNameWithNewLineInExtensionElement) {
24+
this.saveElementNameWithNewLineInExtensionElement = saveElementNameWithNewLineInExtensionElement;
25+
}
26+
27+
}

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/AbstractPlanItemDefinitionExport.java

+14-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.apache.commons.lang3.StringUtils;
1818
import org.flowable.cmmn.converter.CmmnXmlConstants;
19+
import org.flowable.cmmn.converter.CmmnXmlConverterOptions;
1920
import org.flowable.cmmn.converter.util.CmmnXmlUtil;
2021
import org.flowable.cmmn.model.CmmnModel;
2122
import org.flowable.cmmn.model.PlanItemDefinition;
@@ -35,20 +36,20 @@ public abstract class AbstractPlanItemDefinitionExport<T extends PlanItemDefinit
3536
* @param xtw the XML to write the definition to
3637
* @throws Exception in case of write exception
3738
*/
38-
public void writePlanItemDefinition(CmmnModel model, T planItemDefinition, XMLStreamWriter xtw) throws Exception {
39+
public void writePlanItemDefinition(CmmnModel model, T planItemDefinition, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
3940

4041
writePlanItemDefinitionStartElement(planItemDefinition, xtw);
41-
writePlanItemDefinitionCommonAttributes(planItemDefinition, xtw);
42+
writePlanItemDefinitionCommonAttributes(planItemDefinition, xtw, options);
4243
writePlanItemDefinitionSpecificAttributes(planItemDefinition, xtw);
4344

44-
boolean didWriteExtensionElement = writePlanItemDefinitionCommonElements(model, planItemDefinition, xtw);
45+
boolean didWriteExtensionElement = writePlanItemDefinitionCommonElements(model, planItemDefinition, xtw, options);
4546
didWriteExtensionElement = writePlanItemDefinitionExtensionElements(model, planItemDefinition, didWriteExtensionElement, xtw);
4647
if (didWriteExtensionElement) {
4748
xtw.writeEndElement();
4849
}
4950

5051
writePlanItemDefinitionDefaultItemControl(model, planItemDefinition, xtw);
51-
writePlanItemDefinitionBody(model, planItemDefinition, xtw);
52+
writePlanItemDefinitionBody(model, planItemDefinition, xtw, options);
5253
writePlanItemDefinitionEndElement(xtw);
5354
}
5455

@@ -64,10 +65,11 @@ protected void writePlanItemDefinitionStartElement(T planItemDefinition, XMLStre
6465
*/
6566
protected abstract String getPlanItemDefinitionXmlElementValue(T planItemDefinition);
6667

67-
protected void writePlanItemDefinitionCommonAttributes(T planItemDefinition, XMLStreamWriter xtw) throws Exception {
68+
protected void writePlanItemDefinitionCommonAttributes(T planItemDefinition, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
6869
xtw.writeAttribute(ATTRIBUTE_ID, planItemDefinition.getId());
6970

70-
if (StringUtils.isNotEmpty(planItemDefinition.getName()) && !CmmnXmlUtil.containsNewLine(planItemDefinition.getName())) {
71+
if (StringUtils.isNotEmpty(planItemDefinition.getName()) &&
72+
!(options.isSaveElementNameWithNewLineInExtensionElement() && CmmnXmlUtil.containsNewLine(planItemDefinition.getName()))) {
7173
xtw.writeAttribute(ATTRIBUTE_NAME, planItemDefinition.getName());
7274
}
7375
}
@@ -92,14 +94,17 @@ protected void writePlanItemDefinitionSpecificAttributes(T planItemDefinition, X
9294
* @param xtw the XML to write the definition to
9395
* @throws Exception in case of write exception
9496
*/
95-
protected boolean writePlanItemDefinitionCommonElements(CmmnModel model, T planItemDefinition, XMLStreamWriter xtw) throws Exception {
97+
protected boolean writePlanItemDefinitionCommonElements(CmmnModel model, T planItemDefinition, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
9698
if (StringUtils.isNotEmpty(planItemDefinition.getDocumentation())) {
9799
xtw.writeStartElement(ELEMENT_DOCUMENTATION);
98100
xtw.writeCharacters(planItemDefinition.getDocumentation());
99101
xtw.writeEndElement();
100102
}
101103

102-
boolean didWriteExtensionStartElement = CmmnXmlUtil.writeElementNameExtensionElement(planItemDefinition, false, xtw);
104+
boolean didWriteExtensionStartElement = false;
105+
if (options.isSaveElementNameWithNewLineInExtensionElement()) {
106+
didWriteExtensionStartElement = CmmnXmlUtil.writeElementNameExtensionElement(planItemDefinition, didWriteExtensionStartElement, xtw);
107+
}
103108

104109
return CmmnXmlUtil.writeExtensionElements(planItemDefinition, didWriteExtensionStartElement, model.getNamespaces(), xtw);
105110
}
@@ -122,7 +127,7 @@ protected void writePlanItemDefinitionDefaultItemControl(CmmnModel model, T plan
122127
* @param xtw the XML to write the definition to
123128
* @throws Exception in case of write exception
124129
*/
125-
protected void writePlanItemDefinitionBody(CmmnModel model, T planItemDefinition, XMLStreamWriter xtw) throws Exception {
130+
protected void writePlanItemDefinitionBody(CmmnModel model, T planItemDefinition, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
126131

127132
}
128133

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/AbstractServiceTaskExport.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import javax.xml.stream.XMLStreamWriter;
1616

1717
import org.apache.commons.lang3.StringUtils;
18+
import org.flowable.cmmn.converter.CmmnXmlConverterOptions;
1819
import org.flowable.cmmn.model.CmmnModel;
1920
import org.flowable.cmmn.model.HttpServiceTask;
2021
import org.flowable.cmmn.model.ImplementationType;
@@ -93,8 +94,8 @@ protected boolean writePlanItemDefinitionExtensionElements(CmmnModel model, Serv
9394
}
9495

9596
@Override
96-
protected void writePlanItemDefinitionBody(CmmnModel model, ServiceTask serviceTask, XMLStreamWriter xtw) throws Exception {
97-
super.writePlanItemDefinitionBody(model, serviceTask, xtw);
97+
protected void writePlanItemDefinitionBody(CmmnModel model, ServiceTask serviceTask, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
98+
super.writePlanItemDefinitionBody(model, serviceTask, xtw, options);
9899
}
99100

100101
public static class ServiceTaskExport extends AbstractServiceTaskExport<ServiceTask> {

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/CaseTaskExport.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import javax.xml.stream.XMLStreamWriter;
1616

1717
import org.apache.commons.lang3.StringUtils;
18+
import org.flowable.cmmn.converter.CmmnXmlConverterOptions;
1819
import org.flowable.cmmn.model.CaseTask;
1920
import org.flowable.cmmn.model.CmmnModel;
2021

@@ -46,8 +47,8 @@ protected void writePlanItemDefinitionSpecificAttributes(CaseTask caseTask, XMLS
4647
}
4748

4849
@Override
49-
protected void writePlanItemDefinitionBody(CmmnModel model, CaseTask caseTask, XMLStreamWriter xtw) throws Exception {
50-
super.writePlanItemDefinitionBody(model, caseTask, xtw);
50+
protected void writePlanItemDefinitionBody(CmmnModel model, CaseTask caseTask, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
51+
super.writePlanItemDefinitionBody(model, caseTask, xtw, options);
5152

5253
// Always export the case reference as an expression, even if the caseRef is set
5354
if (StringUtils.isNotEmpty(caseTask.getCaseRef()) || StringUtils.isNotEmpty(caseTask.getCaseRefExpression())) {

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/DecisionTaskExport.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import javax.xml.stream.XMLStreamWriter;
1616

1717
import org.apache.commons.lang3.StringUtils;
18+
import org.flowable.cmmn.converter.CmmnXmlConverterOptions;
1819
import org.flowable.cmmn.model.CmmnModel;
1920
import org.flowable.cmmn.model.DecisionTask;
2021

@@ -43,8 +44,8 @@ protected boolean writePlanItemDefinitionExtensionElements(CmmnModel model, Deci
4344
}
4445

4546
@Override
46-
protected void writePlanItemDefinitionBody(CmmnModel model, DecisionTask decisionTask, XMLStreamWriter xtw) throws Exception {
47-
super.writePlanItemDefinitionBody(model, decisionTask, xtw);
47+
protected void writePlanItemDefinitionBody(CmmnModel model, DecisionTask decisionTask, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
48+
super.writePlanItemDefinitionBody(model, decisionTask, xtw, options);
4849
if (StringUtils.isNotEmpty(decisionTask.getDecisionRef()) || StringUtils.isNotEmpty(decisionTask.getDecisionRefExpression())) {
4950
xtw.writeStartElement(ELEMENT_DECISION_REF_EXPRESSION);
5051
xtw.writeCData(

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/PlanFragmentExport.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import javax.xml.stream.XMLStreamWriter;
1616

17+
import org.flowable.cmmn.converter.CmmnXmlConverterOptions;
1718
import org.flowable.cmmn.model.CmmnModel;
1819
import org.flowable.cmmn.model.PlanFragment;
1920
import org.flowable.cmmn.model.PlanItem;
@@ -49,8 +50,8 @@ protected void writePlanItemDefinitionSpecificAttributes(PlanFragment planFragme
4950
}
5051

5152
@Override
52-
protected void writePlanItemDefinitionBody(CmmnModel model, PlanFragment planFragment, XMLStreamWriter xtw) throws Exception {
53-
super.writePlanItemDefinitionBody(model, planFragment, xtw);
53+
protected void writePlanItemDefinitionBody(CmmnModel model, PlanFragment planFragment, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
54+
super.writePlanItemDefinitionBody(model, planFragment, xtw, options);
5455
for (PlanItem planItem : planFragment.getPlanItems()) {
5556
PlanItemExport.writePlanItem(model, planItem, xtw);
5657
}

modules/flowable-cmmn-converter/src/main/java/org/flowable/cmmn/converter/export/PlanItemDefinitionExport.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import javax.xml.stream.XMLStreamWriter;
1919

2020
import org.flowable.cmmn.converter.CmmnXmlConstants;
21+
import org.flowable.cmmn.converter.CmmnXmlConverterOptions;
2122
import org.flowable.cmmn.model.CmmnModel;
2223
import org.flowable.cmmn.model.PlanItemDefinition;
2324
import org.flowable.common.engine.api.FlowableException;
@@ -51,12 +52,12 @@ public static void addPlanItemDefinitionExport(AbstractPlanItemDefinitionExport
5152
planItemDefinitionExporters.put(exporter.getExportablePlanItemDefinitionClass().getCanonicalName(), exporter);
5253
}
5354

54-
public static void writePlanItemDefinition(CmmnModel model, PlanItemDefinition planItemDefinition, XMLStreamWriter xtw) throws Exception {
55+
public static void writePlanItemDefinition(CmmnModel model, PlanItemDefinition planItemDefinition, XMLStreamWriter xtw, CmmnXmlConverterOptions options) throws Exception {
5556
AbstractPlanItemDefinitionExport exporter = determineExporter(planItemDefinition);
5657
if (exporter == null) {
5758
throw new FlowableException("Cannot find a PlanItemDefinitionExporter for '" + planItemDefinition.getClass().getCanonicalName() + "'");
5859
}
59-
exporter.writePlanItemDefinition(model, planItemDefinition, xtw);
60+
exporter.writePlanItemDefinition(model, planItemDefinition, xtw, options);
6061
}
6162

6263
protected static AbstractPlanItemDefinitionExport determineExporter(PlanItemDefinition planItemDefinition) {

0 commit comments

Comments
 (0)