com.github.fengtan.sophie.toolbars.DocumentsToolbar.java Source code

Java tutorial

Introduction

Here is the source code for com.github.fengtan.sophie.toolbars.DocumentsToolbar.java

Source

/**
 * Sophie - A Solr browser and administration tool
 * 
 * Copyright (C) 2016 fengtan<https://github.com/fengtan>
 *
 * 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 com.github.fengtan.sophie.toolbars;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.request.QueryRequest;
import org.apache.solr.client.solrj.response.LukeResponse.FieldInfo;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.util.NamedList;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

import com.github.fengtan.sophie.Sophie;
import com.github.fengtan.sophie.beans.SolrUtils;
import com.github.fengtan.sophie.beans.SophieException;
import com.github.fengtan.sophie.dialogs.CComboDialog;
import com.github.fengtan.sophie.dialogs.ExceptionDialog;
import com.github.fengtan.sophie.tables.DocumentsTable;
import com.github.fengtan.sophie.validators.FieldValidator;

/**
 * Toolbar to make operations on documents.
 */
public class DocumentsToolbar implements SelectionListener, ChangeListener {

    /**
     * Refresh operation - image.
     */
    private Image imgRefresh;

    /**
     * Add document operation - image.
     */
    private Image imgAdd;

    /**
     * Delete document operation - image.
     */
    private Image imgDelete;

    /**
     * Clone document operation - image.
     */
    private Image imgClone;

    /**
     * Upload local modifications operation - image.
     */
    private Image imgUpload;

    /**
     * Add field operation - image.
     */
    private Image imgAddField;

    /**
     * Clear index operation - image.
     */
    private Image imgClear;

    /**
     * Commit index operation - image.
     */
    private Image imgCommit;

    /**
     * Optimize index operation - image.
     */
    private Image imgOptimize;

    /**
     * Export operation - image.
     */
    private Image imgExport;

    /**
     * Backup operation - image.
     */
    private Image imgBackup;

    /**
     * Restore operation - image.
     */
    private Image imgRestore;

    /**
     * Refresh operation - button.
     */
    private ToolItem itemRefresh;

    /**
     * Add document operation - button.
     */
    private ToolItem itemAdd;

    /**
     * Delete document operation - button.
     */
    private ToolItem itemDelete;

    /**
     * Clone document operation - button.
     */
    private ToolItem itemClone;

    /**
     * Upload local modifications operation - button.
     */
    private ToolItem itemUpload;

    /**
     * Add field operation - button.
     */
    private ToolItem itemAddField;

    /**
     * Clear index operation - button.
     */
    private ToolItem itemClear;

    /**
     * Commit index operation - button.
     */
    private ToolItem itemCommit;

    /**
     * Optimize index operation - button.
     */
    private ToolItem itemOptimize;

    /**
     * Export operation - button.
     */
    private ToolItem itemExport;

    /**
     * Backup operation - button.
     */
    private ToolItem itemBackup;

    /**
     * Restore operation - button.
     */
    private ToolItem itemRestore;

    /**
     * Table listing the documents.
     */
    private DocumentsTable table;

    /**
     * Create a new toolbar to make operations on documents.
     * 
     * @param composite
     *            Parent composite.
     */
    public DocumentsToolbar(Composite composite) {
        initToolbar(composite);
    }

    /**
     * Set table.
     * 
     * @param table
     *            Table.
     */
    public void setTable(DocumentsTable table) {
        this.table = table;
    }

