Skip to content

Commit d15aa44

Browse files
committed
Profiler settings improvements
- show Settings by default - check invalid roots/filters - display invalid settings on profiling start
1 parent eb73352 commit d15aa44

File tree

7 files changed

+193
-124
lines changed

7 files changed

+193
-124
lines changed

visualvm/profiler/src/com/sun/tools/visualvm/profiler/ApplicationProfilerView.java

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.sun.tools.visualvm.core.ui.DataSourceView;
3232
import com.sun.tools.visualvm.core.ui.DesktopUtils;
3333
import com.sun.tools.visualvm.core.ui.components.DataViewComponent;
34+
import com.sun.tools.visualvm.core.ui.components.DataViewComponent.DetailsView;
3435
import com.sun.tools.visualvm.profiling.presets.PresetSelector;
3536
import com.sun.tools.visualvm.profiling.presets.ProfilerPresets;
3637
import com.sun.tools.visualvm.uisupport.HTMLLabel;
@@ -79,6 +80,7 @@ final class ApplicationProfilerView extends DataSourceView {
7980
private static final String IMAGE_PATH =
8081
"com/sun/tools/visualvm/profiler/resources/profiler.png"; // NOI18N
8182

83+
private DataViewComponent dvc;
8284
private MasterViewSupport masterViewSupport;
8385
private CPUSettingsSupport cpuSettings;
8486
private MemorySettingsSupport memorySettings;
@@ -140,20 +142,35 @@ private PresetSelector createSelector(Runnable presetSynchronizer, Application a
140142
protected DataViewComponent createComponent() {
141143
Application application = (Application)getDataSource();
142144
ProfilingResultsSupport profilingResultsSupport = new ProfilingResultsSupport();
143-
masterViewSupport = new MasterViewSupport(application, profilingResultsSupport, cpuSettings, memorySettings, jdbcSettings, classSharingBreaksProfiling);
144145

145-
DataViewComponent dvc = new DataViewComponent(
146-
masterViewSupport.getMasterView(),
147-
new DataViewComponent.MasterViewConfiguration(false));
146+
final DetailsView cpuSettingsView = cpuSettings.getDetailsView();
147+
final DetailsView memorySettingsView = memorySettings.getDetailsView();
148+
final DetailsView jdbcSettingsView = jdbcSettings.getDetailsView();
148149

150+
masterViewSupport = new MasterViewSupport(application, profilingResultsSupport, cpuSettings, memorySettings, jdbcSettings, classSharingBreaksProfiling) {
151+
void showCPUSettings() {
152+
if (dvc != null) {
153+
dvc.selectDetailsView(cpuSettingsView);
154+
dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);
155+
}
156+
}
157+
void showMemorySettings() {
158+
if (dvc != null) {
159+
dvc.selectDetailsView(memorySettingsView);
160+
dvc.showDetailsArea(DataViewComponent.TOP_RIGHT);
161+
}
162+
}
163+
};
164+
165+
dvc = new DataViewComponent(masterViewSupport.getMasterView(), new DataViewComponent.MasterViewConfiguration(false));
149166
dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationProfilerView.class, "LBL_Profiling_results"), false), DataViewComponent.TOP_LEFT); // NOI18N
150167
dvc.addDetailsView(profilingResultsSupport.getDetailsView(), DataViewComponent.TOP_LEFT);
151168

152169
dvc.configureDetailsArea(new DataViewComponent.DetailsAreaConfiguration(NbBundle.getMessage(ApplicationProfilerView.class, "LBL_Settings"), true), DataViewComponent.TOP_RIGHT); // NOI18N
153-
dvc.addDetailsView(cpuSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);
154-
dvc.addDetailsView(memorySettings.getDetailsView(), DataViewComponent.TOP_RIGHT);
155-
dvc.addDetailsView(jdbcSettings.getDetailsView(), DataViewComponent.TOP_RIGHT);
156-
dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);
170+
dvc.addDetailsView(cpuSettingsView, DataViewComponent.TOP_RIGHT);
171+
dvc.addDetailsView(memorySettingsView, DataViewComponent.TOP_RIGHT);
172+
dvc.addDetailsView(jdbcSettingsView, DataViewComponent.TOP_RIGHT);
173+
// dvc.hideDetailsArea(DataViewComponent.TOP_RIGHT);
157174

