com.seajas.search.contender.scripting.FeedScriptsTestBase.java Source code

Java tutorial

Introduction

Here is the source code for com.seajas.search.contender.scripting.FeedScriptsTestBase.java

Source

/**
 * Copyright (C) 2013 Seajas, the Netherlands.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.seajas.search.contender.scripting;

import com.google.common.collect.Lists;
import com.seajas.search.bridge.contender.metadata.SeajasEntry;
import com.seajas.search.bridge.jms.model.Feed;
import com.seajas.search.contender.WebResolverSettings;
import com.seajas.search.utilities.web.WebFeeds;
import com.seajas.search.utilities.web.WebPages;
import com.seajas.search.utilities.web.WebResolver;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedOutput;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import static org.apache.commons.io.FileUtils.readFileToString;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

/**
 * Tests scripts in src/main/scripts/feed with src/test/samples/feed files.
 *
 * @author Pascal S. de Kloe <pascal@quies.net>
 * @author Jasper van Veghel <jasper@seajas.com>
 */
public class FeedScriptsTestBase {

    protected final ScriptEngineManager engineManager = new ScriptEngineManager();
    protected final DateFormat dates = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    private LinkedHashMap<String, String> samples = new LinkedHashMap<String, String>();
    private FeedScriptEvaluation subject;
    private MockInjectionService injectionService;

    public FeedScriptsTestBase() {
        dates.setTimeZone(TimeZone.getTimeZone("UTC"));
    }

    /**
     * Set the feed content to the content of the related sample.
     */
    protected void bind(String uri, String sampleFile) throws Exception {
        samples.put(uri, readFileToString(new File("src/test/samples/feed/" + sampleFile), "UTF-8"));
    }

    /**
     * Evaluates the script.
     */
    protected SyndFeed run(final String feedUri, final String scriptFile) throws Exception {
        final ScriptEngine engine = engineManager.getEngineByMimeType("text/javascript");

        injectionService = new MockInjectionService();
        subject = new FeedScriptEvaluation(new WebResolverSettings());
        subject.setScriptResolver(new ScriptCacheResolver<FeedScript>() {
            @Override
            public FeedScript resolve(final Bindings bindings) throws ScriptException {
                try {
                    for (Map.Entry<String, Object> entry : bindings.entrySet())
                        engine.put(entry.getKey(), entry.getValue());

                    engine.eval(readFileToString(new File("src/main/scripts/feed/" + scriptFile), "UTF-8"));

                    return ((Invocable) engine).getInterface(FeedScript.class);
                } catch (IOException e) {
                    throw new IllegalArgumentException("Invalid script", e);
                }
            }
        });

        if (scriptFile.endsWith(".js"))
            subject.setEngine(engine);
        else
            throw new IllegalArgumentException("Unknown script file extension.");

        subject.setFeedContent(samples.values().iterator().next());

        subject.setWebPages(new WebPages());
        subject.setWebResolver(new WebResolver() {
            @Override
            public String retrieveText(URI resource) {
                return samples.get(resource.toString());
            }
        });
        subject.setFeedURI(new URI(feedUri));
        subject.setCacheResolver(new FeedScriptCacheResolver() {
            @Override
            public boolean isCached(String resource) {
                return false;
            }
        });

        subject.setInjectionService(injectionService);

        subject.init();
        subject.run();

        SyndFeed feed = subject.getFeed();
        assertNotNull("feed", feed);

        // The validated feed must be serializable:
        SyndFeed result = (SyndFeed) feed.clone();
        WebFeeds.validate(result, new URI(feedUri));
        new SyndFeedOutput().outputString(result, true);

        return feed;
    }

    protected List<InjectedFeed> getInjectedFeeds() {
        return injectionService.feeds;
    }

    protected SeajasEntry getEntryById(final String uri) {
        for (SeajasEntry candidate : (Collection<SeajasEntry>) subject.getFeed().getEntries())
            if (uri.equals(candidate.getUri()))
                return candidate;

        fail("No entry with URI: " + uri);
        return null;
    }

    static class MockInjectionService implements FeedScriptEvaluation.InjectionService {

        public List<InjectedFeed> feeds = Lists.newArrayList();

        @Override
        public void inject(Feed resultFeed, String hostname, long l) {
            feeds.add(new InjectedFeed(resultFeed, hostname, l));
        }
    }

    public static class InjectedFeed {
        public final Feed resultFeed;
        public final String hostname;
        public final long l;

        InjectedFeed(Feed resultFeed, String hostname, long l) {
            this.resultFeed = resultFeed;
            this.hostname = hostname;
            this.l = l;
        }
    }

}