org.ambraproject.wombat.service.remote.EditorialContentApiImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.ambraproject.wombat.service.remote.EditorialContentApiImpl.java

Source

/*
 * Copyright (c) 2017 Public Library of Science
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

package org.ambraproject.wombat.service.remote;

import org.ambraproject.wombat.config.site.SiteSet;
import org.ambraproject.wombat.freemarker.HtmlElementSubstitution;
import org.ambraproject.wombat.freemarker.HtmlElementTransformation;
import org.ambraproject.wombat.freemarker.SitePageContext;
import org.ambraproject.wombat.util.CacheKey;
import org.apache.commons.io.IOUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

public class EditorialContentApiImpl extends AbstractContentApi implements EditorialContentApi {

    @Autowired
    private SiteSet siteSet;

    @Override
    protected String getRepoConfigKey() {
        return "editorial";
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Applies transforms to HTML attributes and performs substitution of placeholder HTML elements with stored content
     */
    @Override
    public Reader readHtml(final SitePageContext sitePageContext, String pageType, String key,
            final Set<HtmlElementTransformation> transformations,
            final Collection<HtmlElementSubstitution> substitutions) throws IOException {
        Map<String, Object> pageConfig = sitePageContext.getSite().getTheme().getConfigMap(pageType);
        ContentKey version = ContentKey.createForLatestVersion(key); // TODO May want to support page versioning at some point using fetchHtmlDirective
        CacheKey cacheKey = CacheKey.create(pageType, key);
        Number cacheTtl = (Number) pageConfig.get("cacheTtl");
        if (cacheTtl != null) {
            cacheKey = cacheKey.addTimeToLive(cacheTtl.intValue());
        }

        String transformedHtml = requestCachedReader(cacheKey, version, new CacheDeserializer<Reader, String>() {
            @Override
            public String read(Reader htmlReader) throws IOException {
                // It would be nice to feed the reader directly into the parser, but Jsoup's API makes this awkward.
                // The whole document will be in memory anyway, so buffering it into a string is no great performance loss.
                String htmlString = IOUtils.toString(htmlReader);
                Document document = Jsoup.parseBodyFragment(htmlString);

                for (HtmlElementTransformation transformation : transformations) {
                    transformation.apply(sitePageContext, siteSet, document);
                }
                for (HtmlElementSubstitution substitution : substitutions) {
                    substitution.substitute(document);
                }

                // We received a snippet, which Jsoup has automatically turned into a complete HTML document.
                // We want to return only the transformed snippet, so retrieve it from the body tag.
                return document.getElementsByTag("body").html();
            }
        });
        return new StringReader(transformedHtml);
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Returns a JSON object from a remote service
     */
    @Override
    public Object getJson(String pageType, String key) throws IOException {
        CacheKey cacheKey = CacheKey.create(pageType, key);
        ContentKey version = ContentKey.createForLatestVersion(key);
        return requestCachedReader(cacheKey, version, jsonReader -> gson.fromJson(jsonReader, Object.class));
    }
}