/* * Hibernate, Relational Persistence for Idiomatic Java * * JBoss, Home of Professional Open Source * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * * This copyrighted material is made available to anyone wishing to use, * modify, copy, or redistribute it subject to the terms and conditions * of the GNU Lesser General Public License, v. 2.1. * This program is distributed in the hope that it will be useful, but WITHOUT A * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License, * v.2.1 along with this distribution; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package org.hibernate.search.indexes.serialization.avro.impl; import java.util.HashMap; import java.util.Map; import org.apache.avro.Protocol; import org.hibernate.search.indexes.serialization.spi.Deserializer; import org.hibernate.search.indexes.serialization.spi.SerializationProvider; import org.hibernate.search.indexes.serialization.spi.Serializer; import org.hibernate.search.util.impl.FileHelper; import org.hibernate.search.util.logging.impl.Log; import org.hibernate.search.util.logging.impl.LoggerFactory; /** * parsing code inspired by http://www.infoq.com/articles/ApacheAvro * from Boris Lublinsky * * @author Emmanuel Bernard <emmanuel@hibernate.org> */ public class AvroSerializationProvider implements SerializationProvider { private static final Log log = LoggerFactory.make(); private static String V1_PATH = "org/hibernate/search/remote/codex/avro/v1_0/"; private static final String AVRO_SCHEMA_FILE_SUFFIX = ".avro"; private static final String AVRO_PROTOCOL_FILE_SUFFIX = ".avpr"; private Map<String, String> schemas = new HashMap<String, String>(); private Protocol protocol; public static byte MAJOR_VERSION = (byte) ( -128 + 1 ); public static byte MINOR_VERSION = (byte) ( -128 + 0 ); public static int getMajorVersion() { return MAJOR_VERSION + 128; //rebase to 0 } public static int getMinorVersion() { return MINOR_VERSION + 128; //rebase to 0 } @Override public Serializer getSerializer() { return new AvroSerializer( protocol ); } @Override public Deserializer getDeserializer() { return new AvroDeserializer( protocol ); } public AvroSerializationProvider() { log.serializationProtocol( getMajorVersion(), getMinorVersion() ); parseSchema( "attribute/TokenTrackingAttribute" ); parseSchema( "attribute/CharTermAttribute" ); parseSchema( "attribute/PayloadAttribute" ); parseSchema( "attribute/KeywordAttribute" ); parseSchema( "attribute/PositionIncrementAttribute" ); parseSchema( "attribute/FlagsAttribute" ); parseSchema( "attribute/TypeAttribute" ); parseSchema( "attribute/OffsetAttribute" ); parseSchema( "field/TermVector" ); parseSchema( "field/Index" ); parseSchema( "field/Store" ); parseSchema( "field/TokenStreamField" ); parseSchema( "field/ReaderField" ); parseSchema( "field/StringField" ); parseSchema( "field/BinaryField" ); parseSchema( "field/NumericIntField" ); parseSchema( "field/NumericLongField" ); parseSchema( "field/NumericFloatField" ); parseSchema( "field/NumericDoubleField" ); parseSchema( "field/CustomFieldable" ); parseSchema( "Document" ); parseSchema( "operation/Id" ); parseSchema( "operation/OptimizeAll" ); parseSchema( "operation/PurgeAll" ); parseSchema( "operation/Delete" ); parseSchema( "operation/Add" ); parseSchema( "operation/Update" ); parseSchema( "Message" ); this.protocol = parseProtocol( "Works" ); } private void parseSchema(String filename) { String fullFileName = V1_PATH + filename + AVRO_SCHEMA_FILE_SUFFIX; String messageSchemaAsString = FileHelper.readResourceAsString( fullFileName, AvroSerializationProvider.class.getClassLoader() ); schemas.put( filename, messageSchemaAsString ); } public Protocol parseProtocol(String name) { String filename = V1_PATH + name + AVRO_PROTOCOL_FILE_SUFFIX; String protocolSkeleton = FileHelper.readResourceAsString( filename, AvroSerializationProvider.class.getClassLoader() ); String protocolString = inlineSchemas( protocolSkeleton ); return Protocol.parse( protocolString ); } public String inlineSchemas(String protocolSkeleton) { String result = protocolSkeleton; for ( Map.Entry<String, String> entry : schemas.entrySet() ) { result = replace( result, "`" + entry.getKey() + "`", entry.getValue() ); } return result; } static String replace(String str, String pattern, String replace) { int s = 0; int e; StringBuilder result = new StringBuilder(); while ( ( e = str.indexOf( pattern, s ) ) >= 0 ) { result.append( str.substring( s, e ) ); result.append( replace ); s = e + pattern.length(); } result.append( str.substring( s ) ); return result.toString(); } @Override public String toString() { return "Avro SerializationProvider v" + getMajorVersion() + "." + getMinorVersion(); } }