Search in sources :

Example 11 with ProtoSchemaBuilderException

use of org.infinispan.protostream.annotations.ProtoSchemaBuilderException in project protostream by infinispan.

the class ProtoSchemaBuilderTest method testAutoImport.

@Test
public void testAutoImport() throws Exception {
    SerializationContext ctx = createContext();
    new ProtoSchemaBuilder().fileName("test1.proto").packageName("test_package1").addClass(TestEnum.class).build(ctx);
    assertTrue(ctx.canMarshall(TestEnum.class));
    assertTrue(ctx.canMarshall("test_package1.TestEnumABC"));
    ProtoSchemaBuilder protoSchemaBuilder2 = new ProtoSchemaBuilder();
    protoSchemaBuilder2.autoImportClasses(false).fileName("test2.proto").packageName("test_package2").addClass(TestClass.class);
    try {
        // TestClass2 was not added explicitly and is not auto-added because autoImportClasses == false so we expect an exception
        protoSchemaBuilder2.build(ctx);
        fail("ProtoSchemaBuilderException expected");
    } catch (ProtoSchemaBuilderException e) {
        assertTrue(e.getMessage().contains("Found a reference to class org.infinispan.protostream.annotations.impl.testdomain.subpackage.TestClass2 which was not added to the builder and 'autoImportClasses' is disabled."));
    }
    assertFalse(ctx.canMarshall(TestClass.class));
    assertFalse(ctx.canMarshall(TestClass.InnerClass.class));
    assertFalse(ctx.canMarshall(TestClass.InnerClass2.class));
    assertFalse(ctx.canMarshall(TestClass2.class));
    // it must work after explicitly adding TestClass2
    protoSchemaBuilder2.addClass(TestClass2.class).build(ctx);
    assertTrue(ctx.canMarshall(TestClass.class));
    assertTrue(ctx.canMarshall("test_package2.TestClass"));
    assertTrue(ctx.canMarshall(TestClass.InnerClass.class));
    assertTrue(ctx.canMarshall(TestClass.InnerClass2.class));
    assertTrue(ctx.canMarshall(TestClass2.class));
    assertTrue(ctx.canMarshall("test_package1.TestEnumABC"));
    assertFalse(ctx.canMarshall("test_package2.TestEnumABC"));
}
Also used : SerializationContext(org.infinispan.protostream.SerializationContext) ProtoSchemaBuilder(org.infinispan.protostream.annotations.ProtoSchemaBuilder) ProtoSchemaBuilderException(org.infinispan.protostream.annotations.ProtoSchemaBuilderException) TestEnum(org.infinispan.protostream.annotations.impl.testdomain.TestEnum) TestClass(org.infinispan.protostream.annotations.impl.testdomain.TestClass) TestClass2(org.infinispan.protostream.annotations.impl.testdomain.subpackage.TestClass2) Test(org.junit.Test) AbstractProtoStreamTest(org.infinispan.protostream.test.AbstractProtoStreamTest)

Example 12 with ProtoSchemaBuilderException

use of org.infinispan.protostream.annotations.ProtoSchemaBuilderException in project protostream by infinispan.

the class ProtoEnumTypeMetadata method generateProto.

@Override
public void generateProto(IndentWriter iw) {
    scanMemberAnnotations();
    iw.append("\n\n");
    appendDocumentation(iw, getDocumentation());
    iw.append("enum ").append(name);
    if (BaseProtoSchemaGenerator.generateSchemaDebugComments) {
        iw.append(" /* ").append(getJavaClassName()).append(" */");
    }
    iw.append(" {\n");
    iw.inc();
    ReservedProcessor reserved = new ReservedProcessor();
    reserved.scan(annotatedEnumClass);
    for (String memberName : membersByName.keySet()) {
        XClass where = reserved.checkReserved(name);
        if (where != null) {
            throw new ProtoSchemaBuilderException("Protobuf enum value " + memberName + " of enum constant " + membersByName.get(memberName).getJavaEnumName() + " conflicts with 'reserved' statement in " + where.getCanonicalName());
        }
    }
    for (int memberNumber : membersByNumber.keySet()) {
        XClass where = reserved.checkReserved(memberNumber);
        if (where != null) {
            throw new ProtoSchemaBuilderException("Protobuf enum number " + memberNumber + " of enum constant " + membersByNumber.get(memberNumber).getJavaEnumName() + " conflicts with 'reserved' statement in " + where.getCanonicalName());
        }
    }
    reserved.generate(iw);
    for (ProtoEnumValueMetadata m : membersByNumber.values()) {
        m.generateProto(iw);
    }
    iw.dec();
    iw.append("}\n");
}
Also used : ProtoSchemaBuilderException(org.infinispan.protostream.annotations.ProtoSchemaBuilderException) XClass(org.infinispan.protostream.annotations.impl.types.XClass)

