Package org.webharvest.gui

Source Code of org.webharvest.gui.ConfigPanel$ViewerActionListener

/*  Copyright (c) 2006-2007, Vladimir Nikic
    All rights reserved.

    Redistribution and use of this software in source and binary forms,
    with or without modification, are permitted provided that the following
    conditions are met:

    * Redistributions of source code must retain the above
      copyright notice, this list of conditions and the
      following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the
      following disclaimer in the documentation and/or other
      materials provided with the distribution.

    * The name of Web-Harvest may not be used to endorse or promote
      products derived from this software without specific prior
      written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

    You can contact Vladimir Nikic by sending e-mail to
    nikic_vladimir@yahoo.com. Please include the word "Web-Harvest" in the
    subject line.
*/
package org.webharvest.gui;

import org.webharvest.definition.BaseElementDef;
import org.webharvest.definition.ConstantDef;
import org.webharvest.definition.IElementDef;
import org.webharvest.definition.ScraperConfiguration;
import org.webharvest.runtime.Scraper;
import org.webharvest.runtime.ScraperRuntimeListener;
import org.webharvest.runtime.processors.BaseProcessor;
import org.webharvest.runtime.web.HttpClientManager;
import org.webharvest.utils.Constants;
import org.webharvest.gui.component.*;
import org.xml.sax.InputSource;
import org.apache.log4j.Logger;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.BadLocationException;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.URL;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

/**
* Single panel containing XML configuration.
* It is part of multiple-document interface where several such instances may exist at
* the same time.
*/
public class ConfigPanel extends JPanel implements ScraperRuntimeListener, TreeSelectionListener, CaretListener {

    private static final String VIEW_RESULT_AS_TEXT = "View result as text";
    private static final String VIEW_RESULT_AS_XML = "View result as XML";
    private static final String VIEW_RESULT_AS_HTML = "View result as HTML";
    private static final String VIEW_RESULT_AS_IMAGE = "View result as image";
    private static final String VIEW_RESULT_AS_LIST = "View result as list";

    // basic skeletion for new opened configuration
    private static final String BASIC_CONFIG_SKELETION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<config>\n\t\n</config>";

    private XmlEditorScrollPane xmlEditorScrollPane;

    // loger for this configuration panel
    private Logger logger;

    /**
     * Action listener for view menu items
     */
    private class ViewerActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String actionCommand = e.getActionCommand();

            int viewType = ViewerFrame.TEXT_VIEW;
            if ( VIEW_RESULT_AS_HTML.equalsIgnoreCase(actionCommand) ) {
                viewType = ViewerFrame.HTML_VIEW;
            } else if ( VIEW_RESULT_AS_IMAGE.equalsIgnoreCase(actionCommand) ) {
                viewType = ViewerFrame.IMAGE_VIEW;
            } else if ( VIEW_RESULT_AS_LIST.equalsIgnoreCase(actionCommand) ) {
                viewType = ViewerFrame.LIST_VIEW;
            } else if ( VIEW_RESULT_AS_XML.equalsIgnoreCase(actionCommand) ) {
                viewType = ViewerFrame.XML_VIEW;
            }

            DefaultMutableTreeNode treeNode;

