Package org.locationtech.geogig.rest.repository

Source Code of org.locationtech.geogig.rest.repository.FilteredChangesResource

/* Copyright (c) 2014 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.rest.repository;

import static org.locationtech.geogig.rest.repository.RESTUtils.getGeogig;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.locationtech.geogig.api.GeoGIG;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.RepositoryFilter;
import org.locationtech.geogig.api.RevCommit;
import org.locationtech.geogig.api.plumbing.diff.DiffEntry;
import org.locationtech.geogig.api.porcelain.DiffOp;
import org.locationtech.geogig.remote.BinaryPackedChanges;
import org.locationtech.geogig.remote.FilteredDiffIterator;
import org.locationtech.geogig.repository.Repository;
import org.restlet.Context;
import org.restlet.Finder;
import org.restlet.data.MediaType;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.resource.OutputRepresentation;
import org.restlet.resource.Representation;
import org.restlet.resource.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Throwables;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
* Gets a set of changes that match a provided filter from a particular commit.
*/
public class FilteredChangesResource extends Finder {

    private static final Logger LOGGER = LoggerFactory.getLogger(FilteredChangesResource.class);

    @Override
    public Resource findTarget(Request request, Response response) {
        return new ChangesResource(getContext(), request, response);
    }

    private static class ChangesResource extends Resource {
        public ChangesResource(//
                Context context, //
                Request request, //
                Response response) //
        {
            super(context, request, response);
        }

        @Override
        public boolean allowPost() {
            return true;
        }

        @Override
        public void post(Representation entity) {
            try {
                final InputStream inStream;
                try {
                    inStream = entity.getStream();
                } catch (IOException e) {
                    throw Throwables.propagate(e);
                }

                final Reader body = new InputStreamReader(inStream);
                final JsonParser parser = new JsonParser();
                final JsonElement messageJson = parser.parse(body);

                final Set<ObjectId> tracked = new HashSet<ObjectId>();

                RepositoryFilter filter = new RepositoryFilter();

                ObjectId commitId = ObjectId.NULL;

                if (messageJson.isJsonObject()) {
                    final JsonObject message = messageJson.getAsJsonObject();
                    final JsonArray trackedArray;
                    if (message.has("tracked") && message.get("tracked").isJsonArray()) {
                        trackedArray = message.get("tracked").getAsJsonArray();
                    } else {
                        trackedArray = new JsonArray();
                    }
                    if (message.has("commitId") && message.get("commitId").isJsonPrimitive()) {
                        commitId = ObjectId.valueOf(message.get("commitId").getAsJsonPrimitive()
                                .getAsString());
                    } else {
                        commitId = ObjectId.NULL;
                    }
                    for (final JsonElement e : trackedArray) {
                        if (e.isJsonPrimitive()) {
                            tracked.add(ObjectId.valueOf(e.getAsJsonPrimitive().getAsString()));
                        }
                    }

                    if (message.has("filter") && message.get("filter").isJsonArray()) {
                        JsonArray filterArray = message.get("filter").getAsJsonArray();
                        for (final JsonElement e : filterArray) {
                            if (e.isJsonObject()) {
                                JsonObject filterObject = e.getAsJsonObject();
                                String featureType = null;
                                String filterType = null;
                                String filterText = null;
                                if (filterObject.has("featurepath")
                                        && filterObject.get("featurepath").isJsonPrimitive()) {
                                    featureType = filterObject.get("featurepath")
                                            .getAsJsonPrimitive().getAsString();
                                }
                                if (filterObject.has("type")
                                        && filterObject.get("type").isJsonPrimitive()) {
                                    filterType = filterObject.get("type").getAsJsonPrimitive()
                                            .getAsString();
                                }
                                if (filterObject.has("filter")
                                        && filterObject.get("filter").isJsonPrimitive()) {
                                    filterText = filterObject.get("filter").getAsJsonPrimitive()
                                            .getAsString();
                                }
                                if (featureType != null && filterType != null && filterText != null) {
                                    filter.addFilter(featureType, filterType, filterText);
                                }
                            }
                        }

                    }
                }

                final GeoGIG ggit = getGeogig(getRequest()).get();
                final Repository repository = ggit.getRepository();

                RevCommit commit = repository.getCommit(commitId);

                ObjectId parent = ObjectId.NULL;
                if (commit.getParentIds().size() > 0) {
                    parent = commit.getParentIds().get(0);
                }

                Iterator<DiffEntry> changes = ggit.command(DiffOp.class)
                        .setNewVersion(commit.getId()).setOldVersion(parent).setReportTrees(true)
                        .call();
                FilteredDiffIterator filteredChanges = new FilteredDiffIterator(changes,
                        repository, filter) {
                    @Override
                    protected boolean trackingObject(ObjectId objectId) {
                        return tracked.contains(objectId);
                    }

                    @Override
                    public boolean isAutoIngesting() {
                        return false;
                    }
                };

                getResponse().setEntity(
                        new FilteredDiffIteratorRepresentation(new BinaryPackedChanges(repository),
                                filteredChanges));

            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        private static final MediaType PACKED_OBJECTS = new MediaType("application/x-geogig-packed");

        private class FilteredDiffIteratorRepresentation extends OutputRepresentation {

            private final BinaryPackedChanges packer;

            private final FilteredDiffIterator changes;

            public FilteredDiffIteratorRepresentation(BinaryPackedChanges packer,
                    FilteredDiffIterator changes) {
                super(PACKED_OBJECTS);
                this.changes = changes;
                this.packer = packer;
            }

            @Override
            public void write(OutputStream out) throws IOException {
                LOGGER.debug("Writing objects to remote...");
                packer.write(out, changes);
                // signal the end of changes
                out.write(2);
                if (changes.wasFiltered()) {
                    out.write(1);
                } else {
                    out.write(0);
                }
            }
        }
    }
}
TOP

Related Classes of org.locationtech.geogig.rest.repository.FilteredChangesResource

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.