Commit 80f225a2 authored by Martti Käärik's avatar Martti Käärik
Browse files

OpenAPI import updates:

- use schema name as generated package name
- add imports for Tdl and Http sub packages
- use Body as super type for structures (TODO make configurable)
- map JSON primitive types to corresponding Tdl predefined types
parent 5ff5b8f6
Loading
Loading
Loading
Loading
+101 −9
Original line number Diff line number Diff line
package org.etsi.mts.tdl.openapi2tdl.next;

import java.io.File;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;

@@ -9,8 +11,14 @@ import org.eclipse.emf.ecore.resource.Resource;
import org.etsi.mts.tdl.CollectionDataType;
import org.etsi.mts.tdl.DataElementMapping;
import org.etsi.mts.tdl.DataType;
import org.etsi.mts.tdl.ElementImport;
import org.etsi.mts.tdl.Extension;
import org.etsi.mts.tdl.Member;
import org.etsi.mts.tdl.Package;
import org.etsi.mts.tdl.PackageableElement;
import org.etsi.mts.tdl.SimpleDataType;
import org.etsi.mts.tdl.StructuredDataType;
import org.etsi.mts.tdl.tdlFactory;
import org.etsi.mts.tdl.tdlPackage;
import org.etsi.mts.tdl.helper.TDLHelper;
import org.etsi.mts.tdl.transform.AbstractTranslator;
@@ -32,6 +40,8 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {

	private Map<String, String> nameReplacements = new Hashtable();

	private Package theTdlPackage;

	public void translate(String filename) throws Exception {
		translate(filename, sourceMappingTag, targetMappingTag);
	}
@@ -48,15 +58,52 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
		// TODO: separate validation into another component

		model = parseSpec(filename, inline);
		if (model.getInfo().getTitle() != null)
			getGeneratedPackage().setName(cleanName(model.getInfo().getTitle()));
		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");
		

		theTdlPackage = TDLHelper.getTdlPackage(getTargetResource());
		if (theTdlPackage != null) {
			ElementImport importTdl = tdlFactory.eINSTANCE.createElementImport();
			importTdl.setImportedPackage(theTdlPackage);
			getGeneratedPackage().getImport().add(importTdl);
			// TODO Remove default string type
			getGeneratedPackage().getPackagedElement().remove(stringType);
		}
		
		// TODO configurable message vs procedure based API
		boolean useMessageBasedApi = true;
		StructuredDataType messageBody = null;
		if (useMessageBasedApi) {
			Package httpPackage = TDLHelper.getHttpPackage(getTargetResource());
			if (httpPackage != null) {
				Package messageBased = null;
				packages: for (Package p: httpPackage.getNestedPackage()) {
					for (PackageableElement e: p.getPackagedElement()) {
						if (e.eClass().equals(tdlPackage.eINSTANCE.getStructuredDataType()) && e.getName().equals("Body")) {
							messageBody = (StructuredDataType) e;
							messageBased = p;
							break packages;
						}
					}
				}
				if (messageBased != null) {
					ElementImport importHttp = tdlFactory.eINSTANCE.createElementImport();
					importHttp.setImportedPackage(messageBased);
					getGeneratedPackage().getImport().add(importHttp);
				}
			}
		}
		
		for (String schemaName : model.getComponents().getSchemas().keySet()) {
			Schema<?> schema = model.getComponents().getSchemas().get(schemaName);
			schema.setName(schemaName);
			DataType dataType = translate(schema, "");
			DataType dataType = translate(schema, "", messageBody);
			addMapping(schema, dataType, sourceMappingTag, targetMappingTag);
		}

@@ -95,12 +142,12 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
		}
	}

	private DataType translate(Schema<?> schema, String prefix) {
	private DataType translate(Schema<?> schema, String prefix, DataType superType) {
		if (schema.getType() == null && (schema.getProperties() == null || schema.getProperties().isEmpty())) {
			if (schema.getName() == null) {
				System.out.println("Why?");
			}
			return getSimpleDataTypeFor(schema.getName());
			return translateSimpleType(schema, superType);
		} else {
			String name = prefix + schema.getName();
			if (schema.getName() == null) {
@@ -108,13 +155,58 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
			}
			if (schema.getProperties() !=null && !schema.getProperties().isEmpty() || 
					schema.getType().equals("object")) {
				return translateObject(schema, name);
				DataType t = translateObject(schema, name);
				addSuperType(t, superType);
				return t;
			} else if (schema.getType().equals("array")) {
				return translateArray(schema, name);
			} else {
				return getSimpleDataTypeFor(schema.getType());
				return translateSimpleType(schema, superType);
			}
		}
	}

	private DataType translateSimpleType(Schema<?> schema, DataType superType) {
		String name = schema.getName();
		if (name == null)
			name = schema.getType();
		
		if (this.theTdlPackage != null) {
			if (name.equals("string") || 
					name.equals("integer") || 
					name.equals("boolean")) {
				name = name.replaceFirst(Character.toString(name.charAt(0)), Character.toString(name.charAt(0)).toUpperCase());
				for (PackageableElement pe: this.theTdlPackage.getPackagedElement()) {
					if (pe.eClass().equals(tdlPackage.eINSTANCE.getSimpleDataType()) && pe.getName().equals(name))
						return (DataType) pe;
				}
			}
		}
		SimpleDataType t = getSimpleDataTypeFor(name);
		addSuperType(t, superType);
		return t;
	}
	
	private  <T extends DataType> void addSuperType(T type, T superType) {
		if (superType == null)
			return;
		List<Extension> ext = null;
		if (type instanceof SimpleDataType)
			ext = Collections.singletonList(((SimpleDataType) type).getExtension());
		if (type instanceof StructuredDataType)
			ext = ((StructuredDataType) type).getExtension();
		if (ext == null)
			return;
		for (Extension e : ext) {
			if (e.getExtending().equals(superType))
				return;
		}
		Extension e = tdlFactory.eINSTANCE.createExtension();
		e.setExtending(superType);
		if (type instanceof SimpleDataType)
			((SimpleDataType) type).setExtension(e);
		if (type instanceof StructuredDataType)
			((StructuredDataType) type).getExtension().add(e);
	}

	private DataType translateObject(Schema<?> schema, String name) {
@@ -129,9 +221,9 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
			if (reference != null) {
				Schema<?> referencedSchema = ModelUtils.getReferencedSchema(model, propertySchema);
				referencedSchema.setName(ModelUtils.getSimpleRef(reference));
				memberType = translate(referencedSchema, "");
				memberType = translate(referencedSchema, "", null);
			} else {
				memberType = translate(propertySchema, name + "___");
				memberType = translate(propertySchema, name + "___", null);
			}
			Member m = getContentWithName((String) propertyName, dataType, tdlPackage.Literals.MEMBER);
			m.setDataType(memberType);
@@ -149,9 +241,9 @@ public class OpenAPI2TDLTranslatorNext extends AbstractTranslator {
		if (reference != null) {
			Schema<?> referencedSchema = ModelUtils.getReferencedSchema(model, itemsSchema);
			referencedSchema.setName(ModelUtils.getSimpleRef(reference));
			itemType = translate(referencedSchema, "");
			itemType = translate(referencedSchema, "", null);
		} else {
			itemType = translate(itemsSchema, name);
			itemType = translate(itemsSchema, name, null);
		}
		CollectionDataType collectionType = getTypeFor(itemType.getName() + "_collection",
				tdlPackage.Literals.COLLECTION_DATA_TYPE);