/* Copyright (c) 2013-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: * Kelsey Ishmael (LMN Solutions) - initial implementation */ package org.locationtech.geogig.web.api.commands; import java.io.IOException; import java.util.List; import org.locationtech.geogig.api.Context; import org.locationtech.geogig.api.GlobalContextBuilder; import org.locationtech.geogig.api.Ref; import org.locationtech.geogig.api.Remote; import org.locationtech.geogig.api.porcelain.RemoteAddOp; import org.locationtech.geogig.api.porcelain.RemoteException; import org.locationtech.geogig.api.porcelain.RemoteListOp; import org.locationtech.geogig.api.porcelain.RemoteRemoveOp; import org.locationtech.geogig.api.porcelain.RemoteResolve; import org.locationtech.geogig.remote.IRemoteRepo; import org.locationtech.geogig.remote.RemoteUtils; import org.locationtech.geogig.web.api.AbstractWebAPICommand; import org.locationtech.geogig.web.api.CommandContext; import org.locationtech.geogig.web.api.CommandResponse; import org.locationtech.geogig.web.api.CommandSpecException; import org.locationtech.geogig.web.api.ResponseWriter; import com.google.common.base.Optional; /** * Interface for the Remote operations in GeoGig. * * Web interface for {@link RemoteListOp}, {@link RemoteRemoveOp}, {@link RemoteAddOp} */ public class RemoteWebOp extends AbstractWebAPICommand { private boolean list; private boolean remove; private boolean ping; private boolean update; private boolean verbose; private String remoteName; private String newName; private String remoteURL; private String username = null; private String password = null; /** * Mutator for the list variable * * @param list - true to list the names of your remotes */ public void setList(boolean list) { this.list = list; } /** * Mutator for the remove variable * * @param remove - true to remove the given remote */ public void setRemove(boolean remove) { this.remove = remove; } /** * Mutator for the ping variable * * @param ping - true to ping the given remote */ public void setPing(boolean ping) { this.ping = ping; } /** * Mutator for the update variable * * @param update - true to update the given remote */ public void setUpdate(boolean update) { this.update = update; } /** * Mutator for the verbose variable * * @param update - true to show more info for each repo */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Mutator for the remoteName variable * * @param remoteName - the name of the remote to add or remove */ public void setRemoteName(String remoteName) { this.remoteName = remoteName; } /** * Mutator for the newName variable * * @param newName - the new name of the remote to update */ public void setNewName(String newName) { this.newName = newName; } /** * Mutator for the remoteURL variable * * @param remoteURL - the URL to the repo to make a remote */ public void setRemoteURL(String remoteURL) { this.remoteURL = remoteURL; } /** * Mutator for the username variable * * @param username - the username to access the remote */ public void setUserName(String username) { this.username = username; } /** * Mutator for the password variable * * @param password - the password to access the remote */ public void setPassword(String password) { this.password = password; } /** * Runs the command and builds the appropriate response. * * @param context - the context to use for this command */ @Override public void run(CommandContext context) { final Context geogig = this.getCommandLocator(context); if (list) { remoteList(context, geogig); } else if (ping) { remotePing(context, geogig); } else if (remove) { remoteRemove(context, geogig); } else if (update) { remoteUpdate(context, geogig); } else { remoteAdd(context, geogig); } } private void remoteAdd(CommandContext context, final Context geogig) { if (remoteName == null || remoteName.trim().isEmpty()) { throw new CommandSpecException("No remote was specified."); } else if (remoteURL == null || remoteURL.trim().isEmpty()) { throw new CommandSpecException("No URL was specified."); } final Remote remote; try { remote = geogig.command(RemoteAddOp.class).setName(remoteName).setURL(remoteURL) .setUserName(username).setPassword(password).call(); context.setResponseContent(new CommandResponse() { @Override public void write(ResponseWriter out) throws Exception { out.start(); out.writeElement("name", remote.getName()); out.finish(); } }); } catch (RemoteException e) { context.setResponseContent(CommandResponse.error(e.statusCode.toString())); } catch (Exception e) { context.setResponseContent(CommandResponse.error("Aborting Remote Add")); } } private void remoteUpdate(CommandContext context, final Context geogig) { if (remoteName == null || remoteName.trim().isEmpty()) { throw new CommandSpecException("No remote was specified."); } else if (remoteURL == null || remoteURL.trim().isEmpty()) { throw new CommandSpecException("No URL was specified."); } final Remote newRemote; try { if (newName != null && !newName.trim().isEmpty() && !newName.equals(remoteName)) { newRemote = geogig.command(RemoteAddOp.class).setName(newName).setURL(remoteURL) .setUserName(username).setPassword(password).call(); geogig.command(RemoteRemoveOp.class).setName(remoteName).call(); } else { geogig.command(RemoteRemoveOp.class).setName(remoteName).call(); newRemote = geogig.command(RemoteAddOp.class).setName(remoteName).setURL(remoteURL) .setUserName(username).setPassword(password).call(); } context.setResponseContent(new CommandResponse() { @Override public void write(ResponseWriter out) throws Exception { out.start(); out.writeElement("name", newRemote.getName()); out.finish(); } }); } catch (RemoteException e) { context.setResponseContent(CommandResponse.error(e.statusCode.toString())); } catch (Exception e) { context.setResponseContent(CommandResponse.error("Aborting Remote Update")); } } private void remoteRemove(CommandContext context, final Context geogig) { if (remoteName == null || remoteName.trim().isEmpty()) { throw new CommandSpecException("No remote was specified."); } final Remote remote; try { remote = geogig.command(RemoteRemoveOp.class).setName(remoteName).call(); } catch (RemoteException e) { context.setResponseContent(CommandResponse.error(e.statusCode.toString())); return; } catch (Exception e) { context.setResponseContent(CommandResponse.error("Aborting Remote Remove")); return; } context.setResponseContent(new CommandResponse() { @Override public void write(ResponseWriter out) throws Exception { out.start(); out.writeElement("name", remote.getName()); out.finish(); } }); } private void remotePing(CommandContext context, final Context geogig) { Optional<Remote> remote = geogig.command(RemoteResolve.class).setName(remoteName).call(); final boolean remotePingResponse; if (remote.isPresent()) { Optional<IRemoteRepo> remoteRepo = RemoteUtils.newRemote( GlobalContextBuilder.builder.build(), remote.get(), null, null); Ref ref = null; if (remoteRepo.isPresent()) { try { remoteRepo.get().open(); ref = remoteRepo.get().headRef(); remoteRepo.get().close(); } catch (IOException e) { // Do nothing, we will write the response later. } } remotePingResponse = ref != null; } else { remotePingResponse = false; } context.setResponseContent(new CommandResponse() { @Override public void write(ResponseWriter out) throws Exception { out.start(); out.writeRemotePingResponse(remotePingResponse); out.finish(); } }); } private void remoteList(CommandContext context, final Context geogig) { final List<Remote> remotes = geogig.command(RemoteListOp.class).call(); context.setResponseContent(new CommandResponse() { @Override public void write(ResponseWriter out) throws Exception { out.start(); out.writeRemoteListResponse(remotes, verbose); out.finish(); } }); } }