Search in sources :

Example 1 with ObjectDefinition

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

the class BeanGenerator method generateBeanType.

@SuppressWarnings("CyclomaticComplexity")
public static JavaFile generateBeanType(TypeMapper typeMapper, ObjectDefinition typeDef, Map<com.palantir.conjure.spec.TypeName, TypeDefinition> typesMap, Options options) {
    ImmutableList<EnrichedField> fields = createFields(typeMapper, typeDef.getFields());
    ImmutableList<FieldSpec> poetFields = EnrichedField.toPoetSpecs(fields);
    ImmutableList<EnrichedField> nonPrimitiveEnrichedFields = fields.stream().filter(field -> !field.isPrimitive()).collect(ImmutableList.toImmutableList());
    com.palantir.conjure.spec.TypeName prefixedName = Packages.getPrefixedName(typeDef.getTypeName(), options.packagePrefix());
    ClassName objectClass = ClassName.get(prefixedName.getPackage(), prefixedName.getName());
    ClassName builderClass = ClassName.get(objectClass.packageName(), objectClass.simpleName(), "Builder");
    ClassName builderImplementation = options.useStagedBuilders() && fields.stream().anyMatch(field -> !fieldShouldBeInFinalStage(field)) ? ClassName.get(objectClass.packageName(), objectClass.simpleName(), "DefaultBuilder") : builderClass;
    TypeSpec.Builder typeBuilder = TypeSpec.classBuilder(prefixedName.getName()).addModifiers(Modifier.PUBLIC, Modifier.FINAL).addFields(poetFields).addMethod(createConstructor(fields, poetFields)).addMethods(createGetters(fields, typesMap, options));
    if (!poetFields.isEmpty()) {
        typeBuilder.addMethod(MethodSpecs.createEquals(objectClass)).addMethod(MethodSpecs.createEqualTo(objectClass, poetFields));
        if (useCachedHashCode(fields)) {
            MethodSpecs.addCachedHashCode(typeBuilder, poetFields);
        } else {
            typeBuilder.addMethod(MethodSpecs.createHashCode(poetFields));
        }
    }
    typeBuilder.addMethod(MethodSpecs.createToString(prefixedName.getName(), fields.stream().map(EnrichedField::fieldName).collect(Collectors.toList())));
    if (poetFields.size() <= MAX_NUM_PARAMS_FOR_FACTORY) {
        typeBuilder.addMethod(createStaticFactoryMethod(fields, objectClass));
    }
    if (!nonPrimitiveEnrichedFields.isEmpty()) {
        typeBuilder.addMethod(createValidateFields(nonPrimitiveEnrichedFields)).addMethod(createAddFieldIfMissing(nonPrimitiveEnrichedFields.size()));
    }
    if (poetFields.isEmpty()) {
        // Need to add JsonSerialize annotation which indicates that the empty bean serializer should be used to
        // serialize this class. Without this annotation no serializer will be set for this class, thus preventing
        // serialization.
        typeBuilder.addAnnotation(JsonSerialize.class).addField(createSingletonField(objectClass));
        if (!options.strictObjects()) {
            typeBuilder.addAnnotation(AnnotationSpec.builder(JsonIgnoreProperties.class).addMember("ignoreUnknown", "$L", true).build());
        }
    } else {
        ImmutableList<EnrichedField> fieldsNeedingBuilderStage = fields.stream().filter(field -> !fieldShouldBeInFinalStage(field)).collect(ImmutableList.toImmutableList());
        typeBuilder.addAnnotation(AnnotationSpec.builder(JsonDeserialize.class).addMember("builder", "$T.class", builderImplementation).build());
        if (!options.useStagedBuilders() || fieldsNeedingBuilderStage.isEmpty()) {
            typeBuilder.addMethod(createBuilder(builderClass)).addType(BeanBuilderGenerator.generate(typeMapper, objectClass, builderClass, typeDef, typesMap, options, Optional.empty()));
        } else {
            List<TypeSpec> interfaces = generateStageInterfaces(objectClass, builderClass, typeMapper, fieldsNeedingBuilderStage, fields.stream().filter(BeanGenerator::fieldShouldBeInFinalStage).collect(ImmutableList.toImmutableList()));
            List<ClassName> interfacesAsClasses = interfaces.stream().map(stageInterface -> ClassName.get(objectClass.packageName(), objectClass.simpleName(), stageInterface.name)).collect(Collectors.toList());
            TypeSpec builderInterface = TypeSpec.interfaceBuilder("Builder").addModifiers(Modifier.PUBLIC).addMethods(interfaces.stream().map(stageInterface -> stageInterface.methodSpecs).flatMap(List::stream).map(method -> method.toBuilder().addAnnotation(Override.class).returns(method.name.equals("build") ? method.returnType : ClassName.get(objectClass.packageName(), objectClass.simpleName(), "Builder")).build()).collect(Collectors.toSet())).addSuperinterfaces(interfacesAsClasses.stream().map(ClassName::box).collect(Collectors.toList())).build();
            typeBuilder.addTypes(interfaces).addType(builderInterface).addMethod(MethodSpec.methodBuilder("builder").addModifiers(Modifier.PUBLIC, Modifier.STATIC).returns(interfacesAsClasses.get(0)).addStatement("return new DefaultBuilder()").build()).addType(BeanBuilderGenerator.generate(typeMapper, objectClass, builderClass, typeDef, typesMap, options, Optional.of(ClassName.get(objectClass.packageName(), objectClass.simpleName(), builderInterface.name))));
        }
    }
    typeBuilder.addAnnotation(ConjureAnnotations.getConjureGeneratedAnnotation(BeanGenerator.class));
    typeDef.getDocs().ifPresent(docs -> typeBuilder.addJavadoc("$L", Javadoc.render(docs)));
    return JavaFile.builder(prefixedName.getPackage(), typeBuilder.build()).skipJavaLangImports(true).indent("    ").build();
}
Also used : DefaultTypeVisitor(com.palantir.conjure.java.visitor.DefaultTypeVisitor) JsonProperty(com.fasterxml.jackson.annotation.JsonProperty) TypeVisitor(com.palantir.conjure.visitor.TypeVisitor) Modifier(javax.lang.model.element.Modifier) Javadoc(com.palantir.conjure.java.util.Javadoc) ClassName(com.squareup.javapoet.ClassName) Collections2(com.google.common.collect.Collections2) PeekingIterator(com.google.common.collect.PeekingIterator) StringUtils(org.apache.commons.lang3.StringUtils) Options(com.palantir.conjure.java.Options) MapType(com.palantir.conjure.spec.MapType) Map(java.util.Map) OptionalType(com.palantir.conjure.spec.OptionalType) MoreVisitors(com.palantir.conjure.java.visitor.MoreVisitors) ObjectDefinition(com.palantir.conjure.spec.ObjectDefinition) ParameterSpec(com.squareup.javapoet.ParameterSpec) Collection(java.util.Collection) SafeIllegalArgumentException(com.palantir.logsafe.exceptions.SafeIllegalArgumentException) FieldDefinition(com.palantir.conjure.spec.FieldDefinition) Collectors(java.util.stream.Collectors) JavaFile(com.squareup.javapoet.JavaFile) List(java.util.List) Stream(java.util.stream.Stream) TypeName(com.squareup.javapoet.TypeName) Optional(java.util.Optional) CaseConverter(com.palantir.conjure.CaseConverter) PrimitiveType(com.palantir.conjure.spec.PrimitiveType) JsonDeserialize(com.fasterxml.jackson.databind.annotation.JsonDeserialize) JsonIgnoreProperties(com.fasterxml.jackson.annotation.JsonIgnoreProperties) Iterables(com.google.common.collect.Iterables) ListType(com.palantir.conjure.spec.ListType) TypeFunctions(com.palantir.conjure.java.util.TypeFunctions) FieldSpec(com.squareup.javapoet.FieldSpec) Type(com.palantir.conjure.spec.Type) Iterators(com.google.common.collect.Iterators) ArrayList(java.util.ArrayList) SafeArg(com.palantir.logsafe.SafeArg) ImmutableList(com.google.common.collect.ImmutableList) Value(org.immutables.value.Value) JsonSerialize(com.fasterxml.jackson.databind.annotation.JsonSerialize) SetType(com.palantir.conjure.spec.SetType) Nonnull(javax.annotation.Nonnull) CodeBlock(com.squareup.javapoet.CodeBlock) TypeDefinition(com.palantir.conjure.spec.TypeDefinition) MethodSpec(com.squareup.javapoet.MethodSpec) Packages(com.palantir.conjure.java.util.Packages) JavaNameSanitizer(com.palantir.conjure.java.util.JavaNameSanitizer) ParameterizedTypeName(com.squareup.javapoet.ParameterizedTypeName) TypeSpec(com.squareup.javapoet.TypeSpec) AnnotationSpec(com.squareup.javapoet.AnnotationSpec) ConjureAnnotations(com.palantir.conjure.java.ConjureAnnotations) JsonInclude(com.fasterxml.jackson.annotation.JsonInclude) FieldName(com.palantir.conjure.spec.FieldName) Comparator(java.util.Comparator) Collections(java.util.Collections) JsonDeserialize(com.fasterxml.jackson.databind.annotation.JsonDeserialize) FieldSpec(com.squareup.javapoet.FieldSpec) JsonIgnoreProperties(com.fasterxml.jackson.annotation.JsonIgnoreProperties) JsonSerialize(com.fasterxml.jackson.databind.annotation.JsonSerialize) ClassName(com.squareup.javapoet.ClassName) TypeSpec(com.squareup.javapoet.TypeSpec)

