org.eclipse.rcptt.ui.wizards.plain.Q7PortableFormatImportPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.rcptt.ui.wizards.plain.Q7PortableFormatImportPage.java

Source

/*******************************************************************************
 * Copyright (c) 2009, 2015 Xored Software 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:
 *     Xored Software Inc - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.rcptt.ui.wizards.plain;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.rcptt.core.Scenarios;
import org.eclipse.rcptt.core.model.IContext;
import org.eclipse.rcptt.core.model.IQ7Element;
import org.eclipse.rcptt.core.model.IQ7Folder;
import org.eclipse.rcptt.core.model.IQ7NamedElement;
import org.eclipse.rcptt.core.model.IQ7Project;
import org.eclipse.rcptt.core.model.ITestCase;
import org.eclipse.rcptt.core.model.IVerification;
import org.eclipse.rcptt.core.model.ModelException;
import org.eclipse.rcptt.core.model.search.Q7SearchCore;
import org.eclipse.rcptt.core.persistence.IPersistenceModel;
import org.eclipse.rcptt.core.persistence.PersistenceManager;
import org.eclipse.rcptt.core.persistence.plain.IPlainConstants;
import org.eclipse.rcptt.core.scenario.GroupContext;
import org.eclipse.rcptt.core.scenario.Scenario;
import org.eclipse.rcptt.core.workspace.RcpttCore;
import org.eclipse.rcptt.ecl.core.Script;
import org.eclipse.rcptt.internal.core.RcpttPlugin;
import org.eclipse.rcptt.internal.core.model.Q7Folder;
import org.eclipse.rcptt.internal.core.model.Q7ResourceInfo;
import org.eclipse.rcptt.internal.core.model.ReferencedProjectScope;
import org.eclipse.rcptt.internal.ui.Messages;
import org.eclipse.rcptt.internal.ui.Q7UIPlugin;
import org.eclipse.rcptt.ui.utils.WriteAccessChecker;
import org.eclipse.rcptt.ui.wizards.LocationSelectionDialog;
import org.eclipse.rcptt.ui.wizards.plain.DestinationsBox.Selection;
import org.eclipse.rcptt.util.FileUtil;
import org.eclipse.rcptt.util.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class Q7PortableFormatImportPage extends WizardPage implements IPlainConstants {
    private static final String CONTEXTS_PREFIX = "/contexts/";
    private static final String VERIFICATIONS_PREFIX = "/verifications/";
    private DestinationsBox destinations;
    private DataBindingContext dbc = new DataBindingContext();

    private WritableValue previewValue = new WritableValue("", String.class);
    private boolean isValid = false;
    private WritableValue locationValue = new WritableValue("", String.class);
    private WritableValue testcaseNameValue = new WritableValue("", String.class);

    private IContainer initialContainer;

    protected Q7PortableFormatImportPage(String pageName, IContainer container) {
        super(pageName);
        setDescription("Select the source to import test case from");
        setTitle("RCPTT Portable Format");
        this.initialContainer = container;
        if (this.initialContainer != null) {
            this.locationValue.setValue(initialContainer.getFullPath().toString());
        }
    }

    public void createControl(Composite parent) {
        Composite cp = new Composite(parent, SWT.NONE);
        GridLayoutFactory.swtDefaults().applyTo(cp);

        Composite infoGroup = new Composite(cp, SWT.NONE);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(infoGroup);
        GridLayoutFactory.fillDefaults().numColumns(3).applyTo(infoGroup);

        Label label = new Label(infoGroup, SWT.LEFT);
        label.setText(Messages.WizardExecutablePage_LocationLabel);

        Text locationText = new Text(infoGroup, SWT.BORDER);
        GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER).grab(true, false).applyTo(locationText);
        dbc.bindValue(SWTObservables.observeText(locationText, SWT.Modify), locationValue);

        Button browse = new Button(infoGroup, SWT.PUSH);
        browse.setText(Messages.WizardExecutablePage_BrowseButton);
        browse.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                browseLocation();
            }
        });
        setButtonLayoutData(browse);

        Label l = new Label(infoGroup, SWT.NONE);
        l.setText("Testcase name:");
        Text testCaseName = new Text(infoGroup, SWT.BORDER);
        GridDataFactory.fillDefaults().grab(true, false).applyTo(testCaseName);
        dbc.bindValue(SWTObservables.observeText(testCaseName, SWT.Modify), testcaseNameValue);

        destinations = new DestinationsBox(dbc) {
            @Override
            protected String getFileTitle() {
                return "Import from File";
            }

            @Override
            protected String getClipboardTitle() {
                return "Import from Clipboard";
            }

            @Override
            protected int getFileKind() {
                return SWT.OPEN;
            }
        };

        destinations.create(cp);

        Group preview = new Group(cp, SWT.NONE);
        preview.setText("Preview");
        GridDataFactory.fillDefaults().hint(200, 200).grab(true, true).applyTo(preview);
        GridLayoutFactory.swtDefaults().applyTo(preview);

        StyledText text = new StyledText(preview, SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        text.setCaret(null);
        FontData dt = new FontData("monospace", 10, 0);
        text.setFont(new Font(text.getDisplay(), dt));
        dbc.bindValue(SWTObservables.observeText(text, SWT.Modify), previewValue);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(text);

        setControl(cp);

        updateImport();

        locationValue.addChangeListener(new IChangeListener() {
            public void handleChange(ChangeEvent event) {
                validate();
            }
        });

        testcaseNameValue.addChangeListener(new IChangeListener() {
            public void handleChange(ChangeEvent event) {
                validate();
            }
        });

        destinations.addChangeListener(new Runnable() {
            public void run() {
                Selection kind = destinations.getKind();
                switch (kind) {
                case Clipboard:
                    setErrorMessage(null);
                    setPageComplete(true);
                    updateImport();
                    break;
                case Filesystem:
                    String path = destinations.getFileSystemPath();
                    if (path == null || path.trim().length() == 0 || (new File(path).isDirectory())
                            || !(new File(path).exists())) {
                        setErrorMessage("Please specify correct file name to import testcase");
                        setPageComplete(false);
                    } else {
                        setPageComplete(true);
                        setErrorMessage(null);
                        updateImport();
                    }
                    break;
                default:
                    break;
                }
            }
        });
    }

    protected void browseLocation() {
        LocationSelectionDialog dialog = new LocationSelectionDialog(getShell());
        dialog.setLocation((String) locationValue.getValue());
        if (dialog.open() == LocationSelectionDialog.OK) {
            locationValue.setValue(dialog.getLocation());
        }
    }

    private void updateImport() {
        switch (destinations.getKind()) {
        case Clipboard:
            Clipboard clipboard = new Clipboard(Display.getCurrent());
            Object contents = clipboard.getContents(TextTransfer.getInstance());
            if (contents != null && contents instanceof String) {
                previewValue.setValue(contents);
            }
            clipboard.dispose();
            break;
        case Filesystem:
            File file = new File(destinations.getFileSystemPath());
            if (file.exists() && file.isFile()) {
                try {
                    byte[] content = FileUtil.getStreamContent(new BufferedInputStream(new FileInputStream(file)));
                    if (content != null) {
                        previewValue.setValue(new String(content, ENCODING));
                    }
                } catch (Exception e) {
                    Q7UIPlugin.log(e);
                }
            }
            break;
        }
        if (previewValue.getValue() == null) {
            isValid = false;
            return;
        }
        // Validate content
        Q7ResourceInfo info = new Q7ResourceInfo(IPlainConstants.PLAIN_HEADER, URI.createURI("__compare__"));
        final IPersistenceModel model = PersistenceManager.getInstance()
                .getModel(StringUtils.getUtf8Bytes((String) previewValue.getValue()), info.getResource());
        if (model == null) {
            isValid = false;
            validate();
            return;
        }

        isValid = false;
        try {
            info.load(null);
            Scenario element = (Scenario) info.getNamedElement();
            if (element == null) {
                validate();
                return;
            }
            // if (((String) testcaseNameValue.getValue()).trim().isEmpty()) {
            // Update testcase name
            testcaseNameValue.setValue(element.getName());
            // }

            // Validate platform import of modified file

            // update ecl from attachment, to override ecl stored by
            // platform
            InputStream ecl = model.read(PersistenceManager.ECL_CONTENT_ENTRY);
            if (ecl == null) {
                if (element.getTeslaContent() != null || element.getContent() != null) {
                    setErrorMessage("Specified content is not valid RCPTT testcase");
                    setPageComplete(false);
                    return;
                }
            }
            FileUtil.safeClose(ecl);

            model.dispose();
            isValid = true;
        } catch (ModelException e) {
            RcpttPlugin.log(e);
        }
        validate();
    }

    private void validate() {

        IPath containerPath = new Path((String) locationValue.getValue());// containerSelectionGroup.getContainerFullPath();
        IProject project = getProject();
        if ((null == project) || !Path.EMPTY.isValidPath(containerPath.toString())) {
            setErrorMessage(Messages.WizardExecutablePage_EmptyParentMsg);
            setPageComplete(false);
            return;
        }
        IPath path = containerPath.removeFirstSegments(1);
        if (!path.isEmpty()) {
            IFolder folder = project.getFolder(path);
            if (!folder.exists()) {
                setErrorMessage(Messages.WizardExecutablePage_NotExistingFolderMsg);
                setPageComplete(false);
                return;
            }
        }
        // Validate content
        if (!isValid) {
            setErrorMessage("Specified content is not valid RCPTT testcase");
            setPageComplete(false);
            return;
        }
        String testName = (String) testcaseNameValue.getValue();
        if (testName.trim().length() == 0) {
            setErrorMessage("Please specify testcase name");
            setPageComplete(false);
            return;
        }

        IQ7Folder folder = getFolder();
        if (folder != null) {
            List<String> names = Arrays
                    .asList(Q7SearchCore.findAllNames(new ReferencedProjectScope(folder.getQ7Project())));
            if (names.contains(testName)) {
                setErrorMessage("Testcase with same name already exists");
                setPageComplete(false);
                return;
            }
        }
        setErrorMessage(null);
        setPageComplete(true);
    }

    private IProject getProject() {
        IResource member = ResourcesPlugin.getWorkspace().getRoot()
                .findMember(new Path((String) locationValue.getValue()));
        if (member != null && member.exists()) {
            return member.getProject();
        }
        if (initialContainer != null) {
            return initialContainer.getProject();
        }
        return null;
    }

    private IQ7Folder getFolder() {
        IResource member = ResourcesPlugin.getWorkspace().getRoot()
                .findMember(new Path((String) locationValue.getValue()));
        IQ7Element el = RcpttCore.create(member);
        if (el != null && el instanceof IQ7Folder) {
            return (IQ7Folder) el;
        } else if (el instanceof IQ7Project) {
            return ((IQ7Project) el).getRootFolder();
        }
        return null;
    }

    @Override
    public void dispose() {
        dbc.dispose();
        super.dispose();
    }

    public boolean finish() {
        // Create testcase
        try {
            ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
                public void run(IProgressMonitor monitor) throws CoreException {
                    IQ7Folder folder = getFolder();
                    WriteAccessChecker writeAccessChecker = new WriteAccessChecker(getShell());
                    if (!writeAccessChecker.makeResourceWritable(folder.getResource())) {
                        return;
                    }
                    if (folder != null) {
                        IContainer cl = (IContainer) folder.getResource();
                        IFile newFile = ((Q7Folder) folder).getNewFile(cl, (String) testcaseNameValue.getValue(),
                                IQ7Folder.TEST_FILE_EXTENSION);
                        newFile.create(new ByteArrayInputStream(
                                StringUtils.getUtf8Bytes((String) previewValue.getValue())), true, monitor);

                        IQ7NamedElement newEl = (IQ7NamedElement) RcpttCore.create(newFile);
                        ITestCase copy = (ITestCase) newEl.getWorkingCopy(new NullProgressMonitor());
                        try {
                            do {
                                copy.setID(EcoreUtil.generateUUID());
                            } while (folder.haveIDConflict(copy.getID()));
                            copy.setElementName((String) testcaseNameValue.getValue());

                            // Extract all missing contexts
                            IPersistenceModel model = copy.getPersistenceModel();
                            // Replace Ecl context for testcases exported in
                            // platform
                            InputStream ecl = model.read(PersistenceManager.ECL_CONTENT_ENTRY);
                            if (ecl != null) {
                                try {
                                    String streamContent = new String(FileUtil.getStreamContent(ecl), ENCODING);
                                    Script ecl2 = Scenarios.getEcl(copy);
                                    if (!streamContent.equals(ecl2.getContent())) {
                                        Scenarios.setEclContent((Scenario) copy.getNamedElement(), streamContent);
                                    }
                                } catch (IOException e) {
                                    Q7UIPlugin.log(e);
                                } finally {
                                    FileUtil.safeClose(ecl);
                                }
                            }

                            String[] names = model.getNames();
                            Map<String, String> contextIDUpdateMap = new HashMap<String, String>();
                            Map<String, String> verificationIDUpdateMap = new HashMap<String, String>();
                            List<IContext> requiredIDUpdate = new ArrayList<IContext>();
                            for (String name : names) {
                                if (name.startsWith(CONTEXTS_PREFIX)) {
                                    String id = name.substring(CONTEXTS_PREFIX.length());
                                    // if (contexts.contains(id)) {
                                    // Create missing context
                                    IQ7NamedElement[] ctx = Q7SearchCore.findById(id,
                                            new ReferencedProjectScope(folder.getQ7Project()), monitor);
                                    boolean extractContext = false;
                                    if (ctx.length == 0) {
                                        extractContext = true;
                                    } else {
                                        // Compare existing context with
                                        // extracted one to be same, and if
                                        // not same lets create new one
                                        try {
                                            IFile file = (IFile) ctx[0].getResource();
                                            byte[] content = FileUtil
                                                    .getStreamContent(new BufferedInputStream(file.getContents()));
                                            byte[] includedContent = FileUtil.getStreamContent(model.read(name));
                                            extractContext = !Arrays.equals(content, includedContent);
                                        } catch (Exception e) {
                                            Q7UIPlugin.log(e);
                                            extractContext = true;
                                        }
                                    }
                                    if (extractContext) {
                                        doCreateContext(model.read(name), folder, contextIDUpdateMap,
                                                requiredIDUpdate);
                                    }

                                    model.delete(name);
                                } else if (name.startsWith(VERIFICATIONS_PREFIX)) {
                                    String id = name.substring(VERIFICATIONS_PREFIX.length());
                                    // Create missing verifications
                                    IQ7NamedElement[] verification = Q7SearchCore.findById(id,
                                            new ReferencedProjectScope(folder.getQ7Project()), monitor);
                                    boolean extractVerification = false;
                                    if (verification.length == 0) {
                                        extractVerification = true;
                                    } else {
                                        // Compare existing verification with
                                        // extracted one to be same, and if
                                        // not same lets create new one
                                        try {
                                            IFile file = (IFile) verification[0].getResource();
                                            byte[] content = FileUtil
                                                    .getStreamContent(new BufferedInputStream(file.getContents()));
                                            byte[] includedContent = FileUtil.getStreamContent(model.read(name));
                                            extractVerification = !Arrays.equals(content, includedContent);
                                        } catch (Exception e) {
                                            Q7UIPlugin.log(e);
                                            extractVerification = true;
                                        }
                                    }
                                    if (extractVerification) {
                                        doCreateVerification(model.read(name), folder, verificationIDUpdateMap);
                                    }

                                    model.delete(name);
                                }
                            }

                            // Update context ids if requried
                            List<String> newIds = updateIds(contextIDUpdateMap, Arrays.asList(copy.getContexts()));
                            if (newIds != null) {
                                copy.setContexts(newIds.toArray(new String[newIds.size()]));
                            }

                            newIds = updateIds(verificationIDUpdateMap, Arrays.asList(copy.getVerifications()));
                            if (newIds != null) {
                                copy.setVerifications(newIds.toArray(new String[newIds.size()]));
                            }

                            for (IContext cx : requiredIDUpdate) {
                                IQ7NamedElement cxCopy = cx.getWorkingCopy(new NullProgressMonitor());
                                try {
                                    GroupContext group = (GroupContext) cxCopy.getNamedElement();
                                    List<String> newGRCtxs = updateIds(contextIDUpdateMap,
                                            group.getContextReferences());
                                    if (newGRCtxs != null) {
                                        group.getContextReferences().clear();
                                        group.getContextReferences().addAll(newGRCtxs);

                                        cxCopy.commitWorkingCopy(true, new NullProgressMonitor());
                                    }
                                } finally {
                                    cxCopy.discardWorkingCopy();
                                }
                            }

                            // Used incremental file name, so replacing the file does not happen.
                            copy.commitWorkingCopy(true, new NullProgressMonitor());
                        } catch (ModelException e) {
                            Q7UIPlugin.log(e);
                        } finally {
                            copy.discardWorkingCopy();
                        }
                    }
                }

                private void doCreateVerification(InputStream read, IQ7Folder folder,
                        Map<String, String> verificationIDUpdateMap) {
                    IVerification copy = null;
                    try {
                        IContainer cl = (IContainer) folder.getResource();
                        IFile newFile = ((Q7Folder) folder).getNewFile(cl,
                                ((String) testcaseNameValue.getValue()) + "_imported",
                                IQ7Folder.VERIFICATION_FILE_EXTENSION);
                        newFile.create(read, true, new NullProgressMonitor());
                        FileUtil.safeClose(read);

                        IVerification newEl = (IVerification) RcpttCore.create(newFile);
                        copy = (IVerification) newEl.getWorkingCopy(new NullProgressMonitor());
                        String oldID = copy.getID();

                        while (folder.haveIDConflict(copy.getID())) {
                            copy.setID(EcoreUtil.generateUUID());
                        }
                        List<String> names = Arrays.asList(
                                Q7SearchCore.findAllNames(new ReferencedProjectScope(folder.getQ7Project())));
                        String name = copy.getElementName();
                        int i = 2;
                        while (names.contains(name)) {
                            name = copy.getElementName() + "(" + i + ")";
                            i++;
                        }
                        copy.setElementName(name);

                        if (copy.hasUnsavedChanges()) {
                            verificationIDUpdateMap.put(oldID, copy.getID());
                            WriteAccessChecker writeAccessChecker = new WriteAccessChecker(getShell());
                            if (writeAccessChecker.makeResourceWritable(copy)) {
                                copy.commitWorkingCopy(true, new NullProgressMonitor());
                            }
                        }
                    } catch (Exception e) {
                        Q7UIPlugin.log(e);
                    } finally {
                        if (copy != null) {
                            try {
                                copy.discardWorkingCopy();
                            } catch (ModelException e) {
                                Q7UIPlugin.log(e);
                            }
                        }
                    }
                }

                private void doCreateContext(InputStream read, IQ7Folder folder,
                        Map<String, String> contextIDUpdateMap, List<IContext> requiredIDUpdate) {
                    IContext copy = null;
                    try {
                        IContainer cl = (IContainer) folder.getResource();
                        IFile newFile = ((Q7Folder) folder).getNewFile(cl,
                                ((String) testcaseNameValue.getValue()) + "_imported",
                                IQ7Folder.CONTEXT_FILE_EXTENSION);
                        newFile.create(read, true, new NullProgressMonitor());
                        FileUtil.safeClose(read);

                        IContext newEl = (IContext) RcpttCore.create(newFile);
                        copy = (IContext) newEl.getWorkingCopy(new NullProgressMonitor());
                        String oldID = copy.getID();

                        while (folder.haveIDConflict(copy.getID())) {
                            copy.setID(EcoreUtil.generateUUID());
                        }
                        List<String> names = Arrays.asList(
                                Q7SearchCore.findAllNames(new ReferencedProjectScope(folder.getQ7Project())));
                        String name = copy.getElementName();
                        int i = 2;
                        while (names.contains(name)) {
                            name = copy.getElementName() + "(" + i + ")";
                            i++;
                        }
                        copy.setElementName(name);

                        // copy.setElementName(((String) testcaseNameValue
                        // .getValue()) + "_" + copy.getElementName());
                        if (copy.getNamedElement() instanceof GroupContext) {
                            requiredIDUpdate.add(newEl);
                        }
                        if (copy.hasUnsavedChanges()) {
                            contextIDUpdateMap.put(oldID, copy.getID());
                            WriteAccessChecker writeAccessChecker = new WriteAccessChecker(getShell());
                            if (writeAccessChecker.makeResourceWritable(copy)) {
                                copy.commitWorkingCopy(true, new NullProgressMonitor());
                            }
                        }
                    } catch (Exception e) {
                        Q7UIPlugin.log(e);
                    } finally {
                        if (copy != null) {
                            try {
                                copy.discardWorkingCopy();
                            } catch (ModelException e) {
                                Q7UIPlugin.log(e);
                            }
                        }
                    }
                }
            }, new NullProgressMonitor());
            return true;
        } catch (CoreException e) {
            Q7UIPlugin.log(e);
        }
        return false;
    }

    private List<String> updateIds(Map<String, String> idUpdateMap, List<String> ids) {
        boolean changed = false;
        List<String> newIds = new ArrayList<String>();
        for (String id : ids) {
            String newcx = idUpdateMap.get(id);
            if (newcx != null) {
                changed = true;
                newIds.add(newcx);
            } else {
                newIds.add(id);
            }
        }
        if (changed) {
            return newIds;
        }
        return null;
    }
}