Example 13 with ProtoSchemaBuilderException

use of org.infinispan.protostream.annotations.ProtoSchemaBuilderException in project protostream by infinispan.

the class BaseProtoSchemaGenerator method generateAndRegister.

public String generateAndRegister() {
    // collect supers
    for (XClass c : classes) {
        collectKnownClasses(c);
    }
    // scan initial classes
    for (XClass c : classes) {
        collectMetadata(makeTypeMetadata(c));
    }
    // scan member annotations and possibly discover more classes being referenced
    while (true) {
        List<ProtoTypeMetadata> meta = new ArrayList<>(metadataByClass.values());
        for (ProtoTypeMetadata m : meta) {
            m.scanMemberAnnotations();
        }
        if (metadataByClass.size() == meta.size()) {
            // no new classes were discovered
            break;
        }
    }
    // establish the outer-inner relationship between definitions
    for (XClass c : metadataByClass.keySet()) {
        ProtoTypeMetadata m = metadataByClass.get(c);
        if (!m.isImported()) {
            ProtoMessageTypeMetadata outer = findOuterType(c);
            if (outer != null) {
                m.setOuterType(outer);
                outer.addInnerType(m);
            }
        }
    }
    IndentWriter iw = new IndentWriter();
    iw.append("// File name: ").append(fileName).append('\n');
    if (generator != null) {
        iw.append("// Generated from : ").append(generator).append('\n');
    }
    if (generateSchemaDebugComments) {
        iw.append("// Scanned classes:\n");
        // todo [anistor] this list of scanned classes should include all interfaces and base classes not just the ones for which a proto definition was generated
        for (ProtoTypeMetadata ptm : metadataByClass.values()) {
            if (!ptm.isImported()) {
                iw.append("//   ").append(ptm.getJavaClassName()).append('\n');
            }
        }
    }
    iw.append("\nsyntax = \"proto2\";\n\n");
    if (packageName != null) {
        iw.append("package ").append(packageName).append(";\n\n");
    }
    for (String dependency : imports) {
        iw.append("import \"").append(dependency).append("\";\n");
    }
    // generate type definitions for all top-level types, except the ones found in imported files
    for (XClass c : metadataByClass.keySet()) {
        ProtoTypeMetadata m = metadataByClass.get(c);
        if (m.getOuterType() == null && !m.isImported()) {
            m.generateProto(iw);
        }
    }
    String protoFile = iw.toString();
    if (log.isTraceEnabled()) {
        log.tracef("Generated proto file:\n%s", protoFile);
    }
    serializationContext.registerProtoFiles(FileDescriptorSource.fromString(fileName, protoFile));
    try {
        generateMarshallers();
    } catch (Exception e) {
        throw new ProtoSchemaBuilderException("Failed to generate marshaller implementation class", e);
    }
    return protoFile;
}
Also used : ProtoSchemaBuilderException(org.infinispan.protostream.annotations.ProtoSchemaBuilderException) ArrayList(java.util.ArrayList) XClass(org.infinispan.protostream.annotations.impl.types.XClass) ProtoSchemaBuilderException(org.infinispan.protostream.annotations.ProtoSchemaBuilderException)

Example 14 with ProtoSchemaBuilderException

use of org.infinispan.protostream.annotations.ProtoSchemaBuilderException in project protostream by infinispan.

the class ProtoMessageTypeMetadata method getProtoName.

private static String getProtoName(XClass annotatedClass, XClass javaClass) {
    ProtoName annotation = annotatedClass.getAnnotation(ProtoName.class);
    ProtoMessage protoMessageAnnotation = annotatedClass.getAnnotation(ProtoMessage.class);
    if (annotation != null) {
        if (protoMessageAnnotation != null) {
            throw new ProtoSchemaBuilderException("@ProtoMessage annotation cannot be used together with @ProtoName: " + annotatedClass.getName());
        }
        return annotation.value().isEmpty() ? javaClass.getSimpleName() : annotation.value();
    }
    return protoMessageAnnotation == null || protoMessageAnnotation.name().isEmpty() ? javaClass.getSimpleName() : protoMessageAnnotation.name();
}
Also used : ProtoSchemaBuilderException(org.infinispan.protostream.annotations.ProtoSchemaBuilderException) ProtoMessage(org.infinispan.protostream.annotations.ProtoMessage) ProtoName(org.infinispan.protostream.annotations.ProtoName)

