Search in sources :

Example 1 with ErrorDefinition

use of com.palantir.conjure.spec.ErrorDefinition in project conjure-java by palantir.

the class ErrorGenerator method generateErrorTypesForNamespace.

private static JavaFile generateErrorTypesForNamespace(TypeMapper typeMapper, String conjurePackage, ErrorNamespace namespace, List<ErrorDefinition> errorTypeDefinitions) {
    ClassName className = errorTypesClassName(conjurePackage, namespace);
    // Generate ErrorType definitions
    List<FieldSpec> fieldSpecs = errorTypeDefinitions.stream().map(errorDef -> {
        CodeBlock initializer = CodeBlock.of("ErrorType.create(ErrorType.Code.$L, \"$L:$L\")", errorDef.getCode().get(), namespace.get(), errorDef.getErrorName().getName());
        FieldSpec.Builder fieldSpecBuilder = FieldSpec.builder(ClassName.get(ErrorType.class), CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, errorDef.getErrorName().getName()), Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL).initializer(initializer);
        errorDef.getDocs().ifPresent(docs -> fieldSpecBuilder.addJavadoc(docs.get()));
        return fieldSpecBuilder.build();
    }).collect(Collectors.toList());
    // Generate ServiceException factory methods
    List<MethodSpec> methodSpecs = errorTypeDefinitions.stream().flatMap(entry -> {
        MethodSpec withoutCause = generateExceptionFactory(typeMapper, entry, false);
        MethodSpec withCause = generateExceptionFactory(typeMapper, entry, true);
        return Stream.of(withoutCause, withCause);
    }).collect(Collectors.toList());
    // Generate ServiceException factory check methods
    List<MethodSpec> checkMethodSpecs = errorTypeDefinitions.stream().map(entry -> {
        String exceptionMethodName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, entry.getErrorName().getName());
        String methodName = "throwIf" + entry.getErrorName().getName();
        String shouldThrowVar = "shouldThrow";
        MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(methodName).addModifiers(Modifier.PUBLIC, Modifier.STATIC).addParameter(TypeName.BOOLEAN, shouldThrowVar);
        methodBuilder.addJavadoc("Throws a {@link ServiceException} of type $L when {@code $L} is true.\n", entry.getErrorName().getName(), shouldThrowVar);
        methodBuilder.addJavadoc("@param $L $L\n", shouldThrowVar, "Cause the method to throw when true");
        Streams.concat(entry.getSafeArgs().stream(), entry.getUnsafeArgs().stream()).forEach(arg -> {
            methodBuilder.addParameter(typeMapper.getClassName(arg.getType()), arg.getFieldName().get());
            methodBuilder.addJavadoc("@param $L $L", arg.getFieldName().get(), StringUtils.appendIfMissing(arg.getDocs().map(Javadoc::render).orElse(""), "\n"));
        });
        methodBuilder.addCode("if ($L) {", shouldThrowVar);
        methodBuilder.addCode("throw $L;", Expressions.localMethodCall(exceptionMethodName, Streams.concat(entry.getSafeArgs().stream(), entry.getUnsafeArgs().stream()).map(arg -> arg.getFieldName().get()).collect(Collectors.toList())));
        methodBuilder.addCode("}");
        return methodBuilder.build();
    }).collect(Collectors.toList());
    List<MethodSpec> isRemoteExceptionDefinitions = errorTypeDefinitions.stream().map(entry -> {
        String typeName = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, entry.getErrorName().getName());
        String methodName = "is" + entry.getErrorName().getName();
        return MethodSpec.methodBuilder(methodName).addModifiers(Modifier.PUBLIC, Modifier.STATIC).addParameter(RemoteException.class, REMOTE_EXCEPTION_VAR).returns(TypeName.BOOLEAN).addStatement(Expressions.requireNonNull(REMOTE_EXCEPTION_VAR, "remote exception must not be null")).addStatement("return $N.name().equals($N.getError().errorName())", typeName, REMOTE_EXCEPTION_VAR).addJavadoc("Returns true if the {@link $T} is named $L:$L", RemoteException.class, entry.getNamespace(), entry.getErrorName().getName()).build();
    }).collect(Collectors.toList());
    TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(className).addMethod(privateConstructor()).addModifiers(Modifier.PUBLIC, Modifier.FINAL).addFields(fieldSpecs).addMethods(methodSpecs).addMethods(checkMethodSpecs).addMethods(isRemoteExceptionDefinitions).addAnnotation(ConjureAnnotations.getConjureGeneratedAnnotation(ErrorGenerator.class));
    return JavaFile.builder(conjurePackage, typeBuilder.build()).skipJavaLangImports(true).indent("    ").build();
}
Also used : ErrorDefinition(com.palantir.conjure.spec.ErrorDefinition) Modifier(javax.lang.model.element.Modifier) Javadoc(com.palantir.conjure.java.util.Javadoc) TypeFunctions(com.palantir.conjure.java.util.TypeFunctions) FieldSpec(com.squareup.javapoet.FieldSpec) ClassName(com.squareup.javapoet.ClassName) HashMap(java.util.HashMap) ConjureDefinition(com.palantir.conjure.spec.ConjureDefinition) StringUtils(org.apache.commons.lang3.StringUtils) Options(com.palantir.conjure.java.Options) ArrayList(java.util.ArrayList) SafeArg(com.palantir.logsafe.SafeArg) Generator(com.palantir.conjure.java.Generator) Map(java.util.Map) ErrorNamespace(com.palantir.conjure.spec.ErrorNamespace) RemoteException(com.palantir.conjure.java.api.errors.RemoteException) CodeBlock(com.squareup.javapoet.CodeBlock) TypeDefinition(com.palantir.conjure.spec.TypeDefinition) CaseFormat(com.google.common.base.CaseFormat) MethodSpec(com.squareup.javapoet.MethodSpec) Packages(com.palantir.conjure.java.util.Packages) ErrorType(com.palantir.conjure.java.api.errors.ErrorType) Streams(com.google.common.collect.Streams) ServiceException(com.palantir.conjure.java.api.errors.ServiceException) FieldDefinition(com.palantir.conjure.spec.FieldDefinition) TypeSpec(com.squareup.javapoet.TypeSpec) Collectors(java.util.stream.Collectors) JavaFile(com.squareup.javapoet.JavaFile) List(java.util.List) Stream(java.util.stream.Stream) UnsafeArg(com.palantir.logsafe.UnsafeArg) ConjureAnnotations(com.palantir.conjure.java.ConjureAnnotations) TypeName(com.squareup.javapoet.TypeName) MethodSpec(com.squareup.javapoet.MethodSpec) CodeBlock(com.squareup.javapoet.CodeBlock) Javadoc(com.palantir.conjure.java.util.Javadoc) FieldSpec(com.squareup.javapoet.FieldSpec) ErrorType(com.palantir.conjure.java.api.errors.ErrorType) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 2 with ErrorDefinition

