de.thischwa.pmcms.gui.BrowserManager.java Source code

Java tutorial

Introduction

Here is the source code for de.thischwa.pmcms.gui.BrowserManager.java

Source

/*******************************************************************************
 * Poor Man's CMS (pmcms) - A very basic CMS generating static html pages.
 * http://poormans.sourceforge.net
 * Copyright (C) 2004-2013 by Thilo Schwarz
 * 
 * == BEGIN LICENSE ==
 * 
 * Licensed under the terms of any of the following licenses at your
 * choice:
 * 
 *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 *    http://www.gnu.org/licenses/lgpl.html
 * 
 *  - Mozilla Public License Version 1.1 or later (the "MPL")
 *    http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * == END LICENSE ==
 ******************************************************************************/
package de.thischwa.pmcms.gui;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.CloseWindowListener;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.OpenWindowListener;
import org.eclipse.swt.browser.TitleEvent;
import org.eclipse.swt.browser.TitleListener;
import org.eclipse.swt.browser.VisibilityWindowListener;
import org.eclipse.swt.browser.WindowEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import de.thischwa.pmcms.Constants;
import de.thischwa.pmcms.conf.InitializationManager;
import de.thischwa.pmcms.conf.resource.ImageHolder;
import de.thischwa.pmcms.exception.RenderingException;
import de.thischwa.pmcms.gui.treeview.TreeViewManager;
import de.thischwa.pmcms.livecycle.SiteHolder;
import de.thischwa.pmcms.model.IRenderable;
import de.thischwa.pmcms.model.InstanceUtil;
import de.thischwa.pmcms.model.domain.pojo.APoormansObject;
import de.thischwa.pmcms.model.domain.pojo.ASiteResource;
import de.thischwa.pmcms.model.tool.SitePersister;
import de.thischwa.pmcms.server.Action;
import de.thischwa.pmcms.server.ContextUtil;
import de.thischwa.pmcms.tool.Link;
import de.thischwa.pmcms.tool.swt.SWTUtils;
import de.thischwa.pmcms.view.ViewMode;
import de.thischwa.pmcms.view.renderer.VelocityRenderer;

/**
 * Manage the browser component.
 * 
 * @author Thilo Schwarz
 */
@Component
public class BrowserManager {
    private static Logger logger = Logger.getLogger(BrowserManager.class);
    private Browser mainBrowser = null;
    private static String browserType = "n/a";

    @Autowired
    private VelocityRenderer velocityRenderer;
    @Autowired
    private TreeViewManager treeViewManager;
    @Autowired
    private MainWindow mainWindow;

    @Autowired
    private SiteHolder siteHolder;

    private boolean isXulRunnerEnabled;

    private Shell parentShell;

    @Value("${pmcms.xulrunner}")
    private String xulRunnerProp;

    @Value("${baseurl}")
    private String baseUrl;

    public void init(final Composite parent) {
        logger.debug("Entered init!");
        this.isXulRunnerEnabled = (xulRunnerProp != null && Boolean.parseBoolean(xulRunnerProp));
        mainBrowser = getBrowser(parent);
        parentShell = parent.getShell();
        initializeBrowser(parentShell, parent.getDisplay(), mainBrowser);
    }

