All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.joinedworkz.common.helper.OpenApiHelper.xtend Maven / Gradle / Ivy

There is a newer version: 1.3.46
Show newest version
package org.joinedworkz.common.helper

import java.util.List
import java.util.Map
import java.util.Set
import javax.inject.Inject
import javax.inject.Singleton
import org.joinedworkz.common.adapter.ComponentResourcesAdapter
import org.joinedworkz.common.adapter.MergedOperationInfoAdapterForOperation
import org.joinedworkz.common.adapter.MergedOperationInfosAdapter
import org.joinedworkz.common.adapter.ResourceProvideAdapter
import org.joinedworkz.common.context.CommonGeneratorContext
import org.joinedworkz.common.info.MergedResourceOperationInfo
import org.joinedworkz.common.info.ResourceOperationInfo
import org.joinedworkz.common.info.ResponseInfo
import org.joinedworkz.core.model.CmnComplexType
import org.joinedworkz.core.model.CmnComponent
import org.joinedworkz.core.model.CmnContent
import org.joinedworkz.core.model.CmnElement
import org.joinedworkz.core.model.CmnModel
import org.joinedworkz.core.model.CmnObject
import org.joinedworkz.core.model.CmnOperationParameter
import org.joinedworkz.core.model.CmnProvidedResource
import org.joinedworkz.core.model.CmnResource
import org.joinedworkz.core.model.CmnResourceOperation
import org.joinedworkz.core.model.CmnResponse
import org.joinedworkz.core.model.CmnService
import org.joinedworkz.core.model.CmnType
import org.joinedworkz.core.model.Verb
import java.util.function.UnaryOperator
import org.joinedworkz.core.model.CmnProperty
import org.joinedworkz.common.info.MergedResourceOperationPart
import java.util.ArrayList

@Singleton
class OpenApiHelper {
	
	final static char SLASH = '/'
		
	@Inject
	extension NameHelper
	
	@Inject
	extension CmnModelHelper
	
	@Inject
	extension VariableHelper
	
	@Inject
	Inflector inflector;
	
	def boolean isMultiple(CmnContent content) {
        if (content !== null) {
            if (content.maxOccurs !== null) {
                return content.maxOccurs < 0 || content.maxOccurs > 1
            }
        }
        return false
    }
    
        
    def String fullQualifiedTypeName(CmnType type) {
        val schemaName = type.schemaName
        if (schemaName.contains('.')) {
            '''«type.schemaName»'''
        } else {
            '''«type.model.schemaNamespace».«type.schemaName»'''
        }
    }
    
    def generateContentType(CmnType defaultRepresentation, CmnType representation, String contentType, boolean multiple, boolean hasContext) {
        val contentTypes = generateContentTypes(defaultRepresentation, representation, contentType, multiple, hasContext, false)
        return contentTypes?.head
    }
	
	def Set generateContentTypes(CmnType defaultRepresentation, CmnType representation, String contentType, boolean multiple, boolean hasContext, boolean additionallyWithDefault) {
        if (representation instanceof CmnComplexType) {
            if (!hasContext && defaultRepresentation == representation) {
            	if (contentType !== null && !contentType.startsWith("*")) {
	                return #{contentType}
	            } else if (contentType == "**") {
                    return  #{"text/plain"}  // identifier
	            } else {
	                if (additionallyWithDefault) {
    	                val contentTypeForRepresentation = vendorSpecificContentType(representation, multiple)
    	                if (contentTypeForRepresentation !== null) {
    	                      return #{'application/json', contentTypeForRepresentation}
    	                }
	                } else {
                          return #{'application/json'}
	                }
	            }
            } else if (representation !== null) {
                val contentTypeForRepresentation = vendorSpecificContentType(representation, multiple)
                if (contentTypeForRepresentation !== null) {
                    return #{contentTypeForRepresentation}
                }
            }
        } if (contentType !== null) {
            if (!contentType.startsWith("*")) {
                return #{contentType}
            } else {
                return null
            }
        } else {
            return #{'text/plain'}
        }
    }
    
    def responseContentTypeFor(MergedResourceOperationPart operationPart, CmnType representedEntity) {
        if (operationPart.produces?.type !== null) {
            return operationPart.produces?.type
        }
    }
    
    def createResponseInfo(CmnResponse response, CmnResourceOperation operation) {
        val responseInfo = new ResponseInfo(operation, response)
        responseInfo.responseContext = operation.getResponseContext
        responseInfo.responseWrapper = operation.getString("responseWrapper")
        return responseInfo
    }
        
