Package org.epic.debug.remote

Source Code of org.epic.debug.remote.CreateRemotePackageJob

package org.epic.debug.remote;

import java.io.*;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorRegistry;
import org.epic.core.PerlCore;
import org.epic.core.PerlProject;
import org.epic.debug.PerlDebugPlugin;
import org.epic.debug.util.RemotePathMapper;

/**
* Creates a ZIP archive with project files and helper scripts.
* This archive can be manually extracted and executed on a remote
* machine by the user to establish a remote debugging session.
*/
public class CreateRemotePackageJob extends Job
{
    private final byte[] buffer;
    private final File archiveFile;
    private final ZipOutputStream zipOut;
    private final ILaunch launch;
    private final RemoteLaunchConfigurationDelegate launchDelegate;
    private final RemotePathMapper mapper;
   
    public CreateRemotePackageJob(       
        RemoteLaunchConfigurationDelegate launchDelegate,
        ILaunch launch,
        RemotePathMapper mapper) throws CoreException
    {
        super("Create Remote Debug Package");
       
        this.launch = launch;
        this.launchDelegate = launchDelegate;
        this.mapper = mapper;
        this.buffer = new byte[1024];
        this.archiveFile = launchDelegate.getDebugPackageFile(launch);
        this.zipOut = createOutputStream();
    }

    protected IStatus run(IProgressMonitor monitor)
    {
        monitor.beginTask("Create Remote Debug Package", countProjectFiles());
        try
        {
            addProjectFilesToArchive(monitor);
            addHelperScriptToArchive("dumpvar_epic.pm");
            addHelperScriptToArchive("epic_breakpoints.pm");
            addHelperScriptToArchive("autoflush_epic.pm");
            addPerl5DbToArchive();
            addStartScriptToArchive();

            return Status.OK_STATUS;
        }
        catch (CoreException e)
        {
            archiveFile.delete();
            PerlDebugPlugin.log(e);
            return e.getStatus();
        }
        finally
        {
            monitor.done();
            try { zipOut.close(); }
            catch (IOException e) { PerlDebugPlugin.log(e); }
        }       
    }
   
    private void addProjectFilesToArchive(IProgressMonitor monitor)
        throws CoreException
    {
        IResourceVisitor visitor = new ProjectFileArchiver(monitor);
        getProject().accept(visitor);      
    }
   
    private void addHelperScriptToArchive(String scriptName) throws CoreException
    {
        try
        {           
            addFileToArchive(
                PerlDebugPlugin.getDefault().getBundle().getEntry(scriptName).openStream(),
                getWorkingDirPrefix() + scriptName);
        }
        catch (IOException e)
        {
            throw new CoreException(new Status(
                IStatus.ERROR,
                PerlDebugPlugin.getUniqueIdentifier(),
                IStatus.OK,
                "Could not locate helper script " + scriptName,
                e));
        }
    }
   
    private void addFileToArchive(InputStream in, String pathInArchive)
        throws CoreException
    {
        try
        {
            zipOut.putNextEntry(new ZipEntry(pathInArchive));

            int len;
            while ((len = in.read(buffer)) > 0)
                zipOut.write(buffer, 0, len);
        }
        catch (IOException e)
        {
            throw new CoreException(new Status(
                IStatus.ERROR,
                PerlDebugPlugin.getUniqueIdentifier(),
                IStatus.OK,
                "Could not write zip entry " + pathInArchive,
                e));
        }
        finally
        {
            try { in.close(); } catch (IOException e) { }
        }
    }
   
    private void addPerl5DbToArchive() throws CoreException
    {
        try
        {
            File perl5Db = PerlDebugPlugin.getDefault().patchPerl5Db();
            addFileToArchive(
                new BufferedInputStream(new FileInputStream(perl5Db)),
                getWorkingDirPrefix() + "perl5db.pl");
        }
        catch (IOException e)
        {
            throw new CoreException(new Status(
                IStatus.ERROR,
                PerlDebugPlugin.getUniqueIdentifier(),
                IStatus.OK,
                "Could not add patched perl5db.pl to archive",
                e));
        }
    }
   
    private void addStartScriptToArchive() throws CoreException
    {
        try
        {
            zipOut.putNextEntry(new ZipEntry("start_epicDB.pl"));
            String startDB = "$ENV{PERLDB_OPTS}=\"RemotePort="
                + launchDelegate.getEpicDebuggerIP(launch) + ":"
                + launchDelegate.getEpicDebuggerPort(launch)
                + " DumpReused ReadLine=0 PrintRet=0\";\n" + "if( ! -d \""
                + launchDelegate.getRemoteProjectDir(launch)
                + "\" ) {die(\"Target directory does not exist!\")};\n"
                + "chdir(\"" + launchDelegate.getRemoteProjectDir(launch) + "/"
                + launchDelegate.getScriptPath(launch).removeLastSegments(1) + "\");"
                + "\nsystem(\"perl -d " + createIncPath() + " "
                + launchDelegate.getRemoteProjectDir(launch) + "/"
                + launchDelegate.getScriptPath(launch) + "\");";
            zipOut.write(startDB.getBytes());
        }
        catch (IOException e)
        {
            throw new CoreException(new Status(
                IStatus.ERROR,
                PerlDebugPlugin.getUniqueIdentifier(),
                IStatus.OK,
                "Could not write zip entry for start_epicDB.pl",
                e));
        }
    }