    private void initializeBrowser(final Shell shell, final Display display, final Browser browser) {
        final String urlToIgnore = "about:blank";
        final TreeViewManager treeViewManager = this.treeViewManager;

        browser.addLocationListener(new LocationListener() {
            @Override
            public void changing(LocationEvent event) {
                if (!event.location.equals(urlToIgnore))
                    logger.debug("url is changing to: " + event.location);
            }

            @Override
            public void changed(LocationEvent event) {
                if (!event.location.equals(urlToIgnore)) {
                    String url = event.location;
                    logger.debug("url has changed to: " + url);
                    Link link = InitializationManager.getBean(Link.class);
                    link.init(event.location);
                    if (!link.isPoormansRequest())
                        return;
                    String idParam = link.getParameter("id");
                    if (idParam != null && idParam.equals(APoormansObject.UNSET_VALUE + ""))
                        idParam = null;
                    APoormansObject<?> po = StringUtils.isBlank(idParam) ? null : ContextUtil.getpo(link);
                    // synchronizing with the tree view
                    treeViewManager.fillAndExpands(po);

                    // persist the site, if a poormans object was saved    
                    if (url.endsWith(Constants.LINK_IDENTICATOR_SAVE)) {
                        try {
                            SitePersister.write(siteHolder.getSite());
                        } catch (IOException e) {
                            show(e);
                        }
                    }
                }
            }
        });

        // visibility handling
        browser.addVisibilityWindowListener(new VisibilityWindowListener() {
            @Override
            public void hide(WindowEvent event) {
                Browser browser = (Browser) event.widget;
                Shell shell = browser.getShell();
                shell.setVisible(false);
            }

            @Override
            public void show(WindowEvent event) {
                Browser browser = (Browser) event.widget;
                final Shell shell = browser.getShell();
                if (event.location != null)
                    shell.setLocation(event.location);
                if (event.size != null) {
                    Point size = event.size;
                    shell.setSize(shell.computeSize(size.x, size.y));
                }
                shell.open();
            }
        });

        // setting title of the shell
        browser.addTitleListener(new org.eclipse.swt.browser.TitleListener() {
            @Override
            public void changed(org.eclipse.swt.browser.TitleEvent event) {
                final Browser tmpBrowser = (Browser) event.getSource();
                if (mainBrowser.equals(tmpBrowser) && StringUtils.isNotBlank(event.title)) {
                    mainWindow.setTitle(event.title);
                }
            }
        });

        // BEGIN popup handling
        browser.addOpenWindowListener(new OpenWindowListener() {
            @Override
            public void open(WindowEvent event) {
                Shell shell = new Shell(display, SWT.APPLICATION_MODAL | SWT.CLOSE);
                shell.setImages(new Image[] { ImageHolder.SHELL_ICON_SMALL, ImageHolder.SHELL_ICON_BIG });
                shell.setLayout(new FillLayout());
                SWTUtils.center(shell, parentShell.getBounds());
                Browser browser = getBrowser(shell);
                initializeBrowser(shell, display, browser);
                final Browser tempBrowser = browser;

                browser.addTitleListener(new TitleListener() { // set title for the popup
                    @Override
                    public void changed(TitleEvent event) {
                        tempBrowser.getShell().setText(event.title);
                    }
                });

                browser.addVisibilityWindowListener(new VisibilityWindowListener() {
                    @Override
                    public void hide(WindowEvent event) {
                        Browser browser = (Browser) event.widget;
                        Shell shell = browser.getShell();
                        shell.setVisible(false);
                    }

                    @Override
                    public void show(WindowEvent event) {
                        final Browser browser = (Browser) event.widget;
                        Shell shell = browser.getShell();
                        if (event.location != null)
                            shell.setLocation(event.location);
                        if (event.size != null) {
                            Point size = event.size;
                            // hack for bug with too big of safari popups
                            if (StringUtils.containsIgnoreCase(browserType, "webkit")
                                    && (size.x > parentShell.getSize().x || size.y > parentShell.getSize().y)) {
                                size.x = parentShell.getSize().x - 50;
                                size.y = parentShell.getSize().y - 50;
                                shell.setLocation(parentShell.getLocation().x + 15,
                                        parentShell.getLocation().y + 15);
                                shell.setSize(shell.computeSize(size.x, size.y));
                            } else
                                shell.setSize(shell.computeSize(size.x, size.y));
                        }
                        shell.open();
                    }
                });
                event.browser = browser;
            }
        });
        // END popup handling

        browser.addCloseWindowListener(new CloseWindowListener() {
            @Override
            public void close(WindowEvent event) {
                Browser browser = (Browser) event.widget;
                Shell shell = browser.getShell();
                shell.close();
            }
        });
    }

    /**
     * Wrapper for setUrl of the SWT browser.
     */
    public void setUrl(String url) {
        mainBrowser.setUrl(url);
    }

    public void view(final APoormansObject<?> po, ViewMode viewMode) {
        logger.debug(String.format("Show %s(%d), %s", po, po.getId(), viewMode));
        try {
            switch (viewMode) {
            case EDIT:
                String url = Link.buildUrl(baseUrl, po, Action.EDIT);
                mainBrowser.setUrl(url);
                break;
            default: // must be PREVIEW
                String html;
                if (InstanceUtil.isRenderable(po))
                    html = velocityRenderer.render((IRenderable) po, viewMode);
                else if (InstanceUtil.isSiteResource(po))
                    html = velocityRenderer.render((ASiteResource) po);
                else {
                    logger.warn(
                            String.format("Don't know how to render [%s] in mode %s!", po, viewMode.toString()));
                    return;
                }
                mainBrowser.setText(html);
                break;
            }
        } catch (RenderingException e) {
            show(e);
        }
    }

    public void show(Throwable e) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        show(sw.toString());
    }

    public void show(String msg) {
        mainBrowser.setText(String.format("<h1 style=\"color: red;\">%s</h1>", msg));
    }

    public void showHelp() {
        mainBrowser.setUrl(baseUrl + "help/index.html");
    }

    /**
     * Simple factory method to initialize the browser with respect of the property 'pmcms.xulrunner'. If this property is
     * <code>true</code> a mozilla browser will be initialized. (Depending on the existence of the directory 'xulrunner' inside the 
     * application directory, the required system property is set.) Otherwise the swt standard browser of the underlying OS.
     * 
     * @param parent Parent component of the browser.
     * @return Initialized browser.
     */
    private Browser getBrowser(final Composite parent) {
        Browser browser;
        if (isXulRunnerEnabled) {
            logger.info("XULRUNNER property is set, trying to get a mozilla browser!");
            File xulDir = new File(Constants.APPLICATION_DIR, "xulrunner");
            if (xulDir.exists()) {
                logger.info("Found local XULRUNNER. Set required system property.");
                System.setProperty("org.eclipse.swt.browser.XULRunnerPath", xulDir.getAbsolutePath());
            }
            browser = new Browser(parent, SWT.MOZILLA);
        } else
            browser = new Browser(parent, SWT.NONE);
        browserType = browser.getBrowserType();
        logger.info("Constructed browser: " + browserType);
        return browser;
    }

    public static String getBrowserType() {
        return browserType;
    }
}