    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}