org.jboss.tools.common.jdt.ui.buildpath.dialog.MaterializeLibraryDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.common.jdt.ui.buildpath.dialog.MaterializeLibraryDialog.java

Source

/*************************************************************************************
 * Copyright (c) 2009-2011 Red Hat, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     JBoss by Red Hat - Initial implementation.
 ************************************************************************************/
package org.jboss.tools.common.jdt.ui.buildpath.dialog;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;
import org.jboss.tools.common.jdt.ui.JDTExtUIActivator;

public class MaterializeLibraryDialog extends TitleAreaDialog {

    private static final String SOURCE_PROPERTY = "SOURCE_PROPERTY";

    private static final String FILENAME_PROPERTY = "FILENAME_PROPERTY";

    private IContainer libFolder;
    private Map<IClasspathEntry, String> classpathEntryPaths;
    private Map<IPath, String> selectedClasspathEntryPaths;
    private IClasspathContainer containerToMaterialize;

    private final String libName;

    private Image jarImage;
    private Image projectImage;

    private Text libfolderText;

    private CheckboxTableViewer classpathEntriesViewer;

    private Button keepSourceBtn;

    private boolean keepSources;

    private IMaterializeLibraryWarningFactory warningfactory;

    private Label warningImg;

    private Label warningLabel;

    public MaterializeLibraryDialog(Shell shell, IProject project, IClasspathContainer containerToMaterialize,
            String defaultLib) {
        super(shell);
        setShellStyle(super.getShellStyle() | SWT.RESIZE | SWT.MODELESS);
        this.libName = containerToMaterialize.getDescription();
        IPath folderPath = project.getFullPath().append(defaultLib);
        libFolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(folderPath);
        this.containerToMaterialize = containerToMaterialize;
        warningfactory = new MaterializeLibraryWarningFactory();
        initClasspathEntryPaths();
    }

    private void initClasspathEntryPaths() {
        IClasspathEntry[] cpEntries = containerToMaterialize.getClasspathEntries();
        classpathEntryPaths = new LinkedHashMap<IClasspathEntry, String>(cpEntries.length);
        for (IClasspathEntry entry : cpEntries) {
            if ((entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath() != null)
                    || (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT)) {
                IPath sourceFilePath = entry.getPath();
                String fileName = sourceFilePath.lastSegment();
                classpathEntryPaths.put(entry, fileName);
            }
        }
    }

    @Override
    protected void configureShell(Shell shell) {
        super.configureShell(shell);
        shell.setText("Copy Classpath Libraries");
    }

    private void initImages() {
        jarImage = JDTExtUIActivator.getJarIcon();
        projectImage = JDTExtUIActivator.getProjectIcon();
    }

    @Override
    protected Control createDialogArea(Composite parent) {

        initImages();
        setTitle("Copy JAR files from " + libName);

        Composite area = (Composite) super.createDialogArea(parent);

        Composite container = new Composite(area, SWT.NONE);
        container.setEnabled(true);

        GridLayout layout = new GridLayout(3, false);
        layout.marginLeft = 12;
        container.setLayout(layout);
        container.setLayoutData(new GridData(GridData.FILL_BOTH));

        String message = NLS.bind("Copy selected JAR files from {0} to the destination folder.", libName);
        String warning = warningfactory.getWarning(containerToMaterialize);
        if (warning != null) {
            displayWarning(container, warning);
        }
        setMessage(message);

        Label libFolderLabel = new Label(container, SWT.NONE);
        libFolderLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
        libFolderLabel.setText("Destination folder");

        libfolderText = new Text(container, SWT.BORDER);
        libfolderText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
        libfolderText.setEditable(true);
        libfolderText.setText(libFolder.getFullPath().toPortableString());
        libfolderText.addModifyListener(new ModifyListener() {
            @Override
            public void modifyText(ModifyEvent event) {
                validate();
            }
        });

        addSelectFolderButton(container);
        displayClasspathEntriesTable(container);

        return area;
    }