Example 2 with ObjectDefinition

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

the class ConjureParserUtils method parseObjectType.

public static TypeDefinition parseObjectType(TypeName name, com.palantir.conjure.parser.types.complex.ObjectTypeDefinition def, ConjureTypeParserVisitor.ReferenceTypeResolver typeResolver) {
    ObjectDefinition objectType = ObjectDefinition.builder().typeName(name).fields(parseField(def.fields(), typeResolver)).docs(def.docs().map(Documentation::of)).build();
    ObjectDefinitionValidator.validate(objectType);
    return TypeDefinition.object(objectType);
}
Also used : Documentation(com.palantir.conjure.spec.Documentation) ObjectDefinition(com.palantir.conjure.spec.ObjectDefinition)

Example 3 with ObjectDefinition

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

the class ObjectDefinitionValidatorTest method testUniqueFieldNameValidator.

private void testUniqueFieldNameValidator(String fieldName1, String fieldName2) {
    FieldDefinition field1 = FieldDefinition.builder().fieldName(FieldName.of(fieldName1)).type(Type.primitive(PrimitiveType.STRING)).build();
    FieldDefinition field2 = FieldDefinition.builder().fieldName(FieldName.of(fieldName2)).type(Type.primitive(PrimitiveType.STRING)).build();
    TypeName name = TypeName.of("Foo", "package");
    ObjectDefinition definition = ObjectDefinition.builder().typeName(name).fields(field1).fields(field2).build();
    assertThatThrownBy(() -> ObjectDefinitionValidator.validate(definition)).isInstanceOf(IllegalArgumentException.class).hasMessage(String.format("ObjectDefinition must not contain duplicate field names " + "(modulo case normalization): %s vs %s", fieldName2, fieldName1));
}
Also used : TypeName(com.palantir.conjure.spec.TypeName) FieldDefinition(com.palantir.conjure.spec.FieldDefinition) ObjectDefinition(com.palantir.conjure.spec.ObjectDefinition)

