Package tk.eclipse.plugin.wysiwyg

Source Code of tk.eclipse.plugin.wysiwyg.WYSIWYGHTMLEditor$UpdateSaveButtonTimerTask

package tk.eclipse.plugin.wysiwyg;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.StatusTextEvent;
import org.eclipse.swt.browser.StatusTextListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.internal.UIPlugin;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.texteditor.ITextEditor;
import org.jbpm.ui.DesignerLogger;
import org.jbpm.ui.common.model.FormNode;
import org.jbpm.ui.common.model.Variable;
import org.jbpm.ui.util.EditorUtils;

import tk.eclipse.plugin.ftl.FreemarkerUtil;
import tk.eclipse.plugin.htmleditor.HTMLPlugin;
import tk.eclipse.plugin.htmleditor.editors.HTMLConfiguration;
import tk.eclipse.plugin.htmleditor.editors.HTMLSourceEditor;
import tk.eclipse.plugin.vartag.VarTagUtil;

/**
* The WYSIWYG HTML editor using <a
* href="http://www.fckeditor.net/">FCKeditor</a>.
* <p>
* org.eclipse.ui.texteditor.BasicTextEditorActionContributor
* </p>
*/
public class WYSIWYGHTMLEditor extends MultiPageEditorPart implements StatusTextListener, IResourceChangeListener {
    private static final String PREFIX_SYNCHTML = "SYNCHTML:";

    private static final String PREFIX_HTML = "HTML:";

    private static final String PREFIX_STARTSYNC = "STARTSYNC";

    public static final int CLOSED = 197;

    private HTMLSourceEditor sourceEditor;

    private Browser browser;

    private boolean ftlFormat = true;

    private FormNode formNode;
    private List<String> lazyVariableNameList;

    private boolean dirty = false;

    private boolean browserLoaded = false;

    private static final Pattern pattern = Pattern.compile("^(.*?<(body|BODY).*?>)(.*?)(</(body|BODY)>.*?)$", Pattern.DOTALL);

    private Timer updateSaveButtonTimer = new Timer("updateSaveButtonTimer");
    private String savedHTML = "";

    private void syncBrowser2Editor() {
        if (browser != null) {
            browser.execute("getHTML(false)");
        }
    }

    protected synchronized boolean isBrowserLoaded() {
        return browserLoaded;
    }

    protected synchronized void setBrowserLoaded(boolean browserLoaded) {
        this.browserLoaded = browserLoaded;
    }

    public void setFormNode(FormNode formNode) {
        this.formNode = formNode;
    }

    public synchronized List<String> getLazyVariableNameList() {
        if (lazyVariableNameList == null) {
            lazyVariableNameList = new ArrayList<String>();
            for (Variable variable : getVariablesList(false)) {
                lazyVariableNameList.add(variable.getName());
            }
        }
        return lazyVariableNameList;
    }
   
    public List<Variable> getVariablesList(boolean onlyVariablesWithSpace) {
        if (formNode == null) {
            // This is because earlier access from web page (not user request)
            return new ArrayList<Variable>();
        }
        List<Variable> variableWithSwimlanes = new ArrayList<Variable>();
        for (Variable variable : formNode.getProcessDefinition().getVariablesList()) {
            if (onlyVariablesWithSpace || variable.getName().indexOf(" ") == -1) {
                variableWithSwimlanes.add(variable);
            }
        }
        for (String swimlaneName : formNode.getProcessDefinition().getSwimlaneNames()) {
            if (onlyVariablesWithSpace || swimlaneName.indexOf(" ") == -1) {
                variableWithSwimlanes.add(new Variable(swimlaneName)); // string
                                                                       // type
            }
        }
        return variableWithSwimlanes;
    }

