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

Java tutorial

Introduction

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

Source

/*******************************************************************************
 * Copyright (c) 2014 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.*;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.*;
import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
import org.eclipse.orion.internal.server.servlets.file.NewFileServlet;
import org.eclipse.orion.internal.server.servlets.workspace.authorization.AuthorizationService;
import org.eclipse.orion.server.core.*;
import org.eclipse.orion.server.git.servlets.GitUtils.Traverse;
import org.eclipse.orion.server.servlets.OrionServlet;
import org.eclipse.osgi.util.NLS;
import org.json.*;

public class GitIgnoreHandlerV1 extends ServletResourceHandler<String> {

    private final static String DOT_GIT_IGNORE = ".gitignore";
    private ServletResourceHandler<IStatus> statusHandler;

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

    @Override
    public boolean handleRequest(HttpServletRequest request, HttpServletResponse response, String pathInfo)
            throws ServletException {
        try {

            IPath path = pathInfo == null ? Path.ROOT : new Path(pathInfo);
            IPath filePath = path.hasTrailingSeparator() ? path : path.removeLastSegments(1);

            if (!AuthorizationService.checkRights(request.getRemoteUser(), "/" + filePath.toString(),
                    request.getMethod())) {
                String msg = NLS.bind("Forbidden: {0}", EncodingUtils.encodeForHTML(filePath.toString()));
                ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_FORBIDDEN, msg, null);
                return statusHandler.handleRequest(request, response, status);
            }

            /* TODO: Do not duplicate .gitignore entries. Traverse the working directory tree before adding .gitignore rules */
            Set<Entry<IPath, File>> set = GitUtils.getGitDirs(filePath, Traverse.GO_UP).entrySet();
            File gitDir = set.iterator().next().getValue();
            if (gitDir == null)
                return false; // TODO: or an error response code, 405?

            switch (getMethod(request)) {
            case PUT:
                return handlePut(request, response, filePath);
            default:
                //fall through and return false below
            }

            return false;

        } catch (Exception e) {
            String msg = NLS.bind("Failed to process an ignore operation for {0}", //$NON-NLS-1$
                    EncodingUtils.encodeForHTML(pathInfo));
            ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg,
                    e);
            LogHelper.log(status);
            return statusHandler.handleRequest(request, response, status);
        }
    }

    private boolean handlePut(HttpServletRequest request, HttpServletResponse response, IPath filePath)
            throws JSONException, IOException, ServletException, CoreException {

        JSONObject toIgnore = OrionServlet.readJSONRequest(request);
        JSONArray paths = toIgnore.optJSONArray(ProtocolConstants.KEY_PATH);

        if (paths.length() < 1)
            return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR,
                    HttpServletResponse.SC_BAD_REQUEST, "No paths to insert into .gitignore", null));

        /* remove /file */
        IFileStore projectStore = NewFileServlet.getFileStore(null, filePath.removeFirstSegments(1));

        for (int i = 0; i < paths.length(); ++i) {

            IPath path = new Path(paths.getString(i));
            IFileStore pathStore = projectStore.getFileStore(path);
            IFileStore gitignoreStore = pathStore.getParent().getFileStore(new Path(DOT_GIT_IGNORE));

            if (!pathStore.fetchInfo().exists() || !projectStore.isParentOf(gitignoreStore)) {
                String msg = NLS.bind("Invalid path: {0}", EncodingUtils.encodeForHTML(path.toString()));
                ServerStatus status = new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, msg,
                        null);
                return statusHandler.handleRequest(request, response, status);
            }

            /* update the .gitignore file */
            appendGitignore(gitignoreStore, pathStore.getName());
        }

        return true;
    }

    /**
     * Appends a single rule in the given .gitignore file store.
     * If necessary, the .gitignore file is created.
     * @param gitignoreStore The .gitignore file store.
     * @param rule The entry to be appended to the .gitignore.
     * @throws CoreException
     * @throws IOException
     */
    private void appendGitignore(IFileStore gitignoreStore, String rule) throws CoreException, IOException {
        OutputStream out = null;
        try {
            out = gitignoreStore.openOutputStream(EFS.APPEND, null);
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
            bw.write(System.getProperty("line.separator") + "/" + rule);
            bw.flush();
        } finally {
            if (out != null)
                out.close();
        }
    }
}