Example 4 with ObjectDefinition

use of com.palantir.conjure.spec.ObjectDefinition in project conjure-postman by palantir.

the class TemplateTypeVisitor method visitReference.

@SuppressWarnings("PreferSafeLoggingPreconditions")
@Override
public JsonNode visitReference(TypeName value) {
    TypeDefinition definition = types.get(value);
    TemplateTypeVisitor visitor = this;
    return definition.accept(new TypeDefinition.Visitor<JsonNode>() {

        @Override
        public JsonNode visitAlias(AliasDefinition value) {
            JsonNode wrapped = value.getAlias().accept(visitor);
            if (wrapped instanceof TextNode) {
                return new TextNode(String.format("{{ %s(%s) }}", value.getTypeName().getName(), wrapped.toString().replaceAll("[\"{}]", "")));
            }
            return wrapped;
        }

        @Override
        public JsonNode visitEnum(EnumDefinition value) {
            return new TextNode(value.getValues().stream().map(EnumValueDefinition::getValue).collect(Collectors.joining("|")));
        }

        @Override
        public JsonNode visitObject(ObjectDefinition value) {
            if (seenTypeStack.contains(value.getTypeName())) {
                return new TextNode(String.format("{{%s}}", value.getTypeName().getName()));
            }
            seenTypeStack.push(value.getTypeName());
            ObjectNode node = objectMapper.createObjectNode();
            value.getFields().forEach(fieldDefinition -> node.set(fieldDefinition.getFieldName().get(), fieldDefinition.getType().accept(visitor)));
            Preconditions.checkState(seenTypeStack.pop().equals(value.getTypeName()));
            return node;
        }

        @Override
        public JsonNode visitUnion(UnionDefinition value) {
            if (value.getUnion().isEmpty()) {
                return null;
            } else {
                if (seenTypeStack.contains(value.getTypeName())) {
                    return new TextNode(String.format("{{%s}}", value.getTypeName().getName()));
                }
                seenTypeStack.push(value.getTypeName());
                String unionTypes = value.getUnion().stream().map(FieldDefinition::getFieldName).map(FieldName::get).collect(Collectors.joining("|"));
                ObjectNode templates = objectMapper.createObjectNode();
                value.getUnion().forEach(field -> templates.set(field.getFieldName().get(), field.getType().accept(visitor)));
                JsonNode union = objectMapper.createObjectNode().put("type", unionTypes).set("oneOf", templates);
                Preconditions.checkState(seenTypeStack.pop().equals(value.getTypeName()));
                return union;
            }
        }

        @Override
        public JsonNode visitUnknown(String _unknownType) {
            return new TextNode("{{UNKNOWN}}");
        }
    });
}
Also used : ListType(com.palantir.conjure.spec.ListType) ExternalReference(com.palantir.conjure.spec.ExternalReference) Type(com.palantir.conjure.spec.Type) TypeDefinitionVisitor(com.palantir.conjure.visitor.TypeDefinitionVisitor) Function(java.util.function.Function) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) UnionDefinition(com.palantir.conjure.spec.UnionDefinition) MapType(com.palantir.conjure.spec.MapType) Map(java.util.Map) OptionalType(com.palantir.conjure.spec.OptionalType) JsonNode(com.fasterxml.jackson.databind.JsonNode) SetType(com.palantir.conjure.spec.SetType) TypeDefinition(com.palantir.conjure.spec.TypeDefinition) ObjectDefinition(com.palantir.conjure.spec.ObjectDefinition) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) EnumDefinition(com.palantir.conjure.spec.EnumDefinition) EnumValueDefinition(com.palantir.conjure.spec.EnumValueDefinition) FieldDefinition(com.palantir.conjure.spec.FieldDefinition) Collectors(java.util.stream.Collectors) TextNode(com.fasterxml.jackson.databind.node.TextNode) Jdk8Module(com.fasterxml.jackson.datatype.jdk8.Jdk8Module) List(java.util.List) AliasDefinition(com.palantir.conjure.spec.AliasDefinition) TypeName(com.palantir.conjure.spec.TypeName) SerializationFeature(com.fasterxml.jackson.databind.SerializationFeature) Preconditions(com.google.common.base.Preconditions) FieldName(com.palantir.conjure.spec.FieldName) PrimitiveType(com.palantir.conjure.spec.PrimitiveType) ArrayDeque(java.util.ArrayDeque) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) AliasDefinition(com.palantir.conjure.spec.AliasDefinition) UnionDefinition(com.palantir.conjure.spec.UnionDefinition) JsonNode(com.fasterxml.jackson.databind.JsonNode) TextNode(com.fasterxml.jackson.databind.node.TextNode) ObjectDefinition(com.palantir.conjure.spec.ObjectDefinition) EnumDefinition(com.palantir.conjure.spec.EnumDefinition) TypeDefinition(com.palantir.conjure.spec.TypeDefinition) FieldName(com.palantir.conjure.spec.FieldName)

