org.locationtech.geogig.cli.test.functional.CLIContext.java Source code

Java tutorial

Introduction

Here is the source code for org.locationtech.geogig.cli.test.functional.CLIContext.java

Source

/* Copyright (c) 2014-2016 Boundless and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/edl-v10.html
 *
 * Contributors:
 * Gabriel Roldan (Boundless) - initial implementation
 */
package org.locationtech.geogig.cli.test.functional;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.assertNotNull;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.lines1;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.lines2;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.lines3;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.points1;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.points1_FTmodified;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.points2;
import static org.locationtech.geogig.cli.test.functional.TestFeatures.points3;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.locationtech.geogig.cli.Console;
import org.locationtech.geogig.cli.GeogigCLI;
import org.locationtech.geogig.model.ObjectId;
import org.locationtech.geogig.model.RevFeatureType;
import org.locationtech.geogig.model.impl.RevFeatureBuilder;
import org.locationtech.geogig.model.impl.RevFeatureTypeBuilder;
import org.locationtech.geogig.repository.FeatureInfo;
import org.locationtech.geogig.repository.Hints;
import org.locationtech.geogig.repository.NodeRef;
import org.locationtech.geogig.repository.Repository;
import org.locationtech.geogig.repository.WorkingTree;
import org.locationtech.geogig.repository.impl.GeoGIG;
import org.locationtech.geogig.test.TestPlatform;
import org.opengis.feature.Feature;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.Name;

import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.io.CharSource;

/**
 * The "context" for a specific repository when running the CLI functional tests.
 * <p>
 * The repository context includes the reposiroty URI, a {@link GeogigCLI} for that repositry URI,
 * and a pair of input/output streams to be used as stdin and stdout.
 */
public class CLIContext {

    /**
     * If non null, {@link #configureRepository()} will use it as the repository URI, otherwise
     * it'll use the platform's current directory
     */
    public final URI repositoryURI;

    public final TestPlatform platform;

    /**
     * {@link GeogigCLI#execute(String...)} exit code, updated every time a {@link #runCommand
     * command is ran}
     */
    public int exitCode;

    public GeogigCLI geogigCLI;

    public ByteArrayInputStream stdIn;

    public ByteArrayOutputStream stdOut;

    public Console consoleReader;

    public CLIContext(URI repoURI, TestPlatform platform) {
        checkNotNull(repoURI);
        checkNotNull(platform);
        this.repositoryURI = repoURI;
        this.platform = platform;

        stdIn = new ByteArrayInputStream(new byte[0]);
        stdOut = new ByteArrayOutputStream();
        consoleReader = new Console(stdIn, stdOut).disableAnsi();
        geogigCLI = new GeogigCLI(consoleReader);
        geogigCLI.setPlatform(platform);
    }

    public synchronized void dispose() {
        if (geogigCLI != null) {
            geogigCLI.close();
            geogigCLI = null;
        }
        if (consoleReader != null) {
            consoleReader = null;
        }
    }

    public void configureRepository() throws Exception {
        geogigCLI.close();
        URI uri = repositoryURI;
        Preconditions.checkState(uri != null, "repository URI not set");

        geogigCLI.setPlatform(platform);
        geogigCLI.setRepositoryURI(uri.toString());
    }

    /**
     * Runs the given command with its arguments and returns the command output as a list of
     * strings, one per line.
     */
    public List<String> runAndParseCommand(String... command) throws Exception {
        return runAndParseCommand(false, command);
    }

    public List<String> runAndParseCommand(boolean failFast, String... command) throws Exception {
        runCommand(failFast, command);
        CharSource reader = CharSource.wrap(stdOut.toString(Charsets.UTF_8.name()));
        ImmutableList<String> lines = reader.readLines();
        return lines;
    }

    /**
     * @param commandAndArgs the command and its arguments. This method is dumb, be careful of not
     *        using arguments that shouldn't be split on a space (like "commit -m 'separate words')
     */
    public void runCommand(String commandAndArgs) throws Exception {
        runCommand(false, commandAndArgs);
    }

    public void runCommand(boolean failFast, String commandAndArgs) throws Exception {
        runCommand(failFast, commandAndArgs.split(" "));
    }

    /**
     * runs the command, does not fail fast, check {@link CLIContext#exitCode} for the exit code and
     * {@link GeogigCLI#exception} for any caught exception
     */
    public void runCommand(String... command) throws Exception {
        runCommand(false, command);
    }

