org.vaadin.tori.ToriApiLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.vaadin.tori.ToriApiLoader.java

Source

/*
 * Copyright 2014 Vaadin Ltd.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.vaadin.tori;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.Scanner;
import java.util.ServiceLoader;

import javax.portlet.PortletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.vaadin.tori.data.DataSource;
import org.vaadin.tori.data.spi.ServiceProvider;
import org.vaadin.tori.service.AuthorizationService;
import org.vaadin.tori.util.PostFormatter;
import org.vaadin.tori.util.ToriActivityMessaging;
import org.vaadin.tori.util.ToriMailService;
import org.vaadin.tori.util.UrlConverter;
import org.vaadin.tori.util.UserBadgeProvider;

import com.vaadin.server.Page;
import com.vaadin.server.SessionDestroyEvent;
import com.vaadin.server.SessionDestroyListener;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.UI;

@SuppressWarnings("serial")
public class ToriApiLoader implements Serializable, SessionDestroyListener {

    private final ServiceProvider spi;
    private final DataSource ds;
    private final PostFormatter postFormatter;
    private final AuthorizationService authorizationService;

    private final UserBadgeProvider userBadgeProvider;
    private final UrlConverter urlConverter;
    private final ToriActivityMessaging toriActivityMessaging;
    private ToriMailService toriMailService;
    private String sessionId;

    public ToriApiLoader() {
        checkThatCommonIsLoaded();
        spi = newServiceProvider();
        ds = createDataSource();
        postFormatter = createPostFormatter();
        authorizationService = createAuthorizationService();
        toriActivityMessaging = createToriActivityMessaging();
        userBadgeProvider = createService(UserBadgeProvider.class);
        urlConverter = createService(UrlConverter.class);
    }

    private <T> T createService(final Class<T> clazz) {
        T service = null;
        final ServiceLoader<T> loader = ServiceLoader.load(clazz);
        if (loader.iterator().hasNext()) {
            service = loader.iterator().next();
            getLogger().debug(String.format("Using %s implementation: %s", clazz.getSimpleName(),
                    service.getClass().getName()));
        } else {
            getLogger().debug(String.format("No implementation for %s found", clazz.getSimpleName()));
        }
        return service;
    }

    public final void setRequest(final Object request) {
        if (request != null) {
            for (final Object aware : Arrays.asList(ds, authorizationService, toriActivityMessaging, postFormatter,
                    toriMailService)) {
                try {
                    if (aware instanceof PortletRequestAware && request instanceof PortletRequest) {
                        ((PortletRequestAware) aware).setRequest((PortletRequest) request);
                    } else if (aware instanceof HttpServletRequestAware && request instanceof HttpServletRequest) {
                        ((HttpServletRequestAware) aware).setRequest((HttpServletRequest) request);
                    }
                } catch (Exception e) {
                    getLogger().warn("Unable to set request", e);
                }
            }
        }
    }

    /**
     * Verifies that the common project is in the classpath
     * 
     * @throws RuntimeException
     *             if Common is not in the classpath
     */
    private static void checkThatCommonIsLoaded() {
        try {
            Class.forName("org.vaadin.tori.data.spi.ServiceProvider");
        } catch (final ClassNotFoundException e) {
            throw new RuntimeException("Your project was " + "apparently deployed without the Common "
                    + "project (common.jar) in its classpath", e);
        }
    }

    private static ServiceProvider newServiceProvider() {
        final ServiceLoader<ServiceProvider> loader = ServiceLoader.load(ServiceProvider.class);
        if (loader.iterator().hasNext()) {
            return loader.iterator().next();
        } else {
            throw new RuntimeException("It seems you don't have a DataSource in your classpath, "
                    + "or the added data source is misconfigured (see JavaDoc for "
                    + ServiceProvider.class.getName() + ").");
        }
    }

    private DataSource createDataSource() {
        final DataSource ds = spi.createDataSource();
        getLogger().debug(String.format("Using %s implementation: %s", DataSource.class.getSimpleName(),
                ds.getClass().getName()));
        return ds;
    }

    private PostFormatter createPostFormatter() {
        final PostFormatter postFormatter = spi.createPostFormatter();
        getLogger().debug(String.format("Using %s implementation: %s", PostFormatter.class.getSimpleName(),
                postFormatter.getClass().getName()));
        return postFormatter;
    }

    private AuthorizationService createAuthorizationService() {
        final AuthorizationService authorizationService = spi.createAuthorizationService();
        getLogger().debug(String.format("Using %s implementation: %s", PostFormatter.class.getSimpleName(),
                authorizationService.getClass().getName()));
        return authorizationService;
    }

    private ToriActivityMessaging createToriActivityMessaging() {
        final ToriActivityMessaging toriActivityMessaging = spi.createToriActivityMessaging();
        getLogger().debug(String.format("Using %s implementation: %s", ToriActivityMessaging.class.getSimpleName(),
                toriActivityMessaging.getClass().getName()));
        return toriActivityMessaging;
    }

    private static String getToriThemeImagesURL(final VaadinRequest request) throws MalformedURLException {
        URL url = Page.getCurrent().getLocation().toURL();
        int port = url.getPort();

        if (url.getProtocol().equals("http") && port == 80) {
            port = -1;
        } else if (url.getProtocol().equals("https") && port == 443) {
            port = -1;
        }

        URL serverURL = new URL(url.getProtocol(), url.getHost(), port, "");
        String contextPath = request.getContextPath();
        String imagesPath = "/VAADIN/themes/tori/images/";

        return serverURL + contextPath + imagesPath;

    }

    private ToriMailService createToriMailService(final VaadinRequest request) {
        ToriMailService result = null;
        if (request != null) {
            result = spi.createToriMailService();
            try {
                String themeName = UI.getCurrent().getTheme();

                InputStream postTemplateStream = VaadinService.getCurrent()
                        .getThemeResourceAsStream(UI.getCurrent(), "tori", "toripostmailtemplate.xhtml");
                InputStream themeStream = VaadinService.getCurrent().getThemeResourceAsStream(UI.getCurrent(),
                        themeName, "styles.css");

                if (postTemplateStream != null && themeStream != null) {
                    result.setPostMailTemplate(readStream(postTemplateStream));

                    String themeCss = readStream(themeStream);
                    String imagesUrl = getToriThemeImagesURL(request);
                    String quoteImageUrl = imagesUrl + "emailquote.png";
                    String anonymousImageUrl = imagesUrl + "emailanonymous.png";
                    String defaultHeaderImageUrl = imagesUrl + "tori-icon.png";

                    //@formatter:off
                    String quoteRule = "\n\n" + ".v-app blockquote cite, .v-app .quote-title { \n"
                            + "background-image: url('" + quoteImageUrl + "'); \n"
                            + "background-repeat: no-repeat; \n" + "}";

                    String anonymousRule = "\n\n" + ".avatar.anonymous-true { \n" + "background-image: url('"
                            + anonymousImageUrl + "'); \n" + "height: 100%; \n" + "}" + "\n\n"
                            + ".avatar.anonymous-true img { \n" + "display: none; \n" + "}";

                    String customHeaderImageRule = "\n\n" + ".defaultheaderimage-true { \n"
                            + "background-image: url('" + defaultHeaderImageUrl + "'); \n"
                            + "background-repeat: no-repeat; \n" + "}" + "\n\n"
                            + ".defaultheaderimage-true .headerimageplaceholder { \n" + "width: 160px; \n"
                            + "height: 40px; \n" + "}";
                    //@formatter:on
                    result.setMailTheme(themeCss + quoteRule + anonymousRule + customHeaderImageRule);

                    getLogger().debug(String.format("Using %s implementation: %s",
                            ToriMailService.class.getSimpleName(), result.getClass().getName()));
                } else {
                    getLogger().error("Unable to set mail service resources");
                    result = null;
                }
            } catch (IOException e) {
                getLogger().warn("Exception while closing input stream", e);
            } catch (Exception e) {
                getLogger().error("Exception while initiating ToriMailService", e);
                result = null;
            }
        }

        return result;
    }

    private static String readStream(final InputStream is) throws IOException {
        Scanner s = new Scanner(is).useDelimiter("\\A");
        String result = s.hasNext() ? s.next() : "";
        is.close();
        return result;
    }

    private static Logger getLogger() {
        return Logger.getLogger(ToriApiLoader.class);
    }

    public DataSource getDataSource() {
        return ds;
    }

    public PostFormatter getPostFormatter() {
        return postFormatter;
    }

    public AuthorizationService getAuthorizationService() {
        return authorizationService;
    }

    public UserBadgeProvider getUserBadgeProvider() {
        return userBadgeProvider;
    }

    public UrlConverter getUrlConverter() {
        return urlConverter;
    }

    public ToriActivityMessaging getToriActivityMessaging() {
        return toriActivityMessaging;
    }

    public ToriMailService getToriMailService() {
        return toriMailService;
    }

    public static ToriApiLoader getCurrent() {
        final ToriApiLoader apiLoader = VaadinSession.getCurrent().getAttribute(ToriApiLoader.class);
        if (apiLoader != null) {
            return apiLoader;
        } else {
            throw new IllegalStateException(
                    ToriApiLoader.class.getName() + " was not found in the state. This is bad...");
        }
    }

    public static void init(final VaadinRequest request) {
        ToriApiLoader toriApiLoader = VaadinSession.getCurrent().getAttribute(ToriApiLoader.class);
        if (toriApiLoader == null) {
            toriApiLoader = new ToriApiLoader();
            toriApiLoader.toriMailService = toriApiLoader.createToriMailService(request);
            if (toriApiLoader.getToriActivityMessaging() != null) {
                toriApiLoader.getToriActivityMessaging().register();
            }
            request.getService().addSessionDestroyListener(toriApiLoader);
            VaadinSession.getCurrent().setAttribute(ToriApiLoader.class, toriApiLoader);
        }
        toriApiLoader.sessionId = VaadinSession.getCurrent().getSession().getId();
        toriApiLoader.setRequest(request);
    }

    @Override
    public void sessionDestroy(final SessionDestroyEvent event) {
        if (sessionId != null && sessionId.equals(event.getSession().getSession().getId())) {
            if (toriActivityMessaging != null) {
                toriActivityMessaging.deregister();
            }
            event.getService().removeSessionDestroyListener(this);
        }
    }

}