Example 5 with ObjectDefinition

use of com.palantir.conjure.spec.ObjectDefinition in project conjure-postman by palantir.

the class TypeNameFormatterVisitor method visitReference.

@Override
public String visitReference(TypeName value) {
    TypeDefinition definition = types.get(value);
    TypeNameFormatterVisitor visitor = this;
    return definition.accept(new TypeDefinition.Visitor<String>() {

        @Override
        public String visitAlias(AliasDefinition value) {
            return String.format("%s(%s)", value.getTypeName().getName(), value.getAlias().accept(visitor));
        }

        @Override
        public String visitEnum(EnumDefinition value) {
            return value.getTypeName().getName();
        }

        @Override
        public String visitObject(ObjectDefinition value) {
            return value.getTypeName().getName();
        }

        @Override
        public String visitUnion(UnionDefinition value) {
            return value.getTypeName().getName();
        }

        @Override
        public String visitUnknown(String _unknownType) {
            return "UNKNOWN";
        }
    });
}
Also used : AliasDefinition(com.palantir.conjure.spec.AliasDefinition) UnionDefinition(com.palantir.conjure.spec.UnionDefinition) ObjectDefinition(com.palantir.conjure.spec.ObjectDefinition) EnumDefinition(com.palantir.conjure.spec.EnumDefinition) TypeDefinition(com.palantir.conjure.spec.TypeDefinition)