use of com.palantir.conjure.spec.ErrorDefinition in project conjure by palantir.

the class ConjureParserUtils method parseConjureDef.

static ConjureDefinition parseConjureDef(Map<String, AnnotatedConjureSourceFile> annotatedParsedDefs) {
    ImmutableList.Builder<ServiceDefinition> servicesBuilder = ImmutableList.builder();
    ImmutableList.Builder<ErrorDefinition> errorsBuilder = ImmutableList.builder();
    ImmutableList.Builder<TypeDefinition> typesBuilder = ImmutableList.builder();
    annotatedParsedDefs.values().forEach(annotatedParsed -> {
        ConjureSourceFile parsed = annotatedParsed.conjureSourceFile();
        try {
            ConjureTypeParserVisitor.ReferenceTypeResolver typeResolver = new ConjureTypeParserVisitor.ByParsedRepresentationTypeNameResolver(parsed.types(), annotatedParsed.importProviders(), annotatedParsedDefs);
            // Resolve objects first, so we can use them in service validations
            Map<TypeName, TypeDefinition> objects = parseObjects(parsed.types(), typeResolver);
            Map<TypeName, TypeDefinition> importedObjects = parseImportObjects(parsed.types().conjureImports(), annotatedParsedDefs);
            Map<TypeName, TypeDefinition> allObjects = new HashMap<>();
            allObjects.putAll(objects);
            allObjects.putAll(importedObjects);
            DealiasingTypeVisitor dealiasingVisitor = new DealiasingTypeVisitor(allObjects);
            parsed.services().forEach((serviceName, service) -> {
                servicesBuilder.add(parseService(service, TypeName.of(serviceName.name(), parseConjurePackage(service.conjurePackage())), typeResolver, dealiasingVisitor));
            });
            typesBuilder.addAll(objects.values());
            errorsBuilder.addAll(parseErrors(parsed.types().definitions(), typeResolver));
        } catch (RuntimeException e) {
            throw new ConjureRuntimeException(String.format("Encountered error trying to parse file '%s'", annotatedParsed.sourceFile()), e);
        }
    });
    ConjureDefinition definition = ConjureDefinition.builder().version(Conjure.SUPPORTED_IR_VERSION).types(typesBuilder.build()).errors(errorsBuilder.build()).services(servicesBuilder.build()).build();
    ConjureDefinitionValidator.validateAll(definition);
    return definition;
}
Also used : ErrorDefinition(com.palantir.conjure.spec.ErrorDefinition) AnnotatedConjureSourceFile(com.palantir.conjure.parser.AnnotatedConjureSourceFile) ConjureSourceFile(com.palantir.conjure.parser.ConjureSourceFile) TypeName(com.palantir.conjure.spec.TypeName) ReferenceTypeResolver(com.palantir.conjure.defs.ConjureTypeParserVisitor.ReferenceTypeResolver) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) ConjureRuntimeException(com.palantir.conjure.exceptions.ConjureRuntimeException) DealiasingTypeVisitor(com.palantir.conjure.visitor.DealiasingTypeVisitor) TypeDefinition(com.palantir.conjure.spec.TypeDefinition) ConjureRuntimeException(com.palantir.conjure.exceptions.ConjureRuntimeException) ConjureDefinition(com.palantir.conjure.spec.ConjureDefinition) ServiceDefinition(com.palantir.conjure.spec.ServiceDefinition)

