protected static Operation buildOperation(EdmFunction function, String id) { String fqn = function.getFullQualifiedName().getFullQualifiedNameAsString(); Operation operation = new Operation(); operation.setType(Operation.Type.FUNCTION); params.append(fqn); nameFQN.append(fqn); if (!function.getParameterNames().isEmpty() && function.getParameterNames().size() > 1) { params.append("("); nameFQN.append("("); boolean first = true; for (int i = 1; i < function.getParameterNames().size(); i++) { String parameterName = function.getParameterNames().get(i); EdmParameter p = function.getParameter(parameterName); if (first) { first = false;
@Override public EdmReturnType getReturnType() { return getFunction().getReturnType(); }
private void appendFunctions(final XMLStreamWriter writer, final List<EdmFunction> functions) throws XMLStreamException { for (EdmFunction function : functions) { writer.writeStartElement(XML_FUNCTION); writer.writeAttribute(XML_NAME, function.getName()); if (function.getEntitySetPath() != null) { writer.writeAttribute(XML_ENTITY_SET_PATH, function.getEntitySetPath()); } if (function.isBound()) { writer.writeAttribute(XML_IS_BOUND, "" + function.isBound()); } if (function.isComposable()) { writer.writeAttribute(XML_IS_COMPOSABLE, "" + function.isComposable()); } appendOperationParameters(writer, function); appendOperationReturnType(writer, function); appendAnnotations(writer, function); writer.writeEndElement(); } }
@Override public JPAFunction getFunction(final EdmFunction function) { final IntermediateSchema schema = schemaListInternalKey.get(function.getNamespace()); if (schema != null) return schema.getFunction(function.getName()); return null; }
public void cacheFunction(final FullQualifiedName functionName, final EdmFunction function) { final FunctionMapKey key = new FunctionMapKey(functionName, function.getBindingParameterTypeFqn(), function.isBindingParameterTypeCollection(), function.getParameterNames()); if (function.isBound()) { boundFunctions.put(key, function); } else { if (!unboundFunctionsByName.containsKey(functionName)) { unboundFunctionsByName.put(functionName, new ArrayList<EdmFunction>()); } unboundFunctionsByName.get(functionName).add(function); unboundFunctionsByKey.put(key, function); } }
@Override public List<EdmFunction> getUnboundFunctions(final FullQualifiedName functionName) { final FullQualifiedName functionFqn = resolvePossibleAlias(functionName); List<EdmFunction> functions = unboundFunctionsByName.get(functionFqn); if (functions == null) { functions = createUnboundFunctions(functionFqn); if (functions != null) { unboundFunctionsByName.put(functionFqn, functions); for (EdmFunction unbound : functions) { final FunctionMapKey key = new FunctionMapKey( new FullQualifiedName(unbound.getNamespace(), unbound.getName()), unbound.getBindingParameterTypeFqn(), unbound.isBindingParameterTypeCollection(), unbound.getParameterNames()); unboundFunctionsByKey.put(key, unbound); } } } return functions; }
private CustomFunction parseCustomFunction(final FullQualifiedName functionName, final EdmStructuredType referencedType) throws UriParserException, UriValidationException { final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, referencedType, true, aliases); final List<String> parameterNames = ParserHelper.getParameterNames(parameters); final EdmFunction function = edm.getBoundFunction(functionName, referencedType.getFullQualifiedName(), true, parameterNames); if (function == null) { throw new UriParserSemanticException("No function '" + functionName + "' found.", UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, functionName.getFullQualifiedNameAsString()); } ParserHelper.validateFunctionParameters(function, parameters, edm, referencedType, aliases); // The binding parameter and the return type must be of type complex or entity collection. final EdmParameter bindingParameter = function.getParameter(function.getParameterNames().get(0)); final EdmReturnType returnType = function.getReturnType(); if (bindingParameter.getType().getKind() != EdmTypeKind.ENTITY && bindingParameter.getType().getKind() != EdmTypeKind.COMPLEX || !bindingParameter.isCollection() || returnType.getType().getKind() != EdmTypeKind.ENTITY && returnType.getType().getKind() != EdmTypeKind.COMPLEX || !returnType.isCollection()) { throw new UriParserSemanticException("Only entity- or complex-collection functions are allowed.", UriParserSemanticException.MessageKeys.FUNCTION_MUST_USE_COLLECTIONS, functionName.getFullQualifiedNameAsString()); } return new CustomFunctionImpl().setFunction(function).setParameters(parameters); }
@Override public List<EdmFunction> getBoundFunctionsWithBindingType(FullQualifiedName bindingParameterTypeName, Boolean isBindingParameterCollection){ List<EdmFunction> functions = new ArrayList<EdmFunction>(); for (EdmSchema schema:getSchemas()) { for (EdmFunction function: schema.getFunctions()) { if (function.isBound()) { EdmParameter bindingParameter = function.getParameter(function.getParameterNames().get(0)); if (bindingParameter.getType().getFullQualifiedName().equals(bindingParameterTypeName) && bindingParameter.isCollection() == isBindingParameterCollection) { functions.add(function); } } } } return functions; }
private Object getValue(final EdmFunction edmFunction, final JPAParameter parameter, final String uriValue) throws ODataApplicationException { final String value = uriValue.replaceAll("'", ""); final EdmParameter edmParam = edmFunction.getParameter(parameter.getName()); try { return ((EdmPrimitiveType) edmParam.getType()).valueOfString(value, false, parameter.getMaxLength(), parameter.getPrecision(), parameter.getScale(), true, parameter.getType()); } catch (EdmPrimitiveTypeException e) { // Unable to convert value %1$s of parameter %2$s throw new ODataJPADBAdaptorException(ODataJPADBAdaptorException.MessageKeys.PARAMETER_CONVERSION_ERROR, HttpStatusCode.NOT_IMPLEMENTED, uriValue, parameter.getName()); } }
@Override @SuppressWarnings("unchecked") public <RES extends ClientInvokeResult> ODataInvokeRequest<RES> getBoundFunctionInvokeRequest( final URI bindingParameterURI, final FullQualifiedName functionName, final FullQualifiedName bindingParameterTypeName, final Boolean isBindingParameterCollection, final Map<String, ClientValue> parameters) { final EdmFunction function = edmClient.getCachedEdm().getBoundFunction( functionName, bindingParameterTypeName, isBindingParameterCollection, parameters == null ? null : new ArrayList<String>(parameters.keySet())); if (function == null) { throw new IllegalArgumentException("Could not find Function for name " + functionName); } return (ODataInvokeRequest<RES>) getInvokeRequest(HttpMethod.GET, edmClient.newURIBuilder(bindingParameterURI.toASCIIString()). appendOperationCallSegment(function.getFullQualifiedName().toString()).build(), getResultReference(function.getReturnType()), parameters); }
if (function != null && function.isBound()) { String functionBindingParamType = function.getBindingParameterTypeFqn(). getFullQualifiedNameAsString(); if (type.getFullQualifiedName().getFullQualifiedNameAsString(). result.append(','); result.append(Encoder.encode(function.getFullQualifiedName().getFullQualifiedNameAsString()));
@Override public void validateMetadata(Edm edm) { Map<FullQualifiedName, EdmEntityType> edmEntityTypesMap = new HashMap<FullQualifiedName, EdmEntityType>(); Map<FullQualifiedName, EdmComplexType> edmComplexTypesMap = new HashMap<FullQualifiedName, EdmComplexType>(); Map<FullQualifiedName, EdmFunction> edmFunctionsMap = new HashMap<FullQualifiedName, EdmFunction>(); Map<FullQualifiedName, EdmEntityContainer> edmContainersMap = new HashMap<FullQualifiedName, EdmEntityContainer>(); Map<String, String> aliasNamespaceMap = new HashMap<String, String>(); List<EdmSchema> edmSchemas = edm.getSchemas(); for (EdmSchema edmSchema : edmSchemas) { List<EdmEntityType> edmEntityTypes = edmSchema.getEntityTypes(); for (EdmEntityType edmEntityType : edmEntityTypes) { edmEntityTypesMap.put(edmEntityType.getFullQualifiedName(), edmEntityType); } List<EdmComplexType> edmComplexTypes = edmSchema.getComplexTypes(); for (EdmComplexType edmComplexType : edmComplexTypes) { edmComplexTypesMap.put(edmComplexType.getFullQualifiedName(), edmComplexType); } List<EdmFunction> edmFunctions = edmSchema.getFunctions(); for (EdmFunction edmFunction : edmFunctions) { edmFunctionsMap.put(edmFunction.getFullQualifiedName(), edmFunction); } aliasNamespaceMap.put(edmSchema.getAlias(), edmSchema.getNamespace()); if (edmSchema.getEntityContainer() != null) { edmContainersMap.put(edmSchema.getEntityContainer().getFullQualifiedName(), edmSchema.getEntityContainer()); } } EdmTypeValidator edmTypeValidator = new EdmTypeValidator(aliasNamespaceMap, edmContainersMap, edmEntityTypesMap, edmComplexTypesMap, edmFunctionsMap); edmTypeValidator.validateEdm(); }
uriInfo.addResourcePart(functionResource); final EdmReturnType edmReturnType = function.getReturnType(); final EdmType edmType = edmReturnType.getType(); final boolean isCollection = edmReturnType.isCollection(); if (function.isComposable()) { if (edmType instanceof EdmEntityType ) { if (isCollection) {
@Override public String getSegmentValue() { return functionImport == null ? (function == null ? "" : function.getName()) : functionImport.getName(); } }
@Override public boolean assertHttpMethod(ODataResponse response) throws ODataHandlerException { // look for discussion about composable functions in odata-discussion // group with thread "Clarification on "Function" invocations" if (getFunction().isComposable()) { boolean allowed = (isGET() || isPATCH() || isDELETE() || isPOST() || isPUT()); if (!allowed) { return methodNotAllowed(response,httpMethod(), "Only composable functions are allowed PATCH, DELETE, POST and PUT methods", allowedMethods()); } } return ServiceRequest.assertHttpMethod(httpMethod(), allowedMethods(), response); }
@Override public List<EdmFunction> getUnboundFunctions(final FullQualifiedName functionName) { final FullQualifiedName functionFqn = resolvePossibleAlias(functionName); List<EdmFunction> functions = unboundFunctionsByName.get(functionFqn); if (functions == null) { functions = createUnboundFunctions(functionFqn); if (functions != null) { unboundFunctionsByName.put(functionFqn, functions); for (EdmFunction unbound : functions) { final FunctionMapKey key = new FunctionMapKey( new FullQualifiedName(unbound.getNamespace(), unbound.getName()), unbound.getBindingParameterTypeFqn(), unbound.isBindingParameterTypeCollection(), unbound.getParameterNames()); unboundFunctionsByKey.put(key, unbound); } } } return functions; }
private CustomFunction parseCustomFunction(final FullQualifiedName functionName, final EdmStructuredType referencedType) throws UriParserException, UriValidationException { final List<UriParameter> parameters = ParserHelper.parseFunctionParameters(tokenizer, edm, referencedType, true, aliases); final List<String> parameterNames = ParserHelper.getParameterNames(parameters); final EdmFunction function = edm.getBoundFunction(functionName, referencedType.getFullQualifiedName(), true, parameterNames); if (function == null) { throw new UriParserSemanticException("No function '" + functionName + "' found.", UriParserSemanticException.MessageKeys.FUNCTION_NOT_FOUND, functionName.getFullQualifiedNameAsString()); } ParserHelper.validateFunctionParameters(function, parameters, edm, referencedType, aliases); // The binding parameter and the return type must be of type complex or entity collection. final EdmParameter bindingParameter = function.getParameter(function.getParameterNames().get(0)); final EdmReturnType returnType = function.getReturnType(); if (bindingParameter.getType().getKind() != EdmTypeKind.ENTITY && bindingParameter.getType().getKind() != EdmTypeKind.COMPLEX || !bindingParameter.isCollection() || returnType.getType().getKind() != EdmTypeKind.ENTITY && returnType.getType().getKind() != EdmTypeKind.COMPLEX || !returnType.isCollection()) { throw new UriParserSemanticException("Only entity- or complex-collection functions are allowed.", UriParserSemanticException.MessageKeys.FUNCTION_MUST_USE_COLLECTIONS, functionName.getFullQualifiedNameAsString()); } return new CustomFunctionImpl().setFunction(function).setParameters(parameters); }
@Override public List<EdmFunction> getBoundFunctionsWithBindingType(FullQualifiedName bindingParameterTypeName, Boolean isBindingParameterCollection){ List<EdmFunction> functions = new ArrayList<EdmFunction>(); for (EdmSchema schema:getSchemas()) { for (EdmFunction function: schema.getFunctions()) { if (function.isBound()) { EdmParameter bindingParameter = function.getParameter(function.getParameterNames().get(0)); if (bindingParameter.getType().getFullQualifiedName().equals(bindingParameterTypeName) && bindingParameter.isCollection() == isBindingParameterCollection) { functions.add(function); } } } } return functions; } }
private Object getValue(final EdmFunction edmFunction, final JPAParameter parameter, final String uriValue) throws ODataApplicationException { final String value = uriValue.replaceAll("'", ""); final EdmParameter edmParam = edmFunction.getParameter(parameter.getName()); try { return ((EdmPrimitiveType) edmParam.getType()).valueOfString(value, false, parameter.getMaxLength(), parameter.getPrecision(), parameter.getScale(), true, parameter.getType()); } catch (EdmPrimitiveTypeException e) { // Unable to convert value %1$s of parameter %2$s throw new ODataJPADBAdaptorException(ODataJPADBAdaptorException.MessageKeys.PARAMETER_CONVERSION_ERROR, HttpStatusCode.NOT_IMPLEMENTED, uriValue, parameter.getName()); } }
public void cacheFunction(final FullQualifiedName functionName, final EdmFunction function) { final FunctionMapKey key = new FunctionMapKey(functionName, function.getBindingParameterTypeFqn(), function.isBindingParameterTypeCollection(), function.getParameterNames()); if (function.isBound()) { boundFunctions.put(key, function); } else { if (!unboundFunctionsByName.containsKey(functionName)) { unboundFunctionsByName.put(functionName, new ArrayList<EdmFunction>()); } unboundFunctionsByName.get(functionName).add(function); unboundFunctionsByKey.put(key, function); } }