            TreePath path = tree.getSelectionPath();
            if (path != null) {
                treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
                if (treeNode != null) {
                    Object userObject = treeNode.getUserObject();
                    if (userObject instanceof TreeNodeInfo) {
                        TreeNodeInfo treeNodeInfo = (TreeNodeInfo) userObject;
                        Map properties = treeNodeInfo.getProperties();
                        Object value = properties == null ? null : properties.get(Constants.VALUE_PROPERTY_NAME);
                        final ViewerFrame viewerFrame = new ViewerFrame( scraper, Constants.VALUE_PROPERTY_NAME, value, treeNodeInfo, viewType );
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                viewerFrame.setVisible(true);
                                viewerFrame.toFront();
                            }
                        });
                    }
                }
            }
        }
    }

    private ConfigDocument configDocument;

    // initial configuration parameters
    private Map initParams = null;

    private Ide ide;

    private ScraperConfiguration scraperConfiguration;

    private DefaultMutableTreeNode topNode;
    private DefaultTreeModel treeModel;
    private TreeNodeInfo selectedNodeInfo;
    private JTextArea logTextArea;
    private Map nodeInfos = new Hashtable();
    private NodeRenderer nodeRenderer = new NodeRenderer();

    private JSplitPane bottomSplitter;
    private JSplitPane leftSplitter;
    private JSplitPane leftView;
    private JScrollPane bottomView;
    private int leftDividerLocation = 0;
    private int bottomDividerLocation = 0;
   
    private XmlTextPane xmlPane;
    private JTree tree;
    private Scraper scraper;
    private PropertiesGrid propertiesGrid;

    // tree popup menu items
    private JMenuItem textViewMenuItem;
    private JMenuItem xmlViewMenuItem;
    private JMenuItem htmlViewMenuItem;
    private JMenuItem imageViewMenuItem;
    private JMenuItem listViewMenuItem;

    // Log area popup menu items
    private JMenuItem logSelectAllMenuItem;
    private JMenuItem logClearAllMenuItem;

    /**
     * Constructor of the panel - initializes parent Ide instance and name of the document.
     * @param ide
     * @param name
     */
    public ConfigPanel(final Ide ide, String name) {
        super(new BorderLayout());

        this.ide = ide;

        this.topNode = new DefaultMutableTreeNode();
        this.treeModel = new DefaultTreeModel(this.topNode);

        this.tree = new JTree(this.treeModel);
        this.tree.setRootVisible(false);
        this.tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        ToolTipManager.sharedInstance().registerComponent(this.tree);
        this.tree.setCellRenderer(this.nodeRenderer);
        tree.setShowsRootHandles(true);
        this.tree.addTreeSelectionListener(this);

        // defines pop menu for the tree
        final JPopupMenu treePopupMenu = new WHPopupMenu();
        JMenuItem menuItem = new MenuElements.MenuItem("Locate in source");
        menuItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                TreePath path = tree.getSelectionPath();
                if (path != null) {
                    locateInSource( (DefaultMutableTreeNode) path.getLastPathComponent(), false );
                    try {
                        int startPos = xmlPane.getCaretPosition();
                        String content = xmlPane.getDocument().getText( 0, xmlPane.getDocument().getLength() );
                        if (content != null && content.length() > startPos) {
                            int closingIndex = content.indexOf('>', startPos);
                            if (closingIndex > startPos) {
                                xmlPane.select(startPos, closingIndex + 1);
                            }
                        }
                    } catch (BadLocationException e1) {
                    }
                    xmlPane.requestFocus();
                }
            }
        });
        treePopupMenu.add(menuItem);

        treePopupMenu.addSeparator();

        ViewerActionListener viewContentActionListener = new ViewerActionListener();

        textViewMenuItem = new MenuElements.MenuItem(VIEW_RESULT_AS_TEXT);
        textViewMenuItem.addActionListener(viewContentActionListener);
        treePopupMenu.add(textViewMenuItem);

        xmlViewMenuItem = new MenuElements.MenuItem(VIEW_RESULT_AS_XML);
        xmlViewMenuItem.addActionListener(viewContentActionListener);
        treePopupMenu.add(xmlViewMenuItem);

        htmlViewMenuItem = new MenuElements.MenuItem(VIEW_RESULT_AS_HTML);
        htmlViewMenuItem.addActionListener(viewContentActionListener);
        treePopupMenu.add(htmlViewMenuItem);

        imageViewMenuItem = new MenuElements.MenuItem(VIEW_RESULT_AS_IMAGE);
        imageViewMenuItem.addActionListener(viewContentActionListener);
        treePopupMenu.add(imageViewMenuItem);

        listViewMenuItem = new MenuElements.MenuItem(VIEW_RESULT_AS_LIST);
        listViewMenuItem.addActionListener(viewContentActionListener);
        treePopupMenu.add(listViewMenuItem);

        treePopupMenu.setOpaque(true);
        treePopupMenu.setLightWeightPopupEnabled(true);

        this.tree.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent e) {
                if ( e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3 ) {
                    TreePath path = tree.getClosestPathForLocation( e.getX(), e.getY() );
                    if (path != null) {
                        tree.setSelectionPath(path);
                    }
                    treePopupMenu.show( (JComponent)e.getSource(), e.getX(), e.getY() );
                }
            }
        });

        JScrollPane treeView = new JScrollPane(this.tree);
        treeView.setBorder(new EmptyBorder(0, 0, 0, 0));

        // Create the XML editor pane.
        this.xmlPane = new XmlTextPane();
        this.xmlPane.addCaretListener(this);

        final AutoCompleter autoCompleter = new AutoCompleter(this.xmlPane);
        this.xmlPane.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if ( e.getKeyCode() == KeyEvent.VK_SPACE ) {
                    if ( (e.getModifiers() & KeyEvent.CTRL_MASK) != 0 ) {
                        autoCompleter.autoComplete();
                    }
                }
            }
        });

        xmlPane.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent e) {
                if ( e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3 ) {
                    xmlPane.setLastClickPoint(e.getPoint());
                    ide.getEditorPopupMenu().show( (JComponent)e.getSource(), e.getX(), e.getY() );
                }
            }
        });

        // creates document for this configuration panel
        this.configDocument = new ConfigDocument(this, name);

        // initialize document content
        try {
            this.configDocument.load(BASIC_CONFIG_SKELETION);
        } catch (IOException e) {
            GuiUtils.showErrorMessage( e.getMessage() );
        }

        this.xmlEditorScrollPane = new XmlEditorScrollPane( this.xmlPane, this.ide.getSettings().isShowLineNumbersByDefault() );

        this.propertiesGrid = new PropertiesGrid(this);
        JScrollPane propertiesView = new JScrollPane(propertiesGrid);
        propertiesView.setBorder(new EmptyBorder(0, 0, 0, 0));
        propertiesView.getViewport().setBackground(Color.white);
        this.leftView = new ProportionalSplitPane(JSplitPane.VERTICAL_SPLIT);
        this.leftView.setResizeWeight(0.8d);
        this.leftView.setBorder(null);
        this.leftView.setTopComponent(treeView);
        this.leftView.setBottomComponent(propertiesView);
        this.leftView.setDividerLocation(0.8d);
        this.leftView.setDividerSize(Constants.SPLITTER_WIDTH);
