summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authorPiotr Janik2011-06-08 09:19:38 (EDT)
committer Szymon Brandys2011-06-08 09:19:38 (EDT)
commit6ce52f26c2b808e528b04987878259a183d3e45e (patch)
tree9d5089c1074db2df06824451c889b1194f1d9ab3
parent45bbbab97824c02cef3ef1d32283f1418d713d94 (diff)
downloadorg.eclipse.orion.server-6ce52f26c2b808e528b04987878259a183d3e45e.zip
org.eclipse.orion.server-6ce52f26c2b808e528b04987878259a183d3e45e.tar.gz
org.eclipse.orion.server-6ce52f26c2b808e528b04987878259a183d3e45e.tar.bz2
bug 337820 - [server] Provide REST API for git config
https://bugs.eclipse.org/bugs/show_bug.cgi?id=337820
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/BaseToConfigEntryConverter.java30
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitConstants.java6
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitFileDecorator.java5
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java4
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitConfigHandlerV1.java283
-rw-r--r--tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java195
6 files changed, 451 insertions, 72 deletions
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/BaseToConfigEntryConverter.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/BaseToConfigEntryConverter.java
new file mode 100644
index 0000000..31b0ed0
--- /dev/null
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/BaseToConfigEntryConverter.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public abstract class BaseToConfigEntryConverter {
+
+ public static final BaseToConfigEntryConverter REMOVE_FIRST_2 = new BaseToConfigEntryConverter() {
+ @Override
+ public URI baseToConfigEntryLocation(URI base, String entryKey) throws URISyntaxException {
+ IPath p = new Path(base.getPath());
+ p = p.uptoSegment(1).append(GitConstants.CONFIG_RESOURCE).append(entryKey).addTrailingSeparator().append(p.removeFirstSegments(2));
+ return new URI(base.getScheme(), base.getUserInfo(), base.getHost(), base.getPort(), p.toString(), base.getQuery(), base.getFragment());
+ };
+ };
+
+ public abstract URI baseToConfigEntryLocation(URI base, String entryKey) throws URISyntaxException;
+}
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitConstants.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitConstants.java
index 223ebc7..3cff2b9 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitConstants.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitConstants.java
@@ -57,6 +57,8 @@ public class GitConstants {
public static final String KEY_CLONE = "CloneLocation"; //$NON-NLS-1$
+ public static final String KEY_CONFIG = "ConfigLocation"; //$NON-NLS-1$
+
public static final String KEY_BRANCH = "BranchLocation"; //$NON-NLS-1$
public static final String KEY_URL = "GitUrl"; //$NON-NLS-1$
@@ -113,6 +115,10 @@ public class GitConstants {
public static final String KEY_COMMIT_DIFF_CHANGETYPE = "ChangeType"; //$NON-NLS-1$
+ public static final String KEY_CONFIG_ENTRY_KEY = "Key"; //$NON-NLS-1$
+
+ public static final String KEY_CONFIG_ENTRY_VALUE = "Value"; //$NON-NLS-1$
+
public static final String KEY_BRANCH_NAME = "Branch"; //$NON-NLS-1$
public static final String KEY_REMOTE_NAME = "Remote"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitFileDecorator.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitFileDecorator.java
index 98f3e5c..68f38c1 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitFileDecorator.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/GitFileDecorator.java
@@ -134,6 +134,11 @@ public class GitFileDecorator implements IWebResourceDecorator {
link = new URI(location.getScheme(), location.getAuthority(), path.toString(), null, null);
gitSection.put(GitConstants.KEY_REMOTE, link);
+ // add Git Clone Config URI
+ path = new Path(GitServlet.GIT_URI + '/' + GitConstants.CONFIG_RESOURCE + '/' + GitConstants.CLONE_RESOURCE).append(targetPath);
+ link = new URI(location.getScheme(), location.getAuthority(), path.toString(), null, null);
+ gitSection.put(GitConstants.KEY_CONFIG, link);
+
// add Git Default Remote Branch URI
gitSection.put(GitConstants.KEY_DEFAULT_REMOTE_BRANCH, BaseToRemoteConverter.getRemoteBranchLocation(location, db.getBranch(), db, BaseToRemoteConverter.FILE));
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java
index 2b8bb39..522c14e 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java
@@ -486,6 +486,10 @@ public class GitCloneHandlerV1 extends ServletResourceHandler<String> {
location = new URI(baseLocation.getScheme(), baseLocation.getUserInfo(), baseLocation.getHost(), baseLocation.getPort(), np.toString(), baseLocation.getQuery(), baseLocation.getFragment());
result.put(GitConstants.KEY_REMOTE, location);
+ np = new Path(GitServlet.GIT_URI).append(GitConstants.CONFIG_RESOURCE).append(GitConstants.CLONE_RESOURCE).append("file").append(k); //$NON-NLS-1$
+ location = new URI(baseLocation.getScheme(), baseLocation.getUserInfo(), baseLocation.getHost(), baseLocation.getPort(), np.toString(), baseLocation.getQuery(), baseLocation.getFragment());
+ result.put(GitConstants.KEY_CONFIG, location);
+
np = new Path(GitServlet.GIT_URI).append(GitConstants.BRANCH_RESOURCE).append("file").append(k); //$NON-NLS-1$
location = new URI(baseLocation.getScheme(), baseLocation.getUserInfo(), baseLocation.getHost(), baseLocation.getPort(), np.toString(), baseLocation.getQuery(), baseLocation.getFragment());
result.put(GitConstants.KEY_BRANCH, location);
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitConfigHandlerV1.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitConfigHandlerV1.java
index e462098..88d13a7 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitConfigHandlerV1.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitConfigHandlerV1.java
@@ -12,18 +12,25 @@ 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.*;
-import org.eclipse.jgit.lib.Config.SectionParser;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.storage.file.FileRepository;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.internal.server.servlets.ServletResourceHandler;
import org.eclipse.orion.server.core.ServerStatus;
+import org.eclipse.orion.server.git.BaseToConfigEntryConverter;
+import org.eclipse.orion.server.git.GitConstants;
+import org.eclipse.orion.server.servlets.OrionServlet;
import org.eclipse.osgi.util.NLS;
-import org.json.JSONException;
+import org.json.*;
/**
* A handler for Git Clone operation.
@@ -38,89 +45,221 @@ public class GitConfigHandlerV1 extends ServletResourceHandler<String> {
@Override
public boolean handleRequest(HttpServletRequest request, HttpServletResponse response, String path) throws ServletException {
- Repository db = null;
try {
- Path p = new Path(path);
switch (getMethod(request)) {
case GET :
- return handleGet(request, response, db, p);
- // case PUT:
- // return handlePut(request, response, p);
- // case POST :
- // return handlePost(request, response, db, p);
- // case DELETE :
- // return handleDelete(request, response, p);
+ 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));
- } finally {
- if (db != null)
- db.close();
}
return false;
}
- private boolean handleGet(HttpServletRequest request, HttpServletResponse response, Repository db, Path path) throws IOException, JSONException, ServletException, URISyntaxException, CoreException {
- File gitDir = GitUtils.getGitDir(path.removeFirstSegments(1).uptoSegment(2));
- if (gitDir == null)
- return false; // TODO: or an error response code, 405?
- db = new FileRepository(gitDir);
-
- db.getConfig().get(new SectionParser<Object>() {
- @Override
- public Object parse(Config cfg) {
- System.out.println(cfg);
- return null;
+ private boolean handleGet(HttpServletRequest request, HttpServletResponse response, String path) throws IOException, JSONException, ServletException, URISyntaxException, CoreException, ConfigInvalidException {
+ Path p = new Path(path);
+ if (p.segment(0).equals("clone") && p.segment(1).equals("file")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // expected path /gitapi/config/clone/file/{path}
+ File gitDir = GitUtils.getGitDir(p.removeFirstSegments(1).uptoSegment(2));
+ FileBasedConfig config = getLocalConfig(gitDir);
+ URI baseLocation = getURI(request);
+
+ JSONObject result = configToJSON(config, baseLocation);
+ OrionServlet.writeJSONResponse(request, response, result);
+ return true;
+ } else if (p.segment(1).equals("clone") && p.segment(2).equals("file")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // expected path /gitapi/config/{key}/clone/file/{path}
+ File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2).uptoSegment(2));
+ Repository db = new FileRepository(gitDir);
+ StoredConfig config = db.getConfig();
+ URI baseLocation = getURI(request);
+
+ String key = p.segment(0);
+ String[] keySegments = keyToSegments(key);
+ if (keySegments == null)
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Config entry key must be provided in the following form: section[.subsection].name", null));
+ JSONObject result = configEntryToJSON(config, keySegments, baseLocation);
+ if (result == null)
+ 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, result);
+ return true;
+ }
+ 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") && p.segment(1).equals("file")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // expected path /gitapi/config/clone/file/{path}
+ File gitDir = GitUtils.getGitDir(p.removeFirstSegments(1).uptoSegment(2));
+ FileBasedConfig config = getLocalConfig(gitDir);
+ URI baseLocation = getURI(request);
+
+ 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, "Confign 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, "Confign entry value must be provided", null));
+ String[] keySegments = keyToSegments(key);
+ if (keySegments == null)
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Config entry key must be provided in the following form: section[.subsection].name", null));
+
+ // determine if config entry is already present
+ boolean present = false;
+ if (config.getString(keySegments[0], keySegments[1], keySegments[2]) != null)
+ present = true;
+
+ // set new value
+ config.setString(keySegments[0], keySegments[1], keySegments[2], value);
+ config.save();
+
+ JSONObject result = configEntryToJSON(config, keySegments, baseLocation);
+ OrionServlet.writeJSONResponse(request, response, result);
+ response.setHeader(ProtocolConstants.HEADER_LOCATION, result.getString(ProtocolConstants.KEY_LOCATION));
+ if (!present)
+ response.setStatus(HttpServletResponse.SC_CREATED);
+ return true;
+ }
+ 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") && p.segment(2).equals("file")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // expected path /gitapi/config/{key}/clone/file/{path}
+ File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2).uptoSegment(2));
+ FileBasedConfig config = getLocalConfig(gitDir);
+ URI baseLocation = getURI(request);
+
+ String key = p.segment(0);
+ if (key == null || key.isEmpty())
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Confign entry key must be provided in URI", null));
+
+ 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, "Confign entry value must be provided", null));
+
+ String[] keySegments = keyToSegments(key);
+ if (keySegments == null)
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Config entry key must be provided in the following form: section[.subsection].name", null));
+
+ // PUT allows only to modify existing config entries
+ if (config.getString(keySegments[0], keySegments[1], keySegments[2]) == null) {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ return true;
}
- });
-
- // List<WebClone> clones = WebClone.allClones();
- // JSONObject result = new JSONObject();
- // URI baseLocation = getURI(request);
- // JSONArray children = new JSONArray();
- // for (WebClone clone : clones) {
- // JSONObject child = WebCloneResourceHandler.toJSON(clone, baseLocation);
- // children.put(child);
- // }
- // result.put(ProtocolConstants.KEY_CHILDREN, children);
- // OrionServlet.writeJSONResponse(request, response, result);
- return true;
+
+ // set new value
+ config.setString(keySegments[0], keySegments[1], keySegments[2], value);
+ config.save();
+
+ JSONObject result = configEntryToJSON(config, keySegments, baseLocation);
+ OrionServlet.writeJSONResponse(request, response, result);
+ response.setHeader(ProtocolConstants.HEADER_LOCATION, result.getString(ProtocolConstants.KEY_LOCATION));
+ return true;
+ }
+ return false;
}
- // private void doConfigureClone(Git git, String userId) throws IOException, CoreException {
- // StoredConfig config = git.getRepository().getConfig();
- // IOrionUserProfileNode userNode = UserServiceHelper.getDefault().getUserProfileService().getUserProfileNode(userId, true).getUserProfileNode(IOrionUserProfileConstants.GENERAL_PROFILE_PART);
- // if (userNode.get(GitConstants.KEY_NAME, null) != null)
- // config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME, userNode.get(GitConstants.KEY_NAME, null));
- // if (userNode.get(GitConstants.KEY_MAIL, null) != null)
- // config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL, userNode.get(GitConstants.KEY_MAIL, null));
- // config.save();
- // }
-
- /**
- * Validates that the provided clone name is valid. Returns
- * <code>true</code> if the project name is valid, and <code>false</code>
- * otherwise. This method takes care of setting the error response when the
- * clone name is not valid.
- */
- // private boolean validateCloneName(String name, HttpServletRequest request, HttpServletResponse response) throws ServletException {
- // // TODO: implement
- // return true;
- // }
-
- // private boolean validateCloneUrl(String url, HttpServletRequest request, HttpServletResponse response) throws ServletException {
- // if (url == null || url.trim().length() == 0) {
- // statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Clone URL cannot be empty", null)); //$NON-NLS-1$
- // return false;
- // }
- // try {
- // new URIish(url);
- // } catch (URISyntaxException e) {
- // statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, NLS.bind("Invalid clone URL: {0}", url), e)); //$NON-NLS-1$
- // return false;
- // }
- // return true;
- // }
+ private boolean handleDelete(HttpServletRequest request, HttpServletResponse response, String path) throws CoreException, IOException, ServletException, ConfigInvalidException {
+ Path p = new Path(path);
+ if (p.segment(1).equals("clone") && p.segment(2).equals("file")) { //$NON-NLS-1$ //$NON-NLS-2$
+ // expected path /gitapi/config/{key}/clone/file/{path}
+ File gitDir = GitUtils.getGitDir(p.removeFirstSegments(2).uptoSegment(2));
+ FileBasedConfig config = getLocalConfig(gitDir);
+
+ String key = p.segment(0);
+ String[] keySegments = keyToSegments(key);
+ if (keySegments == null)
+ return statusHandler.handleRequest(request, response, new ServerStatus(IStatus.ERROR, HttpServletResponse.SC_BAD_REQUEST, "Config entry key must be provided in the following form: section[.subsection].name", null));
+
+ // determine if config entry exist
+ if (config.getString(keySegments[0], keySegments[1], keySegments[2]) != null) {
+ // delete
+ config.unset(keySegments[0], keySegments[1], keySegments[2]);
+ config.save();
+ response.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ // retrieves local config without any base config
+ private FileBasedConfig getLocalConfig(File gitDirectory) throws IOException, ConfigInvalidException {
+ FileRepository db = new FileRepository(gitDirectory);
+ FileBasedConfig config = new FileBasedConfig(db.getConfig().getFile(), FS.detect());
+ config.load();
+ return config;
+ }
+
+ // converts whole config to JSON representation
+ JSONObject configToJSON(Config config, URI baseLocation) throws JSONException, URISyntaxException {
+ JSONObject result = new JSONObject();
+ JSONArray children = new JSONArray();
+ for (String section : config.getSections()) {
+ // proceed configuration entries: section.name
+ for (String name : config.getNames(section))
+ children.put(configEntryToJSON(config, new String[] {section, null, name}, baseLocation));
+ // proceed configuration entries: section.subsection.name
+ for (String subsection : config.getSubsections(section))
+ for (String name : config.getNames(section, subsection))
+ children.put(configEntryToJSON(config, new String[] {section, subsection, name}, baseLocation));
+ }
+ result.put(ProtocolConstants.KEY_CHILDREN, children);
+ return result;
+ }
+
+ // reads configuration entry and converts it to JSON representation
+ // returns null if there is no entry with given key
+ JSONObject configEntryToJSON(Config config, String[] keySegments, URI baseLocation) throws JSONException, URISyntaxException {
+ String value = config.getString(keySegments[0], keySegments[1], keySegments[2]);
+ if (value == null)
+ return null;
+
+ String key = segmentsToKey(keySegments);
+ JSONObject result = new JSONObject();
+ result.put(GitConstants.KEY_CONFIG_ENTRY_KEY, key);
+ result.put(GitConstants.KEY_CONFIG_ENTRY_VALUE, value);
+ result.put(ProtocolConstants.KEY_LOCATION, BaseToConfigEntryConverter.REMOVE_FIRST_2.baseToConfigEntryLocation(baseLocation, key));
+ return result;
+ }
+
+ // converts segments of key to key representation
+ // returns null if input array is invalid
+ private String segmentsToKey(String[] segments) {
+ if (segments.length == 3)
+ // check if there is subsection part
+ return segments[1] == null ? String.format("%s.%s", segments[0], segments[2]) : String.format("%s.%s.%s", segments[0], segments[1], segments[2]);
+
+ return null;
+ }
+
+ // converts key representation to key segments
+ // returns null if input string is invalid
+ private String[] keyToSegments(String key) {
+ String[] keyParts = key.split("\\.");
+ if (keyParts.length == 3)
+ // section, subsection and name provided
+ return keyParts;
+ else if (keyParts.length == 2)
+ // no subsection provided
+ return keyParts = new String[] {keyParts[0], null, keyParts[1]};
+
+ return null;
+ }
}
diff --git a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java
index 15a73fc..f4e63b9 100644
--- a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java
+++ b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java
@@ -26,10 +26,14 @@ import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.orion.internal.server.servlets.ProtocolConstants;
import org.eclipse.orion.server.git.GitConstants;
+import org.eclipse.orion.server.tests.servlets.internal.DeleteMethodWebRequest;
+import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Test;
+import com.meterware.httpunit.GetMethodWebRequest;
+import com.meterware.httpunit.PostMethodWebRequest;
import com.meterware.httpunit.PutMethodWebRequest;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
@@ -107,6 +111,197 @@ public class GitConfigTest extends GitTest {
assertEquals(2, c);
}
+ @Test
+ public void testSetAndUnsetConfigValues() throws Exception {
+ // clone a repo
+ URI workspaceLocation = createWorkspace(getMethodName());
+ JSONObject project = createProjectOrLink(workspaceLocation, getMethodName(), null);
+ IPath clonePath = new Path("file").append(project.getString(ProtocolConstants.KEY_ID)).makeAbsolute();
+ String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION);
+
+ // get project metadata
+ WebRequest request = getGetFilesRequest(contentLocation);
+ WebResponse response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ project = new JSONObject(response.getText());
+ JSONObject gitSection = project.optJSONObject(GitConstants.KEY_GIT);
+ assertNotNull(gitSection);
+
+ String gitConfigUri = gitSection.getString(GitConstants.KEY_CONFIG);
+ assertNotNull(gitConfigUri);
+
+ // get list of config entries
+ request = getGetGitConfigRequest(gitConfigUri);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ JSONObject configResponse = new JSONObject(response.getText());
+ JSONArray configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN);
+ // initial number of config entries
+ int initialConfigEntriesCount = configEntries.length();
+
+ // set some dummy value
+ final String ENTRY_KEY = "sectionA.subsectionB.nameC";
+ final String ENTRY_VALUE = "valueXYZ";
+
+ request = getPostGitConfigRequest(gitConfigUri, ENTRY_KEY, ENTRY_VALUE);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_CREATED, response.getResponseCode());
+
+ // get list of config entries again
+ request = getGetGitConfigRequest(gitConfigUri);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ configResponse = new JSONObject(response.getText());
+ configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN);
+ assertEquals(initialConfigEntriesCount + 1, configEntries.length());
+
+ String entryLocation = null;
+ for (int i = 0; i < configEntries.length(); i++) {
+ JSONObject configEntry = configEntries.getJSONObject(i);
+ if (ENTRY_KEY.equals(configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_KEY))) {
+ assertEquals(ENTRY_VALUE, configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_VALUE));
+ entryLocation = configEntry.getString(ProtocolConstants.KEY_LOCATION);
+ }
+ }
+ assertNotNull(entryLocation);
+
+ // update config entry using POST
+ final String NEW_ENTRY_VALUE_1 = "valueABC";
+
+ request = getPostGitConfigRequest(gitConfigUri, ENTRY_KEY, NEW_ENTRY_VALUE_1);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // get list of config entries again
+ request = getGetGitConfigRequest(gitConfigUri);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ configResponse = new JSONObject(response.getText());
+ configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN);
+ assertEquals(initialConfigEntriesCount + 1, configEntries.length());
+
+ entryLocation = null;
+ for (int i = 0; i < configEntries.length(); i++) {
+ JSONObject configEntry = configEntries.getJSONObject(i);
+ if (ENTRY_KEY.equals(configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_KEY))) {
+ assertEquals(NEW_ENTRY_VALUE_1, configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_VALUE));
+ entryLocation = configEntry.getString(ProtocolConstants.KEY_LOCATION);
+ }
+ }
+ assertNotNull(entryLocation);
+
+ // update config entry using PUT
+ final String NEW_ENTRY_VALUE_2 = "valueABCXYZ";
+
+ request = getPutGitConfigRequest(entryLocation, NEW_ENTRY_VALUE_2);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // get list of config entries again
+ request = getGetGitConfigRequest(gitConfigUri);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ configResponse = new JSONObject(response.getText());
+ configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN);
+ assertEquals(initialConfigEntriesCount + 1, configEntries.length());
+
+ entryLocation = null;
+ for (int i = 0; i < configEntries.length(); i++) {
+ JSONObject configEntry = configEntries.getJSONObject(i);
+ if (ENTRY_KEY.equals(configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_KEY))) {
+ assertEquals(NEW_ENTRY_VALUE_2, configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_VALUE));
+ entryLocation = configEntry.getString(ProtocolConstants.KEY_LOCATION);
+ }
+ }
+ assertNotNull(entryLocation);
+
+ // test PUT with invalid entry
+ String invalidEntryLocation = entryLocation.replace(ENTRY_KEY, "qwerty.asdfg");
+ request = getPutGitConfigRequest(invalidEntryLocation, NEW_ENTRY_VALUE_2);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_NOT_FOUND, response.getResponseCode());
+
+ // delete config entry
+ request = getDeleteGitConfigRequest(entryLocation);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // get list of config entries again
+ request = getGetGitConfigRequest(gitConfigUri);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ configResponse = new JSONObject(response.getText());
+ configEntries = configResponse.getJSONArray(ProtocolConstants.KEY_CHILDREN);
+ assertEquals(initialConfigEntriesCount, configEntries.length());
+
+ boolean found = false;
+ for (int i = 0; i < configEntries.length(); i++) {
+ JSONObject configEntry = configEntries.getJSONObject(i);
+ if (ENTRY_KEY.equals(configEntry.getString(GitConstants.KEY_CONFIG_ENTRY_KEY)))
+ found = true;
+ }
+ assertEquals(false, found);
+ }
+
+ static WebRequest getDeleteGitConfigRequest(String location) {
+ String requestURI;
+ if (location.startsWith("http://"))
+ requestURI = location;
+ else if (location.startsWith("/"))
+ requestURI = SERVER_LOCATION + location;
+ else
+ requestURI = SERVER_LOCATION + GIT_SERVLET_LOCATION + GitConstants.CONFIG_RESOURCE + location;
+ WebRequest request = new DeleteMethodWebRequest(requestURI);
+ request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
+ setAuthentication(request);
+ return request;
+ }
+
+ static WebRequest getPutGitConfigRequest(String location, String value) throws JSONException, UnsupportedEncodingException {
+ String requestURI;
+ if (location.startsWith("http://"))
+ requestURI = location;
+ else
+ requestURI = SERVER_LOCATION + location;
+ JSONObject body = new JSONObject();
+ body.put(GitConstants.KEY_CONFIG_ENTRY_VALUE, value);
+ WebRequest request = new PutMethodWebRequest(requestURI, getJsonAsStream(body.toString()), "UTF-8");
+ request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
+ setAuthentication(request);
+ return request;
+ }
+
+ static WebRequest getPostGitConfigRequest(String location, String key, String value) throws JSONException, UnsupportedEncodingException {
+ String requestURI;
+ if (location.startsWith("http://"))
+ requestURI = location;
+ else if (location.startsWith("/"))
+ requestURI = SERVER_LOCATION + location;
+ else
+ requestURI = SERVER_LOCATION + GIT_SERVLET_LOCATION + GitConstants.CONFIG_RESOURCE + "/" + GitConstants.CLONE_RESOURCE + location;
+ JSONObject body = new JSONObject();
+ body.put(GitConstants.KEY_CONFIG_ENTRY_KEY, key);
+ body.put(GitConstants.KEY_CONFIG_ENTRY_VALUE, value);
+ WebRequest request = new PostMethodWebRequest(requestURI, getJsonAsStream(body.toString()), "UTF-8");
+ request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
+ setAuthentication(request);
+ return request;
+ }
+
+ static WebRequest getGetGitConfigRequest(String location) {
+ String requestURI;
+ if (location.startsWith("http://"))
+ requestURI = location;
+ else if (location.startsWith("/"))
+ requestURI = SERVER_LOCATION + location;
+ else
+ requestURI = SERVER_LOCATION + GIT_SERVLET_LOCATION + GitConstants.CONFIG_RESOURCE + "/" + GitConstants.CLONE_RESOURCE + location;
+ WebRequest request = new GetMethodWebRequest(requestURI);
+ request.setHeaderField(ProtocolConstants.HEADER_ORION_VERSION, "1");
+ setAuthentication(request);
+ return request;
+ }
+
// TODO: should be moved to User tests as a static method
private WebRequest getPutUserRequest() throws JSONException, UnsupportedEncodingException {
String requestURI = SERVER_LOCATION + "/users/test";