    def CmnComplexType getResponseContext(CmnResourceOperation operation) {
        val fieldFilters = operation.getProperty("responseContext")
        if (fieldFilters !== null) {
            val value = fieldFilters.value
            if (value instanceof CmnComplexType) {
                return value
            }
        }
    }
    
    def String simpleRepresentationTypeName(CmnType type, boolean returnsMultiple) {
        if (type instanceof CmnComplexType) {
            return returnsMultiple ? inflector.pluralize(type.schemaName) : type.schemaName
        }
    }
    
    def schemaNamespace(CmnModel model) {
        val schemaName = model.getString("schemaNamespace")
        if (schemaName !== null) {
            return schemaName
        } else {
            return model.namespace
        }
    }
    
    def vendorSpecificContentType(CmnType representation, boolean multiple) {
        val representationSchemaName = simpleRepresentationTypeName(representation, multiple)
        if (representationSchemaName !== null) {
            val resourceModel = representation.model
            return vendorSpecificContentType(resourceModel.schemaNamespace, representationSchemaName)
        }
    }
	
	def String vendorSpecificContentType(String namespace, String typeName) {
        var lastDotIndex = typeName.lastIndexOf('.')
        if (lastDotIndex >= 0 ) {
            var namespacePart = typeName.substring(0,lastDotIndex)
            var namePart = typeName.substring(lastDotIndex+1)
            return 'application/vnd.'+namespacePart+'.'+camelCaseToDashSeperated(namePart).toLowerCase+'+json'
        } else {
            return 'application/vnd.'+namespace+'.'+camelCaseToDashSeperated(typeName).toLowerCase+'+json'
        }
    }
		
	def void createProvidedResourceAdapters(Iterable components) {
		for (component : components) {
			createProvidedResourceAdaptersForComponent(component)
		}
	}
	
	def Set createProvidedResourceAdaptersForComponent(CmnComponent component) {
		var componentResourcesAdapter = component.getAdapter(ComponentResourcesAdapter)
		
		val resourcesForApi = newLinkedHashSet
		for (providedResource : component.features.filter(CmnProvidedResource) ) {
			val headResource = providedResource.resourcePath.head
			val lastResource = providedResource.resourcePath.last
			var resourceProvidedAdapter = lastResource.getAdapter(ResourceProvideAdapter)
			if (resourceProvidedAdapter === null) {
				resourceProvidedAdapter = new ResourceProvideAdapter()
				lastResource.putAdapter(resourceProvidedAdapter)
			}
			resourceProvidedAdapter.putProvidedResource(component, providedResource)
			resourcesForApi.add(headResource)
		}
		
		if (componentResourcesAdapter === null) {
			componentResourcesAdapter = new ComponentResourcesAdapter()
			component.putAdapter(componentResourcesAdapter)
		}
		componentResourcesAdapter.resourcesForApi = resourcesForApi
		
		return componentResourcesAdapter.resourcesForApi
	}
	
	def Map> createMergedResourceOperationInfos(CmnComponent component, CmnResource it, CommonGeneratorContext ctx) {
		return createMergedResourceOperationInfos(component, it, true, ctx)
	}
	
	def determineControllerTag(CmnProvidedResource it) {
		val controllerName = composeControllerName
		if (controllerName !== null) {
			val lastDotIndex = controllerName.lastIndexOf('.')
			if (lastDotIndex >= 0){
				val shortName = controllerName.substring(lastDotIndex + 1)
				return shortName.camelCaseToDashSeperated
			} else {
				return controllerName.camelCaseToDashSeperated
			}
		}
	}
	
	def composeControllerName(CmnProvidedResource providedResource) {
		var controllerName = providedResource.getQualifiedControllerNameFromProperty
		if (controllerName === null) {
			val lastResourceInPath = providedResource.resourcePath.last
			val singularResourceName = inflector.singularize(lastResourceInPath.name)
			controllerName = singularResourceName.dashSeperatedToCamelCase.toFirstUpper + "Controller"
		}
		return controllerName
	}
	
	def getQualifiedControllerNameFromProperty(CmnElement it) {
		val controller = getProperty('controller')
		if (controller !== null && controller.value !== null) {
			val controllerValue = controller.value
			if (controllerValue instanceof CmnService) {
				return controllerValue.qualifiedName
			} else {
				return controllerValue.toString
			}
		}
	}
	
