nz.co.senanque.vaadinsupport.viewmanager.LoginLayout.java Source code

Java tutorial

Introduction

Here is the source code for nz.co.senanque.vaadinsupport.viewmanager.LoginLayout.java

Source

/*******************************************************************************
 * Copyright (c)2014 Prometheus Consulting
 *
 * 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 nz.co.senanque.vaadinsupport.viewmanager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.text.MessageFormat;

import javax.security.auth.login.LoginException;
import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ContextLoader;

import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.LoginForm;
import com.vaadin.ui.LoginForm.LoginEvent;
import com.vaadin.ui.LoginForm.LoginListener;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.Notification;

/**
 * 
 * Adapted from
 * http://dev.vaadin.com/browser/incubator/gasdiary/src/org/vaadin/gasdiary
 * /ui/LoginScreen.java but that probably does it better long term (allows
 * creation of new user-this doesn't). However this allows you to define the
 * login fragment (login.html) in your theme directory and it calls an external
 * (injected) authentication mechanism. Also nice support for locale.
 * 
 * @author Roger Parkinson
 * @version $Revision:$
 */

public class LoginLayout extends VerticalLayout
        implements InitializingBean, ViewManaged, MessageSourceAware, Serializable, BeanFactoryAware {
    private static final long serialVersionUID = 1L;
    private static Logger logger = LoggerFactory.getLogger(LoginLayout.class);

    @Autowired
    private LoginListener m_loginListener;
    private ViewManager m_viewManager;
    private MessageSource m_messageSource;
    private BeanFactory m_beanFactory;

    public class LoginFormI18n extends LoginForm {
        private static final long serialVersionUID = 8927668036479913166L;
        String usernameCaption;
        String passwordCaption;
        String submitCaption;
        String welcomeCaption;

        public LoginFormI18n(String usernameCaption, String passwordCaption, String submitCaption,
                String welcomeCaption) {
            this.usernameCaption = usernameCaption;
            this.passwordCaption = passwordCaption;
            this.submitCaption = submitCaption;
            this.welcomeCaption = welcomeCaption;
        }

        protected byte[] getLoginHTML() {

            String x = "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Transitional//EN\" "
                    + "\"http://www.w3.org/TR/xhtml1/" + "DTD/xhtml1-transitional.dtd\">\n";

            String appUri = getApplication().getURL().toString() + getWindow().getName() + "/";

            String h = "<head><script type='text/javascript'>" + "var setTarget = function() {" + "  var uri = '"
                    + appUri + "loginHandler';" + "  var f = document.getElementById('loginf');"
                    + "  document.forms[0].action = uri;" + "  document.forms[0].username.focus();" + "};" + ""
                    + "var styles = window.parent.document.styleSheets;"
                    + "for(var j = 0; j < styles.length; j++) {\n" + "  if(styles[j].href) {"
                    + "    var stylesheet = document.createElement('link');\n"
                    + "    stylesheet.setAttribute('rel', 'stylesheet');\n"
                    + "    stylesheet.setAttribute('type', 'text/css');\n"
                    + "    stylesheet.setAttribute('href', styles[j].href);\n"
                    + "    document.getElementsByTagName('head')[0]" + "                .appendChild(stylesheet);\n"
                    + "  }" + "}\n" + "function submitOnEnter(e) {" + "  var keycode = e.keyCode || e.which;"
                    + "  if (keycode == 13) {document.forms[0].submit();}" + "}\n" + "</script>" + "</head>";

            String b = "<body onload='setTarget();'" + "  style='margin:0;padding:0; background:transparent;'"
                    + "  class='" + ApplicationConnection.GENERATED_BODY_CLASSNAME + "'>"
                    + "<div class='v-app v-app-loginpage'" + "     style='background:transparent;'>"
                    + "<iframe name='logintarget' style='width:0;height:0;"
                    + "border:0;margin:0;padding:0;'></iframe>" + "<form id='loginf' target='logintarget'"
                    + "      onkeypress='submitOnEnter(event)'" + "      method='post'>";

            String theme = getApplication().getTheme();
            InputStream is = null;
            StringBuilder sb = new StringBuilder();
            ServletContext servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
            try {
                is = servletContext.getResourceAsStream("/VAADIN/themes/" + theme + "/login.html");
                if (is == null) {
                    is = this.getClass().getResourceAsStream("login.html");
                }

                while (true) {
                    byte[] bytes = new byte[1000];
                    int i = 0;
                    try {
                        i = is.read(bytes);
                    } catch (IOException e) {
                        throw new RuntimeException("Failed to open login.html");
                    }
                    if (i == -1) {
                        break;
                    }
                    sb.append(new String(bytes, 0, i));
                }
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    // ignore close errors
                }
            }
            String c = MessageFormat.format(sb.toString(), welcomeCaption, usernameCaption, passwordCaption,
                    submitCaption);
            return (x + "<html>" + h + b + c + "</form></html>").getBytes();
        }
    }

    public LoginLayout() {

    }

    public void afterPropertiesSet() throws Exception {
        setSizeFull();
        Panel loginPanel = new Panel();
        AbstractLayout panelLayout = (AbstractLayout) loginPanel.getContent();
        panelLayout.setMargin(false);
        loginPanel.setWidth("460px");
        final MessageSourceAccessor messageSourceAccessor = new MessageSourceAccessor(m_messageSource);
        final LoginForm loginForm = new LoginFormI18n(messageSourceAccessor.getMessage("username"),
                messageSourceAccessor.getMessage("password"), messageSourceAccessor.getMessage("login.button"),
                messageSourceAccessor.getMessage("welcome"));
        loginForm.setHeight("300px");
        loginForm.addListener(new LoginListener() {

            private static final long serialVersionUID = 5201900702970450254L;

            public void onLogin(LoginEvent event) {
                if (getLoginListener() != null) {
                    try {
                        getLoginListener().onLogin(event);
                    } catch (Exception e) {
                        Throwable cause = e.getCause();
                        if (cause == null || !(cause instanceof LoginException)) {
                            logger.error(e.getMessage(), e);
                        }
                        String message = messageSourceAccessor.getMessage("Bad.Login", "Bad Login");
                        getViewManager().getMainWindow().showNotification(message, Notification.TYPE_ERROR_MESSAGE);
                        return;
                    }
                }
                getViewManager().loadApplication();
            }
        });
        loginPanel.addComponent(loginForm);
        addComponent(loginPanel);
        setComponentAlignment(loginPanel, Alignment.MIDDLE_CENTER);
    }

    public LoginListener getLoginListener() {
        return m_loginListener;
    }

    public void setLoginListener(LoginListener loginListener) {
        m_loginListener = loginListener;
    }

    public void switchedTo() {
        // TODO Auto-generated method stub
    }

    public void setMessageSource(MessageSource messageSource) {
        m_messageSource = messageSource;
    }

    public ViewManager getViewManager() {
        return m_viewManager;
    }

    public void setViewManager(ViewManager viewManager) {
        m_viewManager = viewManager;
    }

    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        m_beanFactory = arg0;
    }

}