diff --git a/dsl-core/io.mdsl.tests/src/io/mdsl/generator/TextFileFreemarkerTemplateGeneratorTest.java b/dsl-core/io.mdsl.tests/src/io/mdsl/generator/TextFileFreemarkerTemplateGeneratorTest.java index 7532fbe..8ad9129 100644 --- a/dsl-core/io.mdsl.tests/src/io/mdsl/generator/TextFileFreemarkerTemplateGeneratorTest.java +++ b/dsl-core/io.mdsl.tests/src/io/mdsl/generator/TextFileFreemarkerTemplateGeneratorTest.java @@ -54,6 +54,31 @@ public void canGenerateUsingSimpleGeneratorModel() throws IOException { FileUtils.readFileToString(new File(getGenerationDirectory(), "output.txt"), "UTF-8")); } + @Test + public void canGenerateWithDataTypeWithDesc() throws IOException { + // given + Resource inputModel = getTestResource("simple-generation-input-2.mdsl"); + TextFileGenerator generator = new TextFileGenerator(); + generator.setFreemarkerTemplateFile(getTestInputFile("simple-test-with-genmodel-with-desc-template.ftl")); + generator.setTargetFileName("output.txt"); + + // when + JavaIoFileSystemAccess javaIoFileSystemAccess = getFileSystemAccess(); + javaIoFileSystemAccess.setOutputPath(getGenerationDirectory().getAbsolutePath()); + generator.doGenerate(inputModel, javaIoFileSystemAccess, new GeneratorContext()); + + // then + assertEquals( + "TestAPI specified in simple-generation-input-2.mdsl" + System.lineSeparator() + System.lineSeparator() + + "endpoints:" + System.lineSeparator() + "TestEndpoint" + System.lineSeparator() + System.lineSeparator() + + "datatypes:" + System.lineSeparator() + + "name:Description " + System.lineSeparator() + + "doi: string (required, single) " + System.lineSeparator() + + "description: Test" + System.lineSeparator() + "" + , + FileUtils.readFileToString(new File(getGenerationDirectory(), "output.txt"), "UTF-8")); + } + private File getTestFile(String testMDSLName) { return new File(Paths.get("").toAbsolutePath().toString(), testDirectory() + testMDSLName); } diff --git a/dsl-core/io.mdsl.tests/test-data/freemarker-generation/simple-generation-input-2.mdsl b/dsl-core/io.mdsl.tests/test-data/freemarker-generation/simple-generation-input-2.mdsl new file mode 100644 index 0000000..d4f1f4a --- /dev/null +++ b/dsl-core/io.mdsl.tests/test-data/freemarker-generation/simple-generation-input-2.mdsl @@ -0,0 +1,7 @@ +API description TestAPI + +data type Description { "doi":D:"Test" } + +endpoint type TestEndpoint // MDSL compiles only with at least one endpoint + +IPA \ No newline at end of file diff --git a/dsl-core/io.mdsl.tests/test-data/freemarker-generation/simple-test-with-genmodel-with-desc-template.ftl b/dsl-core/io.mdsl.tests/test-data/freemarker-generation/simple-test-with-genmodel-with-desc-template.ftl new file mode 100644 index 0000000..6881a2c --- /dev/null +++ b/dsl-core/io.mdsl.tests/test-data/freemarker-generation/simple-test-with-genmodel-with-desc-template.ftl @@ -0,0 +1,17 @@ +${genModel.apiName} specified in ${fileName} + +endpoints: +<#list genModel.endpoints as endpoint> +${endpoint.name} + + +datatypes: +<#list genModel.dataTypes as dtype> +name:${dtype.name} +<#if dtype.fields?has_content> + <#list dtype.fields as f> +${f.name}: ${f.typeAsString} (${f.nullable?string('optional','required')}, ${f.list?string('list','single')}) +description: ${f.description} + + + diff --git a/dsl-core/io.mdsl.tests/test-data/openapi-generation/simple-generation-input-2.mdsl b/dsl-core/io.mdsl.tests/test-data/openapi-generation/simple-generation-input-2.mdsl new file mode 100644 index 0000000..d4f1f4a --- /dev/null +++ b/dsl-core/io.mdsl.tests/test-data/openapi-generation/simple-generation-input-2.mdsl @@ -0,0 +1,7 @@ +API description TestAPI + +data type Description { "doi":D:"Test" } + +endpoint type TestEndpoint // MDSL compiles only with at least one endpoint + +IPA \ No newline at end of file diff --git a/dsl-core/io.mdsl.tests/test-data/openapi-generation/simple-generation-input-2.yaml b/dsl-core/io.mdsl.tests/test-data/openapi-generation/simple-generation-input-2.yaml new file mode 100644 index 0000000..ba7e723 --- /dev/null +++ b/dsl-core/io.mdsl.tests/test-data/openapi-generation/simple-generation-input-2.yaml @@ -0,0 +1,20 @@ +openapi: 3.0.1 +info: + title: TestAPI + version: "1.0" +servers: [] +tags: +- name: TestEndpoint + externalDocs: + description: TestEndpoint contract + url: "" +paths: + /TestEndpoint: {} +components: + schemas: {} + Description: + type: object + properties: + doi: + type: string + description: Test diff --git a/dsl-core/io.mdsl.ui.tests/META-INF/MANIFEST.MF b/dsl-core/io.mdsl.ui.tests/META-INF/MANIFEST.MF index 7464acb..39b9b08 100644 --- a/dsl-core/io.mdsl.ui.tests/META-INF/MANIFEST.MF +++ b/dsl-core/io.mdsl.ui.tests/META-INF/MANIFEST.MF @@ -1,11 +1,11 @@ Manifest-Version: 1.0 -Automatic-Module-Name: io.mdsl.ui.tests Bundle-ManifestVersion: 2 Bundle-Name: io.mdsl.ui.tests -Bundle-Vendor: MDSL Project +Bundle-SymbolicName: io.mdsl.ui.tests;singleton:=true Bundle-Version: 6.0.0.qualifier -Bundle-SymbolicName: io.mdsl.ui.tests; singleton:=true -Bundle-ActivationPolicy: lazy +Bundle-ClassPath: io.mdsl.ui.tests +Bundle-Vendor: MDSL Project +Export-Package: io.mdsl.ui.tests;x-internal=true Require-Bundle: io.mdsl.ui, org.junit.jupiter.api;bundle-version="[5.0.0,6.0.0)", org.eclipse.xtext.testing, @@ -16,4 +16,5 @@ Require-Bundle: io.mdsl.ui, org.eclipse.ui.workbench;resolution:=optional, org.eclipse.xtext.xbase.ui.testing Bundle-RequiredExecutionEnvironment: JavaSE-1.8 -Export-Package: io.mdsl.ui.tests;x-internal=true +Automatic-Module-Name: io.mdsl.ui.tests +Bundle-ActivationPolicy: lazy diff --git a/dsl-core/io.mdsl.ui/src/io/mdsl/ui/quickfix/CompleteDataType.java b/dsl-core/io.mdsl.ui/src/io/mdsl/ui/quickfix/CompleteDataType.java index 5d5afa3..ac74799 100644 --- a/dsl-core/io.mdsl.ui/src/io/mdsl/ui/quickfix/CompleteDataType.java +++ b/dsl-core/io.mdsl.ui/src/io/mdsl/ui/quickfix/CompleteDataType.java @@ -4,6 +4,7 @@ import org.eclipse.xtext.ui.editor.model.edit.IModificationContext; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.transformations.DataTypeTransformations; class CompleteDataType extends QuickfixSemanticModification { @@ -15,7 +16,7 @@ public CompleteDataType(String type) { @Override public void performQuickfix(EObject element, IModificationContext context) { - RoleAndType rat = (RoleAndType) element; + RoleTypeAndDesc rat = (RoleTypeAndDesc) element; DataTypeTransformations.completeDataType(rat, type); } } \ No newline at end of file diff --git a/dsl-core/io.mdsl/src/io/mdsl/APIDescription.xtext b/dsl-core/io.mdsl/src/io/mdsl/APIDescription.xtext index 4c3ca3b..5c49489 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/APIDescription.xtext +++ b/dsl-core/io.mdsl/src/io/mdsl/APIDescription.xtext @@ -170,7 +170,7 @@ AtomicParameterList: AtomicParameter: classifier=PatternStereotype? - rat=RoleAndType + rat=RoleTypeAndDesc card=Cardinality? ; @@ -179,6 +179,10 @@ RoleAndType: (name=STRING':')? role=ParameterRole ('<'btype=BasicDataType'>' )? ; +RoleTypeAndDesc: + // experimental |'->' ec=[EndpointContract] taken out again + (name=STRING':')? role=ParameterRole ('<'btype=BasicDataType'>' )? (':'description=STRING)? +; DefaultValue: 'default' 'is' default=STRING diff --git a/dsl-core/io.mdsl/src/io/mdsl/generator/jolie/converter/MDSL2JolieConverter.java b/dsl-core/io.mdsl/src/io/mdsl/generator/jolie/converter/MDSL2JolieConverter.java index 77571d8..669db38 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/generator/jolie/converter/MDSL2JolieConverter.java +++ b/dsl-core/io.mdsl/src/io/mdsl/generator/jolie/converter/MDSL2JolieConverter.java @@ -19,6 +19,7 @@ import io.mdsl.apiDescription.ParameterForest; import io.mdsl.apiDescription.ParameterTree; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.apiDescription.ServiceSpecification; import io.mdsl.apiDescription.SingleParameterNode; import io.mdsl.apiDescription.TreeNode; @@ -192,7 +193,7 @@ private void convertAtomicParameterList(AtomicParameterList apl, StringBuffer re } private void convertAtomicParameter(AtomicParameter ap, StringBuffer result) { - RoleAndType rat = ap.getRat(); + RoleTypeAndDesc rat = ap.getRat(); String name = rat.getName(); name = createNameIfEmpty(name); diff --git a/dsl-core/io.mdsl/src/io/mdsl/generator/model/DataTypeField.java b/dsl-core/io.mdsl/src/io/mdsl/generator/model/DataTypeField.java index 69e8aa0..5e4e1bc 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/generator/model/DataTypeField.java +++ b/dsl-core/io.mdsl/src/io/mdsl/generator/model/DataTypeField.java @@ -28,6 +28,7 @@ public class DataTypeField { private MDSLType type; private boolean list = false; private boolean nullable = false; + private String description; private String defaultValue; @@ -116,6 +117,14 @@ public void isNullable(boolean nullable) { public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } /** * Sample data diff --git a/dsl-core/io.mdsl/src/io/mdsl/generator/model/converter/DataTypeConverter.java b/dsl-core/io.mdsl/src/io/mdsl/generator/model/converter/DataTypeConverter.java index 07ac2c0..32484b1 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/generator/model/converter/DataTypeConverter.java +++ b/dsl-core/io.mdsl/src/io/mdsl/generator/model/converter/DataTypeConverter.java @@ -182,6 +182,7 @@ private void mapAtomicParameterList(AtomicParameterList apl, DataType dataType) for (AtomicParameter ap : parameters) { DataTypeField field = new DataTypeField(fieldNameGenerator.getUniqueName(ap.getRat().getName())); field.setType(BasicType.byName(ap.getRat().getBtype())); + field.setDescription(ap.getRat().getDescription()); field.isList(CardinalityHelper.isList(ap.getCard())); field.isNullable(CardinalityHelper.isOptional(ap.getCard())); dataType.addField(field); @@ -196,6 +197,7 @@ private void mapSingleParameterNode(SingleParameterNode spn, DataType dataType) field.isList(CardinalityHelper.isList(spn.getAtomP().getCard())); field.isNullable(CardinalityHelper.isOptional(spn.getAtomP().getCard())); field.setDefaultValue(currentDefaultValue); + field.setDescription(spn.getAtomP().getRat().getDescription()); dataType.addField(field); } else if (spn.getTr() != null) { DataTypeField field = new DataTypeField(fieldNameGenerator.getUniqueName(spn.getTr().getName())); diff --git a/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2ParameterConverter.java b/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2ParameterConverter.java index 09b09d0..aaf5f0a 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2ParameterConverter.java +++ b/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2ParameterConverter.java @@ -14,6 +14,7 @@ import io.mdsl.apiDescription.ParameterTree; import io.mdsl.apiDescription.PatternStereotype; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.apiDescription.SingleParameterNode; import io.mdsl.apiDescription.TypeReference; import io.mdsl.dsl.ServiceSpecificationAdapter; @@ -101,11 +102,13 @@ private List convertAtomicParameterList(List atomicP } private Parameter convertAtomicParameter(AtomicParameter atomicParameter, HTTPParameter parameterType) { - RoleAndType roleAndType = atomicParameter.getRat(); + RoleTypeAndDesc roleAndType = atomicParameter.getRat(); PatternStereotype classifier = atomicParameter.getClassifier(); // MAP decorator or other - String parameterDescription; - parameterDescription = MDSLSpecificationWrapper.getClassifierAndElementStereotype(classifier, roleAndType); + String parameterDescription = MDSLSpecificationWrapper.getClassifierAndElementStereotype(classifier, roleAndType); + if (roleAndType.getDescription()!=null) { + parameterDescription = roleAndType.getDescription(); + } // check and respect '?' cardinality (as well as '*' and '+') boolean required = findOutWhetherParameterIsRequired(atomicParameter); diff --git a/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2SchemaConverter.java b/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2SchemaConverter.java index 2a21747..74d4afe 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2SchemaConverter.java +++ b/dsl-core/io.mdsl/src/io/mdsl/generator/openapi/converter/DataType2SchemaConverter.java @@ -16,6 +16,7 @@ import io.mdsl.apiDescription.ParameterForest; import io.mdsl.apiDescription.ParameterTree; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.apiDescription.SingleParameterNode; import io.mdsl.apiDescription.TreeNode; import io.mdsl.apiDescription.TypeReference; @@ -76,7 +77,7 @@ public Schema convert(ElementStructure structure) { } public Schema convert(AtomicParameter atomicParameter) { - RoleAndType rat = atomicParameter.getRat(); + RoleTypeAndDesc rat = atomicParameter.getRat(); Schema schema = getSchema4ParameterType(atomicParameter); if(schema!=null) { schema.setName(fieldNameGenerator.getUniqueName(rat.getName())); @@ -85,6 +86,10 @@ public Schema convert(AtomicParameter atomicParameter) { } String description = MDSLSpecificationWrapper.getClassifierAndElementStereotype(atomicParameter.getClassifier(), rat); schema.setDescription(description); + if (rat.getDescription()!=null) { + schema.setDescription(rat.getDescription()); + } + } return schema; } diff --git a/dsl-core/io.mdsl/src/io/mdsl/transformations/DataTypeTransformations.java b/dsl-core/io.mdsl/src/io/mdsl/transformations/DataTypeTransformations.java index 1e05399..90d3ce8 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/transformations/DataTypeTransformations.java +++ b/dsl-core/io.mdsl/src/io/mdsl/transformations/DataTypeTransformations.java @@ -11,6 +11,7 @@ import io.mdsl.apiDescription.GenericParameter; import io.mdsl.apiDescription.ParameterTree; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.apiDescription.ServiceSpecification; import io.mdsl.apiDescription.SingleParameterNode; import io.mdsl.apiDescription.TreeNode; @@ -104,7 +105,7 @@ public static AtomicParameter createAtomicDataParameter(String name, String data } public static AtomicParameter createAtomicDataParameter(String name, String role, String dataType) { - RoleAndType newRaT = ApiDescriptionFactory.eINSTANCE.createRoleAndType(); + RoleTypeAndDesc newRaT = ApiDescriptionFactory.eINSTANCE.createRoleTypeAndDesc(); newRaT.setName(name); newRaT.setRole(role); if(!DataTypeTransformationHelpers.isValidTypeRole(role)) { @@ -132,7 +133,7 @@ public static AtomicParameter createMetadataParameter(String name, String dataTy if (!DataTypeTransformationHelpers.isValidBaseType(dataType)) { MDSLLogger.reportError("Can't use " + dataType + " as type of " + name + ": not a valid MDSL base type."); } - RoleAndType newRaT = ApiDescriptionFactory.eINSTANCE.createRoleAndType(); + RoleTypeAndDesc newRaT = ApiDescriptionFactory.eINSTANCE.createRoleTypeAndDesc(); newRaT.setName(name); newRaT.setRole(DataTypeTransformationHelpers.METADATA_ROLE); newRaT.setBtype(dataType); @@ -143,7 +144,7 @@ public static AtomicParameter createMetadataParameter(String name, String dataTy public static AtomicParameter createIDParameter(String name) { AtomicParameter ap = ApiDescriptionFactory.eINSTANCE.createAtomicParameter(); - RoleAndType rat = ApiDescriptionFactory.eINSTANCE.createRoleAndType(); + RoleTypeAndDesc rat = ApiDescriptionFactory.eINSTANCE.createRoleTypeAndDesc(); if (name != null) { rat.setName(name); } @@ -154,7 +155,7 @@ public static AtomicParameter createIDParameter(String name) { } public static AtomicParameter createLinkParameter(String name) { - RoleAndType newRaT = ApiDescriptionFactory.eINSTANCE.createRoleAndType(); + RoleTypeAndDesc newRaT = ApiDescriptionFactory.eINSTANCE.createRoleTypeAndDesc (); newRaT.setName(name); newRaT.setRole(DataTypeTransformationHelpers.LINK_ROLE); newRaT.setBtype(DataTypeTransformationHelpers.STRING); // no string ranges yet ([O] Spring SPeL?) @@ -179,11 +180,12 @@ public static TreeNode turnTypeReferenceIntoTreeNode(TypeReference tr) { return tn; } - public static RoleAndType createRoleAndType(String name, String role, String type) { - RoleAndType rat = ApiDescriptionFactory.eINSTANCE.createRoleAndType(); + public static RoleTypeAndDesc createRoleTypeAndDesc(String name, String role, String type, String desc) { + RoleTypeAndDesc rat = ApiDescriptionFactory.eINSTANCE.createRoleTypeAndDesc(); rat.setName(name); rat.setRole(role); rat.setBtype(type); + rat.setDescription(desc); return rat; } @@ -238,10 +240,11 @@ public static void convertToStringType(GenericParameter gp) { gpn = DataTypeTransformationHelpers.ANONYMOUS; } - RoleAndType newRaT = ApiDescriptionFactory.eINSTANCE.createRoleAndType(); + RoleTypeAndDesc newRaT = ApiDescriptionFactory.eINSTANCE.createRoleTypeAndDesc(); newRaT.setName(gpn); newRaT.setRole(DataTypeTransformationHelpers.DATA_ROLE); newRaT.setBtype(DataTypeTransformationHelpers.STRING); + newRaT.setDescription(DataTypeTransformationHelpers.STRING); AtomicParameter newAP = ApiDescriptionFactory.eINSTANCE.createAtomicParameter(); newAP.setRat(newRaT); @@ -251,7 +254,7 @@ public static void convertToStringType(GenericParameter gp) { spn.setAtomP(newAP); } - public static void completeDataType(RoleAndType rat, String type) { + public static void completeDataType(RoleTypeAndDesc rat, String type) { rat.setBtype(type); } diff --git a/dsl-core/io.mdsl/src/io/mdsl/transformations/MessageTransformations.java b/dsl-core/io.mdsl/src/io/mdsl/transformations/MessageTransformations.java index 470ef8d..70e017b 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/transformations/MessageTransformations.java +++ b/dsl-core/io.mdsl/src/io/mdsl/transformations/MessageTransformations.java @@ -16,6 +16,7 @@ import io.mdsl.apiDescription.ParameterTree; import io.mdsl.apiDescription.PatternStereotype; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.apiDescription.ServiceSpecification; import io.mdsl.apiDescription.SingleParameterNode; import io.mdsl.apiDescription.TreeNode; @@ -363,7 +364,7 @@ public static EObject addKeyValueMapWrapper(AtomicParameter ap) { ParameterTree pt = ApiDescriptionFactory.eINSTANCE.createParameterTree(); AtomicParameter key = ApiDescriptionFactory.eINSTANCE.createAtomicParameter(); - RoleAndType rat = DataTypeTransformations.createRoleAndType("key", "ID", STRING_TYPE); + RoleTypeAndDesc rat = DataTypeTransformations.createRoleTypeAndDesc("key", "ID", STRING_TYPE, STRING_TYPE); key.setRat(rat); TreeNode tn = DataTypeTransformations.turnAtomicParameterIntoTreeNode(key); @@ -374,7 +375,7 @@ public static EObject addKeyValueMapWrapper(AtomicParameter ap) { pt.setClassifier(EcoreUtil.copy(ap.getClassifier())); pt.setCard(EcoreUtil.copy(ap.getCard())); pt.getNexttn().add(tn2); - + EObject containingElement = ap.eContainer().eContainer(); // SPN -> TN or ES MessageTransformationHelpers.wrapParameterTreeInTreeNodeOrElementStructure(containingElement, pt); diff --git a/dsl-core/io.mdsl/src/io/mdsl/utils/MAPLinkResolver.java b/dsl-core/io.mdsl/src/io/mdsl/utils/MAPLinkResolver.java index c83f277..aa4cc43 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/utils/MAPLinkResolver.java +++ b/dsl-core/io.mdsl/src/io/mdsl/utils/MAPLinkResolver.java @@ -6,6 +6,7 @@ import io.mdsl.apiDescription.Operation; import io.mdsl.apiDescription.OperationResponsibility; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; public class MAPLinkResolver { public static String unquoteString(String string) { @@ -167,7 +168,7 @@ public static String explainResponsibilityPattern(Operation mdslOperation) { return ""; // unknown or not yet supported responsibility } - public static String mapParameterRoleAndType(RoleAndType roleAndType) { + public static String mapParameterRoleAndType(RoleTypeAndDesc roleAndType) { if(roleAndType==null) { return ""; } diff --git a/dsl-core/io.mdsl/src/io/mdsl/utils/MDSLSpecificationWrapper.java b/dsl-core/io.mdsl/src/io/mdsl/utils/MDSLSpecificationWrapper.java index d89ca69..ec72224 100644 --- a/dsl-core/io.mdsl/src/io/mdsl/utils/MDSLSpecificationWrapper.java +++ b/dsl-core/io.mdsl/src/io/mdsl/utils/MDSLSpecificationWrapper.java @@ -43,6 +43,7 @@ import io.mdsl.apiDescription.Provider; import io.mdsl.apiDescription.ReportBinding; import io.mdsl.apiDescription.RoleAndType; +import io.mdsl.apiDescription.RoleTypeAndDesc; import io.mdsl.apiDescription.SecurityBinding; import io.mdsl.apiDescription.SecurityPolicy; import io.mdsl.apiDescription.ServiceSpecification; @@ -287,7 +288,7 @@ public List collectTreeNodes(ParameterTree tree) { // finders: - public static String getClassifierAndElementStereotype(PatternStereotype classifier, RoleAndType roleAndType) { + public static String getClassifierAndElementStereotype(PatternStereotype classifier, RoleTypeAndDesc roleAndType) { String result = ""; if (classifier != null) { String patternDecorator = classifier.getPattern();