de.catma.ui.CatmaApplication.java Source code

Java tutorial

Introduction

Here is the source code for de.catma.ui.CatmaApplication.java

Source

/*   
 *   CATMA Computer Aided Text Markup and Analysis
 *   
 *   Copyright (C) 2009-2013  University Of Hamburg
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   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 de.catma.ui;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.vaadin.annotations.PreserveOnRefresh;
import com.vaadin.annotations.Theme;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FontAwesome;
import com.vaadin.server.Page;
import com.vaadin.server.ThemeResource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.Panel;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.BaseTheme;

import de.catma.backgroundservice.BackgroundService;
import de.catma.backgroundservice.BackgroundServiceProvider;
import de.catma.backgroundservice.ExecutionListener;
import de.catma.backgroundservice.LogProgressListener;
import de.catma.backgroundservice.ProgressCallable;
import de.catma.document.Corpus;
import de.catma.document.Range;
import de.catma.document.repository.Repository;
import de.catma.document.repository.RepositoryManager;
import de.catma.document.repository.RepositoryProperties;
import de.catma.document.repository.RepositoryPropertyKey;
import de.catma.document.source.KeywordInContext;
import de.catma.document.source.SourceDocument;
import de.catma.document.standoffmarkup.usermarkup.UserMarkupCollection;
import de.catma.indexer.IndexedRepository;
import de.catma.queryengine.result.computation.DistributionComputation;
import de.catma.queryengine.result.computation.DistributionSelectionListener;
import de.catma.repository.LoginToken;
import de.catma.repository.db.maintenance.UserManager;
import de.catma.tag.TagLibrary;
import de.catma.tag.TagManager;
import de.catma.tag.TagsetDefinition;
import de.catma.ui.analyzer.AnalyzerManagerView;
import de.catma.ui.analyzer.AnalyzerProvider;
import de.catma.ui.component.HTMLNotification;
import de.catma.ui.menu.LoginLogoutCommand;
import de.catma.ui.menu.MainMenu;
import de.catma.ui.menu.MenuFactory;
import de.catma.ui.repository.RepositoryManagerView;
import de.catma.ui.tagger.TaggerManagerView;
import de.catma.ui.tagger.TaggerView;
import de.catma.ui.tagmanager.TagManagerView;
import de.catma.ui.visualizer.VisualizationManagerView;

//@Push(PushMode.MANUAL)
@Theme("catma")
@PreserveOnRefresh
public class CatmaApplication extends UI implements BackgroundServiceProvider, AnalyzerProvider, LoginToken {

    private static final String MINORVERSION = "(build "
            + new SimpleDateFormat("yyyy/MM/dd-HH:mm").format(new Date()) + ")";
    private static final String WEB_INF_DIR = "WEB-INF";

    private RepositoryManagerView repositoryManagerView;
    private TagManagerView tagManagerView;
    private MainMenu menu;
    private String tempDirectory = null;
    private BackgroundService backgroundService;
    private TaggerManagerView taggerManagerView;
    private AnalyzerManagerView analyzerManagerView;
    private TagManager tagManager;
    private VisualizationManagerView visualizationManagerView;
    private Logger logger = Logger.getLogger(this.getClass().getName());
    private Map<String, String[]> parameters = new HashMap<String, String[]>();
    private boolean repositoryOpened = false;
    private UserManager userManager = new UserManager();
    private Object user;
    private VerticalLayout mainLayout;
    private Panel menuPanel;
    private HorizontalLayout menuLayout;
    private Panel contentPanel;
    private Button btHelp;

    private ThemeResource logoResource;

    private Label defaultContentPanelLabel;

    private PropertyChangeSupport propertyChangeSupport;

    private UIHelpWindow uiHelpWindow = new UIHelpWindow();

    /**
     * Events emitted by the CatmaApplication.
     * 
     * @see CatmaApplication#addPropertyChangeListener(CatmaApplicationEvent, PropertyChangeListener)
     */
    public static enum CatmaApplicationEvent {
        /**
         * <p>User logged in:
         * <li>{@link PropertyChangeEvent#getNewValue()} = {@link Object}</li>
         * </p><br />
         * <p>User logged out:
         * <li>{@link PropertyChangeEvent#getNewValue()} = <code>null</code></li>
         * </p><br />
         */
        userChange,;
    }

    public CatmaApplication() {
        propertyChangeSupport = new PropertyChangeSupport(this);
    }

    @Override
    protected void init(VaadinRequest request) {
        backgroundService = new UIBackgroundService(true);

        storeParameters(request.getParameterMap());

        Page.getCurrent().setTitle("CATMA 5.0 " + MINORVERSION);

        mainLayout = new VerticalLayout();
        mainLayout.setSizeFull();

        menuPanel = new Panel();
        menuPanel.addStyleName("menuPanel");
        mainLayout.addComponent(menuPanel);

        contentPanel = new Panel();
        contentPanel.setHeight("100%");
        contentPanel.addStyleName("contentPanel");

        defaultContentPanelLabel = new Label("Please log in to get started");
        defaultContentPanelLabel.addStyleName("defaultContentPanelLabel");
        contentPanel.setContent(defaultContentPanelLabel);

        mainLayout.addComponent(contentPanel);
        mainLayout.setExpandRatio(contentPanel, 1.0f);

        menuLayout = new HorizontalLayout();
        menuLayout.setMargin(true);
        menuLayout.setSpacing(true);

        logoResource = new ThemeResource("catma-logo.png");
        Link logoImage = new Link(null, new ExternalResource("http://www.catma.de"));
        logoImage.setIcon(logoResource);
        logoImage.setTargetName("_blank");
        menuLayout.addComponent(logoImage);

        MenuFactory menuFactory = new MenuFactory();
        try {

            initTempDirectory();
            tagManager = new TagManager();

            repositoryManagerView = new RepositoryManagerView(
                    new RepositoryManager(this, tagManager, RepositoryProperties.INSTANCE.getProperties()));

            tagManagerView = new TagManagerView(tagManager);

            taggerManagerView = new TaggerManagerView();

            analyzerManagerView = new AnalyzerManagerView();

            visualizationManagerView = new VisualizationManagerView();

            menu = menuFactory.createMenu(menuLayout, contentPanel,
                    new MenuFactory.MenuEntryDefinition("Repository Manager", repositoryManagerView),
                    new MenuFactory.MenuEntryDefinition("Tag Type Manager", tagManagerView),
                    new MenuFactory.MenuEntryDefinition("Tagger", taggerManagerView),
                    new MenuFactory.MenuEntryDefinition("Analyzer", analyzerManagerView),
                    new MenuFactory.MenuEntryDefinition("Visualizer", visualizationManagerView));
            addPropertyChangeListener(CatmaApplicationEvent.userChange, menu.userChangeListener);

            Link latestFeaturesLink = new Link("Latest Features",
                    new ExternalResource("http://www.catma.de/latestfeatures"));
            latestFeaturesLink.setTargetName("_blank");
            menuLayout.addComponent(latestFeaturesLink);
            menuLayout.setComponentAlignment(latestFeaturesLink, Alignment.TOP_RIGHT);
            menuLayout.setExpandRatio(latestFeaturesLink, 1.0f);

            Link aboutLink = new Link("About", new ExternalResource("http://www.catma.de"));
            aboutLink.setTargetName("_blank");
            menuLayout.addComponent(aboutLink);
            menuLayout.setComponentAlignment(aboutLink, Alignment.TOP_RIGHT);

            Link termsOfUseLink = new Link("Terms of Use", new ExternalResource("http://www.catma.de/termsofuse"));
            termsOfUseLink.setTargetName("_blank");
            menuLayout.addComponent(termsOfUseLink);
            menuLayout.setComponentAlignment(termsOfUseLink, Alignment.TOP_RIGHT);

            Link manualLink = new Link("Manual", new ExternalResource(request.getContextPath() + "/manual/"));
            manualLink.setTargetName("_blank");
            menuLayout.addComponent(manualLink);
            menuLayout.setComponentAlignment(manualLink, Alignment.TOP_RIGHT);

            Link helpLink = new Link("Helpdesk", new ExternalResource("http://www.catma.de/helpdesk/"));
            helpLink.setTargetName("_blank");
            menuLayout.addComponent(helpLink);
            menuLayout.setComponentAlignment(helpLink, Alignment.TOP_RIGHT);
            helpLink.setVisible(false);

            btHelp = new Button(FontAwesome.QUESTION_CIRCLE);
            btHelp.addStyleName("help-button");
            btHelp.addStyleName("application-help-button");

            menuLayout.addComponent(btHelp);

            btHelp.addClickListener(new ClickListener() {

                public void buttonClick(ClickEvent event) {

                    if (uiHelpWindow.getParent() == null) {
                        UI.getCurrent().addWindow(uiHelpWindow);
                    } else {
                        UI.getCurrent().removeWindow(uiHelpWindow);
                    }

                }
            });

            LoginLogoutCommand loginLogoutCommand = new LoginLogoutCommand(menu, repositoryManagerView);
            Button btloginLogout = new Button("Sign in", event -> loginLogoutCommand.menuSelected(null));
            btloginLogout.setStyleName(BaseTheme.BUTTON_LINK);
            btloginLogout.addStyleName("application-loginlink");

            loginLogoutCommand.setLoginLogoutButton(btloginLogout);

            menuLayout.addComponent(btloginLogout);
            menuLayout.setComponentAlignment(btloginLogout, Alignment.TOP_RIGHT);
            menuLayout.setWidth("100%");

            menuPanel.setContent(menuLayout);

            setContent(mainLayout);

            if (getParameter(Parameter.USER_IDENTIFIER) != null) {
                btloginLogout.click();
            }

            setPollInterval(10000);

            if ((getParameter(Parameter.AUTOLOGIN) != null) && (getUser() == null)) {
                getPage().setLocation(repositoryManagerView.createAuthenticationDialog().createLogInClick(this,
                        RepositoryPropertyKey.CATMA_oauthAuthorizationCodeRequestURL.getValue(),
                        RepositoryPropertyKey.CATMA_oauthAccessTokenRequestURL.getValue(),
                        RepositoryPropertyKey.CATMA_oauthClientId.getValue(),
                        RepositoryPropertyKey.CATMA_oauthClientSecret.getValue(), URLEncoder.encode("/", "UTF-8")));
            }

        } catch (Exception e) {
            showAndLogError("The system could not be initialized!", e);
        }

    }

    private void storeParameters(Map<String, String[]> parameters) {
        this.parameters.putAll(parameters);
    }

    public Map<String, String[]> getParameters() {
        return Collections.unmodifiableMap(parameters);
    }

    public String getParameter(Parameter parameter) {
        return getParameter(parameter.getKey());
    }

    public String getParameter(Parameter parameter, String defaultValue) {
        String value = getParameter(parameter.getKey());
        return value == null ? defaultValue : value;
    }

    public String getParameter(String key) {
        String[] values = parameters.get(key);
        if ((values != null) && (values.length > 0)) {
            return values[0];
        }

        return null;
    }

    public String[] getParameters(Parameter parameter) {
        return getParameters(parameter.getKey());
    }

    public String[] getParameters(String key) {
        return parameters.get(key);
    }

    private void initTempDirectory() throws IOException {
        String tempDirProp = RepositoryPropertyKey.TempDir.getValue();
        File tempDir = new File(tempDirProp);

        if (!tempDir.isAbsolute()) {
            this.tempDirectory = VaadinServlet.getCurrent().getServletContext().getRealPath(//TODO: check
                    WEB_INF_DIR + System.getProperty("file.separator") + tempDirProp);
        } else {
            this.tempDirectory = tempDirProp;
        }

        tempDir = new File(this.tempDirectory);
        if ((!tempDir.exists() && !tempDir.mkdirs())) {
            throw new IOException("could not create temporary directory: " + this.tempDirectory);
        }
    }

    public void addTagsetToActiveDocument(TagsetDefinition tagsetDefinition) {
        TaggerView selectedTab = (TaggerView) taggerManagerView.getSelectedTab();

        if (selectedTab == null) {
            Notification.show("Information", "There is no active document open in the Tagger",
                    Type.TRAY_NOTIFICATION);
            return;
        }

        selectedTab.openTagsetDefinition(this, tagsetDefinition);

        SourceDocument sd = selectedTab.getSourceDocument();
        String sourceDocumentCaption = sd.toString();

        Notification.show("Information", "Tagset loaded into active document: '" + sourceDocumentCaption + "'",
                Type.TRAY_NOTIFICATION);
    }

    public void openRepository(Repository repository) {
        repositoryOpened = true;
        userManager.login(this);
        repositoryManagerView.openRepository(repository);
        logger.info("repository has been opened for user" + getUser());
    }

    public void openTagLibrary(Repository repository, TagLibrary tagLibrary) {
        openTagLibrary(repository, tagLibrary, true);
    }

    public void openTagLibrary(Repository repository, TagLibrary tagLibrary, boolean switchToTagManagerView) {
        if (switchToTagManagerView) {
            menu.executeEntry(tagManagerView);
        }
        tagManagerView.openTagLibrary(this, repository, tagLibrary);
    }

    public TaggerView openSourceDocument(String sourceDocumentId) {

        RepositoryManager repositoryManager = repositoryManagerView.getRepositoryManager();

        if (repositoryManager.hasOpenRepository()) {
            Repository repository = repositoryManager.getFirstOpenRepository();

            SourceDocument sourceDocument = repository.getSourceDocument(sourceDocumentId);
            if (sourceDocument != null) {
                return openSourceDocument(sourceDocument, repository);
            }
        }

        return null;
    }

    public TaggerView openSourceDocument(SourceDocument sourceDocument, Repository repository) {

        menu.executeEntry(taggerManagerView);

        return taggerManagerView.openSourceDocument(sourceDocument, repository);
    }

    public String getTempDirectory() {
        return tempDirectory;
    }

    public BackgroundService getBackgroundService() {
        return backgroundService;
    }

    public <T> void submit(String caption, final ProgressCallable<T> callable,
            final ExecutionListener<T> listener) {
        logger.info("submitting job '" + caption + "' " + callable);
        getBackgroundService().submit(callable, new ExecutionListener<T>() {
            public void done(T result) {
                listener.done(result);
            };

            public void error(Throwable t) {
                listener.error(t);
            }
        }, new LogProgressListener());
    }

    public void openUserMarkupCollection(SourceDocument sourceDocument, UserMarkupCollection userMarkupCollection,
            Repository repository) {
        TaggerView taggerView = openSourceDocument(sourceDocument, repository);
        taggerManagerView.openUserMarkupCollection(taggerView, userMarkupCollection);

    }

    public void analyze(Corpus corpus, IndexedRepository repository) {
        menu.executeEntry(analyzerManagerView);
        analyzerManagerView.analyzeDocuments(corpus, repository);
    }

    public int addVisualization(Integer visualizationId, String caption,
            DistributionComputation distributionComputation,
            DistributionSelectionListener distributionSelectionListener) {

        menu.executeEntry(visualizationManagerView);

        return visualizationManagerView.addVisualization(visualizationId, caption, distributionComputation,
                distributionSelectionListener);
    }

    @Override
    public void close() {
        repositoryManagerView.getRepositoryManager().close();
        logger.info("application for user" + getUser() + " has been closed");
        if (repositoryOpened) {
            userManager.logout(this);
            repositoryOpened = false;
        }
        backgroundService.shutdown();
        super.close();
    }

    public void showAndLogError(String message, Throwable e) {
        logger.log(Level.SEVERE, "[" + getUser() + "]" + message, e);

        if (message == null) {
            message = "internal error";
        }
        if (Page.getCurrent() != null) {
            HTMLNotification.show("Error",
                    "An error has occurred!<br />"
                            + "We've been notified about this error and it will be fixed soon.<br />"
                            + "The underlying error message is:<br />" + message + "<br />" + e.getMessage(),
                    Type.ERROR_MESSAGE);
        }
    }

    public void openSourceDocument(SourceDocument sd, Repository repository, Range range) {
        TaggerView tv = openSourceDocument(sd, repository);
        tv.show(range);
    }

    public void addDoubleTree(List<KeywordInContext> kwics) {
        menu.executeEntry(visualizationManagerView);
        visualizationManagerView.addDoubleTree(kwics);
    }

    @Override
    public Object getUser() {
        return user;
    }

    public void setUser(Object newUser) {
        Object currentUser = this.user;
        this.user = newUser;

        propertyChangeSupport.firePropertyChange(CatmaApplicationEvent.userChange.name(), currentUser, newUser);
    }

    public MainMenu getMenu() {
        return menu;
    }

    @Override
    public void attach() {
        super.attach();
    }

    /**
     * @see CatmaApplicationEvent
     * @see PropertyChangeSupport#addPropertyChangeListener(String, PropertyChangeListener)
     */
    public void addPropertyChangeListener(CatmaApplicationEvent propertyName, PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(propertyName.name(), listener);
    }

    /**
     * @see CatmaApplicationEvent
     * @see PropertyChangeSupport#removePropertyChangeListener(String, PropertyChangeListener)
     */
    public void removePropertyChangeListener(CatmaApplicationEvent propertyName, PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(propertyName.name(), listener);
    }

}