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"));
}
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");
}
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;
}
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();
}
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;
}
Aggregations