    public void runCommand(boolean failFast, String... command) throws Exception {
        assertNotNull(geogigCLI);
        stdOut.reset();
        exitCode = geogigCLI.execute(command);
        if (failFast && geogigCLI.exception != null) {
            Exception exception = geogigCLI.exception;
            throw exception;
        }
    }

    public void insertFeatures() throws Exception {
        insert(points1);
        insert(points2);
        insert(points3);
        insert(lines1);
        insert(lines2);
        insert(lines3);
    }

    public void insertAndAddFeatures() throws Exception {
        insertAndAdd(points1);
        insertAndAdd(points2);
        insertAndAdd(points3);
        insertAndAdd(lines1);
        insertAndAdd(lines2);
        insertAndAdd(lines3);
    }

    public void deleteAndReplaceFeatureType() throws Exception {

        GeoGIG geogig = geogigCLI.newGeoGIG();
        try {
            final WorkingTree workTree = geogig.getRepository().workingTree();
            workTree.delete(points1.getType().getName().getLocalPart());
            FeatureType newType = points1_FTmodified.getType();
            Name name = newType.getName();
            String parentPath = name.getLocalPart();
            RevFeatureType rft = RevFeatureTypeBuilder.build(newType);
            geogig.getRepository().objectDatabase().put(rft);
            String path = NodeRef.appendChild(parentPath, points1_FTmodified.getIdentifier().getID());
            FeatureInfo fi = FeatureInfo.insert(RevFeatureBuilder.build(points1_FTmodified), rft.getId(), path);
            workTree.insert(fi);
        } finally {
            geogig.close();
        }
    }

    /**
     * Inserts the Feature to the index and stages it to be committed.
     */
    public ObjectId insertAndAdd(Feature f) throws Exception {
        ObjectId objectId = insert(f);

        runCommand(true, "add");
        return objectId;
    }

    /**
     * Inserts the feature to the index but does not stages it to be committed
     */
    public ObjectId insert(Feature f) throws Exception {
        return insert(new Feature[] { f }).get(0);
    }

    public List<ObjectId> insertAndAdd(Feature... features) throws Exception {
        List<ObjectId> ids = insert(features);
        geogigCLI.execute("add");
        return ids;
    }

    public List<ObjectId> insert(Feature... features) throws Exception {
        geogigCLI.close();
        GeoGIG geogig = geogigCLI.newGeoGIG(Hints.readWrite());
        Preconditions.checkNotNull(geogig);
        List<ObjectId> ids = Lists.newArrayListWithCapacity(features.length);
        Map<FeatureType, RevFeatureType> types = new HashMap<>();
        for (Feature f : features) {
            FeatureType type = f.getType();
            RevFeatureType rft = types.get(type);
            if (rft == null) {
                rft = RevFeatureTypeBuilder.build(type);
                geogig.getRepository().objectDatabase().put(rft);
                types.put(type, rft);
            }
        }
        try {
            Repository repository = geogig.getRepository();
            final WorkingTree workTree = repository.workingTree();
            for (Feature f : features) {
                FeatureType ft = f.getType();
                RevFeatureType rft = types.get(ft);
                String parentPath = ft.getName().getLocalPart();
                String path = NodeRef.appendChild(parentPath, f.getIdentifier().getID());
                FeatureInfo fi = FeatureInfo.insert(RevFeatureBuilder.build(f), rft.getId(), path);
                workTree.insert(fi);
                ObjectId objectId = fi.getFeature().getId();
                ids.add(objectId);
            }
        } finally {
            geogig.close();
        }
        return ids;
    }

    /**
     * Deletes a feature from the index
     * 
     * @param f
     * @return
     * @throws Exception
     */
    public boolean deleteAndAdd(Feature f) throws Exception {
        boolean existed = delete(f);
        if (existed) {
            runCommand(true, "add");
        }

        return existed;
    }

    public boolean delete(Feature f) throws Exception {
        GeoGIG geogig = geogigCLI.newGeoGIG();
        try {
            final WorkingTree workTree = geogig.getRepository().workingTree();
            Name name = f.getType().getName();
            String localPart = name.getLocalPart();
            String id = f.getIdentifier().getID();
            boolean existed = workTree.delete(localPart, id);
            return existed;
        } finally {
            geogig.close();
        }
    }
}