public DefaultMetadataScopeAdapter(Type extensionElement, MethodElement operation, OperationDeclaration declaration) { operation.getValueFromAnnotation(OutputResolver.class); Optional<OutputResolver> outputResolverDeclaration = operation.getAnnotation(OutputResolver.class); Optional<Pair<MetadataKeyId, MetadataType>> keyId = locateMetadataKeyId(declaration); inputResolvers = declaration.getAllParameters().stream() .filter(p -> getAnnotatedElement(p).map(e -> e.isAnnotationPresent(TypeResolver.class)).orElse(false)) .filter(p -> !hasCustomStaticType(p)) .collect(toMap(p -> p.getName(), p -> ResolverSupplier.of(getAnnotatedElement(p).get().getAnnotation(TypeResolver.class).value()))); if (outputResolverDeclaration.isPresent() || !inputResolvers.isEmpty()) { outputResolverDeclaration.ifPresent(resolverDeclaration -> { if (!hasCustomStaticType(declaration.getOutput())) { outputResolver = ResolverSupplier.of(resolverDeclaration.output()); } if (!hasCustomStaticType(declaration.getOutputAttributes())) { attributesResolver = ResolverSupplier.of(resolverDeclaration.attributes()); } }); keyId.ifPresent(pair -> keysResolver = getKeysResolver(pair.getRight(), pair.getLeft(), () -> getCategoryName(outputResolver, attributesResolver, inputResolvers))); } else { initializeFromClass(extensionElement, operation, declaration); } }
@Override protected void onOperation(OperationDeclaration declaration) { Optional<MetadataType> outputType = declaration.getModelProperty(ExtensionOperationDescriptorModelProperty.class) .map(ExtensionOperationDescriptorModelProperty::getOperationElement) .map(OperationElement::getOperationReturnMetadataType); declareMimeTypeParameters(declaration, outputType); }
@Override public void onOperation(WithOperationsDeclaration owner, OperationDeclaration declaration) { final StereotypeModel defaultStereotype = createStereotype(declaration.getName(), processorParent); ifPresent(declaration.getModelProperty(ImplementingMethodModelProperty.class) .map(ImplementingMethodModelProperty::getMethod) .map(method -> new OperationWrapper(method, typeLoader)), methodElement -> resolveStereotype(methodElement, declaration, defaultStereotype), () -> declaration.withStereotype(defaultStereotype)); addConfigRefStereoTypesIfNeeded(declaration); }
@Override public void onOperation(WithOperationsDeclaration owner, OperationDeclaration declaration) { final StereotypeModel defaultStereotype = createStereotype(declaration.getName(), processorParent); declaration.withStereotype(defaultStereotype); addConfigRefStereoTypesIfNeeded(declaration); }
@Override protected void onOperation(WithOperationsDeclaration owner, OperationDeclaration operation) { operation.getModelProperty(ImplementingMethodModelProperty.class) .map(ImplementingMethodModelProperty::getMethod) .ifPresent(method -> { getOutputType(method).ifPresent(type -> declareCustomType(operation.getOutput(), type)); getAttributesType(method).ifPresent(type -> declareCustomType(operation.getOutputAttributes(), type)); }); declareParametersCustomStaticTypes(operation); }
private OperationDeclaration buildUnauthorizeOperation() { OperationDeclaration operation = new OperationDeclaration(UNAUTHORIZE_OPERATION_NAME); operation.setDescription("Deletes all the access token information of a given resource owner id so that it's impossible to " + "execute any operation for that user without doing the authorization dance again"); operation.setBlocking(true); operation.setExecutionType(BLOCKING); operation.setOutput(toDeclaration(voidType)); operation.setOutputAttributes(toDeclaration(voidType)); operation.setRequiresConnection(false); operation.setSupportsStreaming(false); operation.setTransactional(false); operation.addModelProperty(new ComponentExecutorModelProperty((model, params) -> new UnauthorizeOperationExecutor())); ParameterGroupDeclaration group = operation.getParameterGroup(DEFAULT_GROUP_NAME); group.showInDsl(false); ParameterDeclaration parameter = new ParameterDeclaration(RESOURCE_OWNER_ID_PARAMETER_NAME); parameter.setDescription("The id of the resource owner which access should be invalidated"); parameter.setExpressionSupport(SUPPORTED); parameter.setLayoutModel(LayoutModel.builder().build()); parameter.setRequired(false); parameter.setParameterRole(BEHAVIOUR); parameter.setType(stringType, false); group.addParameter(parameter); return operation; }
assertThat(operation.getAllParameters().isEmpty(), is(true)); assertThat(operation.getAllParameters(), hasSize(1)); assertThat(operation.getOutput().getType(), equalTo(STRING_TYPE)); assertThat(operation.getOutputAttributes().getType(), equalTo(toMetadataType(IntegerAttributes.class))); assertParameter(operation.getAllParameters(), "index", "", INT_TYPE, false, SUPPORTED, "0"); assertConnected(operation, false); assertTransactional(operation, false); assertFalse(operation.getDeprecation().isPresent()); assertThat(operation.getAllParameters(), hasSize(0)); assertThat(operation.getOutput().getType(), is(instanceOf(ArrayType.class))); assertMessageType(((ArrayType) operation.getOutput().getType()).getType(), STRING_TYPE, TYPE_LOADER.load(IntegerAttributes.class)); assertThat(operation.getOutputAttributes().getType(), is(instanceOf(VoidType.class))); assertConnected(operation, false); assertTransactional(operation, false); assertThat(operation.getAllParameters(), hasSize(2)); assertThat(operation.getOutput().getType(), equalTo(STRING_TYPE)); assertThat(operation.getOutputAttributes().getType(), is(instanceOf(VoidType.class))); assertParameter(operation.getAllParameters(), "victim", "", STRING_TYPE, false, SUPPORTED, "#[payload]"); assertParameter(operation.getAllParameters(), "goodbyeMessage", "", STRING_TYPE, false, SUPPORTED, "We are done"); assertConnected(operation, false); assertTransactional(operation, false); assertThat(operation.getAllParameters(), hasSize(3)); assertParameter(operation.getAllParameters(), "weapon", "", WEAPON_TYPE, true, SUPPORTED, null); assertParameter(operation.getAllParameters(), "type", "", toMetadataType(WeaponType.class), true, SUPPORTED, null);
private void addQueryModelProperties(OperationDeclaration declaration, Query query) { ParameterDeclaration parameterDeclaration = declaration.getAllParameters() .stream() .filter(p -> p.getModelProperty(ImplementingParameterModelProperty.class).isPresent()) .filter(p -> p.getModelProperty(ImplementingParameterModelProperty.class).get() .getParameter().isAnnotationPresent(MetadataKeyId.class)) .findFirst() .orElseThrow(() -> new IllegalParameterModelDefinitionException( "Query operation must have a parameter annotated with @MetadataKeyId")); parameterDeclaration.addModelProperty(new QueryParameterModelProperty(query.translator())); parameterDeclaration.setLayoutModel(builderFrom(parameterDeclaration.getLayoutModel()).asQuery().build()); }
@Override protected void onOperation(OperationDeclaration declaration) { declaration.getModelProperty(OperationComponentModelModelProperty.class) .ifPresent(modelProperty -> { ComponentModel bodyComponentModel = modelProperty.getBodyComponentModel(); declaration.getAllParameters().stream() .filter(parameterDeclaration -> parameterDeclaration.getType() instanceof StringType) .forEach(parameterDeclaration -> traverseProperty(bodyComponentModel.getInnerComponents(), parameterDeclaration)); }); } }.walk(extensionDeclaration);
private void documentOperations(WithOperationsDeclaration<?> declaration, Map<String, Element> methods) { for (OperationDeclaration operation : declaration.getOperations()) { Element method = methods.get(operation.getName()); // there are two cases in which method can be null: // * A synthetic operation which was not defined in any class but added by a model property // * An extension which operations are defined across multiple classes and the one being processed is not // the one which defined the operation being processed if (method == null) { continue; } MethodDocumentation documentation = processor.getMethodDocumentation(processingEnv, method); operation.setDescription(documentation.getSummary()); parameterDeclarer.document(operation, method, documentation); } }
@Test public void blockingConnectedOperation() { operation.setBlocking(true); operation.setRequiresConnection(true); enrichAndExpect(BLOCKING); }
@Test public void messageOperationWithoutGenerics() throws Exception { ExtensionDeclarer declarer = loaderFor(HeisenbergWithGenericlessMessageOperation.class) .declare(new DefaultExtensionLoadingContext(HeisenbergWithSameOperationsAndConfigs.class.getClassLoader(), getDefault(emptySet()))); OperationDeclaration operation = getOperation(declarer.getDeclaration(), "noGenerics"); assertThat(operation.getOutput().getType(), is(instanceOf(AnyType.class))); assertThat(operation.getOutputAttributes().getType(), is(instanceOf(AnyType.class))); }
private void enrichWithDsql(OperationDeclaration declaration, MethodElement method) { Query query = method.getAnnotation(Query.class).get(); declaration.addModelProperty(new MetadataResolverFactoryModelProperty(() -> new QueryMetadataResolverFactory( query .nativeOutputResolver(), query .entityResolver()))); addQueryModelProperties(declaration, query); declareDynamicType(declaration.getOutput()); declareMetadataKeyId(declaration, null); enrichMetadataKeyParameters(declaration, nullMetadataResolver); }
@Override public void enrich(ExtensionLoadingContext extensionLoadingContext) { extensionLoadingContext.getExtensionDeclarer().getDeclaration().getOperations().stream() .filter(o -> o.getName().equals("doSomethingAsync")) .findFirst() .ifPresent(operation -> operation.addModelProperty( new ComponentExecutorModelProperty((model, params) -> new PrivilegedNonBlockingComponentExecutor()))); } }
@Before public void before() { when(extensionLoadingContext.getExtensionDeclarer()).thenReturn(extensionDeclarer); when(extensionDeclarer.getDeclaration()).thenReturn(extensionDeclaration); when(extensionDeclaration.getOperations()).thenReturn(singletonList(operation)); when(extensionDeclaration.getMessageSources()).thenReturn(singletonList(source)); when(source.getSuccessCallback()).thenReturn(empty()); when(source.getErrorCallback()).thenReturn(empty()); when(source.getModelProperty(ExtensionTypeDescriptorModelProperty.class)).thenReturn(empty()); when(operation.getModelProperty(ExtensionOperationDescriptorModelProperty.class)).thenReturn(empty()); when(operation.getParameterGroup(DEFAULT_GROUP_NAME)).thenReturn(new ParameterGroupDeclaration(DEFAULT_GROUP_NAME)); when(source.getParameterGroup(DEFAULT_GROUP_NAME)).thenReturn(new ParameterGroupDeclaration(DEFAULT_GROUP_NAME)); mockMediaType(operation, false); mockMediaType(source, false); }
@Test public void enrichConnectedOperation() throws Exception { enricher.enrich(extensionLoadingContext); verify(connectedOperation).addModelProperty(isA(InterceptorsModelProperty.class)); InterceptorsModelProperty interceptors = connectedOperation.getModelProperty(InterceptorsModelProperty.class).get(); assertThat(interceptors.getInterceptorFactories(), hasSize(2)); assertThat(interceptors.getInterceptorFactories().get(0).createInterceptor(), is(instanceOf(ConnectionInterceptor.class))); assertThat(interceptors.getInterceptorFactories().get(1).createInterceptor(), is(instanceOf(CursorResetInterceptor.class))); }
private void assertOperation(String configName, String operationName) { ConfigurationDeclaration config = extensionDeclaration.getConfigurations().stream().filter(c -> c.getName().equals(configName)).findFirst() .orElseThrow(() -> new IllegalArgumentException("No config with name " + configName)); OperationDeclaration operation = config.getOperations().stream().filter(model -> model.getName().equals(operationName)) .findFirst().orElseThrow(() -> new IllegalArgumentException("No operation with name " + operationName)); assertThat(operation.getName(), is(operationName)); } }
@Test public void enrichOnlyOnceWhenFlyweight() throws Exception { when(extensionDeclaration.getOperations()).thenReturn(asList(connectedOperation, connectedOperation, notConnectedOperation)); enricher.enrich(extensionLoadingContext); verify(connectedOperation, times(1)).addModelProperty(isA(InterceptorsModelProperty.class)); }
@Test public void operationSpecifiesExecutionType() { operation.setExecutionType(CPU_INTENSIVE); enrichAndExpect(CPU_INTENSIVE); }
@Test public void listOfResultsOperationWithoutGenerics() throws Exception { ExtensionDeclarer declarer = loaderFor(HeisenbergWithListOfResultOperations.class) .declare(new DefaultExtensionLoadingContext(getClass().getClassLoader(), getDefault(emptySet()))); OperationDeclaration operation = getOperation(declarer.getDeclaration(), "listOfResultsWithoutGenerics"); MetadataType outputType = operation.getOutput().getType(); assertThat(outputType, is(instanceOf(ArrayType.class))); assertMessageType(((ArrayType) outputType).getType(), TYPE_BUILDER.anyType().build(), TYPE_BUILDER.anyType().build()); }