org.eclipse.orion.server.git.servlets.GitConfigHandlerV1.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.orion.server.git.servlets.GitConfigHandlerV1.java

Source

/*******************************************************************************
 * Copyright (c) 2011, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.orion.server.git.servlets;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.runtime.*;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
import org.eclipse.orion.internal.server.servlets.workspace.authorization.AuthorizationService;
import org.eclipse.orion.server.core.ServerStatus;
import org.eclipse.orion.server.git.BaseToCloneConverter;
import org.eclipse.orion.server.git.GitConstants;
import org.eclipse.orion.server.git.objects.Clone;
import org.eclipse.orion.server.git.objects.ConfigOption;
import org.eclipse.orion.server.servlets.OrionServlet;
import org.eclipse.osgi.util.NLS;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * A handler for Git Clone operation.
 */
public class GitConfigHandlerV1 extends ServletResourceHandler<String> {

    private ServletResourceHandler<IStatus> statusHandler;

    GitConfigHandlerV1(ServletResourceHandler<IStatus> statusHandler) {
        this.statusHandler = statusHandler;
    }

    @Override
    public boolean handleRequest(HttpServletRequest request, HttpServletResponse response, String path)
            throws ServletException {
        try {
            Path p = new Path(path);
            IPath filePath = p;
            if (p.segment(0).equals(Clone.RESOURCE) && p.segment(1).equals("file")) { //$NON-NLS-1$
                filePath = p.removeFirstSegments(1);
            } else if (p.segment(1).equals(Clone.RESOURCE) && p.segment(2).equals("file")) { //$NON-NLS-1$
                filePath = p.removeFirstSegments(2);
            }
            if (!AuthorizationService.checkRights(request.getRemoteUser(), "/" + filePath.toString(),
                    request.getMethod())) {
                response.sendError(HttpServletResponse.SC_FORBIDDEN);
                return true;
            }

            switch (getMethod(request)) {
            case GET:
                return handleGet(request, response, path);
            case POST:
                return handlePost(request, response, path);
            case PUT:
                return handlePut(request, response, path);
            case DELETE:
                return handleDelete(request, response, path);
            }
        } catch (Exception e) {
            String msg = NLS.bind("Failed to process an operation on commits for {0}", path); //$NON-NLS-1$
            return statusHandler.handleRequest(request, response,
                    new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg, e));
        }
        return false;
    }

    private boolean handleGet(HttpServletRequest request, HttpServletResponse response, String path)
            throws IOException, JSONException, ServletException, URISyntaxException, CoreException,
            ConfigInvalidException {
        Path p = new Path(path);
        URI baseLocation = getURI(request);
        if (p.segment(0).equals(Clone.RESOURCE) && p.segment(1).equals("file")) { //$NON-NLS-1$
            // expected path /gitapi/config/clone/file/{path}
            File gitDir = GitUtils.getGitDir(p.removeFirstSegments(1));
            if (gitDir == null)
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND,
                                NLS.bind("No repository found under {0}", p.removeFirstSegments(1)), null));
            Repository db = FileRepositoryBuilder.create(gitDir);
            URI cloneLocation = BaseToCloneConverter.getCloneLocation(baseLocation, BaseToCloneConverter.CONFIG);
            ConfigOption configOption = new ConfigOption(cloneLocation, db);
            OrionServlet.writeJSONResponse(request, response, configOption.toJSON(/* all */));
            return true;
        } else if (p.segment(1).equals(Clone.RESOURCE) && p.segment(2).equals("file")) { //$NON-NLS-1$
            // expected path /gitapi/config/{key}/clone/file/{path}
            File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2));
            if (gitDir == null)
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND,
                                NLS.bind("No repository found under {0}", p.removeFirstSegments(2)), null));
            Repository db = FileRepositoryBuilder.create(gitDir);
            URI cloneLocation = BaseToCloneConverter.getCloneLocation(baseLocation,
                    BaseToCloneConverter.CONFIG_OPTION);
            try {
                ConfigOption configOption = new ConfigOption(cloneLocation, db, p.segment(0));
                if (!configOption.exists())
                    return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR,
                            HttpServletResponse.SC_NOT_FOUND, "There is no config entry with key provided", null));
                OrionServlet.writeJSONResponse(request, response, configOption.toJSON());
                return true;
            } catch (IllegalArgumentException e) {
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, e.getMessage(), e));
            }
        }
        return false;
    }

    private boolean handlePost(HttpServletRequest request, HttpServletResponse response, String path)
            throws CoreException, IOException, JSONException, ServletException, URISyntaxException,
            ConfigInvalidException {
        Path p = new Path(path);
        if (p.segment(0).equals(Clone.RESOURCE) && p.segment(1).equals("file")) { //$NON-NLS-1$
            // expected path /gitapi/config/clone/file/{path}
            File gitDir = GitUtils.getGitDir(p.removeFirstSegments(1));
            if (gitDir == null)
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND,
                                NLS.bind("No repository found under {0}", p.removeFirstSegments(1)), null));
            Repository db = FileRepositoryBuilder.create(gitDir);
            URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request), BaseToCloneConverter.CONFIG);
            JSONObject toPost = OrionServlet.readJSONRequest(request);
            String key = toPost.optString(GitConstants.KEY_CONFIG_ENTRY_KEY, null);
            if (key == null || key.isEmpty())
                return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR,
                        HttpServletResponse.SC_BAD_REQUEST, "Config entry key must be provided", null));
            String value = toPost.optString(GitConstants.KEY_CONFIG_ENTRY_VALUE, null);
            if (value == null || value.isEmpty())
                return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR,
                        HttpServletResponse.SC_BAD_REQUEST, "Config entry value must be provided", null));
            try {
                ConfigOption configOption = new ConfigOption(cloneLocation, db, key);
                boolean present = configOption.exists();
                if (present)
                    return statusHandler.handleRequest(request, response,
                            new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_CONFLICT,
                                    NLS.bind("Config entry for {0} already exists", key), null));
                save(configOption, value);

                JSONObject result = configOption.toJSON();
                OrionServlet.writeJSONResponse(request, response, result);
                response.setHeader(ProtocolConstants.HEADER_LOCATION,
                        result.getString(ProtocolConstants.KEY_LOCATION));
                response.setStatus(HttpServletResponse.SC_CREATED);
                return true;
            } catch (IllegalArgumentException e) {
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, e.getMessage(), e));
            }
        }
        return false;
    }

    private boolean handlePut(HttpServletRequest request, HttpServletResponse response, String path)
            throws CoreException, IOException, JSONException, ServletException, URISyntaxException,
            ConfigInvalidException {
        Path p = new Path(path);
        if (p.segment(1).equals(Clone.RESOURCE) && p.segment(2).equals("file")) { //$NON-NLS-1$
            // expected path /gitapi/config/{key}/clone/file/{path}
            File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2));
            if (gitDir == null)
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND,
                                NLS.bind("No repository found under {0}", p.removeFirstSegments(2)), null));
            Repository db = FileRepositoryBuilder.create(gitDir);
            URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request),
                    BaseToCloneConverter.CONFIG_OPTION);
            try {
                ConfigOption configOption = new ConfigOption(cloneLocation, db, p.segment(0));

                JSONObject toPut = OrionServlet.readJSONRequest(request);
                String value = toPut.optString(GitConstants.KEY_CONFIG_ENTRY_VALUE, null);
                if (value == null || value.isEmpty())
                    return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR,
                            HttpServletResponse.SC_BAD_REQUEST, "Config entry value must be provided", null));

                // PUT allows only to modify existing config entries
                if (!configOption.exists()) {
                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    return true;
                }

                save(configOption, value);

                JSONObject result = configOption.toJSON();
                OrionServlet.writeJSONResponse(request, response, result);
                response.setHeader(ProtocolConstants.HEADER_LOCATION,
                        result.getString(ProtocolConstants.KEY_LOCATION));
                return true;
            } catch (IllegalArgumentException e) {
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, e.getMessage(), e));
            }
        }
        return false;
    }

    private boolean handleDelete(HttpServletRequest request, HttpServletResponse response, String path)
            throws CoreException, IOException, ServletException, ConfigInvalidException, URISyntaxException {
        Path p = new Path(path);
        if (p.segment(1).equals(Clone.RESOURCE) && p.segment(2).equals("file")) { //$NON-NLS-1$
            // expected path /gitapi/config/{key}/clone/file/{path}
            File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2));
            if (gitDir == null)
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_NOT_FOUND,
                                NLS.bind("No repository found under {0}", p.removeFirstSegments(2)), null));
            Repository db = FileRepositoryBuilder.create(gitDir);
            URI cloneLocation = BaseToCloneConverter.getCloneLocation(getURI(request),
                    BaseToCloneConverter.CONFIG_OPTION);
            try {
                ConfigOption configOption = new ConfigOption(cloneLocation, db, GitUtils.decode(p.segment(0)));
                if (configOption.exists()) {
                    delete(configOption);
                    response.setStatus(HttpServletResponse.SC_OK);
                } else {
                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                }
                return true;
            } catch (IllegalArgumentException e) {
                return statusHandler.handleRequest(request, response,
                        new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, e.getMessage(), e));
            }
        }
        return false;
    }

    private static void save(ConfigOption co, String value) throws IOException {
        co.getConfig().setString(co.getSection(), co.getSubsection(), co.getName(), value);
        co.getConfig().save();
    }

    private static void delete(ConfigOption co) throws IOException {
        co.getConfig().unset(co.getSection(), co.getSubsection(), co.getName());
        co.getConfig().save();
    }
}