    public Map<String, Variable> getVariablesMap(boolean includeVariablesWithSpace) {
        Map<String, Variable> variableWithSwimlanes = new HashMap<String, Variable>();
        // This is because earlier access from web page (not user request)
        if (formNode != null) {
            for (Variable variable : formNode.getProcessDefinition().getVariablesList()) {
                if (includeVariablesWithSpace || variable.getName().indexOf(" ") == -1) {
                    variableWithSwimlanes.put(variable.getName(), variable);
                }
            }
            for (String swimlaneName : formNode.getProcessDefinition().getSwimlaneNames()) {
                if (includeVariablesWithSpace || swimlaneName.indexOf(" ") == -1) {
                    variableWithSwimlanes.put(swimlaneName, new Variable(swimlaneName)); // string
                                                                                         // type
                }
            }
        }
        return variableWithSwimlanes;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Object getAdapter(Class adapter) {
        if (adapter == ITextEditor.class) {
            return sourceEditor;
        }
        return super.getAdapter(adapter);
    }

    public void resourceChanged(IResourceChangeEvent event) {
        if (sourceEditor != null && sourceEditor.getEditorInput() != null) {
            EditorUtils.closeEditorIfRequired(event, ((IFileEditorInput) sourceEditor.getEditorInput()).getFile(), this);
        }
    }

    private void syncEditor2Browser() {
        String html = getSourceDocumentHTML();
        Matcher matcher = pattern.matcher(html);
        if (matcher.find()) {
            html = matcher.group(3);
        }
        if (isFtlFormat()) {
            try {
                html = FreemarkerUtil.transformToHtml(getVariablesMap(true).keySet(), html);
            } catch (Exception e) {
                WYSIWYGPlugin.logError("ftl WYSIWYGHTMLEditor.syncEditor2Browser()", e);
            }
        }
        html = html.replaceAll("\r\n", "\n");
        html = html.replaceAll("\r", "\n");
        html = html.replaceAll("\n", "\\\\n");
        html = html.replaceAll("'", "\\\\'");
        if (browser != null) {
            browser.execute("setHTML('" + html + "')");
        }
    }

    @Override
    protected void pageChange(int newPageIndex) {
        if (newPageIndex == 1) {
            syncBrowser2Editor();
        } else if (newPageIndex == 0) {
            ConnectorServletHelper.sync();
            syncEditor2Browser();
        }
        super.pageChange(newPageIndex);
    }

    @Override
    protected void createPages() {
        sourceEditor = new HTMLSourceEditor(new HTMLConfiguration(HTMLPlugin.getDefault().getColorProvider()));
        int pageNumber = 0;
        try {
            browser = new Browser(getContainer(), SWT.NULL);
            browser.addStatusTextListener(this);
            browser.addOpenWindowListener(new BrowserWindowHelper(getContainer().getDisplay()));
            addPage(browser);
            setPageText(pageNumber++, WYSIWYGPlugin.getResourceString("wysiwyg.design.tab_name"));
        } catch (Throwable th) {
            DesignerLogger.logError(WYSIWYGPlugin.getResourceString("wysiwyg.design.create_error"), th);
        }
        try {
            addPage(sourceEditor, getEditorInput());
            setPageText(pageNumber++, WYSIWYGPlugin.getResourceString("wysiwyg.source.tab_name"));
        } catch (Exception ex) {
            DesignerLogger.logError(WYSIWYGPlugin.getResourceString("wysiwyg.source.create_error"), ex);
        }

        if (browser == null) {
            return;
        }
        ConnectorServletHelper.setBaseDir(sourceEditor.getFile().getParent());

        try {
            final Display display = Display.getCurrent();
            final ProgressMonitorDialog monitorDialog = new ProgressMonitorDialog(getSite().getShell());
            final IRunnableWithProgress runnable = new IRunnableWithProgress() {

                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    try {
                        monitor.beginTask(WYSIWYGPlugin.getResourceString("editor.task.init_wysiwyg"), 10);
                        WYSIWYGPlugin.getDefault().startWebServer(monitor, 9);
                        monitor.subTask(WYSIWYGPlugin.getResourceString("editor.subtask.waiting_init"));
                        display.asyncExec(new Runnable() {
                            public void run() {
                                monitorDialog.setCancelable(true);
                                browser.setUrl(WYSIWYGPlugin.getDefault().getEditorURL());
                            }
                        });
                        monitorDialog.setCancelable(true);
                        while (!isBrowserLoaded() && !monitor.isCanceled()) {
                            Thread.sleep(1000);
                        }
                        monitor.worked(1);
                        display.asyncExec(new Runnable() {
                            public void run() {
                                setActivePage(0);
                            }
                        });
                    } catch (Exception e) {
                        throw new InvocationTargetException(e);
                    } finally {
                        monitor.done();
                    }
                }
            };
            display.asyncExec(new Runnable() {
                public void run() {
                    try {
                        monitorDialog.run(true, false, runnable);
                    } catch (InvocationTargetException e) {
                        DesignerLogger.logError(WYSIWYGPlugin.getResourceString("wysiwyg.design.create_error"), e.getTargetException());
                    } catch (InterruptedException e) {
                        WYSIWYGPlugin.logError("Web editor page", e);
                    }
                }
            });
            savedHTML = getSourceDocumentHTML();
            savedHTML = removeRN(savedHTML);
        } catch (Exception e) {
            MessageDialog.openError(getContainer().getShell(), WYSIWYGPlugin.getResourceString("wysiwyg.design.create_error"), e.getCause().getMessage());
            WYSIWYGPlugin.logError("Web editor page", e);
        }
    }

