001package com.hammurapi.extract; 002 003import java.util.Iterator; 004import java.util.ServiceLoader; 005 006import com.hammurapi.extract.scripting.ScriptingExtractorFactory; 007 008 009/** 010 * Extractor factory service. Creates scripted extractors and predicates. 011 * The service is discoverable using the Java Service Loader framework. 012 * @author Pavel Vlasov. 013 * 014 */ 015public interface ExtractorFactory { 016 017 /** 018 * Binding for context object. 019 */ 020 String CONTEXT_BINDING = "eCtx"; 021 022 /** 023 * Binding for arguments arrray if parameter names are not provided. 024 */ 025 String ARGS_BINDING = "args"; 026 027 /** 028 * This instance uses the service loading framework to discover 029 * extractor factory providers. It iterates over the providers and 030 * invokes provider's createExtractor() methods until it gets not null 031 * result which is returned from the method. 032 * If there are no providers supporting given language, then null is returned. 033 */ 034 ExtractorFactory INSTANCE = new ExtractorFactory() { 035 036 private ScriptingExtractorFactory sef = new ScriptingExtractorFactory(); 037 038 public <T, V, C> Extractor<T, V, C> createExtractor(String language, String code, String[] parameterNames, Class<T>[] parameterTypes, Class<V> valueType, Class<C> contextType, ClassLoader classLoader) { 039 ServiceLoader<ExtractorFactory> sl = classLoader==null ? ServiceLoader.load(ExtractorFactory.class) : ServiceLoader.load(ExtractorFactory.class, classLoader); 040 Iterator<ExtractorFactory> efi = sl.iterator(); 041 while (efi.hasNext()) { 042 Extractor<T, V, C> ret = efi.next().createExtractor(language, code, parameterNames, parameterTypes, valueType, contextType, classLoader); 043 if (ret!=null) { 044 return ret; 045 } 046 } 047 return sef.createExtractor(language, code, parameterNames, parameterTypes, valueType, contextType, classLoader); 048 } 049 050 public <T, C> Predicate<T, C> createPredicate(String language, String code, String[] parameterNames, Class<T>[] parameterTypes, Class<C> contextType, ClassLoader classLoader) { 051 ServiceLoader<ExtractorFactory> sl = classLoader==null ? ServiceLoader.load(ExtractorFactory.class) : ServiceLoader.load(ExtractorFactory.class, classLoader); 052 Iterator<ExtractorFactory> efi = sl.iterator(); 053 while (efi.hasNext()) { 054 Predicate<T, C> ret = efi.next().createPredicate(language, code, parameterNames, parameterTypes, contextType, classLoader); 055 if (ret!=null) { 056 return ret; 057 } 058 } 059 return sef.createPredicate(language, code, parameterNames, parameterTypes, contextType, classLoader); 060 } 061 062 }; 063 064 /** 065 * Creates extractor. 066 * @param <T> Source objects type. 067 * @param <V> Value type. 068 * @param language Extractor language. 069 * @param code Extractor code. 070 * @param parameterTypes Extractor parameter types. 071 * @param valueType Extractor value type. If this type is Boolean then the factory 072 * shall return Predicate. 073 * @param classLoader Class loader to use for script evaluation. 074 * @return Extractor or null if this factory doesn't support given language. 075 */ 076 <T, V, C> Extractor<T, V, C> createExtractor(String language, String code, String[] parameterNames, Class<T>[] parameterTypes, Class<V> valueType, Class<C> contextType, ClassLoader classLoader); 077 078 /** 079 * Creates extractor. 080 * @param <T> Source objects type. 081 * @param language Extractor language. 082 * @param code Extractor code. 083 * @param parameterTypes Extractor parameter types. 084 * @param valueType Extractor value type. If this type is Boolean then the factory 085 * shall return Predicate. 086 * @param classLoader Class loader to use for script evaluation. 087 * @return Extractor or null if this factory doesn't support given language. 088 */ 089 <T, C> Predicate<T, C> createPredicate(String language, String code, String[] parameterNames, Class<T>[] parameterTypes, Class<C> contextType, ClassLoader classLoader); 090}