package org.infinispan.query.remote.impl.indexing; import java.io.IOException; import org.apache.lucene.document.Document; import org.hibernate.search.bridge.LuceneOptions; import org.infinispan.commons.CacheException; import org.infinispan.protostream.ProtobufParser; import org.infinispan.protostream.SerializationContext; import org.infinispan.protostream.TagHandler; import org.infinispan.protostream.WrappedMessage; import org.infinispan.protostream.descriptors.Descriptor; import org.infinispan.protostream.descriptors.FieldDescriptor; /** * @author anistor@redhat.com * @since 6.0 */ final class WrappedMessageTagHandler implements TagHandler { private final ProtobufValueWrapper valueWrapper; private final Document document; private final LuceneOptions luceneOptions; private final SerializationContext serCtx; private Descriptor messageDescriptor; private byte[] bytes; private Number numericValue; private String stringValue; WrappedMessageTagHandler(ProtobufValueWrapper valueWrapper, Document document, LuceneOptions luceneOptions, SerializationContext serCtx) { this.valueWrapper = valueWrapper; this.document = document; this.luceneOptions = luceneOptions; this.serCtx = serCtx; } @Override public void onStart() { } @Override public void onTag(int fieldNumber, FieldDescriptor fieldDescriptor, Object value) { switch (fieldNumber) { case WrappedMessage.WRAPPED_BOOL: stringValue = value != null ? value.toString() : null; break; case WrappedMessage.WRAPPED_BYTES: case WrappedMessage.WRAPPED_STRING: stringValue = (String) value; break; case WrappedMessage.WRAPPED_ENUM: case WrappedMessage.WRAPPED_DOUBLE: case WrappedMessage.WRAPPED_FLOAT: case WrappedMessage.WRAPPED_INT64: case WrappedMessage.WRAPPED_INT32: case WrappedMessage.WRAPPED_FIXED64: case WrappedMessage.WRAPPED_FIXED32: case WrappedMessage.WRAPPED_UINT32: case WrappedMessage.WRAPPED_SFIXED32: case WrappedMessage.WRAPPED_SFIXED64: case WrappedMessage.WRAPPED_SINT32: case WrappedMessage.WRAPPED_SINT64: numericValue = (Number) value; break; case WrappedMessage.WRAPPED_DESCRIPTOR_FULL_NAME: messageDescriptor = serCtx.getMessageDescriptor((String) value); break; case WrappedMessage.WRAPPED_DESCRIPTOR_ID: String typeName = serCtx.getTypeNameById((Integer) value); messageDescriptor = serCtx.getMessageDescriptor(typeName); break; case WrappedMessage.WRAPPED_MESSAGE: bytes = (byte[]) value; break; default: throw new IllegalStateException("Unexpected field : " + fieldNumber); } } @Override public void onStartNested(int fieldNumber, FieldDescriptor fieldDescriptor) { throw new IllegalStateException("No nested message is expected"); } @Override public void onEndNested(int fieldNumber, FieldDescriptor fieldDescriptor) { throw new IllegalStateException("No nested message is expected"); } @Override public void onEnd() { if (bytes != null) { // it's a message, not a primitive value if (messageDescriptor == null) { throw new IllegalStateException("Type name/id is missing"); } IndexingMetadata indexingMetadata = messageDescriptor.getProcessedAnnotation(IndexingMetadata.INDEXED_ANNOTATION); // if the message definition is not annotated at all we consider all fields indexed and stored, just to be backwards compatible if (indexingMetadata == null || indexingMetadata.isIndexed()) { valueWrapper.setMessageDescriptor(messageDescriptor); try { ProtobufParser.INSTANCE.parse(new IndexingTagHandler(messageDescriptor, document), messageDescriptor, bytes); } catch (IOException e) { throw new CacheException(e); } } } else if (numericValue != null) { //todo [anistor] how do we index a scalar value? luceneOptions.addNumericFieldToDocument("theValue", numericValue, document); } else if (stringValue != null) { luceneOptions.addFieldToDocument("theValue", stringValue, document); } } }