    @Override
    public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
        super.init(site, editorInput);
        setPartName(editorInput.getName());
        ftlFormat = editorInput.getName().endsWith("ftl");
        ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
    }

    // Used from servlets
    public static WYSIWYGHTMLEditor getCurrent() {
        return (WYSIWYGHTMLEditor) UIPlugin.getDefault().getWorkbench().getWorkbenchWindows()[0].getActivePage().getActiveEditor();
    }

    private void setDirty(boolean dirty) {
        boolean changedDirtyState = this.dirty != dirty;
        this.dirty = dirty;
        if (changedDirtyState) {
            firePropertyChange(IEditorPart.PROP_DIRTY);
        }
    }

    @Override
    public boolean isDirty() {
        return dirty || sourceEditor.isDirty();
    }

    @Override
    public void doSave(IProgressMonitor monitor) {
        if (getActivePage() == 0) {
            syncBrowser2Editor();
        }
        sourceEditor.doSave(monitor);
        savedHTML = getSourceDocumentHTML();
        savedHTML = removeRN(savedHTML);
        if (formNode != null) {
            formNode.setDirty();
        }
        setDirty(false);
    }

    public boolean isFtlFormat() {
        return ftlFormat;
    }

    public void changed(StatusTextEvent event) {
        String text = event.text;
        if (text.startsWith(PREFIX_STARTSYNC)) {
            updateSaveButtonTimer.schedule(new UpdateSaveButtonTimerTask(), 5000, 5000);
        } else if (text.startsWith(PREFIX_HTML) && text.length() > PREFIX_HTML.length()) {
            String html = getDesignDocumentHTML(PREFIX_HTML, text);
            String oldContent = getSourceDocumentHTML();
            if (!oldContent.equals(html)) {
                sourceEditor.getDocumentProvider().getDocument(sourceEditor.getEditorInput()).set(html);
                setDirty(true);
            }
        } else if (text.startsWith(PREFIX_SYNCHTML) && text.length() > PREFIX_SYNCHTML.length()) {
            String html = getDesignDocumentHTML(PREFIX_SYNCHTML, text);
            html = removeRN(html);
            String diff = StringUtils.difference(savedHTML, html);
            boolean setDirty = (diff.length() != 0);
            if (setDirty != isDirty()) {
                setDirty(setDirty);
            }
        }
    }
   
    private String removeRN(String string) {
        string = string.replaceAll("\\n", "");
        string = string.replaceAll("\\r", "");
        return string;
    }

    private String getDesignDocumentHTML(String prefix, String statusText) {
        String html = statusText.substring(prefix.length());
        if (isFtlFormat()) {
            try {
                html = FreemarkerUtil.transformFromHtml(html, getLazyVariableNameList());
                Matcher matcher = pattern.matcher(html);
                if (matcher.find()) {
                    html = matcher.group(3);
                }
            } catch (Exception e) {
                DesignerLogger.logErrorWithoutDialog("freemarker html transform", e);
            }
        } else {
            // bug in closing customtag tag
            html = VarTagUtil.normalizeVarTags(html);
        }
        return html;
    }

    private String getSourceDocumentHTML() {
        return sourceEditor.getDocumentProvider().getDocument(sourceEditor.getEditorInput()).get();
    }

    @Override
    public boolean isSaveOnCloseNeeded() {
        if (getActivePage() == 0) {
            syncBrowser2Editor();
            return true;
        }
        return super.isSaveOnCloseNeeded();
    }

    @Override
    public boolean isSaveAsAllowed() {
        return false;
    }

    @Override
    public void doSaveAs() {
    }

    @Override
    public void dispose() {
        updateSaveButtonTimer.cancel();
        firePropertyChange(CLOSED);
        ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
        super.dispose();
    }

    private class UpdateSaveButtonTimerTask extends TimerTask {

        @Override
        public void run() {
            try {
                if (getActivePage() == 0 && browser != null) {
                    Display.getDefault().asyncExec(new Runnable() {
                        public void run() {
                            try {
                                browser.execute("getHTML(true)");
                            } catch (Throwable e) {
                                // ignore
                            }
                        }
                    });
                }
            } catch (Throwable e) {
                // ignore SWTException: Widget is disposed
            }
        }

    }
}
TOP

Related Classes of tk.eclipse.plugin.wysiwyg.WYSIWYGHTMLEditor$UpdateSaveButtonTimerTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.