	def CmnType determineRepresentation(CmnResourceOperation it) {
	    val representationProperty = it.getProperty("representation")
	    if (representationProperty?.value instanceof CmnType) {
	        return representationProperty.value as CmnType
	    }
	    if (container instanceof CmnResource) {
	        val resource = container as CmnResource
	        return resource.determineRepresentation
	    }
	}
	
	def CmnType determineRepresentation(CmnResource it) {
	    if (representation !== null) {
	        return representation
	    } else {
	        parentResource?.determineRepresentation
	    }
    }
	
	def CmnResource getContainingResource(CmnObject it) {
	    val containingResource = parentResource
	    if (containingResource === null) {
	        throw new RuntimeException("No parent found for resource: ")
	    }
	}
	
	def CmnResource parentResource(CmnObject it) {
        if (container instanceof CmnResource) {
            return container as CmnResource
        } else if (container !== null) {
            parentResource(container)
        }
    }
	
	def CmnProvidedResource getProvidedResource(CmnResource it, CmnComponent component) {
		if (it !== null) {
	    	val resourceProvideAdapter = getAdapter(ResourceProvideAdapter)
	    	if (resourceProvideAdapter !== null) {
	    		return resourceProvideAdapter.getProvidedResource(component)
	    	} 
		}
    }
	
	def Map> createMergedResourceOperationInfos(CmnComponent component, CmnResource it, boolean recursive, CommonGeneratorContext ctx) {
		try {
			val Map> collectedOperationInfos = newLinkedHashMap
		    collectedOperationInfos.collectOperationInfos("", "", newArrayList, component, it, null, recursive)
		    return mergeOperations(collectedOperationInfos, ctx)
		} catch (Exception ex) {
			throw new RuntimeException("Failed to create merged operation infos for component: " + component.name, ex)
		}
	}
	
	def List resourceAndSubResources(CmnResource it) {
		val resources = newArrayList
		addResourcesRecursive(resources, it)
		return resources
	}
	
	def void addResourcesRecursive(List resources, CmnResource it) {
		resources.add(it)
		if (subResources !== null) {
			for (subResource : subResources) {
				addResourcesRecursive(resources, subResource)
			}
		}
	}
	
	def void collectOperationInfos(Map> operationInfos, String parentPath, String idPrefix, List parentPathParameters, CmnComponent component, CmnResource resource, CmnProvidedResource providedResourceOfParent, boolean recursive) {
	    val pathParameters = resource.formattedPathParameters
	    
	    val providedSubResource = getProvidedResource(resource, component) 
	    val providedResource = providedSubResource !== null ? providedSubResource : providedResourceOfParent

	    val collectionOperations = resource.operations?.filter[!instanceOperation].iterableToList
        operationInfos.addOperations(resource, providedResource, collectionOperations, parentPath, idPrefix, pathParameters, parentPathParameters)
        
        if (recursive) {
	        val collectionSubResources = resource.subResources?.filter[instanceResource === null || !instanceResource].iterableToList
		    if (collectionSubResources !== null) {
		        collectionSubResources.forEach[
	    	        val subIdPrefix = composeSubIdPrefix(resource, idPrefix, false)
	    	        val forInstanceOperation = resource.name === null
	    	        val relativePath = composeRelativePath(resource, pathParameters, forInstanceOperation)
		            operationInfos.collectOperationInfos(mergePaths(parentPath, relativePath), subIdPrefix, parentPathParameters, component, it, providedResource, recursive)
		        ]
		    }
        }
	    
	    val instanceOperations = resource.operations?.filter[instanceOperation].iterableToList
	    operationInfos.addOperations(resource, providedResource, instanceOperations, parentPath, idPrefix, pathParameters, parentPathParameters)


       if (recursive) {
       	
	        val instanceSubResources = resource.subResources?.filter[instanceResource !== null && instanceResource].iterableToList
	        if (!instanceSubResources.empty) {
	           
	            val List currentPathParameters = newArrayList
	            currentPathParameters.addAll(parentPathParameters)
	            if (resource.identifiers !== null) {
	                currentPathParameters.addAll(resource.identifiers)
	            } 
	            instanceSubResources.forEach[
	                val subIdPrefix = composeSubIdPrefix(resource, idPrefix, true)
	                val relativePath = composeRelativePath(resource, pathParameters, true)
	                operationInfos.collectOperationInfos(mergePaths(parentPath,relativePath), subIdPrefix, currentPathParameters, component, it, providedResource, recursive)
	            ]
	        }
       }
	}
	
