/* * Hibernate Search, full-text search for your domain model * * License: GNU Lesser General Public License (LGPL), version 2.1 or later * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.search.bridge.impl; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.net.URI; import java.sql.Blob; import org.hibernate.search.annotations.TikaBridge; import org.hibernate.search.bridge.FieldBridge; import org.hibernate.search.engine.service.classloading.spi.ClassLoadingException; import org.hibernate.search.engine.service.spi.ServiceManager; import org.hibernate.search.exception.AssertionFailure; import org.hibernate.search.util.impl.ClassLoaderHelper; import org.hibernate.search.util.logging.impl.Log; import org.hibernate.search.util.logging.impl.LoggerFactory; /** * @author Emmanuel Bernard */ class TikaBridgeProvider extends ExtendedBridgeProvider { private static final Log LOG = LoggerFactory.make(); private final String TIKA_BRIDGE_NAME = "org.hibernate.search.bridge.builtin.TikaBridge"; private final String TIKA_BRIDGE_METADATA_PROCESSOR_SETTER = "setMetadataProcessorClass"; private final String TIKA_BRIDGE_PARSE_CONTEXT_SETTER = "setParseContextProviderClass"; @Override public FieldBridge provideFieldBridge(ExtendedBridgeProviderContext context) { AnnotatedElement annotatedElement = context.getAnnotatedElement(); if ( annotatedElement.isAnnotationPresent( TikaBridge.class ) ) { validateMemberType( context ); TikaBridge tikaAnnotation = annotatedElement.getAnnotation( TikaBridge.class ); return createTikaBridge( tikaAnnotation, context.getServiceManager() ); } return null; } private void validateMemberType(ExtendedBridgeProviderContext context) { Class<?> elementType = context.getReturnType(); // Example: URI, List<URI>, List<byte[]> if ( ! Blob.class.isAssignableFrom( elementType ) && ! String.class.isAssignableFrom( elementType ) && ! byte[].class.isAssignableFrom( elementType ) && ! URI.class.isAssignableFrom( elementType ) ) { // byte[] is actually an array but we want to treat it as a simple element Class<?> returnType = context.getElementOrContainerReturnType(); if ( ! byte[].class.isAssignableFrom( returnType ) ) { throw LOG.unsupportedTikaBridgeType( returnType ); } } } private FieldBridge createTikaBridge(org.hibernate.search.annotations.TikaBridge annotation, ServiceManager serviceManager) { Class<?> tikaBridgeClass; FieldBridge tikaBridge; try { tikaBridgeClass = ClassLoaderHelper.classForName( TIKA_BRIDGE_NAME, serviceManager ); tikaBridge = ClassLoaderHelper.instanceFromClass( FieldBridge.class, tikaBridgeClass, "Tika bridge" ); } catch (ClassLoadingException e) { throw new AssertionFailure( "Unable to find Tika bridge class: " + TIKA_BRIDGE_NAME ); } Class<?> tikaMetadataProcessorClass = annotation.metadataProcessor(); if ( tikaMetadataProcessorClass != void.class ) { configureTikaBridgeParameters( tikaBridgeClass, TIKA_BRIDGE_METADATA_PROCESSOR_SETTER, tikaBridge, tikaMetadataProcessorClass ); } Class<?> tikaParseContextProviderClass = annotation.parseContextProvider(); if ( tikaParseContextProviderClass != void.class ) { configureTikaBridgeParameters( tikaBridgeClass, TIKA_BRIDGE_PARSE_CONTEXT_SETTER, tikaBridge, tikaParseContextProviderClass ); } return tikaBridge; } private void configureTikaBridgeParameters(Class<?> tikaBridgeClass, String setter, Object tikaBridge, Class<?> clazz) { try { Method m = tikaBridgeClass.getMethod( setter, Class.class ); m.invoke( tikaBridge, clazz ); } catch (Exception e) { throw LOG.unableToConfigureTikaBridge( TIKA_BRIDGE_NAME, e ); } } }