de.alexkamp.sandbox.ChrootSandboxFactory.java Source code

Java tutorial

Introduction

Here is the source code for de.alexkamp.sandbox.ChrootSandboxFactory.java

Source

package de.alexkamp.sandbox;

/**
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 *
 * If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

import com.fasterxml.jackson.core.JsonFactory;
import de.alexkamp.sandbox.model.Mount;
import de.alexkamp.sandbox.model.SandboxData;

import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * A factory to create sandboxes.
 *
 * Created by akampmann on 2/8/15.
 */
public class ChrootSandboxFactory implements SandboxFactory {
    private final JsonFactory factory = new JsonFactory();

    private final String host;
    private final int port;
    private final File workDir;

    public ChrootSandboxFactory(String host, int port, File workDir) {
        this.host = host;
        this.port = port;
        this.workDir = workDir;

        if (!workDir.exists()) {
            if (!workDir.mkdirs()) {
                throw new SandboxException("Could not create workDir: " + workDir.getAbsolutePath());
            }
        }
    }

    @Override
    public Sandbox start(SandboxData data) {
        return new ChrootSandbox(factory, host, port, data);
    }

    @Override
    public SandboxData copyAsSandbox(String identifier, File baseDir) {
        try {
            // create the copy dir
            File copyDir = new File(workDir, identifier);
            if (copyDir.exists()) {
                throw new SandboxException("A sandbox named \"" + identifier + "\" already exists.");
            }

            // copy all files
            SandboxUtils.copyDirectory(baseDir, copyDir);

            // and return the sandbox
            return new SandboxData(this, identifier, copyDir);
        } catch (IOException ex) {
            throw new SandboxException(ex);
        }
    }

    @Override
    public SandboxData newSandboxData(String identifier) {
        return new SandboxData(this, identifier, new File(workDir, identifier));
    }

    @Override
    public void deleteSandbox(final SandboxData sandbox) {
        File copyDir = sandbox.getBaseDir();

        try {
            final AtomicInteger depth = new AtomicInteger(0);
            Files.walkFileTree(copyDir.toPath(), new FileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes)
                        throws IOException {
                    int d = depth.getAndIncrement();

                    // see whether the mounts are gone
                    if (1 == d) {
                        for (Mount m : sandbox) {
                            if (path.endsWith(m.getMountPoint().substring(1))) {
                                if (0 != path.toFile().listFiles().length) {
                                    throw new IllegalArgumentException(
                                            path.getFileName() + " has not been unmounted.");
                                }
                            }
                        }
                    }

                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes)
                        throws IOException {
                    Files.delete(path);
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException {
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult postVisitDirectory(Path path, IOException e) throws IOException {
                    Files.delete(path);
                    depth.decrementAndGet();
                    return FileVisitResult.CONTINUE;
                }
            });
        } catch (IOException e) {
            throw new SandboxException(e);
        }
    }
}