	def subPathForPath(String rootPath, String path) {
        if (path !== null) {
            val rootPathWithLeadingSlash = "/" + rootPath
            var subPathWithLeadingSlash = path
            if (path.startsWith(rootPathWithLeadingSlash)) {
                subPathWithLeadingSlash = path.substring(rootPathWithLeadingSlash.length)
            }
            var remainingSubPath = subPathWithLeadingSlash
            if (subPathWithLeadingSlash.startsWith("/")) {
                remainingSubPath = subPathWithLeadingSlash.substring(1)
            }
            if (!remainingSubPath.empty) {
                return remainingSubPath
            }
        }
    }
	
	def schemaName(CmnType type) {
		val schemaName = type.getString("schemaName")
		if (schemaName !== null) {
			return schemaName
		} else {
			return type.name
		}
	}
	
	def formattedPathParameters(CmnResource it) {
		if (it.identifiers !== null && !identifiers.empty) {
			'''«FOR identifier : identifiers»/{«identifierName(identifier)»}«ENDFOR»'''
		} else {
		    return ''
		}
	}
	
	def identifierName(CmnOperationParameter it) {
		if (name !== null) {
			return name
		} else if (referencedField !== null) {
			return referencedField.name
		}
	}
	
	def void addOperations(Map> operationInfos, CmnResource resource, CmnProvidedResource providedResource, List operations, String parentPath, String idPrefix, CharSequence formattedPathParameters, List parentPathParameters) {
        for (operation : operations) {
            val operationInfo = createOperationInfo(parentPath, idPrefix, resource, providedResource, formattedPathParameters, parentPathParameters, operation)
            var operationInfoList = operationInfos.get(operationInfo.path)
            if (operationInfoList === null) {
                operationInfoList = newArrayList
                operationInfos.put(operationInfo.path, operationInfoList)
            }
            operationInfoList.add(operationInfo)
        }
	}
	
	def CharSequence generateOperationId(MergedResourceOperationInfo it) {
		val operationId = determineOperationId
		'''operationId: «operationId»'''
	}
	
	def CmnType determineRepresentedEntity(MergedResourceOperationInfo mergedOperationInfo) {
        
        val operation = mergedOperationInfo.operations.head
        return operation.determineRepresentation
    }
    
    def CmnProperty getOperationProperty(MergedResourceOperationInfo mergedOperationInfo, String propertyName) {
         val operation = mergedOperationInfo.operations.head
         return operation.getProperty(propertyName)
    }
    
    def String determineOperationName(MergedResourceOperationInfo it,  MergedResourceOperationPart operationPart) {
        val explicitName = operationPart.operation.name
        if (explicitName !== null) {
            return explicitName
        }
        val operationNameProperty = operationPart.operation.getProperty('operationName')?.value?.toString
        if (operationNameProperty !== null) {
             if (operationNameProperty.indexOf('$') > -1) {
                    val variables = new UnaryOperator() {
                    override apply(String variableName) {
                       val plural = variableName.endsWith("[]")
                       val postProcessedVariableName = plural ? variableName.substring(0, variableName.length-2) : variableName
                       switch (postProcessedVariableName) {
                           case "entity": {
                               val typeName = determineRepresentedEntity().name
                               if (plural) {
                                   return inflector.pluralize(typeName) 
                               } else {
                                    return typeName
                               }
                              }
                           case "resource": return resource.name?.toFirstUpper
                           case "consumes": {
                               val typeName = operationPart.consumes?.type?.name
                               if (plural) {
                                   return inflector.pluralize(typeName) 
                               } else {
                                    return typeName
                               }
                            }
                           case "produces": {
                               val typeName = operationPart.produces?.type?.name
                               if (plural) {
                                   return inflector.pluralize(typeName) 
                               } else {
                                    return typeName
                               }
                            }
                        }
                    }
                }
                return operationNameProperty.replaceVariables(variables)
             } else {
                 return operationNameProperty
             }
        }
        val operationId = determineIndividualOperationId(operationPart)
        if (operationId !== null) {
            return operationId.lastSegment
        }
        return 'do'
    }
    
    def String determineOperationId(MergedResourceOperationInfo it) {
        return determineIndividualOperationId(null)
    }
		