    /**
     * Populate toolbar with buttons.
     * 
     * @param composite
     *            Parent composite.
     */
    private void initToolbar(final Composite composite) {
        Display display = composite.getDisplay();
        ClassLoader loader = getClass().getClassLoader();

        // Instantiate toolbar.
        ToolBar toolBar = new ToolBar(composite, SWT.BORDER);

        // Instantiate images.
        imgRefresh = new Image(display, loader.getResourceAsStream("toolbar/refresh.png"));
        imgAdd = new Image(display, loader.getResourceAsStream("toolbar/add.png"));
        imgDelete = new Image(display, loader.getResourceAsStream("toolbar/delete.png"));
        imgClone = new Image(display, loader.getResourceAsStream("toolbar/clone.png"));
        imgUpload = new Image(display, loader.getResourceAsStream("toolbar/upload.png"));
        imgAddField = new Image(display, loader.getResourceAsStream("toolbar/add_field.png"));
        imgClear = new Image(display, loader.getResourceAsStream("toolbar/clear.png"));
        imgCommit = new Image(display, loader.getResourceAsStream("toolbar/commit.png"));
        imgOptimize = new Image(display, loader.getResourceAsStream("toolbar/optimize.png"));
        imgExport = new Image(display, loader.getResourceAsStream("toolbar/export.png"));
        imgBackup = new Image(display, loader.getResourceAsStream("toolbar/backup.png"));
        imgRestore = new Image(display, loader.getResourceAsStream("toolbar/restore.png"));

        // Instantiate buttons.
        itemRefresh = new ToolItem(toolBar, SWT.PUSH);
        itemRefresh.setImage(imgRefresh);
        itemRefresh.setText("Refresh");
        itemRefresh.setToolTipText("Refresh from Solr: this will wipe out local modifications");
        itemRefresh.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                try {
                    table.refresh();
                } catch (SophieException e) {
                    ExceptionDialog.open(composite.getShell(),
                            new SophieException("Unable to refresh documents from Solr server", e));
                }
            }
        });

        new ToolItem(toolBar, SWT.SEPARATOR);

        itemAdd = new ToolItem(toolBar, SWT.PUSH);
        itemAdd.setImage(imgAdd);
        itemAdd.setText("Add");
        itemAdd.setToolTipText("Add new document");
        itemAdd.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                table.addDocument(new SolrDocument());
            }
        });

        itemDelete = new ToolItem(toolBar, SWT.PUSH);
        itemDelete.setImage(imgDelete);
        itemDelete.setText("Delete");
        itemDelete.setToolTipText("Delete document");
        itemDelete.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                table.deleteSelectedDocument();
            }
        });
        itemDelete.setEnabled(false);

        itemClone = new ToolItem(toolBar, SWT.PUSH);
        itemClone.setImage(imgClone);
        itemClone.setText("Clone");
        itemClone.setToolTipText("Clone document");
        itemClone.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                SolrDocument document = table.getSelectedDocument();
                if (document == null) {
                    return;
                }

                // Unset the unique key field so we don't have two rows
                // describing the same Solr document.
                try {
                    String uniqueKey = SolrUtils.getRemoteUniqueField();
                    document.removeFields(uniqueKey);
                } catch (SophieException e) {
                    Sophie.log.warn("Unable to unset unique key on cloned document");
                }

                // Add cloned document.
                table.addDocument(document);
            }
        });
        itemClone.setEnabled(false);

        itemUpload = new ToolItem(toolBar, SWT.PUSH);
        itemUpload.setImage(imgUpload);
        itemUpload.setText("Upload");
        itemUpload.setToolTipText("Upload local modifications to Solr");
        itemUpload.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                try {
                    table.upload();
                } catch (SophieException e) {
                    ExceptionDialog.open(composite.getShell(),
                            new SophieException("Unable to upload local modifications to Solr", e));
                }
            }
        });
        itemUpload.setEnabled(false);

        new ToolItem(toolBar, SWT.SEPARATOR);

        itemAddField = new ToolItem(toolBar, SWT.PUSH);
        itemAddField.setImage(imgAddField);
        itemAddField.setText("Add field");
        itemAddField.setToolTipText("Add new field");
        itemAddField.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                // Get field schema fields.
                Map<String, FieldInfo> fields;
                try {
                    fields = SolrUtils.getRemoteSchemaFields();
                } catch (SophieException e) {
                    ExceptionDialog.open(composite.getShell(),
                            new SophieException("Unable to fetch schema fields", e));
                    return;
                }
                // Remove universal pattern which is not useful and will match
                // any field name.
                fields.remove("*");
                // Remove fields already displayed in the table.
                Collection<String> excludedFieldNames = table.getFieldNames();
                for (String existingFieldName : excludedFieldNames) {
                    fields.remove(existingFieldName);
                }
                // Extract and sort field names.
                Set<String> fieldNames = fields.keySet();
                String[] fieldNamesArray = new String[fieldNames.size()];
                fieldNames.toArray(fieldNamesArray);
                Arrays.sort(fieldNamesArray);
                // Prompt user for new field name.
                FieldValidator validator = new FieldValidator(fields, excludedFieldNames);
                CComboDialog dialog = new CComboDialog(composite.getShell(), "Add new field", "Field name:",
                        fieldNamesArray, validator);
                dialog.open();
                if (dialog.getReturnCode() != IDialogConstants.OK_ID) {
                    return;
                }
                // Add new field.
                String fieldName = dialog.getValue();
                FieldInfo field = validator.getMatchingField(fieldName);
                table.addField(fieldName, field);
            }
        });

        itemClear = new ToolItem(toolBar, SWT.PUSH);
        itemClear.setImage(imgClear);
        itemClear.setText("Clear");
        itemClear.setToolTipText("Clear index");
        itemClear.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                MessageBox messageBox = new MessageBox(composite.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
                messageBox.setText("Clear index");
                messageBox.setMessage(
                        "Do you really want to clear the index? This will remove all documents from the index.");
                int response = messageBox.open();
                if (response == SWT.YES) {
                    try {
                        Sophie.client.deleteByQuery("*:*");
                        Sophie.client.commit();
                        table.refresh();
                    } catch (SolrServerException | IOException | SolrException | SophieException e) {
                        ExceptionDialog.open(composite.getShell(), new SophieException("Unable to clear index", e));
                    }
                }
            }
        });

        itemCommit = new ToolItem(toolBar, SWT.PUSH);
        itemCommit.setImage(imgCommit);
        itemCommit.setText("Commit");
        itemCommit.setToolTipText("Commit index");
        itemCommit.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                try {
                    Sophie.client.commit();
                    table.refresh();
                } catch (SolrServerException | IOException | SolrException | SophieException e) {
                    ExceptionDialog.open(composite.getShell(), new SophieException("Unable to commit index", e));
                }
            }
        });

        itemOptimize = new ToolItem(toolBar, SWT.PUSH);
        itemOptimize.setImage(imgOptimize);
        itemOptimize.setText("Optimize");
        itemOptimize.setToolTipText("Optimize index");
        itemOptimize.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                MessageBox messageBox = new MessageBox(composite.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
                messageBox.setText("Optimize index");
                messageBox.setMessage(
                        "Do you really want to optimize the index? If the index is highly segmented, this may take several hours and will slow down requests.");
                int response = messageBox.open();
                if (response == SWT.YES) {
                    try {
                        Sophie.client.optimize();
                        // Optimizing drops obsolete documents, obsolete facet
                        // values, etc so we need to refresh the table.
                        table.refresh();
                    } catch (SolrServerException | IOException | SolrException | SophieException e) {
                        ExceptionDialog.open(composite.getShell(),
                                new SophieException("Unable to optimize index", e));
                    }
                }
            }
        });

        new ToolItem(toolBar, SWT.SEPARATOR);

        itemExport = new ToolItem(toolBar, SWT.PUSH);
        itemExport.setImage(imgExport);
        itemExport.setText("Export");
        itemExport.setToolTipText("Export as CSV file");
        itemExport.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                try {
                    table.export();
                } catch (SophieException e) {
                    ExceptionDialog.open(composite.getShell(), e);
                }
            }
        });

        itemBackup = new ToolItem(toolBar, SWT.PUSH);
        itemBackup.setImage(imgBackup);
        itemBackup.setText("Backup");
        itemBackup.setToolTipText("Make a backup of the index");
        itemBackup.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                InputDialog dialog = new InputDialog(composite.getShell(), "Make a backup of the index",
                        "Backup name (leave empty to use a timestamp):", null, null);
                dialog.open();
                if (dialog.getReturnCode() != IDialogConstants.OK_ID) {
                    return;
                }
                String backupName = dialog.getValue();
                ModifiableSolrParams params = new ModifiableSolrParams();
                params.set("command", "backup");
                params.set("name", backupName);
                QueryRequest request = new QueryRequest(params);
                request.setPath("/replication");
                try {
                    NamedList<Object> response = Sophie.client.request(request);
                    // org.apache.solr.handler.ReplicationHandler.OK_STATUS is
                    // "OK".
                    if (StringUtils.equals(response.get("status").toString(), "OK")) {
                        MessageBox messageBox = new MessageBox(composite.getShell(), SWT.ICON_INFORMATION | SWT.OK);
                        messageBox.setText("Backup started");
                        messageBox.setMessage(
                                "Backup started and will be saved into Solr data directory under the name \"snapshot."
                                        + (StringUtils.isEmpty(backupName) ? "<timestamp>" : backupName) + "\".");
                        messageBox.open();
                    } else {
                        MessageBox messageBox = new MessageBox(composite.getShell(), SWT.ICON_ERROR | SWT.OK);
                        messageBox.setText("Backup error");
                        messageBox.setMessage("Unable to backup the index.");
                        messageBox.open();
                    }
                } catch (SolrServerException | IOException | SolrException e) {
                    ExceptionDialog.open(composite.getShell(),
                            new SophieException("Unable to create backup \"" + backupName + "\"", e));
                }
            }
        });

        itemRestore = new ToolItem(toolBar, SWT.PUSH);
        itemRestore.setImage(imgRestore);
        itemRestore.setText("Restore");
        itemRestore.setToolTipText("Restore index from a backup");
        itemRestore.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                // Restoring a backup requires Solr >=5.2
                // @see SOLR-6637
                InputDialog dialog = new InputDialog(composite.getShell(), "Restore index from a backup",
                        "Note: backup restoration requires Solr >= 5.2.\n\nBackup name (leave empty to pick the latest backup available):",
                        null, null);
                dialog.open();
                if (dialog.getReturnCode() != IDialogConstants.OK_ID) {
                    return;
                }
                try {
                    table.restore(dialog.getValue());
                } catch (SophieException e) {
                    ExceptionDialog.open(composite.getShell(), e);
                }
            }
        });

        // Pack.
        toolBar.pack();
    }

    @Override
    public void finalize() {
        imgRefresh.dispose();
        imgAdd.dispose();
        imgDelete.dispose();
        imgClone.dispose();
        imgUpload.dispose();
        imgAddField.dispose();
        imgClear.dispose();
        imgCommit.dispose();
        imgOptimize.dispose();
        imgExport.dispose();
        imgBackup.dispose();
        imgRestore.dispose();
    }

    @Override
    public void widgetDefaultSelected(SelectionEvent e) {
        // Do nothing.
    }

    @Override
    public void widgetSelected(SelectionEvent e) {
        // These buttons require a document to be selected.
        itemDelete.setEnabled(true);
        itemClone.setEnabled(true);
    }

    @Override
    public void changed() {
        // Enable the 'Upload' button if there is at least one local
        // modification to send to Solr.
        itemUpload.setEnabled(true);
    }

    @Override
    public void unchanged() {
        // Disable the 'Upload' button if there is no local modification to send
        // to Solr.
        itemUpload.setEnabled(false);
    }

}