dynamicrefactoring.interfaz.wizard.ImportWizard.java Source code

Java tutorial

Introduction

Here is the source code for dynamicrefactoring.interfaz.wizard.ImportWizard.java

Source

/*<Dynamic Refactoring Plugin For Eclipse 2.0 - Plugin that allows to perform refactorings 
on Java code within Eclipse, as well as to dynamically create and manage new refactorings>
    
Copyright (C) 2009  Laura Fuente De La Fuente
    
This file is part of Foobar
    
Foobar 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 dynamicrefactoring.interfaz.wizard;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.ChoiceFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
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.Point;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
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 dynamicrefactoring.RefactoringImages;
import dynamicrefactoring.RefactoringPlugin;
import dynamicrefactoring.domain.DynamicRefactoringDefinition;
import dynamicrefactoring.domain.RefactoringsCatalog;
import dynamicrefactoring.domain.xml.ExportImportUtilities;
import dynamicrefactoring.domain.xml.XMLRefactoringUtils;
import dynamicrefactoring.domain.xml.XMLRefactoringsCatalog;
import dynamicrefactoring.interfaz.ButtonTextProvider;
import dynamicrefactoring.interfaz.CustomProgressDialog;
import dynamicrefactoring.util.DynamicRefactoringLister;
import dynamicrefactoring.util.io.FileManager;

/**
 * Proporciona un asistente que permite buscar e importar refactorizaciones
 * dinmicas existentes fuera del <i>plugin</i>.
 * 
 * @author <A HREF="mailto:lfd0002@alu.ubu.es">Laura Fuente de la Fuente</A>
 * @author <A HREF="mailto:sfd0009@alu.ubu.es">Sonia Fuente de la Fuente</A>
 * @author <A HREF="mailto:ehp0001@alu.ubu.es">Enrique Herrero Paredes</A>
 */
public class ImportWizard extends Dialog {

    /**
     * Elemento de registro de errores y otros eventos de la clase.
     */
    private static final Logger logger = Logger.getLogger(ImportWizard.class);

    /**
     * Tabla con la lista de refactorizaciones encontradas en el directorio especificado.
     */
    private Table tb_Refactorings;

    /**
     * Ruta del directorio en que se deben buscar las refactorizaciones.
     */
    private Text t_Input;

    /**
     * Botn que lanza el proceso de importacin.
     */
    private Button bt_Import;

    /**
     * Casilla de seleccin que indica si la bsqueda ha de ser recursiva o no.
     */
    private Button cbt_Recursive;

    /**
     * Mensaje informativo mostrado al usuario en cada momento.
     */
    private Text t_Message;

    /**
     * Nombres de las refactorizaciones que, de importarse, sobreescribiran
     * otras ya existentes.
     */
    private ArrayList<String> overwritten;

    /**
     * Consejo mostrado al usuario sobre la bsqueda de refactorizaciones.
     */
    private String advise;

    /**
     * Icono mostrado junto al texto de aviso.
     */
    private Label lb_Icon;

    /**
     * Refactorizaciones encontradas en el directorio destino.
     */
    private HashMap<String, String> refactorings;

    /**
     * Catlogo de refactorizaciones.
     */
    private final RefactoringsCatalog catalog;

    /**
     * Crea la ventana de dilogo.
     * 
     * @param catalog
     *            catlogo de refactorizaciones
     * 
     * @param parentShell
     *            <i>shell</i> padre de la ventana de dilogo.
     */
    public ImportWizard(Shell parentShell, RefactoringsCatalog catalog) {
        super(parentShell);
        this.catalog = catalog;
    }

