From b75734f0600c333d70a3659af82be54caf3cfd3e Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Fri, 21 Oct 2011 17:34:12 -0400 Subject: [PATCH] Revised settings RPC to be Map<String, SettingModel>. --- docs/02_rpc.mkd | 34 ++ src/com/gitblit/client/SettingsModel.java | 24 + src/com/gitblit/client/GitblitModel.java | 17 + src/com/gitblit/client/GitblitPanel.java | 13 + src/com/gitblit/client/SettingCellRenderer.java | 67 +++++ src/com/gitblit/client/SettingPanel.java | 114 +++++++++ src/com/gitblit/utils/RpcUtils.java | 60 ++-- src/com/gitblit/models/ServerStatus.java | 69 +++++ src/com/gitblit/client/EditUserDialog.java | 13 src/com/gitblit/RpcServlet.java | 14 src/com/gitblit/GitBlit.java | 103 ++++++++ src/com/gitblit/models/SettingModel.java | 144 ++++++++++++ tests/com/gitblit/tests/RpcTests.java | 12 build.xml | 8 src/com/gitblit/Constants.java | 3 15 files changed, 624 insertions(+), 71 deletions(-) diff --git a/build.xml b/build.xml index 92174d4..107fac3 100644 --- a/build.xml +++ b/build.xml @@ -104,6 +104,11 @@ </fileset> </copy> + <!-- 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" + file="${basedir}/distrib/gitblit.properties" /> + <!-- Compile the build tool and execute it. This downloads missing compile-time dependencies from Maven. --> @@ -306,10 +311,11 @@ <delete dir="${project.war.dir}" /> - <!-- Copy web.xml and users.properties to WEB-INF --> + <!-- Copy web.xml, users.properties, and gitblit.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" /> diff --git a/docs/02_rpc.mkd b/docs/02_rpc.mkd index fbc5e44..b01eb67 100644 --- a/docs/02_rpc.mkd +++ b/docs/02_rpc.mkd @@ -30,10 +30,10 @@ <tr><td>LIST_FEDERATION_RESULTS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List<FederationModel></td></tr> <tr><td>LIST_FEDERATION_PROPOSALS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List<FederationProposal></td></tr> <tr><td>LIST_FEDERATION_SETS</td><td>-</td><td><em>admin</em></td><td>-</td><td>List<FederationSet></td></tr> -<tr><td>LIST_SETTINGS</td><td>-</td><td><em>admin</em></td><td>-</td><td>Properties</td></tr> +<tr><td>LIST_SETTINGS</td><td>-</td><td><em>admin</em></td><td>-</td><td>Map<String, SettingModel></td></tr> </table> -### RPC Response Codes +### RPC/HTTP Response Codes <table> <tr><th>code</th><th>name</th><th>description</th></tr> <tr><td>200</td><td>success</td><td>Gitblit processed the request successfully</td></tr> @@ -47,7 +47,7 @@ ### Gitblit Manager [Gitblit Manager](http://code.google.com/p/gitblit/downloads/detail?name=%MANAGER%) is an example Java/Swing application that allows remote administration of a Gitblit server. -This application exercises most methods from the utility class `com.gitblit.utils.RpcUtils`. +This application exercises many, but not all, methods from the utility class `com.gitblit.utils.RpcUtils`. ### EGit "Import from Gitblit" Feature (Planning) @@ -153,4 +153,32 @@ ] } ] +</pre> + +### Example: LIST_SETTINGS +**url**: https://localhost/rpc?req=LIST_SETTINGS +**response body**: Map<String, SettingModel> +<pre> +{ + "web.siteName": { + "name": "web.siteName", + "currentValue": "", + "defaultValue": "", + "description": "Gitblit Web Settings\nIf blank Gitblit is displayed.", + "since": "0.5.0", + "caseSensitive": false, + "restartRequired": false, + "spaceDelimited": false + }, + "web.summaryCommitCount": { + "name": "web.summaryCommitCount", + "currentValue": "16", + "defaultValue": "16", + "description": "The number of commits to display on the summary page\nValue must exceed 0 else default of 16 is used", + "since": "0.5.0", + "caseSensitive": false, + "restartRequired": false, + "spaceDelimited": false + } +} </pre> \ No newline at end of file diff --git a/src/com/gitblit/Constants.java b/src/com/gitblit/Constants.java index d6495e6..f3ff6c4 100644 --- a/src/com/gitblit/Constants.java +++ b/src/com/gitblit/Constants.java @@ -204,7 +204,8 @@ LIST_REPOSITORIES, CREATE_REPOSITORY, EDIT_REPOSITORY, DELETE_REPOSITORY, LIST_USERS, CREATE_USER, EDIT_USER, DELETE_USER, LIST_REPOSITORY_MEMBERS, SET_REPOSITORY_MEMBERS, LIST_FEDERATION_REGISTRATIONS, LIST_FEDERATION_RESULTS, - LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, LIST_SETTINGS; + LIST_FEDERATION_PROPOSALS, LIST_FEDERATION_SETS, LIST_SETTINGS, + LIST_SERVER_STATUS; public static RpcRequest fromName(String name) { for (RpcRequest type : values()) { diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 51d5612..238c01f 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -15,9 +15,12 @@ */ package com.gitblit; +import java.io.BufferedReader; import java.io.File; import java.io.FileFilter; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.reflect.Field; import java.text.MessageFormat; import java.util.ArrayList; @@ -27,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; @@ -35,6 +39,7 @@ import javax.mail.Message; import javax.mail.MessagingException; +import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.http.Cookie; @@ -63,6 +68,8 @@ import com.gitblit.models.Metric; import com.gitblit.models.ObjectCache; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.ServerStatus; +import com.gitblit.models.SettingModel; import com.gitblit.models.UserModel; import com.gitblit.utils.ByteFormat; import com.gitblit.utils.FederationUtils; @@ -106,6 +113,8 @@ private RepositoryResolver<Void> repositoryResolver; + private ServletContext servletContext; + private File repositoriesFolder; private boolean exportAll = true; @@ -113,6 +122,10 @@ private IUserService userService; private IStoredSettings settings; + + private Map<String, SettingModel> settingModels; + + private ServerStatus serverStatus; private MailExecutor mailExecutor; @@ -231,6 +244,13 @@ */ public static boolean isDebugMode() { return self().settings.getBoolean(Keys.web.debugMode, false); + } + + public ServerStatus getStatus() { + // update heap memory status + serverStatus.heapAllocated = Runtime.getRuntime().totalMemory(); + serverStatus.heapFree = Runtime.getRuntime().freeMemory(); + return serverStatus; } /** @@ -1253,6 +1273,86 @@ } /** + * Returns the descriptions/comments of the Gitblit config settings. + * + * @return Map<String, SettingModel> + */ + public Map<String, SettingModel> getSettingModels() { + // ensure that the current values are updated in the setting models + for (String key : settings.getAllKeys(null)) { + if (settingModels.containsKey(key)) { + settingModels.get(key).currentValue = settings.getString(key, ""); + } + } + return settingModels; + } + + /** + * Parse the properties file and aggregate all the comments by the setting + * key. A setting model tracks the current value, the default value, the + * description of the setting and and directives about the setting. + * + * @return Map<String, SettingModel> + */ + private Map<String, SettingModel> loadSettingModels() { + Map<String, SettingModel> map = new TreeMap<String, SettingModel>(); + try { + // 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"); + BufferedReader propertiesReader = new BufferedReader(new InputStreamReader(is)); + StringBuilder description = new StringBuilder(); + SettingModel setting = new SettingModel(); + String line = null; + while ((line = propertiesReader.readLine()) != null) { + if (line.length() == 0) { + description.setLength(0); + setting = new SettingModel(); + } else { + if (line.charAt(0) == '#') { + if (line.length() > 1) { + String text = line.substring(1).trim(); + if (SettingModel.CASE_SENSITIVE.equals(text)) { + setting.caseSensitive = true; + } else if (SettingModel.RESTART_REQUIRED.equals(text)) { + setting.restartRequired = true; + } else if (SettingModel.SPACE_DELIMITED.equals(text)) { + setting.spaceDelimited = true; + } else if (text.startsWith(SettingModel.SINCE)) { + try { + setting.since = text.split(" ")[1]; + } catch (Exception e) { + setting.since = text; + } + } else { + description.append(text); + description.append('\n'); + } + } + } else { + String[] kvp = line.split("=", 2); + String key = kvp[0].trim(); + setting.name = key; + setting.defaultValue = kvp[1].trim(); + setting.currentValue = setting.defaultValue; + setting.description = description.toString().trim(); + map.put(key, setting); + description.setLength(0); + setting = new SettingModel(); + } + } + } + propertiesReader.close(); + } catch (NullPointerException e) { + logger.error("Failed to find resource copy of gitblit.properties"); + } catch (IOException e) { + logger.error("Failed to load resource copy of gitblit.properties"); + } + return map; + } + + /** * Configure the Gitblit singleton with the specified settings source. This * source may be file settings (Gitblit GO) or may be web.xml settings * (Gitblit WAR). @@ -1265,6 +1365,7 @@ repositoriesFolder = new File(settings.getString(Keys.git.repositoriesFolder, "git")); logger.info("Git repositories folder " + repositoriesFolder.getAbsolutePath()); repositoryResolver = new FileResolver<Void>(repositoriesFolder, exportAll); + serverStatus = new ServerStatus(); String realm = settings.getString(Keys.realm.userService, "users.properties"); IUserService loginService = null; try { @@ -1307,6 +1408,8 @@ */ @Override public void contextInitialized(ServletContextEvent contextEvent) { + servletContext = contextEvent.getServletContext(); + settingModels = loadSettingModels(); if (settings == null) { // Gitblit WAR is running in a servlet container WebXmlSettings webxmlSettings = new WebXmlSettings(contextEvent.getServletContext()); diff --git a/src/com/gitblit/RpcServlet.java b/src/com/gitblit/RpcServlet.java index 53426da..6a8c2c5 100644 --- a/src/com/gitblit/RpcServlet.java +++ b/src/com/gitblit/RpcServlet.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -183,15 +182,10 @@ } } else if (RpcRequest.LIST_SETTINGS.equals(reqType)) { // return the server's settings - Properties settings = new Properties(); - List<String> keys = GitBlit.getAllKeys(null); - for (String key : keys) { - String value = GitBlit.getString(key, null); - if (value != null) { - settings.put(key, value); - } - } - result = settings; + result = GitBlit.self().getSettingModels(); + } else if (RpcRequest.LIST_SERVER_STATUS.equals(reqType)) { + // return the server's status information + result = GitBlit.self().getStatus(); } // send the result of the request diff --git a/src/com/gitblit/client/EditUserDialog.java b/src/com/gitblit/client/EditUserDialog.java index eacef24..0a1ddd9 100644 --- a/src/com/gitblit/client/EditUserDialog.java +++ b/src/com/gitblit/client/EditUserDialog.java @@ -29,6 +29,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import javax.swing.ImageIcon; @@ -45,9 +46,9 @@ import javax.swing.KeyStroke; import com.gitblit.Constants.AccessRestrictionType; -import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.SettingModel; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; @@ -57,7 +58,7 @@ private final UserModel user; - private final IStoredSettings settings; + private final Map<String, SettingModel> settings; private boolean isCreate; @@ -77,13 +78,13 @@ private Set<String> usernames; - public EditUserDialog(IStoredSettings settings) { + public EditUserDialog(Map<String, SettingModel> settings) { this(new UserModel(""), settings); this.isCreate = true; setTitle(Translation.get("gb.newUser")); } - public EditUserDialog(UserModel anUser, IStoredSettings settings) { + public EditUserDialog(UserModel anUser, Map<String, SettingModel> settings) { super(); this.user = new UserModel(""); this.settings = settings; @@ -196,7 +197,7 @@ } } - int minLength = settings.getInteger(Keys.realm.minPasswordLength, 5); + int minLength = settings.get(Keys.realm.minPasswordLength).getInteger(5); if (minLength < 4) { minLength = 4; } @@ -216,7 +217,7 @@ return false; } user.username = uname; - String type = settings.getString(Keys.realm.passwordStorage, "md5"); + String type = settings.get(Keys.realm.passwordStorage).getString("md5"); if (type.equalsIgnoreCase("md5")) { // store MD5 digest of password user.password = StringUtils.MD5_TYPE + StringUtils.getMD5(new String(pw)); diff --git a/src/com/gitblit/client/GitblitModel.java b/src/com/gitblit/client/GitblitModel.java index 22d67f6..55e74b9 100644 --- a/src/com/gitblit/client/GitblitModel.java +++ b/src/com/gitblit/client/GitblitModel.java @@ -24,10 +24,11 @@ import com.gitblit.GitBlitException.ForbiddenException; import com.gitblit.GitBlitException.UnauthorizedException; -import com.gitblit.IStoredSettings; import com.gitblit.Keys; import com.gitblit.models.FederationModel; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.ServerStatus; +import com.gitblit.models.SettingModel; import com.gitblit.models.UserModel; import com.gitblit.utils.RpcUtils; @@ -43,13 +44,15 @@ private volatile boolean isAdmin; - private volatile IStoredSettings settings; + private volatile Map<String, SettingModel> settings; private final List<RepositoryModel> allRepositories; private final List<UserModel> allUsers; private final List<FederationModel> federationRegistrations; + + private ServerStatus status; public GitblitModel(String url, String account, char[] password) { this.url = url; @@ -66,8 +69,8 @@ try { settings = RpcUtils.getSettings(url, account, password); + status = RpcUtils.getStatus(url, account, password); refreshUsers(); - refreshFederationRegistrations(); isAdmin = true; } catch (UnauthorizedException e) { } catch (ForbiddenException e) { @@ -84,8 +87,12 @@ return account != null && account.equalsIgnoreCase(model.owner); } - public IStoredSettings getSettings() { + public Map<String, SettingModel> getSettings() { return settings; + } + + public String getSettingDescription(String key) { + return settings.get(key).description; } public List<RepositoryModel> refreshRepositories() throws IOException { @@ -135,7 +142,7 @@ } public List<String> getFederationSets() { - return settings.getStrings(Keys.federation.sets); + return settings.get(Keys.federation.sets).getStrings(); } public List<RepositoryModel> getRepositories() { diff --git a/src/com/gitblit/client/GitblitPanel.java b/src/com/gitblit/client/GitblitPanel.java index f0d04b7..8635b00 100644 --- a/src/com/gitblit/client/GitblitPanel.java +++ b/src/com/gitblit/client/GitblitPanel.java @@ -52,6 +52,7 @@ import com.gitblit.Constants.RpcRequest; import com.gitblit.client.ClosableTabComponent.CloseTabListener; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.SettingModel; import com.gitblit.models.UserModel; import com.gitblit.utils.StringUtils; @@ -116,7 +117,6 @@ tabs = new JTabbedPane(JTabbedPane.BOTTOM); tabs.addTab(Translation.get("gb.repositories"), createRepositoriesPanel()); tabs.addTab(Translation.get("gb.users"), createUsersPanel()); - tabs.addTab(Translation.get("gb.federation"), new JPanel()); tabs.addTab(Translation.get("gb.settings"), createSettingsPanel()); setLayout(new BorderLayout()); @@ -380,9 +380,11 @@ } private JPanel createSettingsPanel() { + final SettingPanel settingPanel = new SettingPanel(); settingsModel = new SettingsModel(); defaultSettingsSorter = new TableRowSorter<SettingsModel>(settingsModel); settingsTable = Utils.newTable(settingsModel); + settingsTable.setDefaultRenderer(SettingModel.class, new SettingCellRenderer()); String name = settingsTable.getColumnName(UsersModel.Columns.Name.ordinal()); settingsTable.setRowHeight(nameRenderer.getFont().getSize() + 8); settingsTable.getColumn(name).setCellRenderer(nameRenderer); @@ -398,6 +400,14 @@ boolean selected = settingsTable.getSelectedRow() > -1; boolean singleSelection = settingsTable.getSelectedRows().length == 1; // TODO enable/disable setting buttons + if (singleSelection) { + int viewRow = settingsTable.getSelectedRow(); + int modelRow = settingsTable.convertRowIndexToModel(viewRow); + SettingModel setting = settingsModel.get(modelRow); + settingPanel.setSetting(setting); + } else { + settingPanel.clear(); + } } }); @@ -420,6 +430,7 @@ JPanel settingsTablePanel = new JPanel(new BorderLayout(margin, margin)); settingsTablePanel.add(settingFilterPanel, BorderLayout.NORTH); settingsTablePanel.add(new JScrollPane(settingsTable), BorderLayout.CENTER); + settingsTablePanel.add(settingPanel, BorderLayout.SOUTH); JPanel settingsControls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); // TODO update setting? diff --git a/src/com/gitblit/client/SettingCellRenderer.java b/src/com/gitblit/client/SettingCellRenderer.java new file mode 100644 index 0000000..d164fb1 --- /dev/null +++ b/src/com/gitblit/client/SettingCellRenderer.java @@ -0,0 +1,67 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.client; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; + +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; + +import com.gitblit.models.SettingModel; + +/** + * SettingModel cell renderer that indicates if a setting is the default or + * modified. + * + * @author James Moger + * + */ +public class SettingCellRenderer extends DefaultTableCellRenderer { + + private static final long serialVersionUID = 1L; + + private final Font defaultFont; + + private final Font modifiedFont; + + public SettingCellRenderer() { + defaultFont = getFont(); + modifiedFont = defaultFont.deriveFont(Font.BOLD); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, + boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (value instanceof SettingModel) { + SettingModel setting = (SettingModel) value; + if (setting.isDefaultValue()) { + this.setFont(defaultFont); + if (!isSelected) { + this.setForeground(Color.BLACK); + } + } else { + this.setFont(modifiedFont); + if (!isSelected) { + this.setForeground(Color.BLUE); + } + } + this.setText(setting.getString("")); + } + return this; + } +} \ No newline at end of file diff --git a/src/com/gitblit/client/SettingPanel.java b/src/com/gitblit/client/SettingPanel.java new file mode 100644 index 0000000..8d07dc8 --- /dev/null +++ b/src/com/gitblit/client/SettingPanel.java @@ -0,0 +1,114 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.client; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.GridLayout; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.SwingConstants; + +import com.gitblit.models.SettingModel; +import com.gitblit.utils.StringUtils; + +/** + * This panel displays the metadata for a particular setting. + * + * @author James Moger + */ +public class SettingPanel extends JPanel { + + private static final long serialVersionUID = 1L; + private JTextArea descriptionArea; + private JLabel settingName; + private JLabel settingDefault; + private JLabel sinceVersion; + private JLabel directives; + + public SettingPanel() { + super(); + initialize(); + } + + private void initialize() { + descriptionArea = new JTextArea(); + descriptionArea.setRows(6); + descriptionArea.setFont(new Font("monospaced", Font.PLAIN, 11)); + + settingName = new JLabel(" "); + settingName.setFont(settingName.getFont().deriveFont(Font.BOLD)); + + settingDefault = new JLabel(" "); + + sinceVersion = new JLabel(" ", SwingConstants.RIGHT); + sinceVersion.setForeground(new Color(0, 0x80, 0)); + + directives = new JLabel(" ", SwingConstants.RIGHT); + directives.setFont(directives.getFont().deriveFont(Font.ITALIC)); + + JPanel settingParameters = new JPanel(new GridLayout(2, 2, 0, 0)); + settingParameters.add(settingName); + settingParameters.add(sinceVersion); + settingParameters.add(settingDefault, BorderLayout.CENTER); + settingParameters.add(directives); + + JPanel settingPanel = new JPanel(new BorderLayout(5, 5)); + settingPanel.add(settingParameters, BorderLayout.NORTH); + settingPanel.add(new JScrollPane(descriptionArea), BorderLayout.CENTER); + setLayout(new BorderLayout(0, 0)); + add(settingPanel, BorderLayout.CENTER); + } + + public void setSetting(SettingModel setting) { + settingName.setText(setting.name); + if (setting.since == null) { + sinceVersion.setText("custom"); + } else { + sinceVersion.setText("since " + setting.since); + } + settingDefault.setText("default: " + setting.defaultValue); + + List<String> values = new ArrayList<String>(); + if (setting.caseSensitive) { + values.add("CASE-SENSITIVE"); + } + if (setting.spaceDelimited) { + values.add("SPACE-DELIMITED"); + } + if (setting.restartRequired) { + values.add("RESTART REQUIRED"); + } + directives.setText(StringUtils.flattenStrings(values, ", ")); + + descriptionArea.setText(setting.description); + descriptionArea.setCaretPosition(0); + } + + public void clear() { + settingName.setText(" "); + settingDefault.setText(" "); + sinceVersion.setText(" "); + directives.setText(" "); + descriptionArea.setText(""); + } +} diff --git a/src/com/gitblit/client/SettingsModel.java b/src/com/gitblit/client/SettingsModel.java index 2c7bff8..af3c1b6 100644 --- a/src/com/gitblit/client/SettingsModel.java +++ b/src/com/gitblit/client/SettingsModel.java @@ -18,13 +18,14 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.swing.table.AbstractTableModel; -import com.gitblit.IStoredSettings; +import com.gitblit.models.SettingModel; /** - * Table model of IStoredSettings. + * Table model of Map<String, SettingModel>. * * @author James Moger * @@ -33,7 +34,7 @@ private static final long serialVersionUID = 1L; - IStoredSettings settings; + Map<String, SettingModel> settings; List<String> keys; @@ -50,16 +51,16 @@ this(null); } - public SettingsModel(IStoredSettings settings) { + public SettingsModel(Map<String, SettingModel> settings) { setSettings(settings); } - public void setSettings(IStoredSettings settings) { + public void setSettings(Map<String, SettingModel> settings) { this.settings = settings; if (settings == null) { keys = new ArrayList<String>(); } else { - keys = new ArrayList<String>(settings.getAllKeys(null)); + keys = new ArrayList<String>(settings.keySet()); Collections.sort(keys); } } @@ -92,19 +93,28 @@ * @return the Object.class */ public Class<?> getColumnClass(int columnIndex) { + if (Columns.Value.ordinal() == columnIndex) { + return SettingModel.class; + } return String.class; } @Override public Object getValueAt(int rowIndex, int columnIndex) { String key = keys.get(rowIndex); + SettingModel setting = settings.get(key); Columns col = Columns.values()[columnIndex]; switch (col) { case Name: return key; case Value: - return settings.getString(key, ""); + return setting; } return null; } + + public SettingModel get(int modelRow) { + String key = keys.get(modelRow); + return settings.get(key); + } } diff --git a/src/com/gitblit/models/ServerStatus.java b/src/com/gitblit/models/ServerStatus.java new file mode 100644 index 0000000..b1dc52d --- /dev/null +++ b/src/com/gitblit/models/ServerStatus.java @@ -0,0 +1,69 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.models; + +import java.io.Serializable; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * ServerStatus encapsulates runtime status information about the server + * including the system environment. + * + * @author James Moger + * + */ +public class ServerStatus implements Serializable { + + private static final long serialVersionUID = 1L; + + public final Date bootDate; + + public final long heapSize; + + public final Map<String, String> systemProperties; + + public volatile long heapAllocated; + + public volatile long heapFree; + + public ServerStatus() { + bootDate = new Date(); + + heapSize = Runtime.getRuntime().maxMemory(); + + systemProperties = new HashMap<String, String>(); + put("file.encoding"); + put("java.home"); + put("java.io.tmpdir"); + put("java.runtime.name"); + put("java.runtime.version"); + put("java.vendor"); + put("java.version"); + put("java.vm.info"); + put("java.vm.name"); + put("java.vm.vendor"); + put("java.vm.version"); + put("os.arch"); + put("os.name"); + put("os.version"); + } + + private void put(String key) { + systemProperties.put(key, System.getProperty(key)); + } +} diff --git a/src/com/gitblit/models/SettingModel.java b/src/com/gitblit/models/SettingModel.java new file mode 100644 index 0000000..8a5c0c6 --- /dev/null +++ b/src/com/gitblit/models/SettingModel.java @@ -0,0 +1,144 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.models; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import com.gitblit.utils.StringUtils; + +/** + * SettingModel represents a setting and all its metadata: name, current value, + * default value, description, and directives. + * + * @author James Moger + */ +public class SettingModel implements Serializable { + + public static final String SPACE_DELIMITED = "SPACE-DELIMITED"; + + public static final String CASE_SENSITIVE = "CASE-SENSITIVE"; + + public static final String RESTART_REQUIRED = "RESTART REQUIRED"; + + public static final String SINCE = "SINCE"; + + public String name; + public volatile String currentValue; + public String defaultValue; + public String description; + public String since; + public boolean caseSensitive; + public boolean restartRequired; + public boolean spaceDelimited; + + private static final long serialVersionUID = 1L; + + public SettingModel() { + } + + /** + * Returns true if the current value is the default value. + * + * @return true if current value is the default value + */ + public boolean isDefaultValue() { + return (currentValue != null && currentValue.equals(defaultValue)) + || currentValue.trim().length() == 0; + } + + /** + * Returns the boolean value for the currentValue. If the currentValue can + * not be interpreted as a boolean, the defaultValue is returned. + * + * @param defaultValue + * @return key value or defaultValue + */ + public boolean getBoolean(boolean defaultValue) { + if (!StringUtils.isEmpty(currentValue)) { + return Boolean.parseBoolean(currentValue.trim()); + } + return defaultValue; + } + + /** + * Returns the integer value for the currentValue. If the currentValue can + * not be interpreted as an integer, the defaultValue is returned. + * + * @param defaultValue + * @return key value or defaultValue + */ + public int getInteger(int defaultValue) { + try { + if (!StringUtils.isEmpty(currentValue)) { + return Integer.parseInt(currentValue.trim()); + } + } catch (NumberFormatException e) { + } + return defaultValue; + } + + /** + * Returns the char value for currentValue. If the currentValue can not be + * interpreted as a char, the defaultValue is returned. + * + * @param defaultValue + * @return key value or defaultValue + */ + public char getChar(char defaultValue) { + if (!StringUtils.isEmpty(currentValue)) { + return currentValue.trim().charAt(0); + } + return defaultValue; + } + + /** + * Returns the string value for currentValue. If the currentValue is null, + * the defaultValue is returned. + * + * @param defaultValue + * @return key value or defaultValue + */ + public String getString(String defaultValue) { + if (currentValue != null) { + return currentValue.trim(); + } + return defaultValue; + } + + /** + * Returns a list of space-separated strings from the specified key. + * + * @return list of strings + */ + public List<String> getStrings() { + return getStrings(" "); + } + + /** + * Returns a list of strings from the currentValue using the specified + * string separator. + * + * @param separator + * @return list of strings + */ + public List<String> getStrings(String separator) { + List<String> strings = new ArrayList<String>(); + strings = StringUtils.getStringsFromValue(currentValue, separator); + return strings; + } +} diff --git a/src/com/gitblit/utils/RpcUtils.java b/src/com/gitblit/utils/RpcUtils.java index eb28c0f..440dabd 100644 --- a/src/com/gitblit/utils/RpcUtils.java +++ b/src/com/gitblit/utils/RpcUtils.java @@ -21,15 +21,15 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Properties; import com.gitblit.Constants; import com.gitblit.Constants.RpcRequest; -import com.gitblit.IStoredSettings; import com.gitblit.models.FederationModel; import com.gitblit.models.FederationProposal; import com.gitblit.models.FederationSet; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.ServerStatus; +import com.gitblit.models.SettingModel; import com.gitblit.models.UserModel; import com.google.gson.reflect.TypeToken; @@ -57,6 +57,9 @@ }.getType(); private static final Type SETS_TYPE = new TypeToken<Collection<FederationSet>>() { + }.getType(); + + private static final Type SETTINGS_TYPE = new TypeToken<Map<String, SettingModel>>() { }.getType(); /** @@ -338,15 +341,31 @@ * @param serverUrl * @param account * @param password - * @return an IStoredSettings object + * @return an Map<String, SettingModel> object * @throws IOException */ - public static IStoredSettings getSettings(String serverUrl, String account, char[] password) - throws IOException { + public static Map<String, SettingModel> getSettings(String serverUrl, String account, + char[] password) throws IOException { String url = asLink(serverUrl, RpcRequest.LIST_SETTINGS); - Properties props = JsonUtils.retrieveJson(url, Properties.class, account, password); - RpcSettings settings = new RpcSettings(props); + Map<String, SettingModel> settings = JsonUtils.retrieveJson(url, SETTINGS_TYPE, account, + password); return settings; + } + + /** + * Retrieves the server status object. + * + * @param serverUrl + * @param account + * @param password + * @return an ServerStatus object + * @throws IOException + */ + public static ServerStatus getStatus(String serverUrl, String account, char[] password) + throws IOException { + String url = asLink(serverUrl, RpcRequest.LIST_SERVER_STATUS); + ServerStatus status = JsonUtils.retrieveJson(url, ServerStatus.class, account, password); + return status; } /** @@ -368,32 +387,5 @@ String json = JsonUtils.toJsonString(object); int resultCode = JsonUtils.sendJsonString(url, json, account, password); return resultCode == 200; - } - - /** - * Settings implementation that wraps a retrieved properties instance. This - * class is used for RPC communication. - * - * @author James Moger - * - */ - private static class RpcSettings extends IStoredSettings { - - private final Properties properties = new Properties(); - - public RpcSettings(Properties props) { - super(RpcSettings.class); - properties.putAll(props); - } - - @Override - protected Properties read() { - return properties; - } - - @Override - public String toString() { - return "RpcSettings"; - } } } diff --git a/tests/com/gitblit/tests/RpcTests.java b/tests/com/gitblit/tests/RpcTests.java index 450b597..3c2f61f 100644 --- a/tests/com/gitblit/tests/RpcTests.java +++ b/tests/com/gitblit/tests/RpcTests.java @@ -23,11 +23,12 @@ import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.GitBlitException.UnauthorizedException; -import com.gitblit.IStoredSettings; import com.gitblit.models.FederationModel; import com.gitblit.models.FederationProposal; import com.gitblit.models.FederationSet; import com.gitblit.models.RepositoryModel; +import com.gitblit.models.ServerStatus; +import com.gitblit.models.SettingModel; import com.gitblit.models.UserModel; import com.gitblit.utils.RpcUtils; @@ -206,7 +207,12 @@ } public void testSettings() throws Exception { - IStoredSettings settings = RpcUtils.getSettings(url, account, password.toCharArray()); - assertTrue("No settings were retrieved!", settings.getAllKeys(null).size() > 0); + Map<String, SettingModel> 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); } } -- Gitblit v1.9.1