Example 15 with ProtoSchemaBuilderException

use of org.infinispan.protostream.annotations.ProtoSchemaBuilderException in project protostream by infinispan.

the class ProtoMessageTypeMetadata method getCollectionImplementation.

private XClass getCollectionImplementation(XClass clazz, XClass fieldType, XClass configuredCollection, String fieldName, boolean isRepeated) {
    XClass collectionImplementation;
    XClass javaUtilCollectionClass = typeFactory.fromClass(Collection.class);
    if (isRepeated && !fieldType.isArray()) {
        collectionImplementation = configuredCollection;
        if (collectionImplementation == javaUtilCollectionClass) {
            // default
            if (fieldType == typeFactory.fromClass(Set.class)) {
                collectionImplementation = typeFactory.fromClass(HashSet.class);
            } else if (fieldType == typeFactory.fromClass(List.class) || fieldType == typeFactory.fromClass(Collection.class)) {
                collectionImplementation = typeFactory.fromClass(ArrayList.class);
            } else {
                collectionImplementation = fieldType;
            }
        }
        if (!collectionImplementation.isAssignableTo(javaUtilCollectionClass)) {
            throw new ProtoSchemaBuilderException("The collection class of repeated field '" + fieldName + "' of " + clazz.getCanonicalName() + " must implement java.util.Collection.");
        }
        if (collectionImplementation.isAbstract()) {
            throw new ProtoSchemaBuilderException("The collection class (" + collectionImplementation.getCanonicalName() + ") of repeated field '" + fieldName + "' of " + clazz.getCanonicalName() + " must not be abstract. Please specify an appropriate class in collectionImplementation member.");
        }
        XConstructor ctor = collectionImplementation.getDeclaredConstructor();
        if (ctor == null || ctor.isPrivate()) {
            throw new ProtoSchemaBuilderException("The collection class ('" + collectionImplementation.getCanonicalName() + "') of repeated field '" + fieldName + "' of " + clazz.getCanonicalName() + " must have a public no-argument constructor.");
        }
        if (!collectionImplementation.isAssignableTo(fieldType)) {
            throw new ProtoSchemaBuilderException("The collection implementation class ('" + collectionImplementation.getCanonicalName() + "') of repeated field '" + fieldName + "' of " + clazz.getCanonicalName() + " is not assignable to this field's type.");
        }
    } else {
        if (configuredCollection != javaUtilCollectionClass) {
            throw new ProtoSchemaBuilderException("Specifying the collection implementation class is only allowed for collection (repeated) fields: '" + fieldName + "' of " + clazz.getCanonicalName());
        }
        collectionImplementation = null;
    }
    return collectionImplementation;
}
Also used : ProtoUnknownFieldSet(org.infinispan.protostream.annotations.ProtoUnknownFieldSet) HashSet(java.util.HashSet) Set(java.util.Set) ProtoSchemaBuilderException(org.infinispan.protostream.annotations.ProtoSchemaBuilderException) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) XClass(org.infinispan.protostream.annotations.impl.types.XClass) HashSet(java.util.HashSet) XConstructor(org.infinispan.protostream.annotations.impl.types.XConstructor)

Aggregations

ProtoSchemaBuilderException (org.infinispan.protostream.annotations.ProtoSchemaBuilderException)18 XClass (org.infinispan.protostream.annotations.impl.types.XClass)12 Optional (java.util.Optional)4 SerializationContext (org.infinispan.protostream.SerializationContext)4 ArrayList (java.util.ArrayList)3 Collection (java.util.Collection)3 List (java.util.List)3 XMethod (org.infinispan.protostream.annotations.impl.types.XMethod)3 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 Set (java.util.Set)2 TypeMirror (javax.lang.model.type.TypeMirror)2 ProtoUnknownFieldSet (org.infinispan.protostream.annotations.ProtoUnknownFieldSet)2 XConstructor (org.infinispan.protostream.annotations.impl.types.XConstructor)2 AutoService (com.google.auto.service.AutoService)1 IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Instant (java.time.Instant)1