Aggregations

ObjectDefinition (com.palantir.conjure.spec.ObjectDefinition)6 TypeDefinition (com.palantir.conjure.spec.TypeDefinition)4 AliasDefinition (com.palantir.conjure.spec.AliasDefinition)3 EnumDefinition (com.palantir.conjure.spec.EnumDefinition)3 FieldDefinition (com.palantir.conjure.spec.FieldDefinition)3 UnionDefinition (com.palantir.conjure.spec.UnionDefinition)3 FieldName (com.palantir.conjure.spec.FieldName)2 ListType (com.palantir.conjure.spec.ListType)2 MapType (com.palantir.conjure.spec.MapType)2 OptionalType (com.palantir.conjure.spec.OptionalType)2 PrimitiveType (com.palantir.conjure.spec.PrimitiveType)2 SetType (com.palantir.conjure.spec.SetType)2 Type (com.palantir.conjure.spec.Type)2 TypeName (com.palantir.conjure.spec.TypeName)2 List (java.util.List)2 Map (java.util.Map)2 Collectors (java.util.stream.Collectors)2 JsonIgnoreProperties (com.fasterxml.jackson.annotation.JsonIgnoreProperties)1 JsonInclude (com.fasterxml.jackson.annotation.JsonInclude)1 JsonProperty (com.fasterxml.jackson.annotation.JsonProperty)1