Commits (19)
......@@ -66,6 +66,7 @@ From end-user's perspective this translates to two file extensions - `.tdltx` fo
* Import the plug-ins in the Eclipse workspace
* Generate the meta-model code
* Open the `tdl.genmodel`
* Make sure that the "Realisation of OCL embedded within Ecore models" is set to "Delegate for interpretation at run-time" in the Eclipse preferences
* Right click on the top-node and generate model code
* Generate textual editor code
* Open the `GenerateTDLan2.mwe`
......
......@@ -6,5 +6,6 @@ Bundle-Version: 1.0.0.qualifier
Automatic-Module-Name: org.etsi.mts.tdl.common
Require-Bundle: org.eclipse.xtext,
org.etsi.mts.tdl.model
Export-Package: org.etsi.mts.tdl.scoping,
Export-Package: org.etsi.mts.tdl,
org.etsi.mts.tdl.scoping,
org.etsi.mts.tdl.transform
package org.etsi.mts.tdl;
import org.eclipse.xtext.common.services.Ecore2XtextTerminalConverters;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverter;
import org.eclipse.xtext.conversion.impl.AbstractNullSafeConverter;
import org.eclipse.xtext.nodemodel.INode;
public class EString2XtextConverter extends Ecore2XtextTerminalConverters {
@ValueConverter(rule = "EString")
public IValueConverter<String> EString() {
return new AbstractNullSafeConverter<String>() {
@Override
protected String internalToValue(String string, INode node) {
return STRING().toValue(string, node);
}
@Override
protected String internalToString(String value) {
return STRING().toString(value);
}
};
}
}
\ No newline at end of file
......@@ -196,6 +196,8 @@ context DataElementMapping {
//All parameters shall be mapped
constraint ParameterMappingType {
check: (self.mappableDataElement.oclIsTypeOf(SimpleDataType)
or self.mappableDataElement.oclIsTypeOf(CollectionDataType) //TODO: added CollectionDataType exclusion
or self.mappableDataElement.oclIsTypeOf(DataInstance)//TODO: added DataInstance exclusion
or (self.mappableDataElement.oclIsTypeOf(StructuredDataType)
and self.mappableDataElement.member->forAll(p | //TODO: allMembers()?
self.parameterMapping->exists(m | m.parameter = p)))
......
......@@ -21,6 +21,29 @@ operation Any debugPassthrough(hint: String) : Any {
return self;
}
operation Any debugRM() : Boolean {
(
""+self
+"\n "+self.reduction
+"\n "+self.resolveDataType()
).println();
return true;
}
operation Any debugGT() : Boolean {
//self.extension.extending.oclAsType(GateType).allDataTypes()->union(self.dataType)->asOrderedSet()
(
""+self
+"\n "+self.kind
+"\n "+self.dataType
+"\n "+self.allDataTypes()
).println();
return true;
}
operation Any debugExtensions() : Boolean {
(
""+self
......
......@@ -19,8 +19,11 @@ import org.eclipse.ocl.pivot.internal.delegate.OCLInvocationDelegateFactory;
import org.eclipse.ocl.pivot.internal.delegate.OCLSettingDelegateFactory;
import org.eclipse.ocl.pivot.internal.delegate.OCLValidationDelegateFactory;
import org.eclipse.ocl.xtext.essentialocl.EssentialOCLStandaloneSetup;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.SaveOptions;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.serializer.impl.Serializer;
import org.etsi.mts.tdl.TDLan2StandaloneSetup;
import org.etsi.mts.tdl.TDLtxStandaloneSetup;
import org.etsi.mts.tdl.TDLtxiStandaloneSetup;
......@@ -125,6 +128,22 @@ public class TDLHelper {
resource.save(Collections.emptyMap());
}
/**
* Get textual representation of resource contents.
* @param resource A resource to be represented.
* @throws Exception
*/
public static String getText(Resource resource) throws Exception {
// if (resource instanceof XtextResource) {
// return NodeModelUtils.getNode(resource.getContents().get(0)).getText();
// } else {
//TODO: this needs to be more robust for the desired format
Serializer serializer = injector.getInstance(Serializer.class);
return serializer.serialize(resource.getContents().get(0));
// }
}
/**
* Setup and return an XtextResourceSet with TDLan2 file support.
......
......@@ -21,7 +21,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.ecore;visibility:=reexport,
org.eclipse.emf.ecore.xmi;visibility:=reexport,
org.eclipse.ocl.pivot;visibility:=reexport,
org.eclipse.ocl.xtext.essentialocl,
org.eclipse.ocl.xtext.essentialocl.ui;bundle-version="1.1.0"
org.eclipse.ocl.xtext.essentialocl
Eclipse-LazyStart: true
Bundle-ActivationPolicy: lazy
......@@ -20,6 +20,13 @@
genModel="model/tdl.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.extension_parser">
<!-- @generated tdl -->
<parser
type="tdl"
class="org.etsi.mts.tdl.util.tdlResourceFactoryImpl"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
......
......@@ -15,17 +15,34 @@ import org.etsi.mts.tdl.Package;
public class ConverterNext {
public static void main(String[] args) throws Exception {
String filename = "/Users/philip-iii/Dev/git/etsi-labs/eg-203647-restful-api-guide/OpenAPI/ExampleAPI.yaml";
// TODO Auto-generated method stub
String filename = args[0];
process(filename, filename+"-generated-new.tdltx");
}
public static String processToString(String inputPath, String outputPath) {
return processToString(inputPath, outputPath, "SOURCE_MAPPING", "TARGET_MAPPING");
}
public static String processToString(String inputPath, String outputPath, String sourceMapping, String targetMapping) {
OpenAPI spec = parseSpec(inputPath);
System.out.println("Exporting: "+outputPath+ " : "+ new File(outputPath).getAbsolutePath());
OpenAPI2TDLTranslatorNext translator = new OpenAPI2TDLTranslatorNext();
String content = "Package imported {}";
try {
Resource tr = TDLHelper.create(outputPath);
translator.setTargetResource(tr);
translator.initTargetResource(translator.cleanName(new File(inputPath).getName()));
translator.translate(inputPath, sourceMapping, targetMapping);
content = TDLHelper.getText(tr);
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
public static String process(String inputPath, String outputPath) {
OpenAPI spec = parseSpec(inputPath);
//System.out.println(spec.getComponents());
OpenAPI2TDLTranslatorNext translator = new OpenAPI2TDLTranslatorNext();
String name = "imported";
try {
......
......@@ -6,7 +6,10 @@ import org.etsi.mts.tdl.CollectionDataType;
import org.etsi.mts.tdl.DataElementMapping;
import org.etsi.mts.tdl.DataType;
import org.etsi.mts.tdl.Member;
import org.etsi.mts.tdl.Parameter;
import org.etsi.mts.tdl.ParameterMapping;
import org.etsi.mts.tdl.StructuredDataType;
import org.etsi.mts.tdl.tdlFactory;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.transform.AbstractTranslator;
import org.openapitools.codegen.utils.ModelUtils;
......@@ -22,8 +25,14 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
//TODO: cleanup and prepare for release
private OpenAPI model;
public void translate(String filename) throws Exception {
String sourceMappingTag = "SOURCE_MAPPING";
String targetMappingTag = "TARGET_MAPPING";
translate(filename, sourceMappingTag, targetMappingTag);
}
public void translate(String filename, String sourceMappingTag, String targetMappingTag) throws Exception {
// Converter.setTdlTokens(Arrays.asList(new String[] {"'name'", "'type'", "'size'", "'instance'"}));
// Converter converter = new Converter(filename);
// converter.runConversion();
......@@ -32,33 +41,45 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
//TODO: separate validation into another component
model = parseSpec(filename);
drm = getTypeFor("SOURCE_MAPPING", tdlPackage.Literals.DATA_RESOURCE_MAPPING);
drm.setResourceURI("\""+new File(filename).getName()+"\"");
drmTarget = getTypeFor("TARGET_MAPPING", tdlPackage.Literals.DATA_RESOURCE_MAPPING);
drm = getTypeFor(sourceMappingTag, tdlPackage.Literals.DATA_RESOURCE_MAPPING);
drm.setResourceURI(new File(filename).getName());
drmTarget = getTypeFor(targetMappingTag, tdlPackage.Literals.DATA_RESOURCE_MAPPING);
//TODO: make configurable
drmTarget.setResourceURI("\"generated/java\"");
drmTarget.setResourceURI("generated/java");
for (String schemaName: model.getComponents().getSchemas().keySet()) {
Schema<?> schema = model.getComponents().getSchemas().get(schemaName);
schema.setName(schemaName);
DataType dataType = translate(schema, "");
addMapping(schema, dataType);
addMapping(schema, dataType, sourceMappingTag, targetMappingTag);
}
}
private void addMapping(Schema<?> schema, DataType dataType) {
DataElementMapping sourceMapping = getTypeFor(schema.getName()+"_SOURCE_MAPPING", tdlPackage.Literals.DATA_ELEMENT_MAPPING);
private void addMapping(Schema<?> schema, DataType dataType, String sourceMappingTag, String targetMappingTag) {
DataElementMapping sourceMapping = getTypeFor(schema.getName()+"_"+sourceMappingTag, tdlPackage.Literals.DATA_ELEMENT_MAPPING);
sourceMapping.setMappableDataElement(dataType);
sourceMapping.setElementURI("\"#/components/schemas/"+schema.getName()+"\"");
sourceMapping.setElementURI("#/components/schemas/"+schema.getName()+"");
sourceMapping.setDataResourceMapping(drm);
//TODO: make configurable
DataElementMapping targetMapping = getTypeFor(schema.getName()+"_TARGET_MAPPING", tdlPackage.Literals.DATA_ELEMENT_MAPPING);
//TODO: make configurable?
DataElementMapping targetMapping = getTypeFor(schema.getName()+"_"+targetMappingTag, tdlPackage.Literals.DATA_ELEMENT_MAPPING);
targetMapping.setMappableDataElement(dataType);
//TODO: transform / adapt mapping based on configuration?
targetMapping.setElementURI("\""+schema.getName()+"\"");
targetMapping.setElementURI(""+schema.getName()+"");
targetMapping.setDataResourceMapping(drmTarget);
if (dataType instanceof StructuredDataType) {
for (Member m : ((StructuredDataType) dataType).getMember()) {
addParameterMapping(sourceMapping, m, m.getName());
addParameterMapping(targetMapping, m, m.getName());
}
}
}
private void addParameterMapping(DataElementMapping mapping, Parameter p, String uri) {
ParameterMapping pm = (ParameterMapping) tdlFactory.eINSTANCE.create(tdlPackage.Literals.PARAMETER_MAPPING);
pm.setParameter(p);
pm.setParameterURI(uri.replaceAll("\\^", ""));
mapping.getParameterMapping().add(pm);
}
private DataType translate(Schema<?> schema, String prefix) {
......
......@@ -17,5 +17,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.etsi.mts.tdl.asn2tdl,
org.etsi.mts.tdl.openapi2tdl.next,
org.etsi.mts.tdl.constraints,
org.eclipse.epsilon.evl.engine
org.eclipse.epsilon.evl.engine,
org.etsi.mts.tdl.tools.to.docx.poi
Bundle-ClassPath: .
Package generated_from_ExampleAPI_yaml {
Type String
Type TODO_RESOLVE_REFERENCED
Use "\"ExampleAPI.yaml\"" as SOURCE_MAPPING
Use "\"generated/java\"" as TARGET_MAPPING
Use "ExampleAPI.yaml" as SOURCE_MAPPING
Use "generated/java" as TARGET_MAPPING
Collection SearchResults of SearchResults___item
Structure SearchResults___item (
string id,
......@@ -10,26 +10,36 @@ Package generated_from_ExampleAPI_yaml {
string created
)
Type string
Map SearchResults to "\"#/components/schemas/SearchResults\"" in SOURCE_MAPPING as SearchResults_SOURCE_MAPPING
Map SearchResults to "\"SearchResults\"" in TARGET_MAPPING as SearchResults_TARGET_MAPPING
Map SearchResults to "#/components/schemas/SearchResults" in SOURCE_MAPPING as SearchResults_SOURCE_MAPPING
Map SearchResults to "SearchResults" in TARGET_MAPPING as SearchResults_TARGET_MAPPING
Structure ResourceData (
string id,
string ^size,
string created
)
Map ResourceData to "\"#/components/schemas/ResourceData\"" in SOURCE_MAPPING as ResourceData_SOURCE_MAPPING
Map ResourceData to "\"ResourceData\"" in TARGET_MAPPING as ResourceData_TARGET_MAPPING
Map ResourceData to "#/components/schemas/ResourceData" in SOURCE_MAPPING as ResourceData_SOURCE_MAPPING {
id -> "id",
^size -> "size",
created -> "created" }
Map ResourceData to "ResourceData" in TARGET_MAPPING as ResourceData_TARGET_MAPPING {
id -> "id",
^size -> "size",
created -> "created" }
Structure Subscription (
Credentials credentials
)
Structure Credentials (
string user
)
Map Subscription to "\"#/components/schemas/Subscription\"" in SOURCE_MAPPING as Subscription_SOURCE_MAPPING
Map Subscription to "\"Subscription\"" in TARGET_MAPPING as Subscription_TARGET_MAPPING
Map Subscription to "#/components/schemas/Subscription" in SOURCE_MAPPING as Subscription_SOURCE_MAPPING {
credentials -> "credentials" }
Map Subscription to "Subscription" in TARGET_MAPPING as Subscription_TARGET_MAPPING {
credentials -> "credentials" }
Structure AuthenticatedNotification ( )
Map AuthenticatedNotification to "\"#/components/schemas/AuthenticatedNotification\"" in SOURCE_MAPPING as AuthenticatedNotification_SOURCE_MAPPING
Map AuthenticatedNotification to "\"AuthenticatedNotification\"" in TARGET_MAPPING as AuthenticatedNotification_TARGET_MAPPING
Map Credentials to "\"#/components/schemas/Credentials\"" in SOURCE_MAPPING as Credentials_SOURCE_MAPPING
Map Credentials to "\"Credentials\"" in TARGET_MAPPING as Credentials_TARGET_MAPPING
Map AuthenticatedNotification to "#/components/schemas/AuthenticatedNotification" in SOURCE_MAPPING as AuthenticatedNotification_SOURCE_MAPPING
Map AuthenticatedNotification to "AuthenticatedNotification" in TARGET_MAPPING as AuthenticatedNotification_TARGET_MAPPING
Map Credentials to "#/components/schemas/Credentials" in SOURCE_MAPPING as Credentials_SOURCE_MAPPING {
user -> "user" }
Map Credentials to "Credentials" in TARGET_MAPPING as Credentials_TARGET_MAPPING {
user -> "user" }
}
\ No newline at end of file
Package Wizardry {
Type integer
Type string
Type Integer
Type String
Collection iCol of integer
// Collection nCol of iCol
Message Gate http accepts string, integer, String, Integer
Component node {
gate http interface
gate http interface2
gate http interface3
}
Configuration base {
node sut as SUT,
// node sut as Tester,
node tester as Tester,
connect sut::interface to tester::interface,
connect sut::interface2 to tester::interface,
connect sut::interface to tester::interface3
}
Test example uses base {
tester::interface sends "hello"{string} to sut::interface
tester::interface sends 1 {Integer} to sut::interface
tester::interface sends 1 to sut::interface //TODO: unspecified type not resolved -> standard library Integer required
//better error messages?
// tester::interface3 receives 2 from sut::interface2
}
Annotation Initial conditions
Annotation Expected behaviour
Annotation Final conditions
Annotation Test Purpose Description
Annotation when
Annotation then
Objective name {
Description: "example"
References: "reference"
}
Test Purpose Description exampl {
Objective: name
Configuration: base
Expected behaviour
ensure that {
when {
tester::interface sends "hello" to sut::interface
}
then {
tester::interface receives "hello back" from sut::interface
}
}
}
Test Purpose Description exampl2 {
Objective: name
Configuration: base
Expected behaviour
ensure that {
when {
tester::interface sends "hello" to sut::interface
}
then {
tester::interface receives "hello back" from sut::interface
}
}
}
}
......@@ -2,18 +2,30 @@ package org.etsi.mts.tdl.standalone;
import java.io.File;
import java.io.FilenameFilter;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.epsilon.evl.execute.UnsatisfiedConstraint;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.utilities.OCL;
import org.eclipse.ocl.pivot.utilities.ParserException;
import org.eclipse.ocl.pivot.utilities.Query;
import org.eclipse.xtext.EcoreUtil2;
import org.etsi.mts.tdl.GateType;
import org.etsi.mts.tdl.Package;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.asn2tdl.ASN2TDLTranslator;
import org.etsi.mts.tdl.constraints.evl.Validator;
import org.etsi.mts.tdl.helper.TDLHelper;
import org.etsi.mts.tdl.openapi2tdl.next.OpenAPI2TDLTranslatorNext;
import org.etsi.mts.tdl.tools.to.docx.poi.Generator;
import org.etsi.mts.tdl.transform.AbstractTranslator;
public class Standalone {
......@@ -26,6 +38,8 @@ public class Standalone {
Standalone app = new Standalone();
//folder
String path = "examples/basics";
path = "examples/basics";
app.processElements(path, app::listElements);
//TODO: may fail
......@@ -33,6 +47,14 @@ public class Standalone {
//TODO: may fail
// app.processElements(path, app::translate);
TDLHelper.resetResourceSet();
path = "examples/validation/Example.tdltx";
//TODO: can only be used in isolation as it interferes with OCL delegates afterwards..
// app.processElements(path, app::validateOCL);
//TODO: may fail due to literal value use without data type
// app.processElements(path, app::validate);
app.processElements(path, app::exportDoc);
TDLHelper.resetResourceSet();
path = "examples/openapi";
app.processElements(path, openapiExtension, app::importOpenAPI);
......@@ -118,6 +140,25 @@ public class Standalone {
}
}
private void validateOCL(String path) {
Resource resource = TDLHelper.load(path);
OCL ocl = OCL.newInstance(TDLHelper.getResourceSet());
EClass contextEClass = tdlPackage.Literals.GATE_TYPE;
try {
ExpressionInOCL query = ocl.createQuery(contextEClass,
"self.allDataTypes()"
);
Query queryEval = ocl.createQuery(query);
for (var o : EcoreUtil2.getAllContentsOfType(resource.getContents().get(0), GateType.class)) {
System.out.println(o.allDataTypes());
System.out.println(queryEval.evaluateUnboxed(o));
}
} catch (ParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void translate(String path) {
Resource resource = TDLHelper.load(path);
try {
......@@ -143,7 +184,6 @@ public class Standalone {
}
}
private void importOpenAPI(String path) {
importData(path, new OpenAPI2TDLTranslatorNext());
......@@ -152,6 +192,22 @@ public class Standalone {
private void importASN1(String path) {
importData(path, new ASN2TDLTranslator());
}
private void exportDoc(String path) {
Resource resource = TDLHelper.load(path);
Generator generator = new Generator();
String target = path+".docx";
try {
generator.generate(
resource, target,
"Generated from "+resource.getURI().lastSegment(),
"TO_4_TABLE_TEMPLATE_EDITHELP"
);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// private void importOpenAPIAll(String path) {
// File target = new File(path);
......
......@@ -11,6 +11,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.xtext,
org.etsi.mts.tdl.model,
org.eclipse.ocl.xtext.essentialocl,
org.etsi.mts.tdl.common
org.etsi.mts.tdl.common,
org.etsi.mts.tdl.helper
Export-Package: org.etsi.mts.tdl.to2tdl
Bundle-RequiredExecutionEnvironment: JavaSE-11
......@@ -6,6 +6,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.etsi.mts.tdl.Comment;
......@@ -28,6 +29,7 @@ import org.etsi.mts.tdl.TestConfiguration;
import org.etsi.mts.tdl.TestDescription;
import org.etsi.mts.tdl.tdlFactory;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.helper.TDLHelper;
import org.etsi.mts.tdl.structuredobjectives.Content;
import org.etsi.mts.tdl.structuredobjectives.DataReference;
import org.etsi.mts.tdl.structuredobjectives.EntityReference;
......@@ -463,4 +465,16 @@ public class TO2TDLTranslator extends AbstractTranslator {
transformMembers(generatedType, c.getContent());
return generatedType;
}
@Override
public void translate(String filename) throws Exception {
Resource sr = TDLHelper.load(filename);
Resource tr = TDLHelper.create(filename+"_generated.tdltx");
Package p = (Package) sr.getContents().get(0);
setTargetResource(tr);
initTargetResource("generated_from_"+p.getName());
addImports(p);
transform(p);
TDLHelper.store(tr);
}
}
......@@ -5,6 +5,9 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
......@@ -613,6 +616,12 @@ public class Generator {
return table;
}
public static URL getLocation(final Class cls) {
final ProtectionDomain pd = cls.getProtectionDomain();
final CodeSource cs = pd.getCodeSource();
return cs.getLocation();
}
private String getTemplateLocation(String templateFilename) {
String template = "resource/"+templateFilename;
if (Platform.isRunning()) {
......@@ -623,6 +632,10 @@ public class Generator {
} catch (IOException e) {
e.printStackTrace();
}
} else {
String path = getLocation(this.getClass()).getPath();
String parent = new File(path).getParent();
template = parent+File.separator+template;
}
return template;
}
......
......@@ -5,6 +5,8 @@ package org.etsi.mts.tdl.ui;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;
import org.eclipse.xtext.ui.resource.SimpleResourceSetProvider;
import org.etsi.mts.tdl.ui.hover.TDLtxHoverProvider;
/**
......@@ -19,4 +21,11 @@ public class TDLtxUiModule extends AbstractTDLtxUiModule {
public Class<? extends IEObjectHoverProvider> bindIEObjectHoverProvider() {
return TDLtxHoverProvider.class;
}
@Override
public Class<? extends IResourceSetProvider> bindIResourceSetProvider() {
//potential optimisation based on https://alexruizlog.blogspot.com/2012/07/make-your-xtext-based-editor-300-times.html?m=1#!
//TODO: remove in case of problems
return SimpleResourceSetProvider.class;
}
}
......@@ -16,6 +16,8 @@ public class Messages extends NLS {
public static String TDLtxFileExtras_Description;
public static String TDLtxProjectWithOpenAPI_Label;
public static String TDLtxProjectWithOpenAPI_Description;
public static String TDLtxFileFromOpenAPI_Label;
public static String TDLtxFileFromOpenAPI_Description;
static {
// initialize resource bundle
......