org.parosproxy.paros.extension.history.ExtensionHistory.java Source code

Java tutorial

Introduction

Here is the source code for org.parosproxy.paros.extension.history.ExtensionHistory.java

Source

/*
 *
 * Paros and its related class files.
 * 
 * Paros is an HTTP/HTTPS proxy for assessing web application security.
 * Copyright (C) 2003-2004 Chinotec Technologies Company
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Clarified Artistic License
 * as published by the Free Software Foundation.
 * 
 * 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
 * Clarified Artistic License for more details.
 * 
 * You should have received a copy of the Clarified Artistic License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

// ZAP: 2011/04/08 Changed to support clearview() in HttpPanels
// ZAP: 2011/04/08 Changed to use PopupMenuResendMessage
// ZAP: 2011/07/23 Use new add alert popup
// ZAP: 2011/09/06 Fix alert save plus concurrent mod exceptions
// ZAP: 2011/10/23 Fix add note and manage tags dialogs
// ZAP: 2011/11/20 Set order
// ZAP: 2011/12/21 Added 'show in history' popup
// ZAP: 2012/02/18 Rationalised session handling
// ZAP: 2012/03/03 Moved popups to stdmenus extension
// ZAP: 2012/03/15 Changed the method getResendDialog to pass the configuration key
// to the ManualRequestEditorDialog.
// ZAP: 2012/03/17 Issue 282 Added getAuthor()
// ZAP: 2012/04/24 Added type arguments to generic types, removed unnecessary
// cast and added @Override annotation to all appropriate methods.
// ZAP: 2012/04/28 Added log of exception.
// ZAP: 2012/05/31 Issue 308 NPE in sessionChangedEventHandler in daemon mode
// ZAP: 2012/07/02 Added the method showAlertAddDialog(HttpMessage, int).
// ZAP: 2012/07/29 Issue 43: added sessionScopeChanged event and removed access to some UI elements
// ZAP: 2012/08/01 Issue 332: added support for Modes
// ZAP: 2012/10/08 Issue 391: Performance improvements
// ZAP: 2013/03/03 Issue 546: Remove all template Javadoc comments
// ZAP: 2013/03/03 Issue 547: Deprecate unused classes and methods
// ZAP: 2013/04/14 Issue 588: ExtensionHistory.historyIdToRef should be cleared when changing session
// ZAP: 2013/04/14 Issue 598: Replace/update "old" pop up menu items
// ZAP: 2013/07/14 Issue 725: Clear alert's panel fields
// ZAP: 2013/07/23 Issue 738: Options to hide tabs
// ZAP: 2013/08/07 Also show Authentication messages
// ZAP: 2013/11/16 Issue 869: Differentiate proxied requests from (ZAP) user requests
// ZAP: 2013/12/02 Issue 915: Dynamically filter history based on selection in the sites window
// ZAP: 2014/03/23 Issue 503: Change the footer tabs to display the data
// with tables instead of lists
// ZAP: 2014/03/23 Issue 999: History loaded in wrong order
// ZAP: 2014/04/10 Remove cached history reference when a history reference is removed
// ZAP: 2014/04/10 Issue 1042: Having significant issues opening a previous session
// ZAP: 2014/05/20 Issue 1206: "History" tab is not cleared when a new session is created 
// through the API with ZAP in GUI mode
// ZAP: 2014/12/12 Issue 1449: Added help button
// ZAP: 2015/02/09 Issue 1525: Introduce a database interface layer to allow for alternative implementations
// ZAP: 2015/03/03 Added delete(href) method to ensure local map updated 
// ZAP: 2015/04/02 Issue 321: Support multiple databases and Issue 1582: Low memory option
// ZAP: 2015/07/16 Issue 1617: ZAP 2.4.0 throws HeadlessExceptions when running in daemon mode on headless machine
// ZAP: 2015/09/16 Issue 1890: ZAP can't completely scan OWASP Benchmark

package org.parosproxy.paros.extension.history;

import java.awt.EventQueue;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import org.apache.commons.collections.map.ReferenceMap;
import org.apache.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.control.Control.Mode;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.db.DatabaseException;
import org.parosproxy.paros.extension.ExtensionAdaptor;
import org.parosproxy.paros.extension.ExtensionHook;
import org.parosproxy.paros.extension.ExtensionHookView;
import org.parosproxy.paros.extension.SessionChangedListener;
import org.parosproxy.paros.extension.manualrequest.ManualRequestEditorDialog;
import org.parosproxy.paros.extension.manualrequest.http.impl.ManualHttpRequestEditorDialog;
import org.parosproxy.paros.model.HistoryReference;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.Session;
import org.parosproxy.paros.model.SiteNode;
import org.parosproxy.paros.network.HttpMessage;
import org.parosproxy.paros.view.View;
import org.zaproxy.zap.extension.help.ExtensionHelp;
import org.zaproxy.zap.extension.history.AlertAddDialog;
import org.zaproxy.zap.extension.history.HistoryFilterPlusDialog;
import org.zaproxy.zap.extension.history.ManageTagsDialog;
import org.zaproxy.zap.extension.history.NotesAddDialog;
import org.zaproxy.zap.extension.history.PopupMenuExportURLs;
import org.zaproxy.zap.extension.history.PopupMenuNote;
import org.zaproxy.zap.extension.history.PopupMenuPurgeHistory;
import org.zaproxy.zap.extension.history.PopupMenuTag;
import org.zaproxy.zap.view.table.DefaultHistoryReferencesTableModel;

public class ExtensionHistory extends ExtensionAdaptor implements SessionChangedListener {

    public static final String NAME = "ExtensionHistory";

    private static final DefaultHistoryReferencesTableModel EMPTY_MODEL = new DefaultHistoryReferencesTableModel();

    private LogPanel logPanel = null; //  @jve:decl-index=0:visual-constraint="161,134"
    private ProxyListenerLog proxyListener = null;
    private DefaultHistoryReferencesTableModel historyTableModel;

    // ZAP: added filter plus dialog
    private HistoryFilterPlusDialog filterPlusDialog = null;

    private PopupMenuPurgeHistory popupMenuPurgeHistory = null;
    private ManualRequestEditorDialog resendDialog = null;

    private PopupMenuExportMessage popupMenuExportMessage2 = null;
    private PopupMenuExportResponse popupMenuExportResponse2 = null;
    private PopupMenuTag popupMenuTag = null;
    // ZAP: Added Export URLs
    private PopupMenuExportURLs popupMenuExportURLs = null;
    // ZAP: Added history notes
    private PopupMenuNote popupMenuNote = null;
    private NotesAddDialog dialogNotesAdd = null;
    private AlertAddDialog dialogAlertAdd = null;
    private ManageTagsDialog manageTags = null;

    private boolean showJustInScope = false;
    private boolean linkWithSitesTree;
    private String linkWithSitesTreeBaseUri;

    // Used to cache hrefs not added into the historyList
    private ReferenceMap historyIdToRef = new ReferenceMap();

    private Logger logger = Logger.getLogger(ExtensionHistory.class);

    /**
     * 
     */
    public ExtensionHistory() {
        super();
        initialize();
    }

    /**
     * @param name
     */
    public ExtensionHistory(String name) {
        super(name);
    }

    /**
     * This method initializes this
     */
    private void initialize() {
        this.setName(NAME);
        this.setOrder(16);

    }

    /**
     * This method initializes logPanel   
     *    
     * @return org.parosproxy.paros.extension.history.LogPanel   
     */
    private LogPanel getLogPanel() {
        if (logPanel == null) {
            logPanel = new LogPanel();
            logPanel.setName(Constant.messages.getString("history.panel.title")); // ZAP: i18n
            // ZAP: Added History (calendar) icon
            logPanel.setIcon(new ImageIcon(ExtensionHistory.class.getResource("/resource/icon/16/025.png"))); // 'calendar' icon
            // Dont allow this tab to be hidden
            logPanel.setHideable(false);

            logPanel.setExtension(this);
            logPanel.setModel(historyTableModel);
        }
        return logPanel;
    }

    public void clearLogPanelDisplayQueue() {
        this.getLogPanel().clearDisplayQueue();
    }

    public HistoryReference getSelectedHistoryReference() {
        return getLogPanel().getSelectedHistoryReference();
    }

    public List<HistoryReference> getSelectedHistoryReferences() {
        return getLogPanel().getSelectedHistoryReferences();
    }

    @Override
    public void init() {
        super.init();

        historyTableModel = new DefaultHistoryReferencesTableModel();
    }

    @Override
    public void hook(ExtensionHook extensionHook) {
        super.hook(extensionHook);
        extensionHook.addSessionListener(this);
        extensionHook.addProxyListener(getProxyListenerLog());

        if (getView() != null) {
            ExtensionHookView pv = extensionHook.getHookView();
            pv.addStatusPanel(getLogPanel());
            getLogPanel().setDisplayPanel(getView().getRequestPanel(), getView().getResponsePanel());

            extensionHook.getHookMenu().addPopupMenuItem(getPopupMenuTag());
            // ZAP: Added history notes
            extensionHook.getHookMenu().addPopupMenuItem(getPopupMenuNote());

            //           extensionHook.getHookMenu().addPopupMenuItem(getPopupMenuExportMessage());
            //          extensionHook.getHookMenu().addPopupMenuItem(getPopupMenuExportResponse());

            extensionHook.getHookMenu().addPopupMenuItem(getPopupMenuPurgeHistory());

            // same as PopupMenuExport but for File menu
            // ZAP: Move 'export' menu items to Report menu
            extensionHook.getHookMenu().addReportMenuItem(getPopupMenuExportMessage2());
            extensionHook.getHookMenu().addReportMenuItem(getPopupMenuExportResponse2());
            extensionHook.getHookMenu().addReportMenuItem(getPopupMenuExportURLs());

            ExtensionHelp.enableHelpKey(this.getLogPanel(), "ui.tabs.history");
        }

    }

    @Override
    public void sessionChanged(final Session session) {
        // Actual work done in sessionScopeChanged
    }

    private ProxyListenerLog getProxyListenerLog() {
        if (proxyListener == null) {
            proxyListener = new ProxyListenerLog(getModel(), getView(), this);
        }
        return proxyListener;
    }

    public void removeFromHistoryList(final HistoryReference href) {
        if (!View.isInitialised() || EventQueue.isDispatchThread()) {
            this.historyTableModel.removeEntry(href.getHistoryId());
            historyIdToRef.remove(Integer.valueOf(href.getHistoryId()));
        } else {
            EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    removeFromHistoryList(href);
                }
            });
        }
    }

    public void notifyHistoryItemChanged(final HistoryReference href) {
        if (!View.isInitialised() || EventQueue.isDispatchThread()) {
            this.historyTableModel.refreshEntryRow(href.getHistoryId());
        } else {
            EventQueue.invokeLater(new Runnable() {

                @Override
                public void run() {
                    notifyHistoryItemChanged(href);
                }
            });
        }
    }

    public void delete(HistoryReference href) {
        if (href != null) {
            this.historyIdToRef.remove(href.getHistoryId());
            href.delete();
        }
    }

    public HistoryReference getHistoryReference(int historyId) {
        HistoryReference href = historyTableModel.getHistoryReference(historyId);
        if (href != null) {
            return href;
        }
        href = (HistoryReference) historyIdToRef.get(historyId);
        if (href == null) {
            try {
                href = new HistoryReference(historyId);
                if (href.getHistoryType() != HistoryReference.TYPE_SCANNER_TEMPORARY) {
                    addToMap(href);
                }
            } catch (Exception e) {
                return null;
            }
        }
        return href;

    }

    public int getLastHistoryId() {
        return Model.getSingleton().getDb().getTableHistory().lastIndex();
    }

    public void addHistory(HttpMessage msg, int type) {
        try {
            this.addHistory(new HistoryReference(Model.getSingleton().getSession(), type, msg));
        } catch (final Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    private void addToMap(HistoryReference historyRef) {
        historyIdToRef.put(historyRef.getHistoryId(), historyRef);
    }

    public void addHistory(HistoryReference historyRef) {
        if (Constant.isLowMemoryOptionSet()) {
            return;
        }
        try {
            synchronized (historyTableModel) {
                final int historyType = historyRef.getHistoryType();
                if (historyType == HistoryReference.TYPE_PROXIED || historyType == HistoryReference.TYPE_ZAP_USER
                        || historyRef.getHistoryType() == HistoryReference.TYPE_AUTHENTICATION) {
                    final String uri = historyRef.getURI().toString();
                    if (this.showJustInScope && !getModel().getSession().isInScope(uri)) {
                        // Not in scope
                        addToMap(historyRef);
                        return;
                    } else if (linkWithSitesTree && linkWithSitesTreeBaseUri != null
                            && !uri.startsWith(linkWithSitesTreeBaseUri)) {
                        // Not under the selected node
                        addToMap(historyRef);
                        return;
                    }
                    if (getView() != null) {
                        // Dont do this in daemon mode 
                        HistoryFilterPlusDialog dialog = getFilterPlusDialog();
                        HistoryFilter historyFilter = dialog.getFilter();
                        if (historyFilter != null && !historyFilter.matches(historyRef)) {
                            // Not in filter
                            addToMap(historyRef);
                            return;
                        }

                        addHistoryInEventQueue(historyRef);
                    }
                }
            }
        } catch (final Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    private void addHistoryInEventQueue(final HistoryReference ref) {
        if (!View.isInitialised() || EventQueue.isDispatchThread()) {
            historyTableModel.addHistoryReference(ref);
        } else {
            try {
                EventQueue.invokeAndWait(new Runnable() {
                    @Override
                    public void run() {
                        addHistoryInEventQueue(ref);
                    }
                });
            } catch (final Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    private void searchHistory(HistoryFilter historyFilter) {
        Session session = getModel().getSession();

        synchronized (historyTableModel) {
            try {
                // ZAP: Added type argument.
                List<Integer> list = getModel().getDb().getTableHistory().getHistoryIdsOfHistType(
                        session.getSessionId(), HistoryReference.TYPE_PROXIED, HistoryReference.TYPE_ZAP_USER);

                buildHistory(list, historyFilter);
            } catch (DatabaseException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }

    private void buildHistory(List<Integer> dbList, HistoryFilter historyFilter) {
        HistoryReference historyRef = null;
        synchronized (historyTableModel) {
            if (getView() != null) {
                getLogPanel().setModel(EMPTY_MODEL);
            }
            historyTableModel.clear();

            for (int i = 0; i < dbList.size(); i++) {
                int historyId = (dbList.get(i)).intValue();

                try {
                    SiteNode sn = getModel().getSession().getSiteTree().getSiteNode(historyId);
                    if (sn != null && sn.getHistoryReference() != null
                            && sn.getHistoryReference().getHistoryId() == historyId) {
                        historyRef = sn.getHistoryReference();
                    } else {
                        historyRef = getHistoryReference(historyId);
                        sn.setHistoryReference(historyRef);
                    }
                    final String uri = historyRef.getURI().toString();
                    if (this.showJustInScope && !getModel().getSession().isInScope(uri)) {
                        // Not in scope
                        continue;
                    } else if (linkWithSitesTree && linkWithSitesTreeBaseUri != null
                            && !uri.startsWith(linkWithSitesTreeBaseUri)) {
                        // Not under the selected node
                        continue;
                    }
                    if (historyFilter != null && !historyFilter.matches(historyRef)) {
                        // Not in filter
                        continue;
                    }
                    historyRef.loadAlerts();
                    historyTableModel.addHistoryReference(historyRef);

                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
            if (getView() != null) {
                getLogPanel().setModel(historyTableModel);
            }
        }
    }

    private HistoryFilterPlusDialog getFilterPlusDialog() {
        if (filterPlusDialog == null) {
            filterPlusDialog = new HistoryFilterPlusDialog(getView().getMainFrame(), true);
        }
        return filterPlusDialog;
    }

    protected int showFilterPlusDialog() {
        HistoryFilterPlusDialog dialog = getFilterPlusDialog();
        dialog.setModal(true);
        try {
            dialog.setAllTags(getModel().getDb().getTableTag().getAllTags());
        } catch (DatabaseException e) {
            logger.error(e.getMessage(), e);
        }

        int exit = dialog.showDialog();
        int result = 0; // cancel, state unchanged
        HistoryFilter historyFilter = dialog.getFilter();
        if (exit == JOptionPane.OK_OPTION) {
            searchHistory(historyFilter);
            logPanel.setFilterStatus(historyFilter);
            result = 1; // applied

        } else if (exit == JOptionPane.NO_OPTION) {
            searchHistory(historyFilter);
            logPanel.setFilterStatus(historyFilter);
            result = -1; // reset
        }

        return result;
    }

    private PopupMenuPurgeHistory getPopupMenuPurgeHistory() {
        if (popupMenuPurgeHistory == null) {
            popupMenuPurgeHistory = new PopupMenuPurgeHistory(this);
        }
        return popupMenuPurgeHistory;
    }

    /**
     * This method initializes resendDialog   
     *    
     * @return org.parosproxy.paros.extension.history.ResendDialog   
     */
    public ManualRequestEditorDialog getResendDialog() {
        if (resendDialog == null) {
            resendDialog = new ManualHttpRequestEditorDialog(true, "resend", "ui.dialogs.resend");
            resendDialog.setTitle(Constant.messages.getString("manReq.resend.popup")); // ZAP: i18n
        }
        return resendDialog;
    }

    /**
     * This method initializes popupMenuExport1   
     *    
     * @return org.parosproxy.paros.extension.history.PopupMenuExport   
     */
    private PopupMenuExportMessage getPopupMenuExportMessage2() {
        if (popupMenuExportMessage2 == null) {
            popupMenuExportMessage2 = new PopupMenuExportMessage();
            popupMenuExportMessage2.setExtension(this);
        }
        return popupMenuExportMessage2;
    }

    /**
     * This method initializes popupMenuExportResponse2   
     *    
     * @return org.parosproxy.paros.extension.history.PopupMenuExportResponse   
     */
    private PopupMenuExportResponse getPopupMenuExportResponse2() {
        if (popupMenuExportResponse2 == null) {
            popupMenuExportResponse2 = new PopupMenuExportResponse();
            popupMenuExportResponse2.setExtension(this);

        }
        return popupMenuExportResponse2;
    }

    private PopupMenuTag getPopupMenuTag() {
        if (popupMenuTag == null) {
            popupMenuTag = new PopupMenuTag(this);

        }
        return popupMenuTag;
    }

    private PopupMenuNote getPopupMenuNote() {
        if (popupMenuNote == null) {
            popupMenuNote = new PopupMenuNote(this);

        }
        return popupMenuNote;
    }

    private void populateNotesAddDialogAndSetVisible(HistoryReference ref, String note) {
        dialogNotesAdd.setNote(note);
        dialogNotesAdd.setHistoryRef(ref);
        dialogNotesAdd.setVisible(true);
    }

    public void showNotesAddDialog(HistoryReference ref, String note) {
        if (dialogNotesAdd == null) {
            dialogNotesAdd = new NotesAddDialog(getView().getMainFrame(), false);
            dialogNotesAdd.setPlugin(this);
            populateNotesAddDialogAndSetVisible(ref, note);
        } else if (!dialogNotesAdd.isVisible()) {
            populateNotesAddDialogAndSetVisible(ref, note);
        }
    }

    public void hideNotesAddDialog() {
        dialogNotesAdd.dispose();
    }

    public void showAlertAddDialog(HistoryReference ref) {
        if (dialogAlertAdd == null || !dialogAlertAdd.isVisible()) {
            dialogAlertAdd = new AlertAddDialog(getView().getMainFrame(), false);
            dialogAlertAdd.setPlugin(this);
            dialogAlertAdd.setVisible(true);
            dialogAlertAdd.setHistoryRef(ref);
        }
    }

    /**
     * Sets the {@code HttpMessage} and the history type of the
     * {@code HistoryReference} that will be created if the user creates the
     * alert. The current session will be used to create the
     * {@code HistoryReference}. The alert created will be added to the newly
     * created {@code HistoryReference}.
     * <p>
     * Should be used when the alert is added to a temporary
     * {@code HistoryReference} as the temporary {@code HistoryReference}s are
     * deleted when the session is closed.
     * </p>
     * 
     * @param httpMessage
     *            the {@code HttpMessage} that will be used to create the
     *            {@code HistoryReference}, must not be {@code null}
     * @param historyType
     *            the type of the history reference that will be used to create
     *            the {@code HistoryReference}
     * 
     * @see Model#getSession()
     * @see HistoryReference#HistoryReference(org.parosproxy.paros.model.Session,
     *      int, HttpMessage)
     */
    // ZAP: Added the method.
    public void showAlertAddDialog(HttpMessage httpMessage, int historyType) {
        if (dialogAlertAdd == null || !dialogAlertAdd.isVisible()) {
            dialogAlertAdd = new AlertAddDialog(getView().getMainFrame(), false);
            dialogAlertAdd.setPlugin(this);
            dialogAlertAdd.setHttpMessage(httpMessage, historyType);
            dialogAlertAdd.setVisible(true);
        }
    }

    public void showAlertAddDialog(Alert alert) {
        if (dialogAlertAdd == null || !dialogAlertAdd.isVisible()) {
            dialogAlertAdd = new AlertAddDialog(getView().getMainFrame(), false);
            dialogAlertAdd.setPlugin(this);
            dialogAlertAdd.setVisible(true);
            dialogAlertAdd.setAlert(alert);
        }
    }

    private void populateManageTagsDialogAndSetVisible(HistoryReference ref, List<String> tags) {
        try {
            manageTags.setAllTags(getModel().getDb().getTableTag().getAllTags());
        } catch (DatabaseException e) {
            logger.error(e.getMessage(), e);
        }
        manageTags.setTags(tags);
        manageTags.setHistoryRef(ref);
        manageTags.setVisible(true);
    }

    public void showManageTagsDialog(HistoryReference ref, List<String> tags) {
        if (manageTags == null) {
            manageTags = new ManageTagsDialog(getView().getMainFrame(), false);
            manageTags.setPlugin(this);
            populateManageTagsDialogAndSetVisible(ref, tags);
        } else if (!manageTags.isVisible()) {
            populateManageTagsDialogAndSetVisible(ref, tags);
        }
    }

    public void hideManageTagsDialog() {
        manageTags.dispose();
    }

    private PopupMenuExportURLs getPopupMenuExportURLs() {
        if (popupMenuExportURLs == null) {
            popupMenuExportURLs = new PopupMenuExportURLs();
            popupMenuExportURLs.setExtension(this);
        }
        return popupMenuExportURLs;
    }

    public void showInHistory(HistoryReference href) {
        this.getLogPanel().display(href);
        this.getLogPanel().setTabFocus();
    }

    @Override
    public void sessionAboutToChange(final Session session) {
        if (getView() == null || EventQueue.isDispatchThread()) {
            historyTableModel.clear();
            historyIdToRef.clear();

            if (getView() != null) {
                getView().getRequestPanel().clearView(true);
                getView().getResponsePanel().clearView(false);
            }
        } else {
            try {
                EventQueue.invokeAndWait(new Runnable() {
                    @Override
                    public void run() {
                        sessionAboutToChange(session);
                    }
                });
            } catch (Exception e) {
                // ZAP: Added logging.
                logger.error(e.getMessage(), e);
            }
        }
    }

    @Override
    public String getAuthor() {
        return Constant.PAROS_TEAM;
    }

    public boolean isShowJustInScope() {
        return showJustInScope;
    }

    public void setShowJustInScope(boolean showJustInScope) {
        this.showJustInScope = showJustInScope;
        if (showJustInScope) {
            linkWithSitesTree = false;
        }
        // Refresh with the next option
        searchHistory(getFilterPlusDialog().getFilter());
    }

    void setLinkWithSitesTree(boolean linkWithSitesTree, String baseUri) {
        this.linkWithSitesTree = linkWithSitesTree;
        this.linkWithSitesTreeBaseUri = baseUri;
        if (linkWithSitesTree) {
            this.showJustInScope = false;
        }
        searchHistory(getFilterPlusDialog().getFilter());
    }

    void updateLinkWithSitesTreeBaseUri(String baseUri) {
        this.linkWithSitesTreeBaseUri = baseUri;
        searchHistory(getFilterPlusDialog().getFilter());
    }

    @Override
    public void sessionScopeChanged(Session session) {
        if (getView() != null) {
            searchHistory(getFilterPlusDialog().getFilter());
        } else {
            searchHistory(null);
        }
    }

    @Override
    public void sessionModeChanged(Mode mode) {
        // Ignore
    }

    @Override
    public boolean supportsLowMemory() {
        return true;
    }

    /**
     * Part of the core set of features that should be supported by all db types
     */
    @Override
    public boolean supportsDb(String type) {
        return true;
    }
}