Skip to content

Commit 330802a

Browse files
authored
add user settings (microsoft#94)
* add user settings * add debug settings feature * update java doc for json format of configuration. * update setting names * merge log level together with other settings * add private ctor for DebugSettings to avoid create DebugSettings instance * using JsonUtil to fill settings. * merge log level together with other settings * rollback useless code changes changed by code formater * rollback useless code changes changed by code formater
1 parent 55f571d commit 330802a

10 files changed

Lines changed: 183 additions & 62 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.core;
13+
14+
import java.util.logging.Logger;
15+
16+
import com.google.gson.JsonSyntaxException;
17+
import com.microsoft.java.debug.core.protocol.JsonUtils;
18+
19+
public final class DebugSettings {
20+
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
21+
private static DebugSettings current = new DebugSettings();
22+
23+
public int maxStringLength = 0;
24+
public boolean showStaticVariables = true;
25+
public boolean showQualifiedNames = false;
26+
public boolean showHex = false;
27+
public String logLevel;
28+
29+
public static DebugSettings getCurrent() {
30+
return current;
31+
}
32+
33+
/**
34+
* Update current settings with the values in the parameter.
35+
*
36+
* @param jsonSettings
37+
* the new settings represents in json format.
38+
*/
39+
public void updateSettings(String jsonSettings) {
40+
try {
41+
current = JsonUtils.fromJson(jsonSettings, DebugSettings.class);
42+
} catch (JsonSyntaxException ex) {
43+
logger.severe(String.format("Invalid json for debugSettings: %s, %s", jsonSettings, ex.getMessage()));
44+
}
45+
}
46+
47+
private DebugSettings() {
48+
49+
}
50+
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/formatter/StringObjectFormatter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
public class StringObjectFormatter extends ObjectFormatter implements IValueFormatter {
2828
public static final String MAX_STRING_LENGTH_OPTION = "max_string_length";
29-
private static final int DEFAULT_MAX_STRING_LENGTH = 100;
29+
private static final int DEFAULT_MAX_STRING_LENGTH = 0;
3030
private static final String QUOTE_STRING = "\"";
3131

3232
public StringObjectFormatter() {
@@ -42,9 +42,9 @@ public Map<String, Object> getDefaultOptions() {
4242

4343
@Override
4444
public String toString(Object value, Map<String, Object> options) {
45+
int maxLength = getMaxStringLength(options);
4546
return String.format("\"%s\" %s",
46-
StringUtils.abbreviate(((StringReference) value).value(),
47-
getMaxStringLength(options)),
47+
maxLength > 0 ? StringUtils.abbreviate(((StringReference) value).value(), maxLength) : ((StringReference) value).value(),
4848
getIdPostfix((ObjectReference) value, options));
4949
}
5050

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@
1919

2020
import org.apache.commons.lang3.StringUtils;
2121

22+
import com.microsoft.java.debug.core.DebugSettings;
2223
import com.microsoft.java.debug.core.adapter.AdapterUtils;
2324
import com.microsoft.java.debug.core.adapter.ErrorCode;
2425
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
2526
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
26-
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum;
27-
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatter;
28-
import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter;
2927
import com.microsoft.java.debug.core.adapter.variables.JdiObjectProxy;
3028
import com.microsoft.java.debug.core.adapter.variables.Variable;
3129
import com.microsoft.java.debug.core.adapter.variables.VariableProxy;
@@ -61,18 +59,10 @@ public void handle(Command command, Arguments arguments, Response response, IDeb
6159
return;
6260
}
6361

64-
// This should be false by default(currently true for test).
65-
// User will need to explicitly turn it on by configuring launch.json
66-
final boolean showStaticVariables = true;
67-
// TODO: when vscode protocol support customize settings of value format, showFullyQualifiedNames should be one of the options.
68-
boolean showFullyQualifiedNames = true;
62+
final boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables;
63+
6964
Map<String, Object> options = context.getVariableFormatter().getDefaultOptions();
70-
if (evalArguments.format != null && evalArguments.format.hex) {
71-
options.put(NumericFormatter.NUMERIC_FORMAT_OPTION, NumericFormatEnum.HEX);
72-
}
73-
if (showFullyQualifiedNames) {
74-
options.put(SimpleTypeFormatter.QUALIFIED_CLASS_NAME_OPTION, showFullyQualifiedNames);
75-
}
65+
VariableUtils.applyFormatterOptions(options, evalArguments.format != null && evalArguments.format.hex);
7666
String expression = evalArguments.expression;
7767

7868
if (StringUtils.isBlank(expression)) {
@@ -174,7 +164,7 @@ public void handle(Command command, Arguments arguments, Response response, IDeb
174164
if (currentValue instanceof ObjectReference && VariableUtils.hasChildren(currentValue, showStaticVariables)) {
175165
// save the evaluated value in object pool, because like java.lang.String, the evaluated object will have sub structures
176166
// we need to set up the id map.
177-
VariableProxy varProxy = new VariableProxy(thread.uniqueID(), "Local", (ObjectReference) currentValue);
167+
VariableProxy varProxy = new VariableProxy(thread.uniqueID(), "Local", currentValue);
178168
referenceId = context.getRecyclableIdPool().addObject(thread.uniqueID(), varProxy);
179169
}
180170
int indexedVariables = 0;

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@
2121
import java.util.Set;
2222
import java.util.stream.Collectors;
2323

24+
import com.microsoft.java.debug.core.DebugSettings;
2425
import com.microsoft.java.debug.core.adapter.AdapterUtils;
2526
import com.microsoft.java.debug.core.adapter.ErrorCode;
2627
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
2728
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
28-
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum;
29-
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatter;
30-
import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter;
3129
import com.microsoft.java.debug.core.adapter.variables.IVariableFormatter;
3230
import com.microsoft.java.debug.core.adapter.variables.Variable;
3331
import com.microsoft.java.debug.core.adapter.variables.VariableProxy;
@@ -57,18 +55,11 @@ public void handle(Command command, Arguments arguments, Response response, IDeb
5755
IVariableFormatter variableFormatter = context.getVariableFormatter();
5856
VariablesArguments varArgs = (VariablesArguments) arguments;
5957

58+
59+
boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables;
60+
6061
Map<String, Object> options = variableFormatter.getDefaultOptions();
61-
// This should be false by default(currently true for test).
62-
// User will need to explicitly turn it on by configuring launch.json
63-
boolean showStaticVariables = true;
64-
// TODO: When vscode protocol support customize settings of value format, showFullyQualifiedNames should be one of the options.
65-
boolean showFullyQualifiedNames = true;
66-
if (varArgs.format != null && varArgs.format.hex) {
67-
options.put(NumericFormatter.NUMERIC_FORMAT_OPTION, NumericFormatEnum.HEX);
68-
}
69-
if (showFullyQualifiedNames) {
70-
options.put(SimpleTypeFormatter.QUALIFIED_CLASS_NAME_OPTION, showFullyQualifiedNames);
71-
}
62+
VariableUtils.applyFormatterOptions(options, varArgs.format != null && varArgs.format.hex);
7263

7364
List<Types.Variable> list = new ArrayList<>();
7465
Object container = context.getRecyclableIdPool().getObjectById(varArgs.variablesReference);

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@
1313

1414
import java.util.ArrayList;
1515
import java.util.List;
16+
import java.util.Map;
1617
import java.util.logging.Level;
1718
import java.util.logging.Logger;
1819
import java.util.stream.Collectors;
1920

2021
import com.microsoft.java.debug.core.Configuration;
22+
import com.microsoft.java.debug.core.DebugSettings;
23+
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum;
24+
import com.microsoft.java.debug.core.adapter.formatter.NumericFormatter;
25+
import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter;
26+
import com.microsoft.java.debug.core.adapter.formatter.StringObjectFormatter;
2127
import com.sun.jdi.AbsentInformationException;
2228
import com.sun.jdi.ArrayReference;
2329
import com.sun.jdi.ArrayType;
@@ -222,6 +228,28 @@ public static List<Variable> listStaticVariables(StackFrame stackFrame) {
222228
return res;
223229
}
224230

231+
/**
232+
* Apply the display options for variable formatter, it is used in variable and evaluate requests, controls the display content in
233+
* variable view/debug console.
234+
*
235+
* @param defaultOptions the initial options for adding options from user settings
236+
* @param hexInArgument when request sent by vscode declare hex format explicitly, settings this parameter true to override value in DebugSettings class.
237+
*/
238+
public static void applyFormatterOptions(Map<String, Object> defaultOptions, boolean hexInArgument) {
239+
Map<String, Object> options = defaultOptions;
240+
boolean showFullyQualifiedNames = DebugSettings.getCurrent().showQualifiedNames;
241+
if (hexInArgument || DebugSettings.getCurrent().showHex) {
242+
options.put(NumericFormatter.NUMERIC_FORMAT_OPTION, NumericFormatEnum.HEX);
243+
}
244+
if (showFullyQualifiedNames) {
245+
options.put(SimpleTypeFormatter.QUALIFIED_CLASS_NAME_OPTION, true);
246+
}
247+
248+
if (DebugSettings.getCurrent().maxStringLength > 0) {
249+
options.put(StringObjectFormatter.MAX_STRING_LENGTH_OPTION, DebugSettings.getCurrent().maxStringLength);
250+
}
251+
}
252+
225253
private VariableUtils() {
226254

227255
}

com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/adapter/formatter/StringObjectFormatterTest.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@
1111

1212
package com.microsoft.java.debug.core.adapter.formatter;
1313

14+
import static com.microsoft.java.debug.core.adapter.formatter.StringObjectFormatter.MAX_STRING_LENGTH_OPTION;
15+
import static junit.framework.TestCase.assertNull;
16+
import static org.junit.Assert.assertEquals;
17+
import static org.junit.Assert.assertFalse;
18+
import static org.junit.Assert.assertNotNull;
19+
import static org.junit.Assert.assertTrue;
20+
1421
import java.util.HashMap;
1522
import java.util.Map;
1623

@@ -23,15 +30,9 @@
2330
import com.sun.jdi.StringReference;
2431
import com.sun.jdi.Value;
2532

26-
import static junit.framework.TestCase.assertNull;
27-
import static com.microsoft.java.debug.core.adapter.formatter.StringObjectFormatter.MAX_STRING_LENGTH_OPTION;
28-
import static org.junit.Assert.assertEquals;
29-
import static org.junit.Assert.assertFalse;
30-
import static org.junit.Assert.assertNotNull;
31-
import static org.junit.Assert.assertTrue;
32-
3333
public class StringObjectFormatterTest extends BaseJdiTestCase {
3434
protected StringObjectFormatter formatter;
35+
@Override
3536
@Before
3637
public void setup() throws Exception {
3738
super.setup();
@@ -72,8 +73,8 @@ public void testToString() throws Exception {
7273
assertEquals("Should be able to format string type.", String.format("\"st...\" (id=%d)",
7374
((ObjectReference) string).uniqueID()),
7475
formatter.toString(string, options));
75-
assertTrue("Should be able to trim long string..",
76-
formatter.toString(string, new HashMap<>()).contains("aaaaaaaaaaaaaaaaaaaaaaa...\""));
76+
assertTrue("Should not trim long string by default",
77+
formatter.toString(string, new HashMap<>()).contains(((StringReference) string).value()));
7778
}
7879

7980
@Test

com.microsoft.java.debug.plugin/plugin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<command id="vscode.java.resolveMainClass"/>
99
<command id="vscode.java.buildWorkspace"/>
1010
<command id="vscode.java.fetchUsageData"/>
11-
<command id="vscode.java.configLogLevel"/>
11+
<command id="vscode.java.updateDebugSettings"/>
1212
</delegateCommandHandler>
1313
</extension>
1414
</plugin>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2017 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.plugin.internal;
13+
14+
import java.util.List;
15+
import java.util.logging.Logger;
16+
17+
import org.apache.commons.lang3.StringUtils;
18+
19+
import com.google.gson.JsonSyntaxException;
20+
import com.microsoft.java.debug.core.Configuration;
21+
import com.microsoft.java.debug.core.DebugSettings;
22+
import com.microsoft.java.debug.core.protocol.JsonUtils;
23+
24+
public final class DebugSettingUtils {
25+
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
26+
27+
/**
28+
* Configure setting for java debugger.
29+
*
30+
* @param arguments
31+
* the arguments for the settings, the format is json,
32+
* eg:{"showHex":true,"showStaticVariables":true,"maxStringLength":100}
33+
*/
34+
public static Object configDebugSettings(List<Object> arguments) {
35+
if (arguments != null && arguments.size() > 0) {
36+
arguments.forEach(arg -> {
37+
if (arg instanceof String) {
38+
String jsonStr = (String) arg;
39+
40+
try {
41+
DebugSettings.getCurrent().updateSettings(jsonStr);
42+
DebugSettings.getCurrent().logLevel = LogUtils.configLogLevel(DebugSettings.getCurrent().logLevel);
43+
} catch (JsonSyntaxException ex) {
44+
logger.severe(String.format("Parameters for userSettings must be a valid json: %s", String.valueOf(arg)));
45+
}
46+
47+
} else {
48+
logger.severe(String.format("Parameters for userSettings must be json string: %s", String.valueOf(arg)));
49+
}
50+
});
51+
52+
} else {
53+
logger.severe(String.format("Invalid parameters for debugSettings: %s", StringUtils.join(arguments)));
54+
}
55+
return JsonUtils.toJson(DebugSettings.getCurrent());
56+
}
57+
58+
/**
59+
* Private constructor to prevent creating instance of this class.
60+
*/
61+
private DebugSettingUtils() {
62+
63+
}
64+
}

com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaDebugDelegateCommandHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class JavaDebugDelegateCommandHandler implements IDelegateCommandHandler
3030

3131
public static String BUILD_WORKSPACE = "vscode.java.buildWorkspace";
3232

33-
public static String CONFIG_LOG_LEVEL = "vscode.java.configLogLevel";
33+
public static String UPDATE_DEBUG_SETTINGS = "vscode.java.updateDebugSettings";
3434

3535
@Override
3636
public Object executeCommand(String commandId, List<Object> arguments, IProgressMonitor progress) throws Exception {
@@ -48,8 +48,8 @@ public Object executeCommand(String commandId, List<Object> arguments, IProgress
4848
// TODO
4949
} else if (FETCH_USER_DATA.equals(commandId)) {
5050
return UsageDataStore.getInstance().fetchAll();
51-
} else if (CONFIG_LOG_LEVEL.equals(commandId)) {
52-
return LogUtils.configLogLevel(arguments);
51+
} else if (UPDATE_DEBUG_SETTINGS.equals(commandId)) {
52+
return DebugSettingUtils.configDebugSettings(arguments);
5353
}
5454

5555
throw new UnsupportedOperationException(String.format("Java debug plugin doesn't support the command '%s'.", commandId));

com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/LogUtils.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,9 @@
1111

1212
package com.microsoft.java.debug.plugin.internal;
1313

14-
import java.util.List;
1514
import java.util.logging.Level;
1615
import java.util.logging.Logger;
1716

18-
import org.apache.commons.lang3.StringUtils;
19-
2017
import com.microsoft.java.debug.core.Configuration;
2118

2219
public final class LogUtils {
@@ -37,22 +34,22 @@ public static void initialize(Level level) {
3734

3835
/**
3936
* Configure log level setting for java debugger.
40-
* @param arguments the first element of the arguments should be the String representation of level(info, fine, warning..).
37+
*
38+
* @param logLevel
39+
* the String representation of level(info, fine, warning..).
40+
* @return the updated log level
4141
*/
42-
public static Object configLogLevel(List<Object> arguments) {
43-
if (arguments != null && arguments.size() == 1 && arguments.get(0) instanceof String) {
44-
try {
45-
logger.setLevel(Level.parse((String) arguments.get(0)));
46-
logger.info(String.format("Set log level to : %s", arguments.get(0)));
47-
return logger.getLevel().toString();
48-
} catch (IllegalArgumentException e) {
49-
logger.severe(String.format("Invalid log level: %s", arguments.get(0)));
50-
}
51-
52-
} else {
53-
logger.severe(String.format("Invalid parameters for configLogLevel: %s", StringUtils.join(arguments)));
42+
public static String configLogLevel(Object logLevel) {
43+
try {
44+
logger.setLevel(Level.parse((String) logLevel));
45+
logger.info(String.format("Set log level to : %s", logLevel));
46+
} catch (IllegalArgumentException e) {
47+
logger.severe(String.format("Invalid log level: %s", logLevel));
48+
} catch (ClassCastException e) {
49+
logger.severe("logLevel should be a string.");
5450
}
55-
return null;
51+
52+
return logger.getLevel().toString();
5653
}
5754

5855
}

0 commit comments

Comments
 (0)