Example 3 with ErrorDefinition

use of com.palantir.conjure.spec.ErrorDefinition in project conjure by palantir.

the class ConjureParserUtils method parseErrorType.

public static ErrorDefinition parseErrorType(TypeName name, com.palantir.conjure.parser.types.complex.ErrorTypeDefinition def, ConjureTypeParserVisitor.ReferenceTypeResolver typeResolver) {
    ErrorDefinition errorType = ErrorDefinition.builder().errorName(name).namespace(ErrorNamespace.of(def.namespace().name())).code(def.code().asSpecErrorCode()).safeArgs(parseField(def.safeArgs(), typeResolver)).unsafeArgs(parseField(def.unsafeArgs(), typeResolver)).docs(def.docs().map(Documentation::of)).build();
    ErrorDefinitionValidator.validate(errorType);
    return errorType;
}
Also used : ErrorDefinition(com.palantir.conjure.spec.ErrorDefinition) Documentation(com.palantir.conjure.spec.Documentation)

Example 4 with ErrorDefinition

use of com.palantir.conjure.spec.ErrorDefinition in project conjure by palantir.

the class ConjureParserUtils method parseErrors.

static List<ErrorDefinition> parseErrors(NamedTypesDefinition defs, ConjureTypeParserVisitor.ReferenceTypeResolver typeResolver) {
    Optional<String> defaultPackage = defs.defaultConjurePackage().map(ConjurePackage::name);
    ImmutableList.Builder<ErrorDefinition> errorsBuidler = ImmutableList.builder();
    errorsBuidler.addAll(defs.errors().entrySet().stream().map(entry -> {
        TypeName typeName = TypeName.of(entry.getKey().name(), parsePackageOrElseThrow(entry.getValue().conjurePackage(), defaultPackage));
        return parseErrorType(typeName, entry.getValue(), typeResolver);
    }).collect(Collectors.toList()));
    return errorsBuidler.build();
}
Also used : ErrorDefinition(com.palantir.conjure.spec.ErrorDefinition) TypeName(com.palantir.conjure.spec.TypeName) ImmutableList(com.google.common.collect.ImmutableList) ConjurePackage(com.palantir.conjure.parser.types.names.ConjurePackage) PathString(com.palantir.conjure.parser.services.PathString)

Example 5 with ErrorDefinition

use of com.palantir.conjure.spec.ErrorDefinition in project conjure by palantir.

the class ConjureParserUtils method parseConjureDef.