	def String determineIndividualOperationId(MergedResourceOperationInfo it, MergedResourceOperationPart operationPart) {
	    
	    val boolean takeRepresentationName = resource.isCollectionResource && !returnsMultiple
	    val operationIdProperty = getProperty('operationId')
	    val CmnResourceOperation operation = operationPart !== null ? operationPart.operation : operations?.head
	    val String operationName = operation.name
	    val CmnContent consumes = operationPart !== null && operationPart.consumes !== null ? operationPart.consumes : consumes.head
	    val operationType = operationPart !== null ? operation.operationType : it.operationType
	    
	    if (operationIdProperty !== null) {
	        var operationId = operationIdProperty.value.toString
	        if (operationId.indexOf('$') > -1) {
	            val variables = new UnaryOperator() {
                    override apply(String variableName) {
                       switch (variableName) {
                           case "entity": return determineRepresentedEntity().name
                           case "resource": return resource.name?.toFirstUpper
                           case "consumes": {
                                   if (consumes !== null && consumes.type !== null) {
                                       return consumes.type.name
                                   } else {
                                      val producesProperty = operation.getProperty("produces")
                                      if (producesProperty !== null) {
                                          return producesProperty.value as String
                                      }
                                   }
                               }
                           
                           case "produces": {
                               if (operation !== null && operation.responses !== null) {
                                   val content = operation.responses?.head?.content
                                   if (content !== null && content.type !== null) {
                                       return content.type.name
                                   }
                               }
                            }
                            
                        }
                    }
                }
	            operationId = operationId.replaceVariables(variables)

	        }
	        return operationId
	    }
	    
	    if (operationName !== null) {
	    	return operationName
	    }
	    
	    
	    val resourceName = resource.name !== null ? resource.name : 'By' + resource.composeResourceName.toFirstUpper
	    val namePostFix = if (takeRepresentationName) resource.representation.name else resourceName
	    val name = operationType + namePostFix.toFirstUpper.charSeperatedToCamelCase('-', true)
	    return if (idPrefix !== null && idPrefix.length > 0) idPrefix+"."+name else name
		
	}
	
	/* just for debugging */
	def String stringRepresentation(MergedResourceOperationInfo it) {
	    val operationId = determineOperationId
		return path + " " + verb + " (" + operationId + ")"
		
	}
	
	def boolean isCollectionResource(CmnResource it) {
	    return it !== null && maxOccurs !== null && maxOccurs !== 1
	}
	
	def composeSubIdPrefix(CmnResource resource, String parentIdPrefix, boolean instanceOperation) {
	    val name = if (instanceOperation && resource.isCollectionResource) resource.representation.name else composeResourceName(resource)
	    if (parentIdPrefix !== null && parentIdPrefix.length > 0) parentIdPrefix + "." + name else name
	}
	
	def composeResourceName(CmnResource resource) {
		if (resource.name !== null) {
			return resource.name
		} else if (resource.identifiers !== null) {
			val buffer = new StringBuilder
			var first = true
			for (identifier : resource.identifiers) {
				if (first) {
					first = false
				} else {
					buffer.append('-')
				}
				buffer.append(identifier.name)
			}
			return buffer.toString
		}
	}
	    
    def Map> mergeOperations(Map> map, CommonGeneratorContext ctx) {
        val Map> mergedInfos = newLinkedHashMap
        if (map !== null) {
            for (entry : map.entrySet) {
                val path = entry.key
                val Map mergedInfosForVerb = newLinkedHashMap

                for (info : entry.value) {
                    var mergedInfo = mergedInfosForVerb.get(info.verb)
                    if (mergedInfo === null) {
                        mergedInfo = new MergedResourceOperationInfo(info)
                        mergedInfo.addParentPathParameters(info.parentParameters)
                        mergedInfosForVerb.put(info.verb, mergedInfo)
                    }
                    /* support multiple consumes (=types of request bodies) */
                    if (info.operation.consumes !== null) {
                        mergedInfo.consumes.addAll(info.operation.consumes)
                    }
                    mergedInfo.addOperation(info.operation)
                    if (!info.operation.hasAdapter(MergedOperationInfoAdapterForOperation)) {
//	                    System.out.println("Put adapter for: " + info.operation + " resource name: " + info.resource.name + " verb: " + info.verb.name+ " path: "+info.path)
	                    info.operation.putAdapter(new MergedOperationInfoAdapterForOperation(mergedInfo)) // allow operation to reference mergedInfo
                    }
                }
                val mergedOperationInfoList = mergedInfosForVerb.values.toList
                for (mergedOperationInfo : mergedOperationInfoList) {
                    mergedOperationInfo.operationParts.addAll(createMergedResourceOperationParts(mergedOperationInfo))
                    mergedOperationInfo.setup()
                }
                mergedInfos.put(path, mergedOperationInfoList)
                
                /* create adapter for merged operation infos and add operation infos  */
                for (mergedOperationInfo : mergedOperationInfoList) {
                	val resource = mergedOperationInfo.resource
                	var adapter = resource.getAdapter(MergedOperationInfosAdapter)
                	if (adapter === null) {
                		adapter = new MergedOperationInfosAdapter()
                		resource.putAdapter(adapter)
                		ctx.addObjectWithAdatper(resource)
                	}
                	adapter.operationInfos.add(mergedOperationInfo)
                }
            }
        }
        return mergedInfos
    }
    