158175
return dvc;
159176
}
@@ -169,7 +186,7 @@ protected void removed() {
169186

170187
// --- General data --------------------------------------------------------
171188

172-
private static class MasterViewSupport extends JPanel implements ProfilingStateListener, DataRemovedListener<Application>, ActionListener, PropertyChangeListener {
189+
private static abstract class MasterViewSupport extends JPanel implements ProfilingStateListener, DataRemovedListener<Application>, ActionListener, PropertyChangeListener {
173190

174191
private Application application;
175192
private ProfilingResultsSupport profilingResultsView;
@@ -215,6 +232,11 @@ public MasterViewSupport(final Application application, ProfilingResultsSupport
215232
}
216233

217234

235+
abstract void showCPUSettings();
236+
237+
abstract void showMemorySettings();
238+
239+
218240
public DataViewComponent.MasterView getMasterView() {
219241
return new DataViewComponent.MasterView(NbBundle.getMessage(ApplicationProfilerView.class, "LBL_Profiler"), null, this); // NOI18N
220242
}
@@ -271,6 +293,7 @@ private void handleCPUProfiling() {
271293
internalChange = true;
272294
cpuButton.setSelected(false);
273295
internalChange = false;
296+
showCPUSettings();
274297
ProfilerDialogs.displayError(NbBundle.getMessage(ApplicationProfilerView.class, "MSG_Incorrect_CPU_settings")); // NOI18N
275298
} else {
276299
cpuSettingsSupport.saveSettings();
@@ -297,19 +320,27 @@ private void handleMemoryProfiling() {
297320
cpuButton.setSelected(false);
298321
jdbcButton.setSelected(false);
299322
internalChange = false;
300-
memorySettingsSupport.saveSettings();
301-
if (NetBeansProfiler.getDefaultNB().getProfilingState() == NetBeansProfiler.PROFILING_RUNNING) {
302-
ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {
303-
public void run() {
304-
NetBeansProfiler.getDefaultNB().modifyCurrentProfiling(memorySettingsSupport.getSettings());
305-
}
306-
});
323+
if (!memorySettingsSupport.settingsValid()) {
324+
internalChange = true;
325+
memoryButton.setSelected(false);
326+
internalChange = false;
327+
showMemorySettings();
328+
ProfilerDialogs.displayError(NbBundle.getMessage(ApplicationProfilerView.class, "MSG_Incorrect_Memory_settings")); // NOI18N
307329
} else {
308-
disableControlButtons();
309-
ProfilerSupport.getInstance().setProfiledApplication(application);
310-
ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {
311-
public void run() { startProfiling(application, memorySettingsSupport.getSettings()); }
312-
});
330+
memorySettingsSupport.saveSettings();
331+
if (NetBeansProfiler.getDefaultNB().getProfilingState() == NetBeansProfiler.PROFILING_RUNNING) {
332+
ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {
333+
public void run() {
334+
NetBeansProfiler.getDefaultNB().modifyCurrentProfiling(memorySettingsSupport.getSettings());
335+
}
336+
});
337+
} else {
338+
disableControlButtons();
339+
ProfilerSupport.getInstance().setProfiledApplication(application);
340+
ProfilerUtils.runInProfilerRequestProcessor(new Runnable() {
341+
public void run() { startProfiling(application, memorySettingsSupport.getSettings()); }
342+
});
343+
}
313344
}
314345
}
315346
}

visualvm/profiler/src/com/sun/tools/visualvm/profiler/Bundle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ MSG_Class_Sharing_Nolink=<nobr>https://visualvm.github.io/troubleshooting.html#x
7070

7171
MSG_Incorrect_CPU_settings=Provided CPU settings are invalid.
7272

73+
MSG_Incorrect_Memory_settings=Provided Memory settings are invalid.
74+
7375
LBL_Profile=Profile\:
7476
LBL_Sample=Sample\:
7577

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package com.sun.tools.visualvm.profiling.presets;
27+
28+
import java.util.regex.Pattern;
29+
import org.netbeans.lib.profiler.filters.GenericFilter;
30+
31+
/**
32+
*
33+
* @author Jiri Sedlacek
34+
*/
35+
final class PresetsUtils {
36+
37+
static String normalizeValue(String value) {
38+
String[] values = value.split("\\n"); // NOI18N
39+
StringBuilder normalizedValue = new StringBuilder();
40+
41+
for (int i = 0; i < values.length; i++) {
42+
String filterValue = values[i].trim();
43+
if ((i != (values.length - 1)) && !filterValue.endsWith(",")) // NOI18N
44+
filterValue = filterValue + ","; // NOI18N
45+
normalizedValue.append(filterValue);
46+
}
47+
48+
return normalizedValue.toString();
49+
}
50+
51+
52+
static boolean isValidJavaValue(String normalizedValue, boolean allowEmpty, boolean acceptArrays) {
53+
// check whether empty value is allowed
54+
if (normalizedValue.isEmpty()) return allowEmpty;
55+
56+
String[] values = GenericFilter.values(normalizedValue);
57+
for (String value : values) {
58+
// remove up to two trailing wildcards
59+
boolean hadWildcard = value.endsWith("*"); // NOI18N
60+
if (hadWildcard) value = value.substring(0, value.length() - 1);
61+
if (value.endsWith("*")) value = value.substring(0, value.length() - 1); // NOI18N
62+
63+
if (hadWildcard) {
64+
// wildcards can only be standalone or prefixed by dot
65+
if (!value.isEmpty() && !value.endsWith(".")) return false; // NOI18N
66+
} else if (acceptArrays) {
67+
int len = value.length();
68+
69+
// remove trailing arrays if allowed and not followed by wildcards
70+
while (value.endsWith("[]")) value = value.substring(0, value.length() - 2); // NOI18N
71+
72+
// multiple array marks only allowed when prefixed by Java identifier
73+
if (len - value.length() > 2 && value.isEmpty()) return false;
74+
}
75+
76+
// empty line is allowed
77+
if (value.isEmpty()) continue;
78+
79+
// trailing dot only allowed when followed by wildcards
80+
if (value.endsWith(".")) { // NOI18N
81+
if (!hadWildcard) return false;
82+
value = value.substring(0, value.length() - 1); // NOI18N
83+
}
84+
85+
// check whether the result is a valid Java identifier
86+
if (!isValidJavaIdentifier(value)) return false;
87+
}
88+
89+
return true;
90+
}
91+
92+
93+
private static Pattern JAVA_IDENTIFIER_PATTERN;
94+
private static boolean isValidJavaIdentifier(String identifier) {
95+
if (JAVA_IDENTIFIER_PATTERN == null) {
96+
String ID_PATTERN = "\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*"; // NOI18N
97+
JAVA_IDENTIFIER_PATTERN = Pattern.compile(ID_PATTERN + "(\\." + ID_PATTERN + ")*"); // NOI18N
98+
}
99+
return JAVA_IDENTIFIER_PATTERN.matcher(identifier).matches();
100+
}
101+
102+
}

visualvm/profiling/src/com/sun/tools/visualvm/profiling/presets/ProfilerCPUPanel.java

Lines changed: 16 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,21 @@ public ProfilingSettings getSettings() {
8989
CommonConstants.CPU_INSTR_FULL :
9090
CommonConstants.CPU_INSTR_SAMPLED);
9191

92-
String[] rootsValues = GenericFilter.values(getFlatValues(getRootsValues()));
92+
String[] rootsValues = GenericFilter.values(PresetsUtils.normalizeValue(getRootsValue()));
9393
ClientUtils.SourceCodeSelection[] roots = (rootsValues.length == 1 && rootsValues[0].isEmpty()) ?
9494
new ClientUtils.SourceCodeSelection[0] :
9595
new ClientUtils.SourceCodeSelection[rootsValues.length];
9696
for (int i = 0; i < roots.length; i++)
9797
roots[i] = new ClientUtils.SourceCodeSelection(rootsValues[i], "*", null); // NOI18N
9898
settings.addRootMethods(roots);
9999

100-
String filter = filtersArea.getTextArea().getText();
100+
String filter = getFilterValue();
101101
if (filter.isEmpty() || "*".equals(filter) || "**".equals(filter)) { // NOI18N
102102
settings.setInstrumentationFilter(new JavaTypeFilter());
103103
} else {
104104
int filterType = inclFilterRadioButton.isSelected() ?
105105
JavaTypeFilter.TYPE_INCLUSIVE : JavaTypeFilter.TYPE_EXCLUSIVE;
106-
String filterValue = getFlatValues(getFilterValues());
106+
String filterValue = PresetsUtils.normalizeValue(filter);
107107
settings.setInstrumentationFilter(new JavaTypeFilter(filterValue, filterType));
108108
}
109109

@@ -112,19 +112,6 @@ public ProfilingSettings getSettings() {
112112
return settings;
113113
}
114114

115-
private static String getFlatValues(String[] values) {
116-
StringBuilder convertedValue = new StringBuilder();
117-
118-
for (int i = 0; i < values.length; i++) {
119-
String filterValue = values[i].trim();
120-
if ((i != (values.length - 1)) && !filterValue.endsWith(",")) // NOI18N
121-
filterValue = filterValue + ","; // NOI18N
122-
convertedValue.append(filterValue);
123-
}
124-
125-
return convertedValue.toString();
126-
}
127-
128115

129116
public boolean settingsValid() { return rootsValid && filtersValid; }
130117

@@ -138,15 +125,18 @@ public void loadFromPreset(ProfilerPreset preset) {
138125
exclFilterRadioButton.setSelected(preset.getFilterModeP());
139126
filtersArea.getTextArea().setText(preset.getFilterP());
140127
internalChange = false;
128+
129+
checkRootValidity();
130+
checkFilterValidity();
141131
}
142132

143133
public void saveToPreset(ProfilerPreset preset) {
144134
if (preset == null) return;
145135

146-
preset.setRootsP(rootsArea.getTextArea().getText());
136+
preset.setRootsP(getRootsValue());
147137
// preset.setRunnablesP(runnablesCheckBox.isSelected());
148138
preset.setFilterModeP(exclFilterRadioButton.isSelected());
149-
preset.setFilterP(filtersArea.getTextArea().getText());
139+
preset.setFilterP(getFilterValue());
150140
}
151141

152142
public abstract void settingsChanged();
@@ -165,33 +155,12 @@ private void checkRootValidity() {
165155
}
166156

167157
public boolean isRootValueValid() {
168-
// TODO
169-
String roots = rootsArea.getTextArea().getText().trim();
170-
if (roots.isEmpty() || roots.contains("<") || roots.contains(">")) return false; // NOI18N
171-
172-
return true;
158+
String rootsValue = PresetsUtils.normalizeValue(getRootsValue());
159+
return PresetsUtils.isValidJavaValue(rootsValue, false, false);
173160
}
174161

175-
// private String getRootValue() {
176-
// StringBuilder convertedValue = new StringBuilder();
177-
//
178-
// String[] rootValues = getRootsValues();
179-
//
180-
// for (int i = 0; i < rootValues.length; i++) {
181-
// String filterValue = rootValues[i].trim();
182-
//
183-
// if ((i != (rootValues.length - 1)) && !filterValue.endsWith(",")) { // NOI18N
184-
// filterValue = filterValue + ","; // NOI18N
185-
// }
186-
//
187-
// convertedValue.append(filterValue);
188-
// }
189-
//
190-
// return convertedValue.toString();
191-
// }
192-
193-
private String[] getRootsValues() {
194-
return rootsArea.getTextArea().getText().split("\\n"); // NOI18N
162+
private String getRootsValue() {
163+
return rootsArea.getTextArea().getText().trim();
195164
}
196165

197166
private void checkFilterValidity() {
@@ -202,35 +171,12 @@ private void checkFilterValidity() {
202171
}
203172

204173
public boolean isFilterValueValid() {
205-
// TODO
206-
// String[] filterParts = FilterUtils.getSeparateFilters(getFilterValue());
207-
208-
// for (int i = 0; i < filterParts.length; i++)
209-
// if (!FilterUtils.isValidProfilerFilter(filterParts[i])) return false;
210-
211-
return true;
174+
String filterValue = PresetsUtils.normalizeValue(getFilterValue());
175+
return PresetsUtils.isValidJavaValue(filterValue, true, false);
212176
}
213-
214-
// private String getFilterValue() {
215-
// StringBuilder convertedValue = new StringBuilder();
216-
//
217-
// String[] filterValues = getFilterValues();
218-
//
219-
// for (int i = 0; i < filterValues.length; i++) {
220-
// String filterValue = filterValues[i].trim();
221-
//
222-
// if ((i != (filterValues.length - 1)) && !filterValue.endsWith(",")) { // NOI18N
223-
// filterValue = filterValue + ", "; // NOI18N
224-
// }
225-
//
226-
// convertedValue.append(filterValue);
227-
// }
228-
//
229-
// return convertedValue.toString();
230-
// }
231177

232-
private String[] getFilterValues() {
233-
return filtersArea.getTextArea().getText().split("\\n"); // NOI18N
178+
private String getFilterValue() {
179+
return filtersArea.getTextArea().getText().trim();
234180
}
235181

236182

0 commit comments

Comments
 (0)