//        this.leftView.setDividerSize(Constants.SPLITTER_WIDTH);

        //Add the scroll panes to a split pane.
        leftSplitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        leftSplitter.setBorder(null);
        leftSplitter.setLeftComponent(leftView);
        leftSplitter.setRightComponent( this.xmlEditorScrollPane );
        leftSplitter.setDividerSize(Constants.SPLITTER_WIDTH);

        leftSplitter.setDividerLocation(250);

//        JPanel bottomPanel = new JPanel( new BorderLayout() );
        logTextArea = new JTextArea();
        logTextArea.setFont( new Font("Courier New", Font.PLAIN, 11) );
        logTextArea.setEditable(false);

        // defines pop menu for the log area
        final JPopupMenu logPopupMenu = new WHPopupMenu();

        logSelectAllMenuItem = new MenuElements.MenuItem("Select All");
        logSelectAllMenuItem.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                logTextArea.requestFocus();
                logTextArea.selectAll();
            }
        });
        logPopupMenu.add(logSelectAllMenuItem);

        logClearAllMenuItem = new MenuElements.MenuItem("Clear All");
        logClearAllMenuItem.addActionListener( new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                logTextArea.setText("");
            }
        });
        logPopupMenu.add(logClearAllMenuItem);

        logTextArea.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent e) {
                if ( e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3 ) {
                    String text = logTextArea.getText();
                    logClearAllMenuItem.setEnabled( text != null && !"".equals(text) );
                    logSelectAllMenuItem.setEnabled( text != null && !"".equals(text) );
                    logPopupMenu.show( (JComponent)e.getSource(), e.getX(), e.getY() );
                }
            }
        });

        this.logger = Logger.getLogger(this.toString() + System.currentTimeMillis());
        this.logger.addAppender( new TextAreaAppender(this.logTextArea) );

