Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.reprezen.genflow.rapidml.doc.xtend.XGenerateInterfaces.xtend Maven / Gradle / Ivy
/*******************************************************************************
* Copyright © 2013, 2016 Modelsolv, Inc.
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains the property
* of ModelSolv, Inc. See the file license.html in the root directory of
* this project for further information.
*******************************************************************************/
package com.reprezen.genflow.rapidml.doc.xtend
import com.reprezen.genflow.api.zenmodel.util.CommonServices
import com.reprezen.genflow.common.doc.XDocHelper
import com.reprezen.genflow.common.services.DocServices
import com.reprezen.genflow.common.xtend.XDataTypeExtensions
import com.reprezen.genflow.common.xtend.XImportHelper
import com.reprezen.genflow.common.xtend.XParameterHelper
import com.reprezen.rapidml.CollectionRealizationEnum
import com.reprezen.rapidml.CollectionResource
import com.reprezen.rapidml.Enumeration
import com.reprezen.rapidml.Feature
import com.reprezen.rapidml.HasSecurityValue
import com.reprezen.rapidml.MediaType
import com.reprezen.rapidml.Method
import com.reprezen.rapidml.ObjectRealization
import com.reprezen.rapidml.Parameter
import com.reprezen.rapidml.PrimitiveProperty
import com.reprezen.rapidml.PropertyRealization
import com.reprezen.rapidml.RealizationContainer
import com.reprezen.rapidml.ReferenceEmbed
import com.reprezen.rapidml.ReferenceLink
import com.reprezen.rapidml.ReferenceProperty
import com.reprezen.rapidml.ReferenceTreatment
import com.reprezen.rapidml.ResourceAPI
import com.reprezen.rapidml.ServiceDataResource
import com.reprezen.rapidml.TypedMessage
import com.reprezen.rapidml.TypedRequest
import com.reprezen.rapidml.TypedResponse
import com.reprezen.rapidml.UserDefinedType
import com.reprezen.rapidml.ZenModel
import com.reprezen.rapidml.realization.processor.CycleDetector
import com.reprezen.rapidml.util.InheritanceUtils
import com.reprezen.rapidml.util.TagUtils
import java.util.Collections
import java.util.List
class XGenerateInterfaces {
extension XDocHelper docHelper
val parameterHelper = new XParameterHelper
val docServices = new DocServices
val commonServices = new CommonServices
val XImportHelper importHelper
var boolean isLiveView = false
new(XImportHelper importHelper, XDocHelper docHelper) {
this.importHelper = importHelper
this.docHelper = docHelper
}
def generateInterfaces(ZenModel zenModel) {
'''
«FOR iface : zenModel.resourceAPIs»
«generateInterface(iface, zenModel)»
«ENDFOR»
'''
}
def private generateInterface(ResourceAPI resourceAPI, ZenModel zenModel) {
val alias = importHelper.getAlias(resourceAPI)
val aliasNote = if (alias !== null) ''' [as «alias» ]'''
'''
«resourceAPI.nameOrTitle» («resourceAPI.baseURI»)
«importHelper.getModelFullQualifiedName(resourceAPI)»«aliasNote»
«resourceAPI.generateDocItem»
«generateSecuritySchemeUsage(resourceAPI)»
«FOR resource : resourceAPI.ownedResourceDefinitions»
«generateResource(resource as ServiceDataResource)»
«ENDFOR»
'''
}
def private generateResource(ServiceDataResource resource) {
'''
«IF resource instanceof CollectionResource»
«ELSE»
«ENDIF»
«resource.name» «resource.URI»
«IF resource.dataType !== null»
«importHelper.
getQualifiedName(resource.dataType)»
«ENDIF»
«IF resource.^default»
Default
«ENDIF»
«resource.generateDocItem»
Resource Properties
«generateMediaTypes(resource.mediaTypes)»
«generateLinkDescriptors(resource)»
«generateSecuritySchemeUsage(resource)»
«IF resource.URI !== null && !resource.URI.uriParameters.empty»
Parameters
«generateParams(resource.URI.uriParameters)»
«ENDIF»
«IF resource instanceof CollectionResource»
«IF !(resource as CollectionResource).collectionParameters.empty»
Collection Parameters
«generateParams((resource as CollectionResource).collectionParameters)»
«ENDIF»
«IF (resource as CollectionResource).resourceRealizationKind ==
CollectionRealizationEnum::REFERENCE_LINK_LIST»
Data Properties
«resource.dataType.name»
«val defResource = resource.referenceLinks.get(0).targetResource as ServiceDataResource»
«defResource.name»*
«IF defResource.defaultLinkDescriptor !== null»
«FOR feature : defResource.defaultLinkDescriptor.allIncludedProperties.map[baseProperty]»
«generateReferenceTreatmentPropertyRow(feature, 1, false)»
«ENDFOR»
«ENDIF»
«ELSE»
«generateResourceDataType(resource)»
«ENDIF»
«ELSE»
«generateResourceDataType(resource)»
«ENDIF»
«FOR method : resource.methods»
«generateMethod(method)»
«ENDFOR»
'''
}
def private generateLinkDescriptors(ServiceDataResource resource) {
'''
«IF !resource.definedLinkDescriptors.empty»
Link Descriptors
«FOR link : resource.definedLinkDescriptors SEPARATOR ' '» «link.name»
(«FOR feature : link.allIncludedProperties.map[baseProperty] SEPARATOR ', '»«feature.name»
«ENDFOR»)
«IF link.^default»
Default
«ENDIF»
«ENDFOR»
«ENDIF»
'''
}
def private generateParams(List extends Parameter> params) {
'''
Name
Documentation
Default
Property
Type
«FOR param : params»
«param.name»
«IF !param.required»(optional )«ENDIF»
«param?.generateDoc»
«param.^default»
«parameterHelper.paramName(param.sourceReference)»
«parameterHelper.paramType(param.sourceReference, importHelper)»
«ENDFOR»
'''
}
def private generateRealizationTemplateDetails(RealizationContainer resource) {
if (!isLiveView)
return ''''''
val templateNameTag = TagUtils.getTagWithName(resource, TagUtils.REALIZATION_TEMPLATE_NAME)
val isInline = !resource.isWithDefaultRealization
val realizationName = if (isInline)
"(inline)"
else
resource.realizationName + if(resource instanceof CollectionResource) " [*]" else ""
'''
«IF templateNameTag.isPresent»
Realization: «realizationName»
«IF !isInline»
«ENDIF»
«ENDIF»
'''
}
def private generateResourceDataType(ServiceDataResource resource, String headerMessage) {
'''
Data Properties
«resource.generateRealizationTemplateDetails»
«headerMessage»
Name
Type
Documentation
«FOR aFeature : resource.dataType.ownedFeatures.filter[e|!hasReferenceTreatment(resource, e)]»
«IF resource.isIncluded(aFeature)»
«generateIncludedPropertyRow(getIncludedProperty(resource, aFeature))»
«ENDIF»
«ENDFOR»
«generateReferenceTreatments(resource)»
'''
}
def private generateResourceDataType(ServiceDataResource resource) {
generateResourceDataType(resource, "")
}
def private generateMessageName(TypedMessage message) {
'''
«IF message.resourceType !== null»
«message.resourceType.name»
«ELSEIF message.actualType !== null»
«message.actualType.name»
«ENDIF»
'''
}
def private generateMessageDataType(TypedMessage message) {
'''
«IF !message.referenceTreatments.empty ||
!message.actualType.ownedFeatures.filter[e|!hasReferenceTreatment(message, e) && message.isIncluded(e)].
empty»
Data Properties
«message.generateRealizationTemplateDetails»
Name
Type
Documentation
«FOR aFeature : message.actualType.ownedFeatures.filter[e|!hasReferenceTreatment(message, e)]»
«IF message.isIncluded(aFeature)»
«generateIncludedPropertyRow(getIncludedProperty(message, aFeature))»
«ENDIF»
«ENDFOR»
«generateReferenceTreatments(message)»
«ENDIF»
'''
}
def private generateMethod(Method method) {
'''
«method.httpMethod»
«method.id»
«method.generateDocItem»
«generateSecuritySchemeUsage(method)»
«IF method.request !== null || !method.responses.empty»«ENDIF»
«IF method.request !== null»
«generateRequest(method.request)»
«ENDIF»
«IF !method.responses.empty»
«FOR response : method.responses»
«generateResponse(response)»
«ENDFOR»
«ENDIF»
«IF method.request !== null || !method.responses.empty» «ENDIF»
'''
}
def private generateRequest(TypedRequest request) {
var id = docServices.randomId
'''
«IF request !== null»
Request «generateMessageName(request)»
«IF request.hasOverridedMediaTypes»
Properties
«generateMediaTypes(request.mediaTypes)»
«ENDIF»
«IF showMessageDataType(request)»
«generateMessageDataType(request)»
«ENDIF»
«request.generateDocItem»
«IF !request.parameters.empty»
Parameters
«generateParams(request.parameters)»
«ENDIF»
«ENDIF»
'''
}
def private generateResponse(TypedResponse response) {
'''
Response «generateMessageName(response)»
«IF response.statusCode > 0»
«response.statusCode»
«ENDIF»
«IF response.hasOverridedMediaTypes»
Properties
«generateMediaTypes(response.mediaTypes)»
«ENDIF»
«IF showMessageDataType(response)»
«generateMessageDataType(response)»
«ENDIF»
«response.generateDocItem»
'''
}
def private boolean showMessageDataType(TypedMessage message) {
// if usesResourcesDefaultRealization then skip the message data types table because it's identical to the one of the resource,
// and there is a hyperlink the resource in the header
return message.actualType !== null && message.resourceType === null
}
def private generateIncludedPropertyRow(PropertyRealization includedProperty) {
'''
«includedProperty.baseProperty.name»
«IF includedProperty.baseProperty instanceof ReferenceProperty»
«generateIncludedPropertyType(
includedProperty)»
«ELSE»
«val type = (includedProperty.baseProperty as PrimitiveProperty).type»
«IF type instanceof Enumeration || type instanceof UserDefinedType»
«generateIncludedPropertyType(includedProperty)»
«ELSE»
«generateIncludedPropertyType(includedProperty)»
«ENDIF»
«ENDIF»
«includedProperty.allConstraints.generateInlineConstraints»
«includedProperty.baseProperty?.generateDoc»
'''
}
def private generateMediaTypes(List mediaTypes) {
'''
«IF !mediaTypes.empty»
Media Types
«FOR mediaType : mediaTypes SEPARATOR ', '»«mediaType.name» «ENDFOR»
«ENDIF»
'''
}
def private boolean hasOverridedMediaTypes(TypedMessage message) {
if (!message.mediaTypes.empty) {
return !message.mediaTypes.elementsEqual(
(message.eContainer as Method).containingResourceDefinition.mediaTypes)
}
return false
}
def private boolean hasReferenceTreatment(ServiceDataResource resource, Feature feature) {
resource.referenceTreatments.map[referenceElement].exists[f|f === feature]
}
def private boolean hasReferenceTreatment(TypedMessage message, Feature feature) {
message.referenceTreatments.map[referenceElement].exists[f|f === feature]
}
def private PropertyRealization getIncludedProperty(ServiceDataResource resource, Feature feature) {
getIncludedProperty(resource.properties, feature)
}
def private PropertyRealization getIncludedProperty(TypedMessage message, Feature feature) {
getIncludedProperty(message.properties, feature)
}
def private PropertyRealization getIncludedProperty(ObjectRealization objectRealization, Feature feature) {
objectRealization.allIncludedProperties.filter[InheritanceUtils::sameOrOverrides(it.baseProperty, feature)].head
}
def private generateReferenceTreatments(ServiceDataResource resource) {
'''
«FOR ReferenceTreatment refTreatment : resource.referenceTreatments»
«generateReferenceTreatment(refTreatment, resource.includedProperties, new CycleDetector, 0)»
«ENDFOR»
'''
}
def private generateReferenceTreatments(TypedMessage message) {
'''
«FOR ReferenceTreatment refTreatment : message.referenceTreatments»
«generateReferenceTreatment(refTreatment, message.includedProperties, new CycleDetector, 0)»
«ENDFOR»
'''
}
def dispatch private String generateReferenceTreatment(ReferenceLink refLink,
List includedProperies, CycleDetector cycleDetector, Integer indent) {
val referencedProperty = refLink.referenceElement
val cardinality = XDataTypeExtensions::getCardinalityLabel(refLink, includedProperies)
'''
«referencedProperty.name»
«refLink.targetResource.name» «cardinality»
«if(referencedProperty instanceof ReferenceProperty) (referencedProperty as ReferenceProperty).generateDoc
else "TODO"»
«FOR feature : getIncludedProperties(refLink)»
«generateReferenceTreatmentPropertyRow(feature, indent + 1, true)»
«ENDFOR»
'''
}
def dispatch private String generateReferenceTreatment(ReferenceEmbed refEmbed,
List includedProperies, CycleDetector cycleDetector, Integer indent) {
val isRecursive = !cycleDetector.visit(refEmbed)
val referencedProperty = refEmbed.referenceElement
val cardinality = XDataTypeExtensions::getCardinalityLabel(refEmbed, includedProperies)
'''
«referencedProperty.name» «IF isRecursive» (recursive) «ENDIF»
«importHelper.getQualifiedName(referencedProperty.dataType)» «cardinality»
«if(referencedProperty instanceof ReferenceProperty) (referencedProperty as ReferenceProperty).generateDoc else "TODO"»
«IF !isRecursive»
«FOR feature : getIncludedProperties(refEmbed).filter[e|e instanceof PrimitiveProperty]»
«generateReferenceTreatmentPropertyRow(feature, indent + 1, true)»
«ENDFOR»
«FOR ReferenceTreatment refTreatment : refEmbed.nestedReferenceTreatments»
«generateReferenceTreatment(refTreatment, includedProperies, cycleDetector, indent + 1)»
«ENDFOR»
«ENDIF»
'''
}
def private generateIncludedPropertyType(PropertyRealization includedProperty) {
'''
«parameterHelper.featureType(includedProperty.baseProperty, importHelper)»«commonServices.
getPrettyPrintedCardinality(includedProperty)»
'''
}
def private List getIncludedProperties(ReferenceTreatment refLink) {
if (refLink.linkDescriptor === null) {
Collections::emptyList
} else {
refLink.linkDescriptor.allIncludedProperties.map[baseProperty]
}
}
def private generateReferenceTreatmentPropertyRow(Feature property, Integer indent, boolean genDoc) {
'''
«property.name»
«IF property instanceof ReferenceProperty»
«parameterHelper.
featureType(property, importHelper)»«commonServices.getPrettyPrintedMultiplicity(property)»
«ELSE»
«parameterHelper.featureType(property, importHelper)»«commonServices.
getPrettyPrintedMultiplicity(property)»
«ENDIF»
«IF genDoc»
«property?.generateDoc»
«ENDIF»
'''
}
def protected generateSecuritySchemeUsage(HasSecurityValue hasSecuredValue) {
'''
«IF !hasSecuredValue.securedBy.empty»
«XDocHelper.tableWithHeader("Security Schemes", "Name", "Type", "Authorized Scopes")»
«FOR authMethod : hasSecuredValue.securedBy»
«authMethod.scheme.name»
«authMethod.scheme.type.toString»
«FOR scope : authMethod.scopes SEPARATOR ', '»«scope.name»«ENDFOR»
«ENDFOR»
«ENDIF»
'''
}
def static String statusColorCode(Integer code) {
switch code {
case code >= 100 && code < 200: "info"
case code >= 200 && code < 300: "success"
case code >= 300 && code < 400: "info"
default: "danger"
}
}
def isLiveView(boolean isLiveView) {
this.isLiveView = isLiveView
}
}