static ConjureDefinition parseConjureDef(Map<String, AnnotatedConjureSourceFile> annotatedParsedDefs, SafetyDeclarationRequirements safetyDeclarations) {
    ImmutableList.Builder<ServiceDefinition> servicesBuilder = ImmutableList.builder();
    ImmutableList.Builder<ErrorDefinition> errorsBuilder = ImmutableList.builder();
    ImmutableList.Builder<TypeDefinition> typesBuilder = ImmutableList.builder();
    annotatedParsedDefs.values().forEach(annotatedParsed -> {
        ConjureSourceFile parsed = annotatedParsed.conjureSourceFile();
        try {
            ConjureTypeParserVisitor.ReferenceTypeResolver typeResolver = new ConjureTypeParserVisitor.ByParsedRepresentationTypeNameResolver(parsed.types(), annotatedParsed.importProviders(), annotatedParsedDefs);
            // Resolve objects first, so we can use them in service validations
            Map<TypeName, TypeDefinition> objects = parseObjects(parsed.types(), typeResolver);
            Map<TypeName, TypeDefinition> importedObjects = parseImportObjects(parsed.types().conjureImports(), annotatedParsedDefs);
            Map<TypeName, TypeDefinition> allObjects = new HashMap<>();
            allObjects.putAll(objects);
            allObjects.putAll(importedObjects);
            DealiasingTypeVisitor dealiasingVisitor = new DealiasingTypeVisitor(allObjects);
            parsed.services().forEach((serviceName, service) -> {
                servicesBuilder.add(parseService(service, TypeName.of(serviceName.name(), parseConjurePackage(service.conjurePackage())), typeResolver, dealiasingVisitor));
            });
            typesBuilder.addAll(objects.values());
            errorsBuilder.addAll(parseErrors(parsed.types().definitions(), typeResolver));
        } catch (RuntimeException e) {
            throw new ConjureRuntimeException(String.format("Encountered error trying to parse file '%s'", annotatedParsed.sourceFile()), e);
        }
    });
    ConjureDefinition definition = ConjureDefinition.builder().version(Conjure.SUPPORTED_IR_VERSION).types(typesBuilder.build()).errors(errorsBuilder.build()).services(servicesBuilder.build()).build();
    ConjureDefinitionValidator.validateAll(definition, safetyDeclarations);
    return definition;
}
Also used : ErrorDefinition(com.palantir.conjure.spec.ErrorDefinition) AnnotatedConjureSourceFile(com.palantir.conjure.parser.AnnotatedConjureSourceFile) ConjureSourceFile(com.palantir.conjure.parser.ConjureSourceFile) TypeName(com.palantir.conjure.spec.TypeName) ReferenceTypeResolver(com.palantir.conjure.defs.ConjureTypeParserVisitor.ReferenceTypeResolver) HashMap(java.util.HashMap) ImmutableList(com.google.common.collect.ImmutableList) ConjureRuntimeException(com.palantir.conjure.exceptions.ConjureRuntimeException) DealiasingTypeVisitor(com.palantir.conjure.visitor.DealiasingTypeVisitor) TypeDefinition(com.palantir.conjure.spec.TypeDefinition) ConjureRuntimeException(com.palantir.conjure.exceptions.ConjureRuntimeException) ConjureDefinition(com.palantir.conjure.spec.ConjureDefinition) ServiceDefinition(com.palantir.conjure.spec.ServiceDefinition)

Aggregations

ErrorDefinition (com.palantir.conjure.spec.ErrorDefinition)7 HashMap (java.util.HashMap)4 ImmutableList (com.google.common.collect.ImmutableList)3 ConjureDefinition (com.palantir.conjure.spec.ConjureDefinition)3 TypeDefinition (com.palantir.conjure.spec.TypeDefinition)3 TypeName (com.palantir.conjure.spec.TypeName)3 ReferenceTypeResolver (com.palantir.conjure.defs.ConjureTypeParserVisitor.ReferenceTypeResolver)2 ConjureRuntimeException (com.palantir.conjure.exceptions.ConjureRuntimeException)2 AnnotatedConjureSourceFile (com.palantir.conjure.parser.AnnotatedConjureSourceFile)2 ConjureSourceFile (com.palantir.conjure.parser.ConjureSourceFile)2 ErrorNamespace (com.palantir.conjure.spec.ErrorNamespace)2 FieldDefinition (com.palantir.conjure.spec.FieldDefinition)2 ServiceDefinition (com.palantir.conjure.spec.ServiceDefinition)2 DealiasingTypeVisitor (com.palantir.conjure.visitor.DealiasingTypeVisitor)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Map (java.util.Map)2 CaseFormat (com.google.common.base.CaseFormat)1 Streams (com.google.common.collect.Streams)1 ConjureAnnotations (com.palantir.conjure.java.ConjureAnnotations)1