//        bottomPanel.add(logTextArea , BorderLayout.CENTER );

        bottomSplitter = new ProportionalSplitPane(JSplitPane.VERTICAL_SPLIT);
        bottomSplitter.setResizeWeight(1.0d);
        bottomSplitter.setBorder(null);
        bottomSplitter.setTopComponent(leftSplitter);
        bottomSplitter.setDividerSize(Constants.SPLITTER_WIDTH);
        bottomView = new JScrollPane(logTextArea);
        bottomView.setBorder(new EmptyBorder(0, 0, 0, 0));
        bottomSplitter.setBottomComponent(this.bottomView);
        bottomSplitter.setDividerLocation(0.8d);


        this.add(bottomSplitter, BorderLayout.CENTER);

        if ( !ide.getSettings().isShowHierarchyByDefault() ) {
            showHierarchy();
        }

        if ( !ide.getSettings().isShowLogByDefault() ) {
            showLog();
        }

        updateControls();
    }

    /**
     * Occures whenever caret position is changed inside editor
     * @param e
     */
    public void caretUpdate(CaretEvent e) {
        ide.updateGUI();
    }

    private void updateControls() {
        boolean viewAllowed = false;

        if (this.scraper != null) {
            viewAllowed = this.scraper.getStatus() != Scraper.STATUS_READY;
        }

        this.textViewMenuItem.setEnabled(viewAllowed);
        this.xmlViewMenuItem.setEnabled(viewAllowed);
        this.htmlViewMenuItem.setEnabled(viewAllowed);
        this.imageViewMenuItem.setEnabled(viewAllowed);
        this.listViewMenuItem.setEnabled(viewAllowed);
    }

    private void releaseScraper() {
        if (scraper != null) {
            scraper.dispose();
            scraper = null;
        }
    }

    /** Required by TreeSelectionListener interface. */
    public void valueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        if (node == null) {
            return;
        }

        Object userObject =  node.getUserObject();
        if (userObject instanceof TreeNodeInfo) {
            this.selectedNodeInfo = (TreeNodeInfo) userObject;
            PropertiesGridModel model =  this.propertiesGrid.getPropertiesGridModel();
            if (model != null) {
                model.setProperties( this.selectedNodeInfo.getProperties(), this.selectedNodeInfo );
            }
        }
    }

    /**
     * Recursively traverses the configuration and creates visual tree representation.
     * @param root
     * @param defs
     */
    private void createNodes(DefaultMutableTreeNode root, IElementDef[] defs) {
        if (defs != null) {
            for (int i = 0; i < defs.length; i++) {
                IElementDef elementDef = defs[i];
                // constant text is not interesting to be in the visual tree
                if ( !(elementDef instanceof ConstantDef) ) {
                    TreeNodeInfo treeNodeInfo = new TreeNodeInfo(elementDef);
                    this.nodeInfos.put( treeNodeInfo.getElementDef(), treeNodeInfo );
                    DefaultMutableTreeNode node = treeNodeInfo.getNode();
                    this.treeModel.insertNodeInto(node, root, root.getChildCount());
                    createNodes( node, elementDef.getOperationDefs() );
                }
            }
        }
    }

    /**
     * Loads configuration from the specified source.
     * @param source CAn be instance of File, URL or String
     */
    public void loadConfig(Object source) {
        try {
            if (source instanceof URL) {
                this.configDocument.load((URL)source);
            } else if (source instanceof File) {
                this.configDocument.load((File)source);
            } else {
                this.configDocument.load(source == null ? "" : source.toString());
            }
           
            refreshTree();
            InputSource in = new InputSource(new StringReader(xmlPane.getText()));
            ScraperConfiguration scraperConfiguration = new ScraperConfiguration(in);
            setScraperConfiguration(scraperConfiguration);
        } catch (IOException e) {
            GuiUtils.showErrorMessage( e.getMessage() );
        }
    }

    /**
     * Refreshes tree view.
     * @return
     */
    public boolean refreshTree() {
        releaseScraper();
        xmlPane.clearMarkerLine();
        xmlPane.clearErrorLine();
        xmlPane.clearStopDebugLine();
        updateControls();

        String xmlContent = this.xmlPane.getText();
        InputSource in = new InputSource( new StringReader(xmlContent) );
        try {
            ScraperConfiguration scraperConfiguration = new ScraperConfiguration(in);
            scraperConfiguration.setSourceFile( this.configDocument.getFile() );
            scraperConfiguration.setUrl( this.configDocument.getUrl() );

            setScraperConfiguration(scraperConfiguration);

            ide.setTabIcon(this, null);
        } catch(Exception e) {
            e.printStackTrace();

            String errorMessage = e.getMessage();

            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            this.logger.error(errorMessage + "\n" + writer.getBuffer().toString());
           
            ide.setTabIcon(this, ResourceManager.SMALL_ERROR_ICON);
            GuiUtils.showErrorMessage(errorMessage);
            return false;
        }

        return true;
    }

    private void setScraperConfiguration(ScraperConfiguration scraperConfiguration) {
        this.scraperConfiguration = scraperConfiguration;

        java.util.List operationDefs = scraperConfiguration.getOperations();
        IElementDef[] defs = new IElementDef[operationDefs.size()];
        Iterator it = operationDefs.iterator();
        int index = 0;
        while (it.hasNext()) {
            defs[index++] = (IElementDef) it.next();
        }

        this.topNode.removeAllChildren();
        this.nodeInfos.clear();
        createNodes(this.topNode, defs);
        this.treeModel.reload();
        expandTree();
    }

    /**
     * Expands whole tree.
     */
    private void expandTree() {
        for (int row = 0; row < tree.getRowCount(); row++) {
            tree.expandRow(row);
        }
    }

    public void onNewProcessorExecution(Scraper scraper, BaseProcessor processor) {
        BaseElementDef elementDef = processor.getElementDef();
        if (elementDef != null) {
            TreeNodeInfo nodeInfo = (TreeNodeInfo) this.nodeInfos.get(elementDef);
            if (nodeInfo != null) {
                nodeInfo.increaseExecutionCount();
                setExecutingNode(nodeInfo);
                int lineNumber = locateInSource( nodeInfo.getNode(), true ) - 1;
                if (xmlPane.getBreakpoints().isThereBreakpoint(lineNumber)) {
                    scraper.pauseExecution();
                    xmlPane.clearMarkerLine();
                    xmlPane.setStopDebugLine(lineNumber);
                    ide.setTabIcon(ConfigPanel.this, ResourceManager.SMALL_BREAKPOINT_ICON);
                } else if ( ide.getSettings().isDynamicConfigLocate() ) {
                    xmlPane.setMarkerLine(lineNumber);
                    xmlPane.repaint();
                }
            }
        }
    }

    public void onExecutionStart(Scraper scraper) {
        xmlPane.clearStopDebugLine();
        xmlPane.clearErrorLine();
        xmlPane.clearMarkerLine();
        updateControls();
        this.ide.updateGUI();
    }

    public void onExecutionContinued(Scraper scraper) {
        xmlPane.clearStopDebugLine();
        xmlPane.clearErrorLine();
        xmlPane.clearMarkerLine();
        this.ide.updateGUI();
    }

    public void onExecutionPaused(Scraper scraper) {
        this.ide.updateGUI();
    }

    public void onExecutionEnd(Scraper scraper) {
        final Settings settings = ide.getSettings();
        if ( settings.isDynamicConfigLocate() ) {
            this.xmlPane.setEditable(true);
        }

        int status = scraper.getStatus();
        final String message = scraper.getMessage();
       
        if (status == Scraper.STATUS_FINISHED) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    ide.setTabIcon(ConfigPanel.this, ResourceManager.SMALL_FINISHED_ICON);
                    if (settings.isShowFinishDialog()) {
                        GuiUtils.showInfoMessage("Configuration \"" + configDocument.getName() + "\" finished execution.");
                    }
                }
            });
        } else if (status == Scraper.STATUS_STOPPED) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    GuiUtils.showWarningMessage("Configuration \"" + configDocument.getName() + "\" aborted by user!");
                    ide.setTabIcon(ConfigPanel.this, ResourceManager.SMALL_FINISHED_ICON);
                }
            });
        } else if ( status == Scraper.STATUS_EXIT && message != null && !"".equals(message.trim()) ) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    GuiUtils.showWarningMessage("Configuration exited: " + message);
                    ide.setTabIcon(ConfigPanel.this, ResourceManager.SMALL_FINISHED_ICON);
                }
            });
        }

        // refresh last executing node
        TreeNodeInfo previousNodeInfo = this.nodeRenderer.getExecutingNodeInfo();
        setExecutingNode(null);
        if (previousNodeInfo != null) {
            this.treeModel.nodeChanged( previousNodeInfo.getNode() );
        }

        xmlPane.clearMarkerLine();
        xmlPane.clearStopDebugLine();

        // update GUI controls
        this.ide.updateGUI();

        // releases scraper in order help garbage collector