    /**
     * Crea el contenido de la ventana de dilogo.
     * 
     * @param parent
     *            componente padre de los contenidos de la ventana.
     * 
     * @return el control asociado al rea de dilogo.
     */
    @Override
    protected Control createDialogArea(Composite parent) {
        Composite container = (Composite) super.createDialogArea(parent);
        container.setLayout(null);

        t_Input = new Text(container, SWT.BORDER);
        t_Input.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
        t_Input.setEnabled(false);
        t_Input.setToolTipText(Messages.ImportWizard_SelectInputFolder);
        t_Input.setBounds(10, 34, 234, 25);
        t_Input.addModifyListener(new InputListener());

        final Button bt_Examine = new Button(container, SWT.NONE);
        bt_Examine.setText("..."); //$NON-NLS-1$
        bt_Examine.setBounds(250, 36, 24, 23);
        bt_Examine.addSelectionListener(
                new FolderSelectionListener(t_Input, getShell(), Messages.ImportWizard_SelectImportFolder + ".")); //$NON-NLS-1$

        final Label lb_Input = new Label(container, SWT.NONE);
        lb_Input.setText(Messages.ImportWizard_InputFolder);
        lb_Input.setBounds(10, 15, 353, 13);

        lb_Icon = new Label(container, SWT.CENTER);
        lb_Icon.setBounds(9, 303, 25, 25);

        tb_Refactorings = new Table(container, SWT.CHECK | SWT.MULTI | SWT.BORDER);
        tb_Refactorings.setSortDirection(SWT.UP);
        tb_Refactorings.setToolTipText(Messages.ImportWizard_SelectRefactorings);
        tb_Refactorings.setLinesVisible(true);
        tb_Refactorings.setHeaderVisible(true);
        tb_Refactorings.setBounds(10, 95, 383, 202);
        tb_Refactorings.addSelectionListener(new SelectionListener() {
            public void widgetDefaultSelected(SelectionEvent e) {
                widgetSelected(e);
            }

            public void widgetSelected(SelectionEvent e) {
                int count = 0;
                for (int i = 0; i < tb_Refactorings.getItemCount(); i++)
                    if (tb_Refactorings.getItem(i).getChecked())
                        count++;

                if (count > 0)
                    bt_Import.setEnabled(true);
                else
                    bt_Import.setEnabled(false);

                double limits[] = { 0, 1, ChoiceFormat.nextDouble(1) };
                String formats[] = { Messages.ImportWizard_0Imported, Messages.ImportWizard_1Imported,
                        Messages.ImportWizard_SeveralImported };
                ChoiceFormat form = new ChoiceFormat(limits, formats);

                Object[] messageArgs = { count };
                MessageFormat formatter = new MessageFormat(""); //$NON-NLS-1$
                formatter.applyPattern(form.format(count));

                t_Message.setText(formatter.format(messageArgs) + "."); //$NON-NLS-1$
                lb_Icon.setImage(RefactoringImages.getInfoIcon());
            }
        });

        final TableColumn cl_Name = new TableColumn(tb_Refactorings, SWT.NONE);
        cl_Name.setWidth(379);
        cl_Name.setText(Messages.ImportWizard_Name);

        final Label theFollowingRefactoringsLabel = new Label(container, SWT.NONE);
        theFollowingRefactoringsLabel.setText(Messages.ImportWizard_FoundRefactorings);
        theFollowingRefactoringsLabel.setBounds(10, 76, 383, 13);

        t_Message = new Text(container, SWT.WRAP | SWT.V_SCROLL | SWT.READ_ONLY | SWT.MULTI);
        t_Message.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_CYAN));
        t_Message.setEditable(false);
        t_Message.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
        t_Message.setBounds(40, 312, 353, 64);

        cbt_Recursive = new Button(container, SWT.CHECK);
        cbt_Recursive.setToolTipText(Messages.ImportWizard_SelectRecursive);
        cbt_Recursive.setImage(RefactoringImages.getRecursiveIcon());
        cbt_Recursive.setText(Messages.ImportWizard_Recursive);
        cbt_Recursive.setBounds(294, 40, 107, 16);

        return container;
    }

    /**
     * Crea el contenido de la barra de botones.
     * 
     * @param parent elemento padre de los contenidos de la barra de botones.
     */
    @Override
    protected void createButtonsForButtonBar(Composite parent) {
        bt_Import = createButton(parent, IDialogConstants.OK_ID, Messages.ImportWizard_Import, true);
        bt_Import.setEnabled(false);
        createButton(parent, IDialogConstants.CANCEL_ID, ButtonTextProvider.getCancelText(), false);
    }

    /**
     * Obtiene el tamao inicial de la ventana de dilogo.
     * @return tamao inicial
     */
    @Override
    protected Point getInitialSize() {
        return new Point(411, 458);
    }

    /**
     * Prepara la ventana de dilogo para su apertura.
     * 
     * @param newShell
     *            <i>shell</i> que abrir la ventana.
     */
    @Override
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        newShell.setText(Messages.ImportWizard_ImportRefactorings);
        newShell.setImage(RefactoringImages.getImportIcon());
    }

    /**
     * Puebla la tabla con los nombres de las refactorizaciones encontradas.
     */
    private void fillInTable() {
        for (Entry<String, String> entry : refactorings.entrySet()) {
            // Se crea la nueva entrada de la tabla.
            TableItem item = new TableItem(tb_Refactorings, SWT.BORDER);
            item.setText(0, entry.getKey());
            item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_CYAN));
        }
    }

    /**
     * Elimina los elementos de la tabla.
     */
    private void cleanTable() {
        tb_Refactorings.removeAll();
    }

    /**
     * Implementa la funcionalidad de importacin, lanzada como respuesta a la
     * pulsacin del botn correspondiente.
     * 
     * @param buttonId
     *            identificador del botn que ha sido pulsado en el dilogo.
     */
    @Override
    protected void buttonPressed(int buttonId) {
        if (buttonId == IDialogConstants.OK_ID) {

            ArrayList<String> checked = new ArrayList<String>(tb_Refactorings.getItemCount());
            for (int i = 0; i < tb_Refactorings.getItemCount(); i++)
                if (tb_Refactorings.getItem(i).getChecked())
                    checked.add(tb_Refactorings.getItem(i).getText(0));

            if (checked.size() > 0) {

                String[] names = new String[checked.size()];
                names = checked.toArray(names);

                try {
                    ImportJob job = new ImportJob(names);
                    new CustomProgressDialog(getShell()).run(true, false, job);

                    double limits[] = { 0, 1, ChoiceFormat.nextDouble(1) };
                    String formats[] = { Messages.ImportWizard_0WereImproted, Messages.ImportWizard_1WereImproted,
                            Messages.ImportWizard_SeveralWereImproted };
                    ChoiceFormat form = new ChoiceFormat(limits, formats);

                    Object[] messageArgs = { checked.size() };
                    MessageFormat formatter = new MessageFormat(""); //$NON-NLS-1$
                    formatter.applyPattern(form.format(checked.size()));

                    MessageDialog.openInformation(getShell(), Messages.ImportWizard_ImportDone,
                            formatter.format(messageArgs) + "."); //$NON-NLS-1$
                } catch (InterruptedException e) {
                    // El usuario cancel el proceso.
                    logger.warn(e.getMessage());
                } catch (Exception exception) {
                    String message = Messages.ImportWizard_NotAllImported + ":\n\n" + exception.getMessage(); //$NON-NLS-1$
                    logger.fatal(message);
                    MessageDialog.openError(getShell(), Messages.ImportWizard_Error, message);
                }
            }
        }
        super.buttonPressed(buttonId);
    }

    /**
     * Actualiza el mensaje de aviso mostrado en la ventana, en funcin de los
     * valores de configuracin actuales resultantes de la ltima bsqueda.
     */
    private void updateMessage() {
        if (overwritten != null && overwritten.size() > 0) {
            String names = overwritten.get(0);
            for (int i = 1; i < overwritten.size(); i++) {
                names += ", " + overwritten.get(i); //$NON-NLS-1$
            }

            Object[] messageArgs = { names };
            MessageFormat formatter = new MessageFormat(""); //$NON-NLS-1$
            formatter.applyPattern(Messages.ImportWizard_NamesAlreadyExist);

            t_Message.setText(formatter.format(messageArgs) + ". " + //$NON-NLS-1$
                    Messages.ImportWizard_WillOverwrite + "."); //$NON-NLS-1$
            lb_Icon.setImage(RefactoringImages.getWarningIcon());

        } else if (advise == null) {
            Object[] messageArgs = { refactorings.size() };
            MessageFormat formatter = new MessageFormat(""); //$NON-NLS-1$
            formatter.applyPattern(Messages.ImportWizard_NumberFound);

            t_Message.setText(formatter.format(messageArgs) + "."); //$NON-NLS-1$
            lb_Icon.setImage(RefactoringImages.getInfoIcon());
        } else {
            t_Message.setText(advise);
            lb_Icon.setImage(RefactoringImages.getWarningIcon());
        }
    }

    /**
     * Actualiza la tabla de refactorizaciones encontradas que se pueden importar.
     * 
     * @author <A HREF="mailto:sfd0009@alu.ubu.es">Sonia Fuente de la Fuente</A>
     * @author <A HREF="mailto:ehp0001@alu.ubu.es">Enrique Herrero Paredes</A>
     */
    private class InputListener implements ModifyListener {

        /**
         * Recibe notificaciones cada vez que se modifica el texto observado.
         * 
         * @param e
         *            el evento de modificacin del texto.
         */
        @Override
        public void modifyText(ModifyEvent e) {
            Text field = (Text) e.getSource();

            try {
                refactorings = new HashMap<String, String>();
                overwritten = new ArrayList<String>();

                try {
                    RefactoringSearchJob job = new RefactoringSearchJob(field.getText().trim(),
                            cbt_Recursive.getSelection());
                    new CustomProgressDialog(getShell()).run(true, true, job);

                    cleanTable();
                    fillInTable();
                    updateMessage();
                } catch (InterruptedException exception) {
                    // El usuario cancel el proceso.
                    logger.warn(exception.getMessage());
                } catch (Exception exception) {
                    String message = Messages.ImportWizard_ErrorWhileLooking + ".\n\n:" + exception.getMessage(); //$NON-NLS-1$
                    logger.fatal(message);
                    MessageDialog.openError(getShell(), Messages.ImportWizard_Error, message);
                }
            } catch (Exception exception) {
                String message = Messages.ImportWizard_FolderCannotBeAccessed;
                logger.error(message + ": " + exception.getMessage()); //$NON-NLS-1$
                t_Message.setText(message);
                lb_Icon.setImage(RefactoringImages.getErrorIcon());
            }
        }
    }

    /**
     * Permite lanzar el trabajo de importacin de refactorizaciones y hacer un
     * seguimiento de su progreso.
     * 
     * @author <A HREF="mailto:sfd0009@alu.ubu.es">Sonia Fuente de la Fuente</A>
     * @author <A HREF="mailto:ehp0001@alu.ubu.es">Enrique Herrero Paredes</A>
     */
    private class ImportJob implements IRunnableWithProgress {

        /**
         * Nombres de las refactorizaciones que se deben importar.
         */
        private String[] names;

        /**
         * Constructor.
         * 
         * @param names nombres de las refactorizaciones que se deben importar.
         */
        public ImportJob(String[] names) {
            this.names = names;
        }

        /**
         * Ejecuta el trabajo de importacin de refactorizaciones.
         * 
         * @param monitor
         *            el monitor de progreso que deber usarse para mostrar el
         *            progreso.
         * 
         * @throws InvocationTargetException
         *             utilizada como envoltura si el mtodo debe propagar una
         *             excepcin (<i>checked exception</i>). Las excepciones de
         *             tipo <i>runtime exception</i> se envuelven
         *             automticamente en una excepcin de este tipo por el
         *             contexto que efecta la llamada.
         * @throws InterruptedException
         *             si la operacin detecta una solicitud de cancelacin (no
         *             disponible).
         * 
         * @see IRunnableWithProgress#run(IProgressMonitor)
         */
        @Override
        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

            monitor.beginTask(Messages.ImportWizard_Importing, names.length);
            try {

                for (String next : names) {

                    Object[] messageArgs = { next };
                    MessageFormat formatter = new MessageFormat(""); //$NON-NLS-1$
                    formatter.applyPattern(Messages.ImportWizard_ImportingFile);
                    monitor.subTask(formatter.format(messageArgs) + "..."); //$NON-NLS-1$

                    // Se obtiene la ruta del fichero con la definicin.
                    String definition = refactorings.get(next);
                    String folder = new File(definition).getParent();

                    try {
                        ExportImportUtilities.importRefactoring(definition, false,
                                XMLRefactoringsCatalog.getInstance());
                    } catch (FileNotFoundException e) {

                        // Elimina la carpeta de la refactorizacin ya que
                        // si ha llegado
                        //a este punto quiere decir que no se ha podido completar la tarea
                        //adecuadamente.
                        StringTokenizer st_namefolder = new StringTokenizer(folder, "" + File.separatorChar + "");
                        String namefolder = "";
                        while (st_namefolder.hasMoreTokens()) {
                            namefolder = st_namefolder.nextElement().toString();
                        }
                        FileManager.emptyDirectories(RefactoringPlugin.getDynamicRefactoringsDir() + ""
                                + File.separatorChar + "" + namefolder);
                        FileManager.deleteDirectories(RefactoringPlugin.getDynamicRefactoringsDir() + ""
                                + File.separatorChar + "" + namefolder, true);
                        throw e;

                    } catch (IOException e) {
                        messageArgs = new Object[] { folder };
                        formatter = new MessageFormat(""); //$NON-NLS-1$
                        formatter.applyPattern(Messages.ImportWizard_NotCopied);
                        throw new Exception(formatter.format(messageArgs) + "."); //$NON-NLS-1$
                    }

                    monitor.worked(1);
                }
            } catch (Exception exception) {
                String message = Messages.ImportWizard_ErrorImporting + ":\n\n" + exception.getMessage(); //$NON-NLS-1$
                logger.error(message);
                throw new InvocationTargetException(exception);
            } finally {
                monitor.done();
            }
        }
    }

    /**
     * Permite lanzar el trabajo de bsqueda de refactorizaciones y hacer un
     * seguimiento de su progreso.
     * 
     * @author <A HREF="mailto:sfd0009@alu.ubu.es">Sonia Fuente de la Fuente</A>
     * @author <A HREF="mailto:ehp0001@alu.ubu.es">Enrique Herrero Paredes</A>
     */
    private class RefactoringSearchJob implements IRunnableWithProgress {

        /**
         * Directorio a partir del que se buscan refactorizaciones.
         */
        private String folder;

        /**
         * Si la bsqueda ha de ser recursiva o no.
         */
        private boolean recursive;

        /**
         * Constructor.
         * 
         * @param folder
         *            directorio a partir del que se deben buscar las
         *            refactorizaciones.
         * @param recursive
         *            si la bsqueda debe ser recursiva o no.
         */
        public RefactoringSearchJob(String folder, boolean recursive) {
            this.folder = folder;
            this.recursive = recursive;
        }

        /**
         * Ejecuta el trabajo de bsqueda de refactorizaciones.
         * 
         * @param monitor
         *            el monitor de progreso que deber usarse para mostrar el
         *            progreso.
         * 
         * @throws InvocationTargetException
         *             utilizada como envoltura si el mtodo debe propagar una
         *             excepcin (<i>checked exception</i>). Las excepciones de
         *             tipo <i>runtime exception</i> se envuelven
         *             automticamente en una excepcin de este tipo por el
         *             contexto que efecta la llamada.
         * @throws InterruptedException
         *             si la operacin detecta una solicitud de cancelacin (no
         *             disponible).
         * 
         * @see IRunnableWithProgress#run(IProgressMonitor)
         */
        @Override
        public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {

            monitor.beginTask(Messages.ImportWizard_Looking, IProgressMonitor.UNKNOWN);
            try {
                monitor.subTask(Messages.ImportWizard_Traversing);
                DynamicRefactoringLister lister = DynamicRefactoringLister.getInstance();
                refactorings = lister.getDynamicRefactoringNameList(folder, recursive, monitor);
                monitor.worked(1);

                String[] names = refactorings.keySet().toArray(new String[0]);
                monitor.beginTask(Messages.ImportWizard_Validating, names.length);
                for (int i = 0; i < names.length; i++) {
                    String path = refactorings.get(names[i]);

                    Object[] messageArgs = { names[i] };
                    MessageFormat formatter = new MessageFormat(""); //$NON-NLS-1$
                    formatter.applyPattern(Messages.ImportWizard_ValidatingFile);

                    monitor.subTask(formatter.format(messageArgs) + "..."); //$NON-NLS-1$

                    try {
                        // Se intenta obtener la definicin de la siguiente
                        // refactorizacin.
                        XMLRefactoringUtils.getRefactoringDefinition(path);

                        // Solo se recogen refactorizaciones cuya carpeta se
                        // llame igual que su fichero.
                        File definition = new File(path);
                        String fileName = definition.getName();
                        String folderName = definition.getParentFile().getName();
                        fileName = fileName.substring(0, fileName.toLowerCase().lastIndexOf(".xml")); //$NON-NLS-1$
                        if (!fileName.equals(folderName)) {
                            advise = Messages.ImportWizard_FoundDiscarded + ": " //$NON-NLS-1$
                                    + Messages.ImportWizard_MakeSureSameName + ".";
                            throw new Exception();
                        }

                        // Si ya hay una refactorizacin con ese nombre.
                        if (catalog.hasRefactoring(fileName)) {
                            DynamicRefactoringDefinition refact = catalog.getRefactoring(fileName);
                            // Si es editable se aade un aviso de
                            // sobreescritura.
                            if (refact.isEditable()) {
                                overwritten.add(names[i].substring(0, names[i].indexOf(" ("))); //$NON-NLS-1$
                                // Si no es de usuario, se descarta.
                            } else {
                                refactorings.remove(names[i]);
                            }
                        }
                    } catch (Exception exception) {
                        refactorings.remove(names[i]);
                    }

                    monitor.worked(1);

                    if (refactorings.size() == 0)
                        advise = Messages.ImportWizard_NoneFound;
                }
            } catch (Exception exception) {
                String message = Messages.ImportWizard_ErrorLooking + ":\n\n" + exception.getMessage(); //$NON-NLS-1$
                logger.error(message);
                throw new InvocationTargetException(exception);
            } finally {
                monitor.done();
            }
        }
    }
}