    private void displayWarning(Composite container, String warning) {
        Composite composite = new Composite(container, SWT.NONE);
        GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).span(3, 1).applyTo(composite);
        GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);
        warningImg = new Label(composite, SWT.CENTER);
        warningImg.setImage(JFaceResources.getImage(DLG_IMG_MESSAGE_WARNING));
        GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).applyTo(warningImg);
        warningLabel = new Label(composite, SWT.NONE);
        warningLabel.setText(warning);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).applyTo(warningLabel);
    }

    private void addSelectFolderButton(Composite container) {

        Button button = new Button(container, SWT.NONE);
        button.setLayoutData(new GridData(SWT.FILL, SWT.UP, false, false, 1, 1));
        button.setText("Select Folder");
        button.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(),
                        getLibFolderFromText(libfolderText.getText()), true, "Select Destination Folder");
                dialog.setTitle("Container Selection");
                dialog.open();
                Object[] result = dialog.getResult();
                if (result != null && result[0] instanceof IPath) {
                    libfolderText.setText(((IPath) result[0]).toPortableString());
                }
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
    }

    @Override
    public boolean close() {
        if (jarImage != null) {
            jarImage.dispose();
        }
        if (projectImage != null) {
            projectImage.dispose();
        }
        return super.close();
    }

    private void displayClasspathEntriesTable(Composite container) {
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 4);
        gd.heightHint = 500;
        gd.widthHint = 550;

        classpathEntriesViewer = CheckboxTableViewer.newCheckList(container,
                SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
        Table table = classpathEntriesViewer.getTable();
        table.setFocus();
        table.setLayoutData(gd);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);

        TableColumn emptyColumn = new TableColumn(table, SWT.NONE);
        emptyColumn.setWidth(20);

        TableViewerColumn sourceColumn = new TableViewerColumn(classpathEntriesViewer, SWT.NONE);
        sourceColumn.getColumn().setText("Source ");
        sourceColumn.getColumn().setWidth(299);

        TableViewerColumn destinationColumn = new TableViewerColumn(classpathEntriesViewer, SWT.NONE);
        destinationColumn.getColumn().setText("Copy as...");
        destinationColumn.getColumn().setWidth(248);

        classpathEntriesViewer.setContentProvider(ArrayContentProvider.getInstance());
        classpathEntriesViewer.setLabelProvider(new ClasspathEntryLabelProvider());
        classpathEntriesViewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(CheckStateChangedEvent event) {
                refresh();
            }
        });
        classpathEntriesViewer.setInput(classpathEntryPaths.entrySet());
        classpathEntriesViewer.setAllChecked(true);

        addSelectionButton(container, "Select All", true);
        addSelectionButton(container, "Deselect All", false);
        addResetButton(container, "Reset");

        keepSourceBtn = addCheckButton(container, "Keep source attachments", keepSources);
        keepSourceBtn.setToolTipText("Source attachment paths may contain absolute paths");
        addTableListeners();

    }

    private Button addCheckButton(Composite container, String label, boolean selected) {
        Button checkBtn = new Button(container, SWT.CHECK);
        checkBtn.setText(label);
        checkBtn.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
        checkBtn.setSelection(selected);
        return checkBtn;
    }

    private void addTableListeners() {
        addCellEditors();
    }

    protected void addCellEditors() {
        classpathEntriesViewer.setColumnProperties(new String[] { "EMPTY", SOURCE_PROPERTY, FILENAME_PROPERTY });

        TextCellEditor ce = new TextCellEditor(classpathEntriesViewer.getTable());
        CellEditor[] editors = new CellEditor[] { null, ce, ce };
        classpathEntriesViewer.setCellEditors(editors);
        classpathEntriesViewer.setCellModifier(new FileNameCellModifier());
    }

    public Map<IPath, String> getSelectedClasspathEntryPaths() {
        return selectedClasspathEntryPaths;
    }

    public IContainer getLibFolder() {
        return libFolder;
    }

    public boolean isKeepSources() {
        return keepSources;
    }

    private static IContainer getLibFolderFromText(String text) {
        String portablePath = text.replaceAll("\\\\", "/");
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
        IPath path = new Path(portablePath);
        if (path.segmentCount() == 1) {
            return workspaceRoot.getProject(path.segment(0));
        }
        if (path.segmentCount() > 1) {
            return ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
        }
        return null;
    }

    @Override
    protected void okPressed() {
        if (!validate()) {
            return;
        }

        String dialogWarning = warningfactory.getDialogWarning(containerToMaterialize);
        if (dialogWarning != null) {
            String[] buttonLabels = new String[] { IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL };

            MessageDialog dialog = new MessageDialog(getShell(), getShell().getText(), null, dialogWarning,
                    MessageDialog.WARNING, buttonLabels, 0);
            if (dialog.open() == CANCEL) {
                return;
            }
        }
        libFolder = getLibFolderFromText(libfolderText.getText());
        keepSources = keepSourceBtn.getSelection();
        super.okPressed();
    }

    private boolean validate() {
        boolean valid = validateLibFolder() && validateEntries();
        if (valid) {
            setErrorMessage(null);
        }
        return valid;
    }

    private boolean validateLibFolder() {
        IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

        IContainer folder = getLibFolderFromText(libfolderText.getText());
        if (folder == null || workspaceRoot.equals(folder)) {
            setErrorMessage("You must select a project destination to copy classpath entries");
            return false;
        }
        String ancestorPath = folder.getFullPath().segment(0);
        IResource ancestor = workspaceRoot.findMember(ancestorPath);
        if (ancestor == null || !ancestor.exists()) {
            setErrorMessage(ancestorPath + " does not exist ");
            return false;
        }
        return true;
    }

    @SuppressWarnings("unchecked")
    private boolean validateEntries() {
        Object[] selection = classpathEntriesViewer.getCheckedElements();
        selectedClasspathEntryPaths = new LinkedHashMap<IPath, String>(selection.length);
        for (Object o : selection) {
            Map.Entry<IClasspathEntry, String> entry = (Map.Entry<IClasspathEntry, String>) o;
            if (entry.getKey().getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                String name = entry.getValue();
                if (!checkValidName(name)) {
                    setErrorMessage(name + " is not a valid file name");
                    return false;
                }
            }
            selectedClasspathEntryPaths.put(entry.getKey().getPath(), entry.getValue());
        }

        Set<String> duplicates = findDuplicates(selectedClasspathEntryPaths.values());
        if (!duplicates.isEmpty()) {
            setErrorMessage("Duplicate entries found : " + duplicates.toString());
            return false;
        }
        return true;
    }

    private Set<String> findDuplicates(Collection<String> values) {
        Set<String> uniqueNames = new HashSet<String>(values.size());
        Set<String> duplicateNames = new HashSet<String>();
        for (String name : values) {
            if (!uniqueNames.add(name)) {
                duplicateNames.add(name);
            }
        }
        return duplicateNames;
    }

    @SuppressWarnings("unchecked")
    private class ClasspathEntryLabelProvider extends LabelProvider implements ITableLabelProvider {

        private static final int SOURCE_COLUMN = 1;
        private static final int FILENAME_COLUMN = 2;

        public String getColumnText(Object element, int columnIndex) {
            Map.Entry<IClasspathEntry, String> entry = (Map.Entry<IClasspathEntry, String>) element;
            StringBuilder text = new StringBuilder();
            if (entry != null) {
                if (columnIndex == SOURCE_COLUMN) {
                    text.append(entry.getKey().getPath().lastSegment());
                } else if (columnIndex == FILENAME_COLUMN) {
                    text.append(entry.getValue());
                }
            }

            return text.toString();
        }

        @Override
        public Image getColumnImage(Object element, int columnIndex) {
            Image img = null;
            if (columnIndex > 0) {
                Map.Entry<IClasspathEntry, String> entry = (Map.Entry<IClasspathEntry, String>) element;
                if (entry.getKey().getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                    img = jarImage;
                } else {
                    img = projectImage;
                }
            }
            return img;
        }
    }

    private Button addSelectionButton(Composite container, String label, final boolean ischecked) {
        Button button = new Button(container, SWT.NONE);
        button.setLayoutData(new GridData(SWT.FILL, SWT.UP, false, false, 1, 1));
        button.setText(label);
        button.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                classpathEntriesViewer.setAllChecked(ischecked);
                refresh();
            }

            public void widgetDefaultSelected(SelectionEvent e) {

            }
        });

        return button;
    }

    private Button addResetButton(Composite container, String label) {
        Button button = new Button(container, SWT.NONE);
        button.setLayoutData(new GridData(SWT.FILL, SWT.UP, false, false, 1, 1));
        button.setText(label);
        button.addSelectionListener(new SelectionListener() {
            public void widgetSelected(SelectionEvent e) {
                initClasspathEntryPaths();
                classpathEntriesViewer.setInput(classpathEntryPaths.entrySet());
                classpathEntriesViewer.setAllChecked(true);
                refresh();
            }

            public void widgetDefaultSelected(SelectionEvent e) {

            }
        });

        return button;
    }

    protected void refresh() {
        classpathEntriesViewer.refresh();
    }

    @SuppressWarnings("unchecked")
    private class FileNameCellModifier implements ICellModifier {

        public boolean canModify(Object element, String property) {
            Map.Entry<IClasspathEntry, String> entry = (Map.Entry<IClasspathEntry, String>) element;
            return (entry.getKey().getEntryKind() == IClasspathEntry.CPE_LIBRARY)
                    && (FILENAME_PROPERTY.equals(property) || SOURCE_PROPERTY.equals(property));
        }

        public Object getValue(Object element, String property) {
            Map.Entry<IClasspathEntry, String> entry = (Map.Entry<IClasspathEntry, String>) element;
            // if(entry.getKey().getEntryKind() == IClasspathEntry.CPE_LIBRARY)
            // {
            if (property.equals(SOURCE_PROPERTY)) {
                return entry.getKey().getPath().toOSString();
            } else if (property.equals(FILENAME_PROPERTY)) {
                return entry.getValue();
            }
            // }
            return ""; //$NON-NLS-1$
        }

        public void modify(Object element, String property, Object value) {
            if (property.equals(FILENAME_PROPERTY)) {
                TableItem item = (TableItem) element;
                Map.Entry<IClasspathEntry, String> entry = (Map.Entry<IClasspathEntry, String>) item.getData();
                if (entry.getKey().getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
                    String name = value.toString();
                    entry.setValue(name);
                    validate();
                    classpathEntriesViewer.refresh();
                }
            }
        }
    }

    public boolean checkValidName(String name) {
        // TODO checks for :
        // - duplicates
        // - existing CPE
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        IStatus result = workspace.validateName(name, IResource.FILE);
        if (!result.isOK()) {
            return false;
        }
        return !name.contains("\\") && (name.endsWith(".jar") || name.endsWith(".zip"));
    }
}