//        releaseScraper();
    }

    public void onProcessorExecutionFinished(Scraper scraper, BaseProcessor processor, Map properties) {
        BaseElementDef elementDef = processor.getElementDef();
        if (elementDef != null) {
            TreeNodeInfo nodeInfo = (TreeNodeInfo) this.nodeInfos.get(elementDef);
            if (nodeInfo != null) {
                nodeInfo.setProperties(properties);
                if ( nodeInfo == this.selectedNodeInfo ) {
                    PropertiesGridModel model =  this.propertiesGrid.getPropertiesGridModel();
                    if (model != null) {
                        model.setProperties( nodeInfo.getProperties(), nodeInfo );
                    }
                }

                java.util.List syncViews = nodeInfo.getSynchronizedViews();
                if (syncViews != null) {
                    for (int i = 0; i < syncViews.size(); i++) {
                        ViewerFrame viewerFrame = (ViewerFrame) syncViews.get(i);
                        viewerFrame.setValue(properties);
                    }
                }
            }
        }
    }

    public void onExecutionError(Scraper scraper, Exception e) {
        final Settings settings = ide.getSettings();
        if ( settings.isDynamicConfigLocate() ) {
            this.xmlPane.setEditable(true);
        }

        markException(e);
        String errorMessage = e.getMessage();

        StringWriter writer = new StringWriter();
        e.printStackTrace(new PrintWriter(writer));
        if (this.scraper != null) {
            this.scraper.getLogger().error(errorMessage + "\n" + writer.getBuffer().toString());
        }

        if (settings.isShowFinishDialog()) {
            GuiUtils.showErrorMessage(errorMessage);
        }
       
        this.ide.setTabIcon(this, ResourceManager.SMALL_ERROR_ICON);
        this.ide.updateGUI();

        xmlPane.clearMarkerLine();
        xmlPane.clearStopDebugLine();

        // releases scraper in order to help garbage collector
//        releaseScraper();
    }

    private void setExecutingNode(TreeNodeInfo nodeInfo) {
        TreeNodeInfo previousNodeInfo = this.nodeRenderer.getExecutingNodeInfo();
        if (previousNodeInfo != null) {
            this.treeModel.nodeChanged( previousNodeInfo.getNode() );
        }
        this.nodeRenderer.setExecutingNodeInfo(nodeInfo);
        if (nodeInfo != null) {
            this.treeModel.nodeChanged( nodeInfo.getNode() );
        }
    }

    public void markException(Exception e) {
        this.nodeRenderer.markException(e);
        TreeNodeInfo treeNodeInfo = this.nodeRenderer.getExecutingNodeInfo();
        if (treeNodeInfo != null) {
            this.treeModel.nodeChanged( treeNodeInfo.getNode() );
            int line = locateInSource( treeNodeInfo.getNode(), true ) - 1;
            xmlPane.setErrorLine(line);
        }
    }

    public void runConfiguration() {
        if ( this.scraper != null && this.scraper.getStatus() == Scraper.STATUS_PAUSED ) {
            synchronized (this.scraper) {
                this.scraper.notifyAll();
            }

            ide.setTabIcon(this, ResourceManager.SMALL_RUN_ICON);
        } else if ( this.scraper == null || this.scraper.getStatus() != Scraper.STATUS_RUNNING ) {
            boolean ok = refreshTree();
            if (ok) {
                Settings settings = ide.getSettings();
                this.scraper = new Scraper(this.scraperConfiguration, settings.getWorkingPath());
                this.scraper.addVariablesToContext(initParams);
                if ( settings.isProxyEnabled() ) {
                    HttpClientManager httpClientManager = scraper.getHttpClientManager();

                    int proxyPort = settings.getProxyPort();
                    String proxyServer = settings.getProxyServer();
                    if (proxyPort > 0) {
                        httpClientManager.setHttpProxy(proxyServer, proxyPort);
                    } else {
                    httpClientManager.setHttpProxy(proxyServer);
                  }

                    if ( settings.isProxyAuthEnabled() ) {
                        String ntlmHost = settings.isNtlmAuthEnabled() ?  settings.getNtlmHost() : null;
                        String ntlmDomain = settings.isNtlmAuthEnabled() ?  settings.getNtlmDomain() : null;
                        httpClientManager.setHttpProxyCredentials(
                            settings.getProxyUserename(), settings.getProxyPassword(), ntlmHost, ntlmDomain
                        );
                    }
                }

                this.scraper.setDebug(true);
                this.logTextArea.setText(null);
                this.scraper.getLogger().addAppender( new TextAreaAppender(this.logTextArea) );
                this.scraper.addRuntimeListener(this);

                ide.setTabIcon(this, ResourceManager.SMALL_RUN_ICON);

                // starts scrapping in separate thread
                new ScraperExecutionThread(this.scraper).start();
            }
        }
    }

    public Scraper getScraper() {
        return scraper;
    }

    public synchronized int getScraperStatus() {
        if (this.scraper != null) {
            return this.scraper.getStatus();
        }

        return -1;
    }

    public Ide getIde() {
        return ide;
    }

    public synchronized void stopScraperExecution() {
        if (this.scraper != null) {
            this.scraper.stopExecution();
        }
    }

    public synchronized void pauseScraperExecution() {
        if (this.scraper != null) {
            this.scraper.pauseExecution();
            ide.setTabIcon(this, ResourceManager.SMALL_PAUSED_ICON);
        }
    }

    private int locateInSource(DefaultMutableTreeNode treeNode, boolean locateAtLineBeginning) {
        if (treeNode != null) {
            Object userObject = treeNode.getUserObject();
            if (userObject instanceof TreeNodeInfo) {
                TreeNodeInfo treeNodeInfo = (TreeNodeInfo) userObject;
                BaseElementDef elementDef = (BaseElementDef) treeNodeInfo.getElementDef();
                int lineNumber = elementDef.getLineNumber();
                int columnNumber = elementDef.getColumnNumber();

                String content = null;
                try {
                    content = this.xmlPane.getDocument().getText( 0, this.xmlPane.getDocument().getLength() );
                    String[] lines = content.split("\n");
                    int offset = 0;
                    int lineCount = 1;
                    for (int i = 0; i < lines.length; i++) {
                        String line = lines[i];
                        if(lineCount == lineNumber) {
                            offset += locateAtLineBeginning ? 1 : columnNumber;
                            break;
                        }
                        lineCount++;
                        if(lineCount > 2) {
                            offset++;
                        }
                        offset += line.length();
                    }

                    if (offset < content.length()) {
                        content = content.substring(0, offset);
                    }

                    int startIndex = content.lastIndexOf('<');

                    this.xmlPane.setCaretPosition(startIndex >= 0 ? startIndex : 0);
                } catch (BadLocationException e) {
                    e.printStackTrace();
                }

                return lineNumber;
            }
        }

        return -1;
    }

    public void undo() {
        this.xmlPane.undo();
    }

    public void redo() {
        this.xmlPane.redo();
    }

    public String getXml() {
        return this.xmlPane.getText();
    }

    public XmlTextPane getXmlPane() {
        return xmlPane;
    }

    public JTree getTree() {
        return tree;
    }

    public XmlEditorScrollPane getXmlEditorScrollPane() {
        return xmlEditorScrollPane;
    }

    public void setConfigFile(File file) {
        if (this.scraperConfiguration != null) {
            this.scraperConfiguration.setSourceFile(file);
        }
    }

    public ConfigDocument getConfigDocument() {
        return configDocument;
    }

    public void showHierarchy() {
        boolean isVisible = this.leftView.isVisible();
        if (isVisible) {
            this.leftDividerLocation = this.leftSplitter.getDividerLocation();
        }
        this.leftView.setVisible(!isVisible);
        if (!isVisible) {
            this.leftSplitter.setDividerLocation(this.leftDividerLocation);
        }
    }

    public void showLog() {
        boolean isVisible = this.bottomView.isVisible();
        if (isVisible) {
            this.bottomDividerLocation = this.bottomSplitter.getDividerLocation();
        }
        this.bottomView.setVisible(!isVisible);
        if (!isVisible) {
            this.bottomSplitter.setDividerLocation(this.bottomDividerLocation);
        }
    }

    public boolean isHierarchyVisible() {
        return this.leftView.isVisible();
    }

    public boolean isLogVisible() {
        return this.bottomView.isVisible();
    }

    public Map getInitParams() {
        return initParams;
    }

    public void setInitParams(Map initParams) {
        this.initParams = initParams;
    }

    public void dispose() {
        if (this.configDocument != null) {
            this.configDocument.dispose();
        }
        if (this.scraper != null) {
            this.scraper.removeRuntimeListener(this);
            this.scraper = null;
        }

        this.xmlPane.removeCaretListener(this);
        this.tree.removeTreeSelectionListener(this);

        this.scraperConfiguration = null;
        this.ide = null;
        this.tree = null;
        this.treeModel = null;
        this.nodeInfos = null;
        this.nodeRenderer = null;
        this.configDocument = null;
        this.topNode = null;

        this.logger.removeAllAppenders();
    }
   
}
TOP

Related Classes of org.webharvest.gui.ConfigPanel$ViewerActionListener

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.