    private String createIncPath() throws CoreException
    {
        StringBuffer buf = new StringBuffer();
        String localProjectDir = getPerlProject().getProjectDir().toString();
        String remoteProjectDir = launchDelegate.getRemoteProjectDir(launch);
       
        buf.append(" -I \\\"");
        buf.append(launchDelegate.getRemoteProjectDir(launch));
        buf.append("\\\"");
       
        for (Iterator i = getPerlProject().getRawIncPath().iterator(); i.hasNext();)
        {
            String path = new Path((String) i.next()).toString();

            if (path.startsWith(localProjectDir))
                path = remoteProjectDir + path.substring(localProjectDir.length());
               
            buf.append(" -I \\\"");
            buf.append(path);
            buf.append("\\\"");
        }
        return buf.toString();
    }

    private int countProjectFiles()
    {
        PerlFileCounter visitor = new PerlFileCounter();
        try
        {
            getProject().accept(visitor);
            return visitor.getCount();
        }
        catch (CoreException e)
        {
            PerlDebugPlugin.log(e);
            return 0;
        }
    }
   
    private ZipOutputStream createOutputStream() throws CoreException
    {
        try
        {
            return new ZipOutputStream(new FileOutputStream(archiveFile));
        }
        catch (FileNotFoundException e)
        {
            throw new CoreException(new Status(
                IStatus.ERROR,
                PerlDebugPlugin.getUniqueIdentifier(),
                IStatus.OK,
                "Could not write remote debug package file " +
                archiveFile.getAbsolutePath(),
                e));
        }
    }
   
    private PerlProject getPerlProject() throws CoreException
    {
        return PerlCore.create(getProject());
    }
   
    private IProject getProject() throws CoreException
    {
        return launchDelegate.getProject(launch);
    }
   
    private String getWorkingDirPrefix() throws CoreException
    {
        String prefix = launchDelegate.getScriptPath(launch).removeLastSegments(1).toString();
        if (prefix.length() > 0) prefix += "/";
        return prefix;
    }

    private class ProjectFileArchiver implements IResourceVisitor
    {
        private final IProgressMonitor monitor;

        public ProjectFileArchiver(IProgressMonitor monitor)
        {
            this.monitor = monitor;
        }

        public boolean visit(IResource resource) throws CoreException
        {
            if (resource.isLinked() && resource instanceof IFolder)
                mapper.addLinkedFolderMapping((IFolder) resource);

            if (resource instanceof IFile)
            {
                addFileToArchive((IFile) resource);
                monitor.worked(1);
            }

            return true;
        }
       
        private void addFileToArchive(IFile resource) throws CoreException
        {
            try
            {
                CreateRemotePackageJob.this.addFileToArchive(
                    new BufferedInputStream(
                        new FileInputStream(resource.getLocation().toString())),
                    resource.getFullPath().removeFirstSegments(1).toString());
            }
            catch (IOException e)
            {
                throw new CoreException(new Status(
                    IStatus.ERROR,
                    PerlDebugPlugin.getUniqueIdentifier(),
                    IStatus.OK,
                    "Could not read file " + resource.getLocation(),
                    e));
            }
        }
    }

    private static class PerlFileCounter implements IResourceVisitor
    {
        private static final String PERL_EDITOR_ID = "org.epic.perleditor.editors.PerlEditor";
        private static final String EMB_PERL_FILE_EXTENSION = "epl";
        private final IEditorRegistry registry;
        private int count;

        public PerlFileCounter()
        {
            count = 0;
            registry = PerlDebugPlugin.getDefault().getWorkbench().getEditorRegistry();
        }

        public int getCount()
        {
            return count;
        }

        public boolean visit(IResource resource) throws CoreException
        {
            IEditorDescriptor defaultEditorDescriptor =
                registry.getDefaultEditor(resource.getFullPath().toString());

            if (defaultEditorDescriptor != null &&
                defaultEditorDescriptor.getId().equals(PERL_EDITOR_ID) &&
                !resource.getFileExtension().equals(EMB_PERL_FILE_EXTENSION))
            {
                count++;
            }
            return true;
        }
    }
}
TOP

Related Classes of org.epic.debug.remote.CreateRemotePackageJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.