    def List createMergedResourceOperationParts(MergedResourceOperationInfo mergedResourceOperationInfo) {
        if (mergedResourceOperationInfo.operations !== null && !mergedResourceOperationInfo.operations.empty) {
            val operationParts = new ArrayList()
            for (operation : mergedResourceOperationInfo.operations) {
                val hasConsumes = operation.consumes !== null && !operation.consumes.empty
                val hasResponses = operation.responses !== null && !operation.responses.empty
                val producesOfOperation = hasResponses ? operation.responses.filter[statusCode < 300 && content !== null].map[content] : emptyList
                val hasProduces = !producesOfOperation.empty
                if (hasConsumes) {
                    for (consumes : operation.consumes) {
                        if (hasProduces) {
                            for (produces : producesOfOperation) {
                                if (!produces.derivedFromRepresentation) {
                                    val part = createMergedResourceOperationPart(operation, consumes, produces);
                                    operationParts.add(part)
                                } else if (!consumes.derivedFromRepresentation || consumes.type === produces.type) {
                                    val part = createMergedResourceOperationPart(operation, consumes, produces);
                                    operationParts.add(part)
                                }
                            }
                        } else {
                            val part = createMergedResourceOperationPart(operation, consumes, null);
                            operationParts.add(part)
                        }
                    }
                } else if (hasProduces) {
                  for (produces : producesOfOperation) {
                        val part = createMergedResourceOperationPart(operation, null, produces);
                        operationParts.add(part)
                    }
                } else {
                    val part = createMergedResourceOperationPart(operation, null, null);
                    operationParts.add(part)
                }
            }
            return operationParts
        }
        return emptyList
    }
    
    def MergedResourceOperationPart createMergedResourceOperationPart(CmnResourceOperation operation, CmnContent consumes, CmnContent produces) {
        return new MergedResourceOperationPart(operation, consumes, produces)
    }
	
	def MergedOperationInfoAdapterForOperation(MergedResourceOperationInfo info) {
		throw new UnsupportedOperationException("TODO: auto-generated method stub")
	}
    
    def getMergedOperationInfos(CmnResource resource) {
    	val adapter = resource.getAdapter(MergedOperationInfosAdapter)
    	return adapter !== null ? adapter.operationInfos : emptyList
    }
	
		
	def createOperationInfo(String parentPath, String idPrefix, CmnResource resource, CmnProvidedResource providedResource, CharSequence pathParameters, List parentPathParameters, CmnResourceOperation operation) {
	    val operationInfo = new ResourceOperationInfo(parentPath, operation, idPrefix)
	    val forInstanceOperation = operation?.instanceOperation || resource.name === null
	    val relativePath = composeRelativePath(resource, pathParameters, forInstanceOperation)
	    operationInfo.path = mergePaths(parentPath,relativePath)
	    if (operationInfo.path === null) {
	    	throw new RuntimeException("OperationInfo path is null")
	    }
	    operationInfo.resource = resource
	    operationInfo.providedResource = providedResource
	    operationInfo.addParentPathParameters(parentPathParameters)
	    return operationInfo
	}
	
	def composeRelativePath(CmnResource it, CharSequence pathParameters, boolean forInstanceOperation) {
		val resourcePath = pathSegment
		if (resourcePath === null) {
			return forInstanceOperation ? pathParameters : ""
		} else {
			return forInstanceOperation ? resourcePath + pathParameters : resourcePath
		}
	}

	def String mergePaths(CharSequence parentPath, CharSequence subPath) {
		if (subPath !== null && subPath.length > 0) {
			if (subPath.charAt(0) === SLASH) {
				return parentPath + subPath.toString
			} else {
				return parentPath + "/" + subPath 
			}
		} else {
			return parentPath.toString
		}
	}
	
	def String pathSegment(CmnResource it) {
	    return name
	}
	
	def  iterableToList(Iterable it) {
	    if (it !== null) {
	        toList
	    } else {
	        emptyList
	    }
	}
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy