summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Moger <james.moger@gitblit.com>2011-10-24 21:51:46 -0400
committerJames Moger <james.moger@gitblit.com>2011-10-24 21:51:46 -0400
commit97a20ed01cb5ec890517e4fcbd67b8d8ff381787 (patch)
tree620bce135606c569c9429205b1b541bcf356f08e
parentf306ef8552efe1580e9c16e1d944f5ed1dca4aae (diff)
downloadgitblit-97a20ed01cb5ec890517e4fcbd67b8d8ff381787.tar.gz
gitblit-97a20ed01cb5ec890517e4fcbd67b8d8ff381787.zip
Working edit settings RPC. Web.xml is not directly modified.
-rw-r--r--.gitignore2
-rw-r--r--build.xml9
-rw-r--r--docs/02_rpc.mkd1
-rw-r--r--src/com/gitblit/FileSettings.java22
-rw-r--r--src/com/gitblit/GitBlit.java8
-rw-r--r--src/com/gitblit/IStoredSettings.java11
-rw-r--r--src/com/gitblit/RpcServlet.java2
-rw-r--r--src/com/gitblit/WebXmlSettings.java47
-rw-r--r--src/com/gitblit/utils/RpcUtils.java3
-rw-r--r--tests/com/gitblit/tests/RpcTests.java28
10 files changed, 120 insertions, 13 deletions
diff --git a/.gitignore b/.gitignore
index 86347ca9..3c0210d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,6 @@
/federation.properties
/mailtest.properties
/.settings/*.prefs
-/src/WEB-INF/gitblit.properties
+/src/WEB-INF/reference.properties
/bin/
/.settings/
diff --git a/build.xml b/build.xml
index 107fac37..4a5c8867 100644
--- a/build.xml
+++ b/build.xml
@@ -106,7 +106,7 @@
<!-- copy gitblit.properties to the WEB-INF folder.
this file is only used for parsing setting descriptions. -->
- <copy todir="${basedir}/src/WEB-INF" overwrite="true"
+ <copy tofile="${basedir}/src/WEB-INF/reference.properties" overwrite="true"
file="${basedir}/distrib/gitblit.properties" />
<!-- Compile the build tool and execute it.
@@ -311,11 +311,10 @@
<delete dir="${project.war.dir}" />
- <!-- Copy web.xml, users.properties, and gitblit.properties to WEB-INF -->
+ <!-- Copy web.xml and users.properties to WEB-INF -->
<copy todir="${project.war.dir}/WEB-INF">
<fileset dir="${basedir}/distrib">
<include name="users.properties" />
- <include name="gitblit.properties" />
</fileset>
<fileset dir="${basedir}/src/WEB-INF">
<include name="web.xml" />
@@ -326,6 +325,10 @@
</fileset>
</copy>
+ <!-- Copy gitblit.properties as reference.properties -->
+ <copy tofile="${project.war.dir}/WEB-INF/reference.properties"
+ file="${basedir}/distrib/gitblit.properties"/>
+
<!-- Build the docs for the WAR build -->
<antcall target="buildDocs" inheritall="true" inheritrefs="true">
<param name="docs.output.dir" value="${project.war.dir}/WEB-INF/docs" />
diff --git a/docs/02_rpc.mkd b/docs/02_rpc.mkd
index 0150d168..82655085 100644
--- a/docs/02_rpc.mkd
+++ b/docs/02_rpc.mkd
@@ -31,6 +31,7 @@ The Gitblit RPC mechanism, like the Gitblit JGit servlet, syndication/feed servl
<tr><td>LIST_FEDERATION_PROPOSALS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List&lt;FederationProposal&gt;</td></tr>
<tr><td>LIST_FEDERATION_SETS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List&lt;FederationSet&gt;</td></tr>
<tr><td>LIST_SETTINGS</td><td>-</td><td><em>admin</em></td><td>-</td><td>ServerSettings (see example below)</td></tr>
+<tr><td>EDIT_SETTINGS</td><td>-</td><td><em>admin</em></td><td>Map&lt;String, String&gt;</td><td>-</td></tr>
<tr><td>LIST_STATUS</td><td>-</td><td><em>admin</em></td><td>-</td><td>ServerStatus (see example below)</td></tr>
</table>
diff --git a/src/com/gitblit/FileSettings.java b/src/com/gitblit/FileSettings.java
index 56aac8b7..61100587 100644
--- a/src/com/gitblit/FileSettings.java
+++ b/src/com/gitblit/FileSettings.java
@@ -18,7 +18,11 @@ package com.gitblit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.util.Map;
import java.util.Properties;
+import java.util.regex.Pattern;
+
+import com.gitblit.utils.FileUtils;
/**
* Dynamically loads and reloads a properties file by keeping track of the last
@@ -75,6 +79,24 @@ public class FileSettings extends IStoredSettings {
}
/**
+ * Updates the specified settings in the settings file.
+ */
+ public synchronized boolean saveSettings(Map<String, String> settings) {
+ String content = FileUtils.readContent(propertiesFile, "\n");
+ for (Map.Entry<String, String> setting:settings.entrySet()) {
+ String regex = "(?m)^(" + regExEscape(setting.getKey()) + "\\s*+=\\s*+)"
+ + "(?:[^\r\n\\\\]++|\\\\(?:\r?\n|\r|.))*+$";
+ content = content.replaceAll(regex, setting.getKey() + " = " + setting.getValue());
+ }
+ FileUtils.writeContent(propertiesFile, content);
+ return true;
+ }
+
+ private String regExEscape(String input) {
+ return input.replace(".", "\\.");
+ }
+
+ /**
* @return the last modification date of the properties file
*/
protected long lastModified() {
diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index ffef94a7..8386d2d4 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -25,7 +25,6 @@ import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -253,9 +252,8 @@ public class GitBlit implements ServletContextListener {
* @param settings
* @return true if the update succeeded
*/
- public boolean updateSettings(Collection<SettingModel> settings) {
- // TODO update the settings
- return false;
+ public boolean updateSettings(Map<String, String> updatedSettings) {
+ return settings.saveSettings(updatedSettings);
}
public ServerStatus getStatus() {
@@ -1326,7 +1324,7 @@ public class GitBlit implements ServletContextListener {
// Read bundled Gitblit properties to extract setting descriptions.
// This copy is pristine and only used for populating the setting
// models map.
- InputStream is = servletContext.getResourceAsStream("/WEB-INF/gitblit.properties");
+ InputStream is = servletContext.getResourceAsStream("/WEB-INF/reference.properties");
BufferedReader propertiesReader = new BufferedReader(new InputStreamReader(is));
StringBuilder description = new StringBuilder();
SettingModel setting = new SettingModel();
diff --git a/src/com/gitblit/IStoredSettings.java b/src/com/gitblit/IStoredSettings.java
index a376c81a..2d8b6055 100644
--- a/src/com/gitblit/IStoredSettings.java
+++ b/src/com/gitblit/IStoredSettings.java
@@ -17,6 +17,7 @@ package com.gitblit;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import org.slf4j.Logger;
@@ -194,4 +195,14 @@ public abstract class IStoredSettings {
public void overrideSetting(String key, String value) {
overrides.put(key, value);
}
+
+ /**
+ * Updates the values for the specified keys and persists the entire
+ * configuration file.
+ *
+ * @param map
+ * of key, value pairs
+ * @return true if successful
+ */
+ public abstract boolean saveSettings(Map<String, String> updatedSettings);
} \ No newline at end of file
diff --git a/src/com/gitblit/RpcServlet.java b/src/com/gitblit/RpcServlet.java
index 7cf3a598..1136692a 100644
--- a/src/com/gitblit/RpcServlet.java
+++ b/src/com/gitblit/RpcServlet.java
@@ -191,7 +191,7 @@ public class RpcServlet extends JsonServlet {
} else if (RpcRequest.EDIT_SETTINGS.equals(reqType)) {
// update settings on the server
if (GitBlit.getBoolean(Keys.web.enableRpcAdministration, false)) {
- Collection<SettingModel> settings = deserialize(request, response,
+ Map<String, String> settings = deserialize(request, response,
RpcUtils.SETTINGS_TYPE);
GitBlit.self().updateSettings(settings);
} else {
diff --git a/src/com/gitblit/WebXmlSettings.java b/src/com/gitblit/WebXmlSettings.java
index 4b0358d2..055c7d35 100644
--- a/src/com/gitblit/WebXmlSettings.java
+++ b/src/com/gitblit/WebXmlSettings.java
@@ -15,7 +15,13 @@
*/
package com.gitblit;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.Enumeration;
+import java.util.Map;
import java.util.Properties;
import javax.servlet.ServletContext;
@@ -32,8 +38,11 @@ public class WebXmlSettings extends IStoredSettings {
private final Properties properties = new Properties();
+ private final ServletContext context;
+
public WebXmlSettings(ServletContext context) {
super(WebXmlSettings.class);
+ this.context = context;
Enumeration<?> keys = context.getInitParameterNames();
while (keys.hasMoreElements()) {
String key = keys.nextElement().toString();
@@ -41,6 +50,17 @@ public class WebXmlSettings extends IStoredSettings {
properties.put(key, decodeValue(value));
logger.debug(key + "=" + properties.getProperty(key));
}
+ // apply any web-configured overrides
+ File file = new File(context.getRealPath("/WEB-INF/web.properties"));
+ if (file.exists()) {
+ try {
+ InputStream is = new FileInputStream(file);
+ properties.load(is);
+ is.close();
+ } catch (Throwable t) {
+ logger.error("Failed to load web.properties setting overrides", t);
+ }
+ }
}
private String decodeValue(String value) {
@@ -54,6 +74,33 @@ public class WebXmlSettings extends IStoredSettings {
}
@Override
+ public synchronized boolean saveSettings(Map<String, String> settings) {
+ try {
+ Properties props = new Properties();
+ // load pre-existing web-configuration
+ File file = new File(context.getRealPath("/WEB-INF/web.properties"));
+ if (file.exists()) {
+ InputStream is = new FileInputStream(file);
+ props.load(is);
+ is.close();
+ }
+
+ // put all new settings and persist
+ props.putAll(settings);
+ OutputStream os = new FileOutputStream(file);
+ props.store(os, null);
+ os.close();
+
+ // override current runtime settings
+ properties.putAll(settings);
+ return true;
+ } catch (Throwable t) {
+ logger.error("Failed to save settings!", t);
+ }
+ return false;
+ }
+
+ @Override
public String toString() {
return "WEB.XML";
}
diff --git a/src/com/gitblit/utils/RpcUtils.java b/src/com/gitblit/utils/RpcUtils.java
index 6572cd9d..e5841518 100644
--- a/src/com/gitblit/utils/RpcUtils.java
+++ b/src/com/gitblit/utils/RpcUtils.java
@@ -30,7 +30,6 @@ import com.gitblit.models.FederationSet;
import com.gitblit.models.RepositoryModel;
import com.gitblit.models.ServerSettings;
import com.gitblit.models.ServerStatus;
-import com.gitblit.models.SettingModel;
import com.gitblit.models.UserModel;
import com.google.gson.reflect.TypeToken;
@@ -45,7 +44,7 @@ public class RpcUtils {
public static final Type NAMES_TYPE = new TypeToken<Collection<String>>() {
}.getType();
- public static final Type SETTINGS_TYPE = new TypeToken<Collection<SettingModel>>() {
+ public static final Type SETTINGS_TYPE = new TypeToken<Map<String, String>>() {
}.getType();
private static final Type REPOSITORIES_TYPE = new TypeToken<Map<String, RepositoryModel>>() {
diff --git a/tests/com/gitblit/tests/RpcTests.java b/tests/com/gitblit/tests/RpcTests.java
index 11a340a9..2860f32b 100644
--- a/tests/com/gitblit/tests/RpcTests.java
+++ b/tests/com/gitblit/tests/RpcTests.java
@@ -16,6 +16,7 @@
package com.gitblit.tests;
import java.io.IOException;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -23,6 +24,7 @@ import junit.framework.TestCase;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.GitBlitException.UnauthorizedException;
+import com.gitblit.Keys;
import com.gitblit.models.FederationModel;
import com.gitblit.models.FederationProposal;
import com.gitblit.models.FederationSet;
@@ -210,9 +212,33 @@ public class RpcTests extends TestCase {
ServerSettings settings = RpcUtils.getSettings(url, account, password.toCharArray());
assertTrue("No settings were retrieved!", settings != null);
}
-
+
public void testServerStatus() throws Exception {
ServerStatus status = RpcUtils.getStatus(url, account, password.toCharArray());
assertTrue("No status was retrieved!", status != null);
}
+
+ public void testUpdateSettings() throws Exception {
+ Map<String, String> updated = new HashMap<String, String>();
+
+ // grab current setting
+ ServerSettings settings = RpcUtils.getSettings(url, account, password.toCharArray());
+ boolean showSizes = settings.get(Keys.web.showRepositorySizes).getBoolean(true);
+ showSizes = !showSizes;
+
+ // update setting
+ updated.put(Keys.web.showRepositorySizes, String.valueOf(showSizes));
+ boolean success = RpcUtils.updateSettings(updated, "http://localhost:8080/gb", account,
+ password.toCharArray());
+ assertTrue("Failed to update server settings", success);
+
+ // confirm setting change
+ settings = RpcUtils.getSettings(url, account, password.toCharArray());
+ boolean newValue = settings.get(Keys.web.showRepositorySizes).getBoolean(false);
+ assertEquals(newValue, showSizes);
+
+ // restore setting
+ newValue = !newValue;
+ updated.put(Keys.web.showRepositorySizes, String.valueOf(newValue));
+ }
}