/* 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: * Victor Olaya (Boundless) - initial implementation */ package org.locationtech.geogig.cli; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.util.Iterator; import java.util.NoSuchElementException; import jline.console.ConsoleReader; import org.locationtech.geogig.api.DefaultPlatform; import org.locationtech.geogig.api.DefaultProgressListener; import org.locationtech.geogig.api.ProgressListener; import py4j.GatewayServer; import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.google.common.base.Throwables; /** * Provides an entry point using the py4j library, to expose GeoGig functionality to python * applications */ public class GeogigPy4JEntryPoint { ConsoleReader consoleReader; /** * A class to parse and store console output of GeoGig commands */ public class ToStringOutputStream extends OutputStream { private static final int PAGE_SIZE = 1000; StringBuffer sb = new StringBuffer(); @Override public void write(int b) throws IOException { char c = (char) b; String s = String.valueOf(c); sb.append(s); } public void clear() { sb = new StringBuffer(); } public String asString() { return sb.toString(); } public Iterator<String> getIterator() { Splitter page = Splitter.fixedLength(PAGE_SIZE); return page.split(sb.toString()).iterator(); } } private PrintStream stream; private ToStringOutputStream os; private Iterator<String> pages = null; private GeoGigPy4JProgressListener listener; public GeogigPy4JEntryPoint() { listener = new SilentProgressListener(); os = new ToStringOutputStream(); stream = new PrintStream(os); try { consoleReader = new ConsoleReader(System.in, stream); consoleReader.getTerminal().setEchoEnabled(true); } catch (Exception e) { throw Throwables.propagate(e); } } /** * Runs a command on a given repository * * @param folder the repository folder * @param args the args to run, including the command itself and additional parameters * @return * @throws IOException */ public int runCommand(String folder, String[] args) throws IOException { System.gc(); GeogigCLI cli = new GeogigCLI(consoleReader) { @Override public synchronized ProgressListener getProgressListener() { if (super.progressListener == null) { super.progressListener = new DefaultProgressListener() { @Override public void setDescription(String s) { GeogigPy4JEntryPoint.this.listener.setProgressText(s); } @Override public synchronized void setProgress(float percent) { GeogigPy4JEntryPoint.this.listener.setProgress(percent); } }; } return super.progressListener; } }; DefaultPlatform platform = new DefaultPlatform(); platform.setWorkingDir(new File(folder)); cli.setPlatform(platform); String command = Joiner.on(" ").join(args); os.clear(); pages = null; System.out.print("Running command: " + command); int ret = cli.execute(args); cli.close(); if (ret == 0) { System.out.println(" [OK]"); } else { System.out.println(" [Error]"); } stream.flush(); os.flush(); return ret; } public String nextOutputPage() throws IOException { if (pages == null) { pages = os.getIterator(); } String next; try { next = pages.next(); } catch (NoSuchElementException e) { next = null; } return next; } public boolean isGeoGigServer() { return true; } /** * Shutdowns the server */ public void shutdown() { System.out.println("Shutting down GeoGig server."); System.exit(0); } /** * Sets the progress listener that will receive progress updates * * @param listener */ public void setProgressListener(GeoGigPy4JProgressListener listener) { this.listener = listener; } /** * Removes the progress listener, if set */ public void removeProgressListener() { this.listener = new SilentProgressListener(); } public static void main(String[] args) { Logging.tryConfigureLogging(); int port = GatewayServer.DEFAULT_PORT; if (args.length != 0) { if (args.length > 1) { System.out.println("Too many arguments.\n Usage: geogig-gateway [port]"); return; } try { port = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.out.println("Wrong argument: " + args[0] + "\nUsage: geogig-gateway [port]"); return; } } GatewayServer gatewayServer = new GatewayServer(new GeogigPy4JEntryPoint(), port); gatewayServer.start(); System.out.println("GeoGig server correctly started and waiting for conections at port " + Integer.toString(port)); } } class SilentProgressListener implements GeoGigPy4JProgressListener { @Override public void setProgress(float i) { } @Override public void setProgressText(String s) { } }